Last active
October 28, 2021 02:49
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)); | |
} | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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: '[email protected]', | |
pass: 'somepassword', | |
} | |
}; | |
const transporter = nodemailer.createTransport(smtpConfig); | |
const mailOptions = { | |
from: '[email protected]', | |
to: '[email protected]', | |
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