Twilio - Send email from function - twilio

Is there a way to send email from Twilio function? I understand that we can use sendgrid. I am looking a simpler solution.

Twilio evangelist here. 👋
As of now, you can use SendGrid from within a Twilio Function. The code below does the job for me and I just sent an email via a function
exports.handler = function(context, event, callback) {
const sgMail = require('#sendgrid/mail');
sgMail.setApiKey(process.env.SENDGRID_API_KEY);
const msg = {
to: 'sjudis#twilio.com',
from: 'test#example.com',
subject: 'Sending with SendGrid is Fun',
text: 'and easy to do anywhere, even with Node.js',
html: '<strong>and easy to do anywhere, even with Node.js</strong>',
};
sgMail.send(msg)
.then(() => {
callback(null, 'Email sent...');
})
.catch((e) => {
console.log(e);
})
};
The above email will most like end up in spam as test#example.com is not a very trust worthy email address. If you want to send emails from your own domains additional configuration is needed.
To run the code inside of the function, you have to make sure to install the sendgrid/mail mail dependency and provide the sendgrid token in the function configuration.
If you want to use this function to power e.g. messages you have to make sure that your return valid TwiML. :) When you create a new function you will get examples showing on how to do that.
Hope that helps. :)

Another way is to use the SendGrid API
const got = require('got');
exports.handler = function(context, event, callback) {
const requestBody = {
personalizations: [{ to: [{ email: context.TO_EMAIL_ADDRESS }] }],
from: { email: context.FROM_EMAIL_ADDRESS },
subject: `New SMS message from: ${event.From}`,
content: [
{
type: 'text/plain',
value: event.Body
}
]
};
got.post('https://api.sendgrid.com/v3/mail/send', {
headers: {
Authorization: `Bearer ${context.SENDGRID_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(requestBody)
})
.then(response => {
let twiml = new Twilio.twiml.MessagingResponse();
callback(null, twiml);
})
.catch(err => {
callback(err);
});
};
};
Source: https://www.twilio.com/blog/2017/07/forward-incoming-sms-messages-to-email-with-node-js-sendgrid-and-twilio-functions.html

Related

Error 504 - Using Twilio Functions to Send Alerts to Slack

I'm using Twilio Functions as a webhook to send Slack messages anytime an error occurs. The error message is successfully sent to Slack. However, this triggers Error code 504 (runtime application timed out) in Twilio. From the Twilio documentation, it seems I'm not properly implementing the callback method. Is there something I'm missing?
const https = require("https");
// Make sure to declare SLACK_WEBHOOK_PATH in your Environment
// variables at
// https://www.twilio.com/console/runtime/functions/configure
exports.handler = function(context, event, callback) {
const { AccountSid } = event;
const message = `New error for Twilio Account ${AccountSid}.`
const slackBody = JSON.stringify({
channel: "#channel",
icon_emoji: ":test_tube:",
username: "Twilio Alert",
attachments: [{
fallback: "twilio alert",
color: "#d00000",
pretext: "",
text: message
}]
});
// Form our request specification
const options = {
host: "hooks.slack.com",
port: 443,
path: context.SLACK_WEBHOOK_PATH,
method: "POST",
headers: {
"Content-Type": "application/json",
"Content-Length": slackBody.length
}
};
// send the request
const post = https.request(options, res => {
// only respond once we're done, or Twilio's functions
// may kill our execution before we finish.
res.on("end", () => {
// respond with an empty message
return callback(null);
});
});
post.on('error', (e) => {
console.log(e);
});
post.write(slackBody);
post.end();
}

Testing graphql subscriptions with k6

Is it possible to test graphql subscriptions using k6 framework?
I tried to do it, but did not have much success. Also tried to do it with k6 websockets, but did not help.
Thanks
Grapqhql Subscription is based on Websockets so this is theoretically possible to implement using k6 WebSocket.
You can also refer to the documentation for subscriptions here.
You can also use the playground and Networks tab in developer tools to figure out the messages/requests that are sent to the server.
Here is how I was able to achieve it:
import ws from "k6/ws";
export default function(){
const url = "ws://localhost:4000/graphql" // replace with your url
const token = null; // replace with your auth token
const operation = `
subscription PostFeed {
postCreated {
author
comment
}
}` // replace with your subscription
const headers = {
"Sec-WebSocket-Protocol": "graphql-ws",
};
if (token != null) Object.assign(headers,{ Authorization: `Bearer ${token}`});
ws.connect(
url,
{
headers,
},
(socket) => {
socket.on("message", (msg) => {
const message = JSON.parse(msg);
if (message.type == "connection_ack")
console.log("Connection Established with WebSocket");
if (message.type == "data") console.log(`Message Received: ${message}`)
});
socket.on("open", () => {
socket.send(
JSON.stringify({
type: "connection_init",
payload: headers,
})
);
socket.send(
JSON.stringify({
type: "start",
payload: {
query: operation,
},
})
);
});
}
);
}
Hope this helps! 🍻

Twilio Functions - Pass in parameters and format SMS body to include parameters

I am using Twilio to create an 'attendance line' where employees can provide information about why they will be absent and then Twilio will send separate, curated messages to supervisors and human resources.
To do this, I've created a Flow in Twilio Studio and I would like to use a Twilio Function to handle sending the mass SMS messages notifying users of a new absence.
I am passing parameters to the function like name, dept, shift, reason, etc with the intent to then share these values via SMS.
I am having the hardest time getting all of these different values properly into the body of the message.
exports.handler = function(context, event, callback) {
// Create a reference to the user notification service
const client = context.getTwilioClient();
const service = client.notify.services(
context.TWILIO_NOTIFICATION_SERVICE_SID
);
const notification = {
toBinding: JSON.stringify({
binding_type: 'sms', address: '+1XXXXXXXXXX',
binding_type: 'sms', address: '+1XXXXXXXXXX',
}),
body: 'New Attendance Notification',
event.question_name,
event.question_dept,
event.question_reason,
event.contactChannelAddress,
};
console.log(notification);
// Send a notification
return service.notifications.create(notification).then((message) => {
console.log('Notification Message',message);
callback(null, "Message sent.");
}).catch((error) => {
console.log(error);
callback(error,null);
});
};
Now I know the 'body' of the message above will not work but I'm a bit lost...
The text below is how I would like my SMS message to read out when sent.
New Attendance Notification
Name: event.Name
Dept: event.Dept
Reason: event.Reason
Contact: event.ContactChannelAddress
Is what I am trying to accomplish even possible?
Something like this...
exports.handler = function(context, event, callback) {
// Create a reference to the user notification service
const client = context.getTwilioClient();
const service = client.notify.services(
context.TWILIO_NOTIFICATION_SERVICE_SID
);
const bindings = [
'{ "binding_type": "sms", "address": "+14071234567" }',
'{ "binding_type": "sms", "address": "+18021234567" }'
];
const notice = `New Attendance Notification\nName: ${event.question_name}\nDept: ${event.question_dept} \nReason: ${event.question_reason}\nContact: ${event.contactChannelAddress} \n`;
// Send a notification
service.notifications.create({ toBinding: bindings, body: notice }).then((message) => {
console.log('Notification Message',message);
callback(null, "Message sent.");
})
.catch((error) => {
console.log(error);
callback(error,null);
});
};

Twilio Studio Function to Send Voicemail URL

I am using Twilio Studio for to collect messages for our small church. When someone records a voicemail, I am using a function to send the recording URL to the group members. Here is what that function looks like currently:
var groupmembers = [
{
name: 'Person1',
number: '+11111111111'
},
{
name: 'Person2',
number: '+11111111111'
}
];
exports.handler = function(context, event, callback) {
let twiml = new Twilio.twiml.MessagingResponse();
groupmembers.forEach(function(member) {
// Now, forward on the message to the group member, using the sender's name
twiml.message(`Text from ${event.senderFrom}: ${event.senderMessage}`, {
to: member.number
});
})
callback(null, twiml);
};
This gives me a '12200 Schema validation warning' with the detail: Invalid content was found starting with element 'Message'. One of '{Play
I'm fairly sure the issue is because I am trying to send an SMS during a call but I am not sure how to update my TWIML or Studio flow to accommodate for this.
Any help is appreciated!
you need the REST API rather then TwiML in this case. You could use code similar to what is shown below to do this.
Make sure to check the box below, under Function Config for your Function,
exports.handler = function(context, event, callback) {
const twilioClient = context.getTwilioClient();
let groupMembers = [
{
name: 'Person1',
number: '+14701111111'
},
{
name: 'Person2',
number: '+18082222222'
},
{
name: 'Person3',
number: '+18021111111'
}
];
function sendSMS(member) {
return twilioClient.messages.create({
from: '+13054444444',
to: member.number,
body: 'Hello World!'
});
}
let promises = [];
groupMembers.forEach((member) => {
console.log(member);
promises.push(sendSMS(member));
});
Promise.all(promises)
.then((values) => {
console.log(values);
callback(null,"Success");
})
.catch(error => {
console.log(error);
callback("Failure");
});
};

Twilio Forward SMS to email - Cannot find module 'got'

I'm new to Twilio. I'm attempting to forward an SMS to an email address using this tutorial:
https://www.twilio.com/blog/2017/07/forward-incoming-sms-messages-to-email-with-node-js-sendgrid-and-twilio-functions.html
I feel certain I've done everything it says to do, but I get an error 11200 HTTP retrieval failure every time, with these details:
{
"message": "Cannot find module 'got'",
"name": "Error",
"stack": "Error: Cannot find module 'got'\n at Function.Module._resolveFilename (module.js:547:15)\n at
Function.Module._load (module.js:474:25)\n at Module.require
(module.js:596:17)\n at Module.twilioRequire [as require]
(/var/task/node_modules/enigma-lambda/src/dependency.js:28:21)\n at
require (internal/module.js:11:18)\n at Object.
(/var/task/handlers/ZFa37cc3db9fd8db0501c2e5fc92137969.js:1:75)\n
at Module._compile (module.js:652:30)\n at
Object.Module._extensions..js (module.js:663:10)\n at Module.load
(module.js:565:32)\n at tryModuleLoad (module.js:505:12)" }
I've tried making absolutely sure I have the function written the same as the tutorial. I copied it directly from the github page to be sure. I'm not sure how to proceed in troubleshooting this, it seems it's telling me that 'got' isn't found but it's supposed to be available in Twilio functions. Any ideas? Thanks.
Edit: Here is the code:
const got = require('got');
exports.handler = function(context, event, callback) {
const requestBody = {
personalizations: [{ to: [{ email: context.TO_EMAIL_ADDRESS }] }],
from: { email: context.FROM_EMAIL_ADDRESS },
subject: `New SMS message from: ${event.From}`,
content: [
{
type: 'text/plain',
value: event.Body
}
]
};
got
.post('https://api.sendgrid.com/v3/mail/send', {
headers: {
Authorization: `Bearer ${context.SENDGRID_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(requestBody)
})
.then(response => {
let twiml = new Twilio.twiml.MessagingResponse();
callback(null, twiml);
})
.catch(err => {
callback(err);
});
};
After a little more research, I found some comments on GitHub that indicate 'got' is no longer included by default in the Twilio dependencies. Per the instructions there I went to the Runtime Functions Config section of the Twilio console and added got version 6.7.1 and now the original source code works!
I prefer Alex's solution however since it works "out of the box" and I'm keeping it as the accepted answer.
First, the above code with got works with my Twilio and SendGrid accounts, I just tested, I don't know why you're having trouble..., maybe try to create a Twilio subaccount and run from there.
Second, if you still can't get got to work, here is some code, you could try,
and I'we also tested and it works. It's using https instead:
const https = require('https');
exports.handler = function (context, event, callback) {
let postData = JSON.stringify({
personalizations: [{
to: [{
email: 'somebody#gmail.com'
}]
}],
from: {
email: 'somebody#gmail.com'
},
subject: `New SMS message from: ${event.From}`,
content: [{
type: 'text/plain',
value: event.Body
}]
});
let postOptions = {
host: 'api.sendgrid.com',
port: '443',
path: '/v3/mail/send',
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(postData),
}
};
let req = https.request(postOptions, function (res) {
// some code to handle the async response if needed
let twiml = new Twilio.twiml.MessagingResponse();
callback(null, twiml);
});
req.write(postData);
req.end();
};
Good luck!
I was able to get this to work by making sure that "got" is installed as a dependency under these settings here:
https://www.twilio.com/console/runtime/functions/configure
Functions Screenshot

Resources