Why do I get message-count = 3 from nexmo send SMS callback? - vonage

I send SMS using Node.js like this:
const Nexmo = require('nexmo');
const nexmo = new Nexmo({
apiKey: process.env.NEXMO_API_KEY,
apiSecret: process.env.NEXMO_API_SECRET
});
const opts = {
'type': 'unicode'
};
function sendSMS(to, content) {
nexmo.message.sendSms('qwe, to, content, opts, (err, data) => {
if (err) return console.error(err);
console.log('Data: ', data);
})
}
After in callback data, I'm getting the response like this:
{
"message-count":"3",
"messages":[
{
"to":"380967547714",
"message-id":"0C000000E412D0DB",
"status":"0",
"remaining-balance":"238.91280000",
"message-price":"0.07300000",
"network":"25503"
},
{
"to":"380967547714",
"message-id":"0C000000E412D0DC",
"status":"0",
"remaining-balance":"238.91280000",
"message-price":"0.07300000",
"network":"25503"
},
{
"to":"380967547714",
"message-id":"0C000000E412D0DD",
"status":"0",
"remaining-balance":"238.91280000",
"message-price":"0.07300000",
"network":"25503"
}
]
}
I've got the reasonable question: why do I get "message-count": 3?
It turns out that I get 3 webhook. Is it should work like this?

I can see that you are sending Unicode messages. Maximum length allowed for Unicode content is 70 characters, whilst "normal" text messages will allow up to 160 characters.
When a single SMS body exceeds 70 characters, the SMS will be split into multiple parts and then will be reconstructed at the handset level.
That is why you are getting multiple webhook calls for the sent message.
If you were to send messages as "normal" text SMS and not Unicode type, you'd have 160 characters for a single SMS.

Related

Node JS AWS SQS only receiving one message

I have 3 messages at my aws message inbox. But i am only getting one message when I'm trying
to retrieve all. I am getting only the last message, but the other two messages are not showing.
Here is my code:
const AWS = require("aws-sdk");
AWS.config.update({ region: "REGION" });
const sqs = new AWS.SQS({ apiVersion: "2012-11-05" });
const readMessage = function () {
const params = {
MaxNumberOfMessages: 10,
QueueUrl: "https://sqs.us-east-1.amazonaws.com/56622448/my-queue",
};
sqs.receiveMessage(params, function (err, data) {
if (err) {
console.log("Error", err);
} else if (data.Messages) {
console.log(data);
}
});
};
readMessage();
This is the output:
{
ResponseMetadata: { RequestId: 'a9e53cee-afc8-57c-664408f1e602' },
Messages: [
{
MessageId: 'bb3e23f9-07fd-4205-9b53-a48f826',
ReceiptHandle: 'AQEBD6rCOZlaBfCNn3nU4AEE7OlYwFJFeblTaiDoxIy8HiwsjdxZX+3SICY/YW5PI+RuFscMMh6VyExoo1i8Zo2JlbYj3t32b9CXnToYugzBqgZuxuYOTzXRAnrGwlavSL7hcLQvW6y8me1gnj65N3tPYEmcfXX5GIiQTn1yNEou3rUNff9DfkSije/0zvp33yfWfcW+RDzB2y6ND6eKHxfsP/cqmHjRaT0bE9rlXorjgh36YwVJ57e5bjUa/1dVqOf3ybXfEX/5C2eZM+T1V2JBxlguvuL1B3aHKAC+R9Pdgpdg2kmK3+bVmOxbQJKfU0s3sD9fElZJmLuLLMPb835z5hbVv44fKJVuEc7ad2uL3d1AUCbq3MKRCb38t77L4Ifa/ob3QQ==',
MD5OfBody: '7b84813a4b4bf10f0edb9e8da7',
Body: "Handsome Person Basic Information."
}
]
}
My Expected Output:
{
ResponseMetadata: { RequestId: 'a9e53cee-afc8-57c-664408f1e602' },
Messages: [
{
MessageId: 'bb3e23f9-07fd-4205-9b53-a48f826',
ReceiptHandle: 'AQEBD6rCOZlaBfCNn3nU4AEE7OlYwFJFeblTaiDoxIy8HiwsjdxZX+3SICY/YW5PI+RuFscMMh6VyExoo1i8Zo2JlbYj3t32b9CXnToYugzBqgZuxuYOTzXRAnrGwlavSL7hcLQvW6y8me1gnj65N3tPYEmcfXX5GIiQTn1yNEou3rUNff9DfkSije/0zvp33yfWfcW+RDzB2y6ND6eKHxfsP/cqmHjRaT0bE9rlXorjgh36YwVJ57e5bjUa/1dVqOf3ybXfEX/5C2eZM+T1V2JBxlguvuL1B3aHKAC+R9Pdgpdg2kmK3+bVmOxbQJKfU0s3sD9fElZJmLuLLMPb835z5hbVv44fKJVuEc7ad2uL3d1AUCbq3MKRCb38t77L4Ifa/ob3QQ==',
MD5OfBody: '7b84813a4b4bf10f0edb9e8da7',
Body: "Handsome Person Basic Information."
},
{
Body: "Handsome Person Basic Information II"
},
{
Body: "Handsome Person Basic Information III"
}
]
}
Under messages, i should be getting three. but retrieving is only one message.
Take note: I have just short cut the value of my expected value just to prove my point.
How would I able to get all of the three messages? Thanks !
This is the default behavior of AWS SQS
"If the number of messages in the queue is small (fewer than 1,000), you most likely get fewer messages than you requested per ReceiveMessage call. If the number of messages in the queue is extremely small, you might not receive any messages in a particular ReceiveMessage response. If this happens, repeat the request. "
Class ReceiveMessageCommand
Long polling might help, but not guarantee you will receive all message at once
Long polling is the solution. You can achieve by 2 ways :
Recall your "readMessage()" recursively(I won't recommend to use setInterval)
Use npm SQS-consumer

Node.js/Firebase: Notifications won't reach device

A few months ago i started using Firebase's backend tools. they're awesome. So i had to move our current method of notifying users of their to-do list. We moved to Cloud Functions and it was 40x faster. Until a week ago i got a fresh copy of MacOS i had to delete everything in my Solid State Drive. When i did i also installed the firebase command line tools. I had my code which i used to notify users, it suddenly stopped working
Here's what happens:
When someone adds a new record to our daily list. the app notifies other family members about the new record. So i had to come up with a method to do so..
OLD CODE (worked seamlessly)
const functions = require('firebase-functions');
var admin = require("firebase-admin");
admin.initializeApp();
var registrationToken = 'egV-C3ItwJE:APA91bGf5ezSRQQFHkzCNzfqhS6tiKRbs6IXXs57DFTrNCWRrVY0pZ4PHsK8G3ZjvvvO4JCvd13j_jBcJkgRh06YJ5Jw6tohc81Ro0k4HdHG-Jlv4sbW5t1DNmJBDeGf48l05eDlfMGO';
var payload = {
data: {
title: 'TEST/2',
body: 'TEST/2'
}
};
// registration token.
admin.messaging().sendToDevice(registrationToken, payload)
.then((response) => {
// Response is a message ID string.
console.log('Successfully sent message:', response, payload);
return
})
.catch((error) => {
console.log('Error sending message:', error);
});
Back in my previous version of macOS this code had no issues. upgrading Firebase Command Line tools i had to make some edits to the code:
NEW CODE (NOT WORKING)
// This registration token comes from the client FCM SDKs.
var registrationToken = 'egV-C3ItwJE:APA91bGf5ezSRQQFHkzCNzfqhS6tiKRbs6IXXs57DFTrNCWRrVY0pZ4PHsK8G3ZjvvvO4JCvd13j_jBcJkgRh06YJ5Jw6tohc81Ro0k4HdHG-Jlv4sbW5t1DNmJBDeGf48l05eDlfMGO';
// See documentation on defining a message payload.
var message = {
data: {
title: '850',
body: '2:45'
},
token: registrationToken
};
// Don't use the legacy sendToDevice
admin.messaging().send(message)
.then((response) => {
// Response is a message ID string.
console.log('Successfully sent message:', response);
return
})
.catch((error) => {
console.log('Error sending message:', error);
});
The Problem is:
1- When this function hits. i get the "Successfully sent message:" response. but the message won't reach the device
Things i have tried:
1- The device token is correct and i have tested it using the manual push notification on single devices
2- The device receives notifications.
3- The device runs on iOS 11.1 same as before
Thanks
Can u check with this function,I had tried with this I am able to get notifications.
In you first code sample u had user sendToDevice but in second sample you had used send
function sendPushNotification(fcmtoken, notificationTitle, notificationMessage) {
if (fcmtoken != null && fcmtoken != "" && fcmtoken != " ") {
var payload = {
notification: {
title: notificationTitle,
body: notificationMessage,
sound: "default"
}
};
admin.messaging().sendToDevice(fcmtoken, payload)
.then(function (response) {
}).catch(function (error) {
console.log("Error sending message:", error);
});
}
}

Getting list of messages from Twilio with pagenation

I want to get all the messages from my twilio account.
I tried this code
var client = new twilio(twilioConfig.accountSid, twilioConfig.authToken);
client.messages.list({ Page: 0, PageSize: 10 }, function (err, data) {
console.log(data);
res.send({ message: "Success" });
});
in this code getting all messages, i need 10 per page
Twilio developer evangelist here.
If you are using the latest version of the Twilio Node module then you can get all your messages in a couple of ways.
You can call each on the message list object which lazily streams the messages.
const client = require('twilio')(YOUR_ACCOUNT_SID, YOUR_AUTH_TOKEN);
client.messages.each({ pageSize: 10 }, function(message) {
console.log(message);
});
Or you can call list on the message list, which eagerly loads all of the messages.
client.messages.list({ pageSize: 10 }, function(messages) {
messages.forEach(function(message) {
console.log(message);
});
});
You can also use page and subsequently nextPage to manually page through all of the messages.
client.messages.page({ pageSize: 10 }, function pageReceived(page) {
page.instances.forEach(function(message) {
console.log(message);
});
if (page.nextPage) {
page.nextPage().then(pageReceived);
}
})
Let me know if any of that helps at all.

Facebook Messenger bot not sending messages in order

I'm playing around with building a simple Facebook Messenger chatbot and I'm having trouble sending messages in sequence.
In the example above, it should have printed "Hello!", "1", "2", "3" in order. I'm currently following the Facebook docs found here to implement this simple text message function. I've included my Express Node.JS server code below:
Defining the sendTextMessage() function:
var request = require("request");
function sendTextMessage(user, text) {
messageData = {
text: text
};
request({
url: "https://graph.facebook.com/v2.6/me/messages",
qs: {access_token: PAGE_ACCESS_TOKEN},
method: "POST",
json: {
recipient: {id: user},
message: messageData
}
}, function(error, response, body) {
if (error) {
console.log("Error sending message: ", error);
} else if (response.body.error) {
console.log("Error: ", response.body.error);
} else {
console.log("Message successfully send.")
}
});
}
Using it to send a response:
sendTextMessage(user, "Hello!");
sendTextMessage(user, "1");
sendTextMessage(user, "2");
sendTextMessage(user, "3");
I even tried implementing a simple queue that queues messages and only sends one message at a time after each request's success callback. This is making me suspect that I'm not interacting with the Messenger API correctly.
Has anyone encountered this issue? How can I get messages to send in sequence? Thanks!
EDIT
Because I implemented a simple queue but still experiencing this problem, I'm including the code for my simple queue system here.
var queue = [];
var queueProcessing = false;
function queueRequest(request) {
queue.push(request);
if (queueProcessing) {
return;
}
queueProcessing = true;
processQueue();
}
function processQueue() {
if (queue.length == 0) {
queueProcessing = false;
return;
}
var currentRequest = queue.shift();
request(currentRequest, function(error, response, body) {
if (error || response.body.error) {
console.log("Error sending messages!");
}
processQueue();
});
}
queueRequest(/* Message 1 */);
queueRequest(/* Message 2 */);
queueRequest(/* Message 3 */);
UPDATE
This "bug" was reported to Facebook but it sounds like they aren't going to fix it. Please read the ticket thread on Facebook's post here for details on what they say is going on. (Thank you to Louise for getting Facebook's attention on this)
I submitted a bug report to Facebook about this because I was having the same problem. They acknowledged that it is indeed a bug and are working to fix it: https://developers.facebook.com/bugs/565416400306038
After you send a POST to /me/messages, you'll receive a response that has a message id (mine start with 'mid.' which maybe stands for message id?):
{ recipient_id: '1015411228555555',
message_id: 'mid.1464375085492:b9606c00ca33c12345' }
After being completely received by the FB Messenger API, you'll get a call to your webhook (with no message events) that confirms receipt:
{ sender: { id: '1015411228555555' },
recipient: { id: '566031806XXXXXX' },
delivery:
{ mids: [ 'mid.1464375085492:b9606c00ca33c12345' ],
watermark: 1464375085604,
seq: 176 } }
I think that delivery receipt is the best way to ensure delivery, then send the next message.
Implement the send request as a Promise and only send consequent messages once the previous one is resolved
const send = (userId, messageData) => {
return new Promise((resolve, reject) => {
request
(
{
url : BASE_URL + "me/messages",
qs : { access_token : PAGE_ACCESS_TOKEN },
method : "POST",
json :
{
recipient: { id : userId },
message: messageData,
}
}, (error, response, body) =>
{
if (error) { console.log("Error sending message: " + response.error); return reject(response.error); }
else if (response.body.error) { console.log('Response body Error: ' + response.body.error); return reject(response.body.error); }
console.log("Message sent successfully to " + userId);
return resolve(response);
}
);
});
};
You can achieve QUEUING by promises.
function delay(time) {
return new Promise(function(resolve, reject) {
setTimeout(resolve, time);
});
}
delay(2000).then(() => {
console.log('hi');
delay(2000).then(() => {
console.log('hello');
delay(2000).then(() => {
console.log('welcome');
})
})
})
Instead of adding static timeouts, I would create a queue data structure. When the bot wants to send a message, append the contents to the end of the queue. On the message post callback, check if there are any messages still in the queue and call the function again using recursion and remove from the queue accordingly.
They should be received in the order that they are sent. Make sure you're actually sending them in order and not calling an async function 4 times (and send order isn't guaranteed). (I read that you tested it but in all my testing I've never seen a receive come out of order if the send order was guaranteed.)
I added a messageId counter to the app that resets to 0 on every start of messagehandling. Then I delay with that number * 100 ms. This way I can add intentional delays as well with code like messageDelay += 15
receivedMessage(event) {
messageDelay = 0;
//...
sendMessage extend:
function sendTextMessage(recipientId, messageText) {
//...
setTimeout(function() {
callSendAPI(messageData);
}, messageDelay++ * 100)
}
The message is not sending in order because, the request is sent asynchronously to facebook, and can be sent in any order.
To solve this you have to call the next sendTextMessage when the message that should be sent before it has received a response.
Based on the recursive solution proposed by #user3884594, I kind of make it work using this (I removed the error handling in order to simplify):
send_messages (["message 01", "message 02", "message 03"]);
function send_messages (which, i = 0)
{
request({
url: 'https://graph.facebook.com/v2.10/me/messages',
qs: { access_token: FACEBOOK_ACCESS_TOKEN },
method: 'POST',
json: { recipient: { id: senderId }, message: { text: which [i] }
}, (error, response, body) =>
{
// You need to put your error handling logic here
if (i++ < which.length - 1)
send_messages (which, i);
});
}
I had exactly same problem, that solution worked for me:
function sendMessage(recipient, messages, accessToken, i) {
axios.post(baseURL + 'v2.11/me/messages/?access_token=' + accessToken,
Object.assign({}, {
messaging_type: "RESPONSE",
recipient: {
id: recipient
}
}, messages[i]['payload']) )
.then(response => {
if(i < messages.length) sendMessage( recipient, messages, accessToken, i+1 );
},
error => {})
.catch(error => {});
}
sendMessage(recipient, flow['messages'], flow['page']['accessToken'], 0);
That's my question: Sequential Message Sending Using Facebook Send-API
You can try putting them inside a setTimeout function so each one goes after a certain period of time.
So replace this:
sendTextMessage(user, "Hello!");
sendTextMessage(user, "1");
sendTextMessage(user, "2");
sendTextMessage(user, "3");
With this:
sendTextMessage(user, "Hello!");
// 1 second
setTimeout(function() {
sendTextMessage(user, "1");
}, 1000)
// 2 seconds
setTimeout(function() {
sendTextMessage(user, "2");
}, 2000)
// 3 seconds
setTimeout(function() {
sendTextMessage(user, "3");
}, 3000)
And they should go one after another. You could also embed the functions inside each other if need be.

how to receive and process a photo mms using twilio

Looking for an example, of how to receive and process images via mms to my app using Twilio.
Looking at the number configuration screen in the twilio dashboard, I assume that I set up an incoming phone number and a HTTP POST url to send incoming mms to. However, I'm not sure what gets posted to that url and don't know the structure of that data.
Does someone have an example of what data gets POSTed to the url and in what format? Any javascript examples of what data the server would process would be great.
Firstly use the twilio-node module(npm install twilio). Once you have that in place, you can just access the webhook request body like you would any request body req.body.
As depicted in twilio's docs, the structure is like so:
{
MessageSid: String, //ID pertaining to this message
AccountSid: String, //ID pertaining to your twilio account
From: String, //phone number of sender
To: String, //recipients phone number, you in this case
Body: String, //Message body
NumMedia: Number, //number of attached media
//these values only appear when media is present(NumMedia.length > 0)
MediaContentType: [String] //type of content in SMS
MediaUrl: [String] //URL to download the media
}
You can then do something like this using the twilio modules, caolan/async module, and the popular request/request module:
var twilio = require('twilio'),
fs = require('fs'),
async = require('async'),
request = require('request');
app.post('/mms', function(req, res) {
var options = { url: 'https://subtle-gradient-188.herokuapp.com/twiml' };
if (!twilio.validateExpressrequire(req, 'YOUR_TWILIO_AUTH_TOKEN', options)) return res.status(401).send("Bad key!");
if(!req.body.hasOwnProperty('MediaUrl')) return res.send("Missing media...");
var media = req.body.MediaUrl;
//download all media
async.map(media, download, function(err, filenames) {
var resp = new twilio.TwimlResponse();
if(err) {
resp.say("Problem occured");
console.log(err);
}
else resp.say('Files recieved: ' + filenames.join(', '));
res.type('text/xml');
res.send(resp.toString());
});
});
//download a single url to a unique filename
function download(url, cb) {
var name = Date.now() + url.split('/').pop();
request
.get(url)
.on('error', cb)
.on('end', function() {
cb(null, name);
})
.pipe(fs.createWriteStream(name));
}

Resources