Skip to content

Instantly share code, notes, and snippets.

@j-fischer
Last active October 28, 2021 02:49
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save j-fischer/3d07bb470fe3de88afa196cb54044568 to your computer and use it in GitHub Desktop.
Save j-fischer/3d07bb470fe3de88afa196cb54044568 to your computer and use it in GitHub Desktop.
Twilio functions to forward phone calls to multiple cell phones. See https://cloudthingsyyc.wordpress.com/2018/01/15/hpaas-home-phone-as-a-service/ for more details.
const format = require('string-format');
// These are the numbers to forward the call to
const destinations = ['+1', '+1'];
// These are the numbers that will be forwarded to the cell phones
const allowedCallers = [
'+1', //
];
// These are the numbers that will be hung up on right away
const blockedCallers = [
'+1',
];
exports.handler = function(context, event, callback) {
try {
console.log(format('Incoming call: from={}, whitelist={}', event.From, JSON.stringify(allowedCallers)));
let twiml = new Twilio.twiml.VoiceResponse();
if (blockedCallers.indexOf(event.From) > -1) {
twiml.hangup();
callback(null, twiml);
return;
}
if (allowedCallers.indexOf(event.From) > -1) {
console.log('Forwarding call');
let dial = twiml.dial();
// Set call destinations and filter
let numDest = destinations.length;
for (var i = 0; i < numDest; i++) {
let dest = destinations[i];
// Make sure not to call the person who dialed in
if (event.From !== dest) {
dial.number(dest);
}
}
}
else {
console.log('Voicemail');
twiml.say(
'This is the phone of Mr. and Mrs. Smith. Please leave a message after the beep.\n' +
'Thank you for calling!'
);
twiml.record({
method: 'POST',
maxLength: 120,
transcribeCallback: 'https://yourdomain.twil.io/transcriptionComplete',
});
twiml.say('Unfortunately, I was unable to record the message, please call back again later.');
twiml.hangup();
}
// return the TwiML
console.log('Result: ' + twiml.toString());
callback(null, twiml);
} catch (ex) {
callback('Failed to execute function: ' + JSON.stringify(ex));
}
};
const phoneRegistry = {
1: {
number: "+49123455667",
name: "Max Mustermann"
},
2: {
number: "+49123488998",
name: "Maria Musterfrau"
},
// more numbers here
}
exports.handler = function(context, event, callback) {
let twiml = new Twilio.twiml.VoiceResponse();
// Ensure the incoming call is from one of the two whitelisted numbers.
if (event.From !== "+14035555551" && event.From !== "+14035555552") {
twiml.hangup();
callback(null, twiml);
return;
}
// If the selection was made during the previous function call, dial that number.
let selection = event.Digits;
if (selection) {
twiml.dial(phoneRegistry[selection].number);
callback(null, twiml);
return;
}
let message = "Who would you like to call?";
for (let key in phoneRegistry) {
let entry = phoneRegistry[key];
message += "Press " + key + " for " + entry.name + ".";
}
let gather = twiml.gather({
numDigits: '1'
});
gather.say(message);
// return the TwiML
callback(null, twiml);
};
const format = require('string-format')
const nodemailer = require('nodemailer');
exports.handler = function(context, event, callback) {
try {
console.log(format('Transcription result received: caller={}, status={}', event.From , event.TranscriptionStatus));
const transcript = event.TranscriptionStatus === 'completed' ?
event.TranscriptionText :
'No transcript!';
let emailText = 'You received a voicemail from {from}. Transcription: \n\n{transcript}\n\nRecording: {recording}';
console.log('Email template ready');
sendEmail(
event.From,
format(emailText, {
from: event.From,
transcript: transcript,
recording: event.RecordingUrl
}),
callback
);
} catch (ex) {
callback('Failed to email transcription: ' + JSON.stringify(ex));
}
};
/**
* Send email message for the transcript and recording.
*
* @param {String} text
*/
function sendEmail(from, text, callback) {
console.log('Sending email');
let smtpConfig = {
host: 'myhost.com',
port: 465,
secure: true,
auth: {
user: 'user@email.com',
pass: 'somepassword',
}
};
const transporter = nodemailer.createTransport(smtpConfig);
const mailOptions = {
from: 'changeme@email.com',
to: 'my-email@address.com',
subject: 'Voicemail left by ' + from,
text: text,
};
transporter.sendMail(mailOptions, function(error, info) {
if (error) {
console.log('Failed to send email: ' + error);
callback('Failed to send email: ' + error);
} else {
console.log('Email sent: ' + info.response);
callback(null, null);
}
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment