Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
April 14, 2022 05:21 pm GMT

Playing Breaking Bad Quotes From a Phone Call Using Node.JS and Twilio

Howdy Reader

Have you ever been in a situation where you wanted to hear quotes from your favorite show but didn't have a way to? I recently watched Breaking Bad and Walter's and Jesse's iconic voices still bounce around in my head.

Today, I'll be teaching you how to set up a number that automatically plays Breaking Bad quotes when called, or you can use it for something lame like setting up an automated support line for a product, startup, or whatever capitalistic endeavor you have in mind.

Call this number for a Demo: +1(318) 490-4496

Prerequisites

  • Basic JavaScript Knowledge.
  • A Twilio Account
  • A recent Node.js installation.

What is Twilio?

Twilio is a company that provides APIs for various communicating needs like phone calls, text messaging, or P2P video streaming.

We are using the Programmable Voice API that exposes functionality for playing a voice or audio.

Project Design

Let's go over the design!

A user first calls our number, then Twilio calls an endpoint on our express server which tells Twilio "Hey, answer the call and return this audio". Twilio says ok, then plays the audio back to the caller.

Project Setup

Let's start cooking our project.

Twilio API Keys

Let's kick off by getting our Twilio API keys, we'll need them later for testing. If you don't have a Twilio account, heres the sign-up page (don't worry it's not an affiliate link). Don't forget to generate a free phone number.

The console should show two tokens connected to your account info, the Account SID and Auth Token.

Adding Environment Variables

One of the packages we installed was dotenv. Dotenv allows us to define a .env file for variables or sensitive keys (depending on who you ask) that are loaded into process.env.

Open the .env file and add your Twilio API keys and your generated phone number.

TWILIO_ACCOUNT_SID=<YOU_ACCOUNT_SID>TWILIO_AUTH_TOKEN=<YOUR_AUTH_TOKEN>TWILIO_NUMBER=<YOUR_GENERATED_TWILIO_NUMBER> # Ex. +14045555555

Creating Express.js Server

To handle Twilio asking "what should I do?", we need an Express.js server. Create an empty directory and init an empty npm project and set whatever configs you want except change "entry" to app.js.

npm init

Then run the NPM command below to install our required packages.

npm install express dotenv twilio ngrok

Create the below folder structure.

 public/ - Public static files routes/ - HTTP routes     voice.js - Twilio API endpoints .env app.js - HTTP server definition package.json package-lock.json

Let's add some server code to app.js!

const express = require('express');const path = require('path');const http = require('http');// Pull environment variables require('dotenv').config();// Init Expressconst app = express();app.use(express.json());app.use(express.urlencoded({extended: false}));app.use(express.static(path.join(__dirname, 'public')));// Set portconst port = '3000';app.set('port', port);// Create HTTP serverconst server = http.createServer(app);// Start server on portserver.listen(port, () => {  console.log("Started server");});module.exports = app;

Run this command to start the server.

node app.js

Adding Audio Files

As per our requirements, let's gather some audio files to play when someone calls our number. You already know I'm doing Breaking Bad quotes but you can use whatever you want, I'm not your boss.

I used this site to download Breaking Bad quotes.

After getting your audio files, place them in the public folder. If you don't want your audio files exposed publicly, you can create another folder and relocate them.

Create Audio Response Endpoint

When someone calls our Twilio number, we direct Twilio to our POST endpoint that tells Twilio how to respond to the caller using TwiML, Twilios markup language for commands.

Navigate to the routes/voice.js file. We are adding an POST endpoint named /voice which randomly selects a quote, then creates and returns a TwiML command telling Twilio to play this file.

const express = require('express');const VoiceResponse = require('twilio').twiml.VoiceResponse;const fs = require('fs');// Create routerconst router = express.Router();// Create a 'POST' endpoint named '/voice'router.post('/voice', (req, res) => {  // Get all the files in the /public folder   // then filter for only .mp3 files.  const audioFiles = fs.readdirSync('./public').filter((file) => {    return file.match(new RegExp('.*\.(mp3)', 'ig'));  });  // Choose a random .mp3  const randomAudioFile = audioFiles[Math.floor(Math.random() * audioFiles.length)];  // Create a voice response  const voiceResponse = new VoiceResponse();  // Add a pause because the audio starts too quickly  // and the person calling might miss the beginning.  voiceResponse.pause({    length: 1,  });  // Generate a TwiML command that says   // "Play this audio file once".  voiceResponse.play({    loop: 1  }, randomAudioFile);  // Send response to Twilio  res.type('text/xml')    .status(200).send(voiceResponse.toString());});module.exports = router;

Now attach the route to our server by editing app.js.

const voiceRouter = require('./routes/voice');app.use(voiceRouter);

Make sure to restart your server on code changes.

Testing '/voice' Endpoint

Before attaching our endpoint to Twilio, we'd better test it first unless you're a bad programmer then by all means skip this section. Just tell me what your product is so I know NOT to add my debit card to it .

To check if the endpoint path works, use an HTTP client like Postman to send a POST request to localhost:3000/voice. You should see something like this:

<?xml version="1.0" encoding="UTF-8"?><Response>    <Pause length="1"/>    <Play loop="1">who_knocks.mp3</Play></Response>

To test the functionality of our endpoint, we create a Twilio function to call a number using the command from the /voice endpoint. If your Twilio account isn't activated, the only number you can call is the one you created your account with.

Before we can do that, Twilio can't run commands that run on localhost. Doesn't matter if we're testing or not. Luckily, there is a tool called Ngrok, a reverse proxy that exposes our localhost:3000 express server to the internet like it's an actual server!

Navigate to the app.js file. In the server.listen command's callback, add code to connect our express server to the internet then restart the server.

const ngrok = require('ngrok');// Listen on portserver.listen(port, () => {  console.log("Started server");  // Create a public url for our  // `localhost:3000` express server.  ngrok.connect({    addr: 3000, // Our localhost port  }).then((ngrokUrl) => {    console.log("Connected to url: " + ngrokUrl);  });});

You should see something like:

Connected to url: https://xxxx-xx-xx-xxx-xx.ngrok.io

Now we create the Twilio code to test our command! Create a Twilio client using the TWILIO_ACCOUNT_SID and TWILIO_AUTH_TOKEN environment variables we added earlier.

const twilio = require("twilio");// Listen on portserver.listen(port, () => {  console.log("Started server");   // Create Twilio client  const twilioClient =     new twilio(process.env.TWILIO_ACCOUNT_SID, process.env.TWILIO_AUTH_TOKEN);...

With our Twilio client, we send a command to call a phone number using the command from the /voice endpoint.

// Listen on portserver.listen(port, () => {  console.log("Started server");  // Create a public url for our  // `localhost:3000` express server.  ngrok.connect({    addr: 3000,  }).then((ngrokUrl) => {    console.log("Connected to url: " + ngrokUrl);    // Append voice endpoint to ngrokUrl    const voiceUrl = `${ngrokUrl}/voice`;    // Create Twilio client    const twilioClient = new twilio(process.env.TWILIO_ACCOUNT_SID, process.env.TWILIO_AUTH_TOKEN);    // Call a phone number using the    // command from the /voice endpoint.    twilioClient.calls.create({      to: '<TARGET_PHONE_NUMBER>', // Target number to call      from: process.env.TWILIO_NUMBER, // Your generated Twilio number      url: voiceUrl, // The ngrok url that points to the /voice endpoint      method: 'POST'    }).then((call) => {      console.log(call); // Print call log    }).catch((err) => {      console.log("Error making call " + err); // Print error    });  });});

After a few seconds, you should get a call playing the selected audio file!! Pretty cool right?

Connect /voice Endpoint to Twilio

It's time for the moment of truth! We are going to connect our /voice endpoint to Twilio. Login to your Twilio account and navigate to the console. Click 'Explore Products' in the left sidebar.

Twilio Sidebar

Scroll down and click 'Phone Numbers'.

Phone Numbers

Select your Twilio number.

Twilio Number

Scroll down to 'Voice & Fax' and add your ngrok url that points to the /voice endpoint as a webhook for 'A CALL COMES IN'.

Webhook

Call your Twilio phone number and your audio will play right into your ear!!!

Final Thoughts

Who says T.V rots your brain? Because of Breaking Bad, we learned about system design, creating a server, how to use environment variables, the importance of testing, and most importantly how to cook... code . Hopefully, you've enjoyed the read and taken something from it.

I'm Gregory Gaines, a goofy software engineer who's trying to write good articles. If you want more content, follow me on Twitter at @GregoryAGaines.

Now go create something great! If you create a Twilio app or need some help hit me up on Twitter (@GregoryAGaines) and we can talk about it.


Original Link: https://dev.to/gregorygaines/playing-breaking-bad-quotes-from-a-phone-call-using-nodejs-and-twilio-20ld

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To