Twilio Functions - SMS masking - node.js

Hello I am quite new to Twilio, but I have tried to look up how to answer this question. I would like to use Twilio Functions to solve my problem. I was wondering if it is possible for two people to send SMS messages to each other without revealing either of their numbers.
I was hoping to do this with only one new number per pair.
I imagined it would be through a conditional statement, where person X sends a message to the twilio number and person Y receives it, and vice versa. I assume this cannot be done with the twiML bins because of this conditional statement.
Thanks for your attention.

Twilio developer evangelist here.
You could absolutely do this with Twilio Functions. Here's a simple example of using a number to mask SMS messages between two callers.
class NumberMapping {
constructor() {
this.mapping = {};
}
addMaskedPair(numberA, numberB, twilioNumber) {
if (!this.mapping[twilioNumber]) {
this.mapping[twilioNumber] = {};
}
this.mapping[twilioNumber][numberA] = numberB;
this.mapping[twilioNumber][numberB] = numberA;
}
findNumber(from, to) {
const numberPairs = this.mapping[to];
if (!numberPairs) { return undefined; }
return numberPairs[from];
}
}
const numberMapping = new NumberMapping();
numberMapping.addMaskedPair('+1234567890', '+1098765432', '+1203948576');
exports.handler = function(context, event, callback) {
const to = numberMapping.findNumber(event.From, event.To);
if (typeof to !== 'undefined') {
const response = new Twilio.twiml.MessagingResponse();
response.message({ from: event.To, to: to }, event.Body);
callback(null, response);
} else {
callback(new Error(`Number mapping couldn't be found for sender ${event.From} and Twilio number ${event.To}.`));
}
};
The idea is that you create a NumberMapping object that maps between the two external numbers and your Twilio number. You add your mappings using:
numberMapping.addMaskedPair(firstNumber, secondNumber, twilioNumber);
and then when you need to retrieve the other number in a pair you can call
numberMapping.findNumber(number, twilioNumber);
The rest is just the function to return TwiML.
Note, you will only need as many Twilio numbers as there are relationships of the number that has the maximum set of relationships.
Let me know if that helps at all.

You need to purchase a number from twilio, then use node JS code to send and receive sms with it. You can also send voice messages too. The thing with twilio is that when you receive messages, twilio saves it to its website so you have to go to website and check it explicitly with your account.
You can create account and receive messages with this link
Here is some tutorial on how to send messages, you have to choose node.JS option.

Related

Using the Twilio API, how can I check if a number is in use by a service?

I am trying to create a new messaging service using the Node.js twilio sdk. To do so, I have devised the following workflow.
I've created a new service like so.
client.messaging.v1.services.create({
friendlyName: 'test service,
inboundRequestUrl: 'https://someUrl.com',
inboundMethod: 'POST',
usecase: 'discussion'
})
I list all the numbers I own like so:
client.incomingPhoneNumbers.list()
I assign a number to my service like so (where the serviceSid is the sid of the service created in step 1 and the phoneNumberSid is the sid of one of phone numbers returned in step 2):
client.messaging.v1.services(<serviceSid>)
.phoneNumbers
.create({ phoneNumberSid: <phoneNumberSid> })
I am happy with this workflow, with the exception of one problem. You cannot assign the same number to two different messaging services, so I need to make sure the phone number whose sid I pass into step 3, doesn't already have a service. The problem is that the response I get back from step 2 doesn't tell me whether the numbers are used by another service.
All of this to say, can anyone suggest some way to modify this workflow to be more robust? Ideally, is there some way I can tell from step 2 whether or not a number is already being used by a service, so I know not to pass it in to step 3?
Thanks
Yes, there is a way to do this. To be honest, it's not very nice, but you can iterate over all messages services and test if your phone number (SID) belongs to a mapping of one of the services and then remove this mapping. Once removed, you can assign the phone number to any other messaging service.
async function unbindPhoneFromMessagingServices(phoneNumberSid) {
const allServices = await client.messaging.v1.services.list();
await Promise.all(
allServices.map(async (service) => {
const mapping = client.messaging.v1
.services(service.sid)
.phoneNumbers(phoneNumberSid);
try {
await mapping.fetch();
} catch (e) {
const RESOURCE_NOT_FOUND = e.code === 20404;
if (RESOURCE_NOT_FOUND) {
return;
}
throw e;
}
await mapping.remove();
console.log(
`The phone number was decoupled from messaging service ${service.sid}.`
);
})
);
}
PS: This snippet is taken from one of my repositories. Feel free to check out the complete code on GitHub.

How change friendly name notify twilio sms

I am having some problems, I want to change the name of the sender. I mean, it is possible to assign an Alphanumeric Sender ID, I reviewed the documentation and followed the guidelines, in the response of the twilio api the name goes but when in the messages I receive it sends them to the same number. I know that it is not something due to the regulations of the country because according to the twilio documentation, it is possible. (https://support.twilio.com/hc/en-us/articles/223133767-International-support-for-Alphanumeric-Sender-ID) What is happening? How can I fix? Do I have to do any configuration?
How I want the sender ID to be seen
As I receive the sender ID
UPDATING QUESTION
Ok, the way I have structured the code is as follows:
I am working on a nodejs project, I need to send a message to multiple phone numbers so in order to do it I used the SMS notification service offered by Twilio, this is the method that was created:
async sendSMSAsNotify(req: Request, res: Response) {
try {
console.log("req.body:", req.body);
let messageBody = req.body.body;
console.log(messageBody);
let numberList = req.body.toBinding;
let extractBody = messageBody.replace(/<[^>]+>/g, '');
console.log(extractBody);
var decodedStripedHtml = he.decode(extractBody);
//console.log(decodedStripedHtml);
//console.log(`Body: ${messageBody}`);
var numbers = [];
for (let i = 0; i < numberList.length; i++) {
numbers.push(
JSON.stringify({
binding_type: "sms",
address: numberList[i],
})
);
}
const notificationOpts = {
toBinding: numbers,
body: decodedStripedHtml,
title: 'MyCompany'
};
// console.log("numbers:", notificationOpts.toBinding);
// console.log("body", notificationOpts.body);
const response = await this.client.notify
.services(process.env.SERVICE_SID_NTF)
.notifications.create(notificationOpts);
console.log('response', response);
res.json({
msg: `Message sent successfully! ${response}`,
});
} catch (e) {
throw new HttpException(HttpErrors.NOT_FOUND_ERROR, HttpStatus.NOT_FOUND);
}
}
The sendSMSAsNotify() method works great, I can send the same SMS to multiple numbers. But now what I want to achieve is that every message I send shows the sender id. I didn't find how to do it in the documentation of the SMS notification service, so I tried to change it and use a very simple method to send SMS via twilio to a single number just for testing.
async sendSMS(sms: SMSDto) {
try {
return await this.client.messages.create({
body: sms.message,
from: 'MyCompany',
to: sms.number,
});
} catch (e) {
return e
}
}
But in neither of the two methods in which I tried to change the sender identification it did not allow me and that is what brings me here, I really need help, it is a requirement that I need to fulfill and I cannot find a way to help me.
First up, while the list of countries that support alphanumeric sender IDs does contain Honduras there are further guidelines for SMS in Honduras that say:
Dynamic Alphanumeric Sender IDs are not fully supported for Honduras mobile operators. Sender IDs may be overwritten with a local long code or short code outside the Twilio platform.
So, even if you set everything up as I am about to explain, it is still possible that your sender ID may be overwritten with a local long code or short code and that Twilio is unable to do anything about that.
That being said, here's how to set up for alphanumeric sender IDs.
Since you are using Notify to send the messages, you will have set up a Messaging Service to use with Notify.
The Messaging Service controls how the SMS messages are sent out from Notify, from a pool of numbers. That pool can also contain your alphanumeric sender ID
So, to send from an alphanumeric sender ID you need to go to your Sender Pool within your Messaging Service and add an alpha sender.
Once you have the alpha sender set in your Messaging Service's pool, it will be used to send your messages out. You can even remove any long code numbers you have in the pool, if you do not plan to use them, though they are useful to fallback to if you do send to a country that doesn't support alphanumeric sender IDs.
Is it possible that you are in a country that does not support alphanumeric sender IDs and that Twilio falls back on a short code then?
PS: It would be helpful if you could add a code snippet, that shows the code you run, to your question.

Gmail API get messages where there are contacts included in the CC

I'm trying to get all the messages where:
I cced someone
Someone has cced somebody to a message inbound to me.
I looked in the advanced search operators for some guides, but all I can see is specifying a contact to a cc: search operator, reference.
There's really no docs for searching all messages where there are someone who's being cced to a message. Be it SENT or INBOX
It would be good if someone can provide an answer to this.
Issue:
You want to list all messages where there Cc header is populated.
There's no way to directly filter out by whether any cc is present, just for a certain email address (i.e. cc:my_user#my_domain.com). That's the case for the API as well as the UI.
Solution:
In that case, I'd suggest the following worflow:
Call users.messages.list to list all messages in your mailbox. You'll have to handle pagination at this point, if you want to retrieve all messages, using pageToken and nextPageToken.
For each message id, call users.messages.get to get the corresponding message (only id and threadId are returned from list).
Filter out messages that don't have the Cc header.
Code sample:
For example, in Apps Script you could do something like this (pagination is not implemented in this sample):
function getCcMessages() {
const userId = "me";
const { messages } = Gmail.Users.Messages.list(userId);
const messageIds = messages.map(m => m["id"]);
const optionalArgs = {
format: "METADATA",
metadataHeaders: "Cc"
}
const ccMessages = messageIds.map(id => {
const message = Gmail.Users.Messages.get(userId, id, optionalArgs);
return message;
}).filter(m => {
const headers = m["payload"]["headers"];
return headers;
});
return ccMessages;
}

Sending Hundreds of SMS With Different Numbers with Twilio Caused Duplicate Messages to be Sent

I have a list of about 470 numbers with different messaging I would like to send SMS to. I'm currently using Firebase Cloud Functions as my backend. Everything seemed to work perfectly locally without sending duplicate SMS to about 5 different test numbers.
By using the code below with the 470 numbers, each number got the same SMS 3-4 times each. I don't know if the issue is with Firebase Cloud Functions or not.
The concept is to send a SMS with Twilio and if it's a success. I use Firebase Firestore to store the message in a database. I'm trying to prevent Twilio from sending duplicate SMS to the same number with the same message.
Sample Code from Client:
textMessages[
{phoneNumber: "1111111111", message: "Test message 1 ", campaign: "Test Campaign"},
{phoneNumber: "2222222222", message: "Test message 2", campaign: "Test Campaign"},
{phoneNumber: "3333333333", message: "Test message 3", campaign: "Test Campaign"}]
exports.bulkTextWeb = functions.https.onCall(async (data) => {
const records = data.textMessages;
for (let i = 0, j = records.length; i < j; i++) {
const { phoneNumber, message, campaign } = records[i];
var msgFrom = twilio_number;
var msgTo = phoneNumber;
var msgBody = message;
await client.messages.create({
to: '1' + phoneNumber,
from: twilio_number,
body: message
})
.then(async message => {
if (message.status === 'queued' || message.status === 'sent' || message.status === 'delivered') {
// Check if campaign already exist
let docRef = await db.collection('campaigns')
.where('campaigns', 'array-contains', campaign).get()
.then(snapshot => {
// If there no campaign, add it to Firestore.
if (snapshot.empty) {
addCampaign(campaign);
}
// Add new message to Firestore
addNewMessage(msgFrom, msgTo, msgBody, campaign);
})
}
})
if (i === (j - 1)) {
// Return back to the client when all messages are sent
return { messages: 'Sent' }
}
}
})
In my opinion the amount of code provided in the question is just fine, in fact it let me remember having the same problem some time ago with a Node.js application.
The problem is not at Twilio.
You send one message via Twilio with one call of client.messages.create(). Since the same message is sent multiple times it's clear that client.messages.create() is called multiple times and it's called multiple times because of async/await.
I solved the problem by getting rid of async/await and using recursion to send the messages one after another.
You can see some code using recursion in answers I gave
here:
twillio multiple numbers whatsaap
and here: Twilio Functions Error 20429 - Too many requests multiple sms messages
(I suggest to also read the question and Phil's answer too).

Get user join / leave events retroactively from Channels

I'm trying to do some analytics on average response time from some of our users on Twilio Chat.
I'm iterating through my channels, and I'm able to pull the info about messages, so I can compare times a message went un-responded to. However, I can't determine which users were in the channel at that time.
Is there anything on the channel that would give me historic member data? Who was in the channel? The channel.messages().list() method is only giving me the text of the messages sent to the channel and who it was by, but the user who may have been in a channel to respond changes throughout a channel's life time.
This is on the backend using the node.js SDK. note: This isn't a complete implementation for what I'm trying to do, but taking it in steps to get access to the information I'd need to do this. Once I have these messages and know which users are supposed to be in a channel at a given time, I can do the analytics to see how long it took for the users I am looking for to respond.
var fs = require('fs');
const Twilio = require('twilio');
const client = new Twilio(env.TWILIO_ACCOUNT_SID, env.TWILIO_AUTH);
const service = client.chat.services(env.TWILIO_IPM_SERVICE_SID);
async function getChatMessages() {
const fileName = 'fileName.csv';
const getLine = message => {
return `${message.channelSid},${message.sid},${message.dateCreated},${message.from},${message.type},${message.body}\n`;
}
const writeToFile = message => { fs.appendFileSync(fileName, getLine(message)); };
const headerLine = `channelSid,messageSid,dateCreated,author,type,body`;
fs.writeFileSync(fileName, headerLine);
await service.channels.each(
async (channel, done) => {
i++;
let channelSid = channel.sid;
if( channel.messagesCount == 0 ) return;
try {
await channel.messages().list({limit:1000, order:"asc"}).then(
messages => {
messages.forEach( writeToFile );
}
);
} catch(e) {
console.log(`There was an error getting messages for ${channelSid}: ${e.toString()}`);
}
if( i >= max ) done();
}
);
}
I'm beginning to be resigned to the fact that maybe this would only have been possible to track had I set up the proper event listeners / webhooks to begin with. If that's the case, I'd like to know so I can get that set up. But, if there's any endpoint I can reach out to and see who was joining / leaving a channel, that would be ideal for now.
The answer is that unfortunately you can not get this data retroactively. Twilio offers a webhooks API for chat which you can use to track this data yourself as it happens, but if you don't capture the events, you do not get access to them again.

Resources