Twilio return self._qs.unescape error - node.js

when i use Twilio to send SMS it return
TypeError: self._qs.unescape is not a function
packaje.json :
"dependencies": {
"twilio": "^2.11.1",
"typescript": "^2.8.3",
},
"devDependencies": {
"#types/lodash": "^4.14.108",
"#types/node": "^9.6.6",
"#types/twilio": "0.0.9"
}
And My Code :
var twilio = require('twilio');
var ACCOUNT_SID = "***";
var AUTH_TOKEN = "***";
TwilioClient.messages.create({
body: 'Welcome ',
to: '+*****'
from: '+****' // From a valid Twilio number
}).then((message) => console.log(message.sid));
and returned :
Exception in delivering result of invoking 'Register': TypeError: self._qs.unescape is not a function

you need to initiate the twilio client and then use it :
var client = new twilio(ACCOUNT_SID, AUTH_TOKEN);
client.messages.create({
body: 'Welcome ',
to: '+*****'
from: '+****' // From a valid Twilio number
}).then((message) => console.log(message.sid));

In Meteor, I should connect to the Twilio API from the server.
When I requested from the client, I got the error.

Related

Modify Twilio sample code to attach voicemail recoding and send by email

The following post from Twilio explains how to write and implement a function for sending the link of a recorded message to email.
https://www.twilio.com/blog/forward-voicemail-recordings-to-email
I want to attach to the voicemail recording rather than just send the link. Here is my attempt at modifying their code. Unfortunately it's causing a 500 error. I'm not very experience with NodeJS so perhaps you can help.
Dependencies for SendGrid and FS are included and this function worked perfectly until I modified it with FS, pathToAttachment, attachment variables and the attachments array.
//Initialize SendGrid Mail Client
const sgMail = require('#sendgrid/mail');
//FileSystem
const fs = require("fs");
// Define Handler function required for all Twilio Functions
exports.handler = function(context, event, callback) {
pathToAttachment = `${event.RecordingUrl}`;
attachment = fs.readFileSync(pathToAttachment).toString("base64");
// Build SG mail request
sgMail.setApiKey(context.SENDGRID_API_SECRET);
// Define message params
const msg = {
to: context.TO_EMAIL_ADDRESS,
from: context.FROM_EMAIL_ADDRESS,
fromname: 'Voicemail',
text: `URL is: ${event.RecordingUrl}`,
subject: `${event.From} (${event.country} / ${event.lang})`,
attachments: [
{
content: attachment,
filename: "Voicemail.wav",
disposition: "attachment"
}
]
};
// Send message
sgMail.send(msg)
.then(response => {
console.log("Neat.")
callback();
})
.catch(err => {
console.log("Not neat.")
callback(err);
});
};
This is how you modify the code from the Twilio blog:
Forward Voicemail Recordings to Email w/ Studio, Functions, & SendGrid
https://www.twilio.com/blog/forward-voicemail-recordings-to-email
.. to attach the email recording instead of link to it and how to add a from name as well as a from email address.
const request = require('request');
const sgMail = require('#sendgrid/mail');
exports.handler = function(context, event, callback) {
const fileUrl = event.RecordingUrl;
// Build SG mail request
sgMail.setApiKey(context.SENDGRID_API_SECRET);
request.get({ uri: fileUrl, encoding: null }, (error, response, body) => {
const msg = {
to: context.TO_EMAIL_ADDRESS,
from: {
"email": context.FROM_EMAIL_ADDRESS,
"name": `My company`
},
text: `Attached voicemail from ${event.From}.`,
subject: `${event.From}`,
attachments: [
{
content: body.toString('base64'),
filename: `MyRecording.wav`,
type: response.headers['content-type']
}
]
};
// Send message
sgMail.send(msg)
.then(response => {
console.log("Neat.")
callback();
})
.catch(err => {
console.log("Not neat.")
callback(err);
});
});
};
This is how you modify the code from

Twilio No Errors shown for Programmable Message

I am following Twilio's API for sending outbound messages.
I've followed their short code implementation using Nodejs.
Dependencies
"dependencies": {
"express": "^4.17.1",
"read-excel-file": "^4.0.6",
"twilio": "^3.0.0"
}
Code
const accountSid = '[account sid]';
const authToken = '[account authtoken]';
var client = require('twilio')(accountSid, authToken);
client.messages.create({
body: 'Hello from Node',
from: '[usa number]',
to: '[singapore number]'
})
.then((message) => console.log(message.sid));
i run the code with node index.js
but nothing comes out. I've tried changing vars to const and const to vars but nothing works.
Console shows nothing at all.
It looks like your promise is being rejected, at a .catch, to see what the error is. You can check to see if SMS Geographic permissions are set appropriately.
Something like:
const accountSid = '[account sid]';
const authToken = '[account authtoken]';
var client = require('twilio')(accountSid, authToken);
client.messages.create({
body: 'Hello from Node',
from: '[usa number]',
to: '[singapore number]'
})
.then((message) => console.log(message.sid))
.catch(err => console.log(err));

Nodemailer SMTP not working on production server

I am having issues sending email via nodemailer - SMTP(from another host) on production
i uploaded my API on a server(Scaleway Dev), i'm using Ubuntu Bionic and while testing noticed it is not sending emails(which i need for verification of a user).
at first i thought the request isn't getting to the server, but when i tried logging in i got a "confirm your password" response, i check the mongoDB database and the user is there, but still no confirmation email.
I tried checking it on localhost, thinking it might be the dotenv dependency, but it works there, what gives?
node version on my server is 8.10.0
and on my personal computer 11.12.0
these are my dependencies
enter code here
"dependencies": {
"bcrypt": "^3.0.6",
"body-parse": "^0.1.0",
"client-sessions": "^0.8.0",
"connect": "^3.6.6",
"cookie-parser": "~1.4.4",
"cors": "^2.8.5",
"debug": "~2.6.9",
"dotenv": "^8.0.0",
"express": "~4.16.1",
"express-session": "^1.16.1",
"express-validator": "^5.3.1",
"http-errors": "~1.6.3",
"moment": "^2.24.0",
"mongoose": "^5.5.8",
"morgan": "~1.9.1",
"nodemailer": "^6.1.1",
"nodemon": "^1.19.0",
"passport": "^0.4.0",
"pug": "2.0.0-beta11",
"randomstring": "^1.1.5",
"session": "^0.1.0",
"session-mongoose": "^0.5.2"
}
these options used are specified by the host that i'm using
//this is my transporter constant
const transporter = nodemailer.createTransport({
host: '*different host from the server*',
port: 465,
secure: true,
auth: {
user: my used email(hardcoded),
pass: process.env.EMAILPASS
},
tls: {
rejectUnauthorized: false
}
});
//my email options
let mailOptions ={
from: '"Company Name <noreply#*different host DNS*>',
to: req.body.email,
subject: *subject*
html: `Email Content with confirmation token`
}
//emailing the message itself
transporter.sendMail(mailOptions, (err, info) => {
if(err){
return console.log(err);
}
console.log("message sent");
});
i'm using this email generator(https://generator.email/) for fast throwaway emails. the mailing starts after i save the user.
I'm perplexed as to what should i do... any and all help is appreciated
I have had issues with nodemailer in the past. I'm using mailgun (https://www.mailgun.com/) to send my emails. They offer 10,000 emails a month for free. Here is a code that works with mailgun:
dependencies:
"express": "4.16.4",
"config": "3.0.1",
"nodemailer": "5.1.1",
"nodemailer-mailgun-transport": "1.4.0"
code (it is wrapped inside an express router) :
const config = require('config');
const nodemailer = require('nodemailer');
const mg = require('nodemailer-mailgun-transport');
const express = require('express');
const router = express.Router();
router.post('/', async (req, res) => {
//the data has to be an array. It will send as many emails as the number of items in the array
var emailsList = ["test#test.com"];
emailsList[0].name = "Test Name";
var auth = {
auth: {
api_key: config.get('mailgunApiKey'),
domain: config.get('mailgunDomain')
}
};
transporter = nodemailer.createTransport(mg(auth)),
EmailTemplate = require('email-templates').EmailTemplate,
path = require('path'),
Promise = require('bluebird');
function sendEmail (obj) {
return transporter.sendMail(obj);
}
function loadTemplate (templateName, contexts) {
let template = new EmailTemplate(path.join(__dirname, '../templates', templateName));
return Promise.all(contexts.map((context) => {
return new Promise((resolve, reject) => {
template.render(context, (err, result) => {
if (err) reject(err);
else resolve({
email: result,
context,
});
});
});
}));
}
loadTemplate('dailyReferralEmail', emailsList).then((results) => {
return Promise.all(results.map((result) => {
sendEmail({
to: result.context.email,
from: 'Your Name <your-email#test.com>',
'h:Reply-To': 'your-email#test.com',
subject: result.email.subject,
html: result.email.html,
text: result.email.text,
});
}));
}).then(() => {
var response = {
text: "Email sent"
}
JSON.stringify(response);
res.status(200).send(response);
});
});
module.exports = router;
As a template generator, I'm using HBS. So you must have a templates folder in the root folder of your project, with this tree:
You can use your variables inside your email with {{ }}.
Inside html.hbs:
<p>Hello {{name}}</p>
Inside subject.hbs
Subject of your email
Inside text.hbs
Preview text of your email
Hope this helps!

Invalid registration token provided. Make sure it matches the registration token the client app receives from registering with FCM

I got this code from my client iOS app on XCode console
Firebase registration token: diWY78iar8s:APA91bHJAzXe384OEYvfk4bKsyS1NQvteph7DwG7JRIMm_HuXg8EeNllVrsSi0v9W_Gh95ezbOStp3ZWuWl0AzFKxMaCOjN81yiz7A5qhkONrd7lP2CTkUbFErw28r3ONTLvo8c8sO7h
diWY78iar8s:APA91bHJAzXe384OEYvfk4bKsyS1NQvteph7DwG7JRIMm_HuXg8EeNllVrsSi0v9W_Gh95ezbOStp3ZWuWl0AzFKxMaCOjN81yiz7A5qhkONrd7lP2CTkUbFErw28r3ONTLvo8c8sO7h
NodeJS
console.log("START");
var FCM = require('fcm-node');
var serverKey = require('/Users/bheng/Desktop/Apps/APNS/node/mhn-app-firebase-adminsdk-bs45c-5ac3770488.json')
var fcm = new FCM(serverKey)
var collapseKey = 'new_message';
var message = {
to: 'diWY78iar8s:APA91bHJAzXe384OEYvfk4bKsyS1NQvteph7DwG7JRIMm_HuXg8EeNllVrsSi0v9W_Gh95ezbOStp3ZWuWl0AzFKxMaCOjN81yiz7A5qhkONrd7lP2CTkUbFErw28r3ONTLvo8c8sO7hdiWY78iar8s:APA91bHJAzXe384OEYvfk4bKsyS1NQvteph7DwG7JRIMm_HuXg8EeNllVrsSi0v9W_Gh95ezbOStp3ZWuWl0AzFKxMaCOjN81yiz7A5qhkONrd7lP2CTkUbFErw28r3ONTLvo8c8sO7h',
data: {
cpeMac: '000000000000',
type: 'malware'
},
notification: {
title: 'Hello baby',
body: 'Nice body',
tag: collapseKey,
icon: 'ic_notification',
color: '#18d821',
sound: 'default',
},
};
fcm.send(message, function(err, response){
if (err) {
console.log("Something has gone wrong!")
console.log(JSON.stringify(err));
} else {
console.log("Successfully sent with response: ", JSON.stringify(response))
}
})
console.log("END");
Result
When I run it
node app.js
I kept getting
START
END
Successfully sent with response: {"results":[{"error":{"code":"messaging/invalid-registration-token","message":"Invalid registration token provided. Make sure it matches the registration token the client app receives from registering with FCM."}}],"canonicalRegistrationTokenCount":0,"failureCount":1,"successCount":0,"multicastId":7577724855311354000}
How would one go about debugging this further?
your token has some additional random string such as
to: 'diWY78iar8s:APA91bHJAzXe384OEYvfk4bKsyS1NQvteph7DwG7JRIMm_HuXg8EeNllVrsSi0v9W_Gh95ezbOStp3ZWuWl0AzFKxMaCOjN81yiz7A5qhkONrd7lP2CTkUbFErw28r3ONTLvo8c8sO7hdiWY78iar8s:APA91bHJAzXe384OEYvfk4bKsyS1NQvteph7DwG7JRIMm_HuXg8EeNllVrsSi0v9W_Gh95ezbOStp3ZWuWl0AzFKxMaCOjN81yiz7A5qhkONrd7lP2CTkUbFErw28r3ONTLvo8c8sO7h',
just remove : diWY78iar8s: from your token string
console.log("START");
var FCM = require('fcm-node');
var serverKey = require('/Users/bheng/Desktop/Apps/APNS/node/mhn-app-firebase-adminsdk-bs45c-5ac3770488.json')
var fcm = new FCM(serverKey)
var collapseKey = 'new_message';
var message = {
to: 'APA91bHJAzXe384OEYvfk4bKsyS1NQvteph7DwG7JRIMm_HuXg8EeNllVrsSi0v9W_Gh95ezbOStp3ZWuWl0AzFKxMaCOjN81yiz7A5qhkONrd7lP2CTkUbFErw28r3ONTLvo8c8sO7hdiWY78iar8s:APA91bHJAzXe384OEYvfk4bKsyS1NQvteph7DwG7JRIMm_HuXg8EeNllVrsSi0v9W_Gh95ezbOStp3ZWuWl0AzFKxMaCOjN81yiz7A5qhkONrd7lP2CTkUbFErw28r3ONTLvo8c8sO7h',
data: {
cpeMac: '000000000000',
type: 'malware'
},
notification: {
title: 'Hello baby',
body: 'Nice body',
tag: collapseKey,
icon: 'ic_notification',
color: '#18d821',
sound: 'default',
},
};
fcm.send(message, function(err, response){
if (err) {
console.log("Something has gone wrong!")
console.log(JSON.stringify(err));
} else {
console.log("Successfully sent with response: ", JSON.stringify(response))
}
})
console.log("END");
Response from FCM :
Successfully sent with response: { results: [ { messageId: '0:1543448946734425%479ec0e2479ec0e2' } ],
canonicalRegistrationTokenCount: 0,
failureCount: 0,
successCount: 1,
multicastId: 6133765431734591000 }
One of the interesting reasons for invalid registration is: that device have a different token. Maybe you are trying to use a past token.
In my case what happened was I was getting the FCMRegistrationToken from my colleague via Discord and the Ctrl+C Ctrl+V was modifying the token. On obtaining the token via email solved the issue.

I can not get information with "DialogflowApp.getUser" method

https://developers.google.com/actions/reference/nodejs/ApiAiApp
I'd like to obtain an access token on Dialogflow by referring to the above official website, but the execution result of DialogflowApp.getUser() will be null.
Account linking is set up and on the client side it is certified with a Google Account.
AssistantToAgentDebug.assistantToAgentJson.user on the DEBUG tab of DialogFlow Simulator contains a value.
Also, I can get an access token by referring req.body.originalRequest.data.user.accessToken variable on the request body.
I'd like to obtain user information with DialogflowApp.getUser(),
Is there a mistake in the definition below?
*Using the Fullfilment, the logic is described in index.js.
*index.js
'use strict';
const App = require('actions-on-google').DialogflowApp;
exports.testMethod = (req, res) => {
// result is null
const app = new App({req, res});
let user = app.getUser();
console.log('User is ' + user);
// Access token can be acquired
let accessToken = req.body.originalRequest.data.user.accessToken;
console.log('accessToken is ' + accessToken);
res.setHeader('Content-Type', 'application/json');
res.send(JSON.stringify({ 'speech': 'success!', 'displayText': 'success!' }));
};
*package.json
{
"name": "testMethod",
"engines": {
"node": "~4.2"
},
"dependencies": {
"actions-on-google": "^1.0.0",
"firebase-admin": "^4.2.1",
"firebase-functions": "^0.5.7"
}
}
The problem is that the call to the constructor expect the parameters to be named request and response. So you should write the line as
const app = new App({request:req, response:res});
You need to use getUser().accesToken like this:
let accestoken = app.getUser().accessToken;

Resources