Skip to content

Instantly share code, notes, and snippets.

@juliacodez
Created July 15, 2019 15:53
Show Gist options
  • Save juliacodez/24f972c23b92a120bde39a9b8163d872 to your computer and use it in GitHub Desktop.
Save juliacodez/24f972c23b92a120bde39a9b8163d872 to your computer and use it in GitHub Desktop.
Play an Audio File to a Caller

This flow plays an audio file to a caller, so you can give your friendly neighborhood robot a break.

There is a step-by-step tutorial on this if you'd like to follow along.

Prerequisites

Before getting started, you’ll need a couple of things:

  • A Nexmo account - create one for free if you haven't already
  • A way to expose your server to the internet. This either means you're running a hosted version of Node-RED, or in case you're developing locally, using a tunneling service like ngrok - get up to speed with this Getting Started with Ngrok in Node-RED tutorial
[
{
"id": "48504048.5a88a",
"type": "tab",
"label": "Play an Audio File to a Caller",
"disabled": false,
"info": ""
},
{
"id": "4bfb0e04.b9d298",
"type": "ngrok",
"z": "48504048.5a88a",
"port": "1880",
"creds": "",
"region": "us",
"subdomain": "",
"name": "",
"x": 430,
"y": 220,
"wires": [
[
"81e5ec41.c572"
]
]
},
{
"id": "f21da75e.6acca",
"type": "inject",
"z": "48504048.5a88a",
"name": "",
"topic": "",
"payload": "on",
"payloadType": "str",
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"x": 150,
"y": 180,
"wires": [
[
"4bfb0e04.b9d298"
]
]
},
{
"id": "a429eda7.56f8f8",
"type": "inject",
"z": "48504048.5a88a",
"name": "",
"topic": "",
"payload": "off",
"payloadType": "str",
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"x": 150,
"y": 240,
"wires": [
[
"4bfb0e04.b9d298"
]
]
},
{
"id": "81e5ec41.c572",
"type": "debug",
"z": "48504048.5a88a",
"name": "",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"x": 670,
"y": 220,
"wires": []
},
{
"id": "14e17abe.22ac55",
"type": "http in",
"z": "48504048.5a88a",
"name": "",
"url": "/event",
"method": "post",
"upload": false,
"swaggerDoc": "",
"x": 170,
"y": 400,
"wires": [
[
"736cdf39.35089",
"3f87b67f.6c119a"
]
]
},
{
"id": "736cdf39.35089",
"type": "http response",
"z": "48504048.5a88a",
"name": "",
"statusCode": "",
"headers": {},
"x": 430,
"y": 400,
"wires": []
},
{
"id": "3f87b67f.6c119a",
"type": "debug",
"z": "48504048.5a88a",
"name": "",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"x": 450,
"y": 460,
"wires": []
},
{
"id": "3a141a20.5ea67e",
"type": "http response",
"z": "48504048.5a88a",
"name": "",
"statusCode": "",
"headers": {},
"x": 750,
"y": 600,
"wires": []
},
{
"id": "4f542a7b.a05434",
"type": "http in",
"z": "48504048.5a88a",
"name": "",
"url": "/FILENAME.mp3",
"method": "get",
"upload": false,
"swaggerDoc": "",
"x": 200,
"y": 600,
"wires": [
[
"a5c76fb9.37a868"
]
]
},
{
"id": "94f8414.762bec",
"type": "change",
"z": "48504048.5a88a",
"name": "Set Headers",
"rules": [
{
"t": "set",
"p": "headers",
"pt": "msg",
"to": "{}",
"tot": "json"
},
{
"t": "set",
"p": "headers.content-type",
"pt": "msg",
"to": "audio/mp3",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 570,
"y": 600,
"wires": [
[
"3a141a20.5ea67e"
]
]
},
{
"id": "a5c76fb9.37a868",
"type": "file in",
"z": "48504048.5a88a",
"name": "Music",
"filename": "ABSOLUTE_PATH_TO_FILENAME.mp3",
"format": "",
"chunk": false,
"sendError": true,
"encoding": "none",
"x": 390,
"y": 600,
"wires": [
[
"94f8414.762bec"
]
]
},
{
"id": "a0e04151.1029c8",
"type": "createcall",
"z": "48504048.5a88a",
"creds": "",
"endpoint": "phone",
"to": "{{msg.payload}}",
"dtmfanswer": "",
"wsuri": "",
"headers": "",
"sipuri": "",
"extension": "",
"from": "YOUR_NEXMO_NUMBER",
"ringingtimer": "",
"lengthtimer": "",
"machinedetection": "",
"answer": "https://YOUR_URL/answer",
"answertype": "url",
"eventurl": "https://YOUR_URL/event",
"x": 170,
"y": 780,
"wires": [
[]
]
},
{
"id": "d75a8b3d.e0595",
"type": "stream",
"z": "48504048.5a88a",
"streamurl": "https://YOUR_URL/FILENAME.mp3",
"bargein": false,
"loop": "",
"level": "",
"x": 360,
"y": 940,
"wires": [
[
"e16d213a.4661c"
]
]
},
{
"id": "36e58d42.221692",
"type": "comment",
"z": "48504048.5a88a",
"name": "📖 Check out the tutorial",
"info": "Go to the step-by-step [tutorial](https://www.nexmo.com/blog/2019/07/15/stream-audio-node-red-dr).",
"x": 150,
"y": 40,
"wires": []
},
{
"id": "11b37610.15aaba",
"type": "comment",
"z": "48504048.5a88a",
"name": "❓About This Path - Exposing Your Local Server to the Internet",
"info": "You'll need to [expose your local server to the internet](https://www.nexmo.com/blog/2019/07/03/ngrok-in-node-red-dr/), so that Nexmo can access it. If you’re running Node-RED on a public webserver instead of your local machine, you can skip this stage. \n\nOtherwise, a convenient way to do this is by using a tunneling service like [ngrok](https://ngrok.com).\n\nFirst, you'll need to install the ngrok node. To do so, open up _Manage palette_ from the hamburger menu, search for the `node-red-contrib-ngrok` package and click install. After restarting your editor, the **`ngrok`** node should appear in the node palette.\n\nOpen up the **`ngrok`** node properties and specify the port number. In case of Node-RED, the default value is `1880`. The default ngrok Region is US but you can also set it to Europe or Asia. You can also add your authtoken for your [ngrok account](https://ngrok.com) if you have one. Don't worry if you don't, just skip this step for now. The node will warn that it is not fully configured but this is not an issue.\n\nAnd you're all set! Once you hit deploy and click on the **on** `inject` node's button, navigate to the URL displayed in the debug sidebar (*YOUR_URL* for future reference) to find your Node-RED editor at a public address.",
"x": 270,
"y": 120,
"wires": []
},
{
"id": "fba35bc4.3f8418",
"type": "comment",
"z": "48504048.5a88a",
"name": "❓About This Path - Event Webhook",
"info": "If you'd like to receive events about the progress of your call, you can also setup an event webhook.\nThe `http` input node is connected to a `http response` node, as well as to a `debug` node, so that you can view your call events in the debug sidebar too.\n\nThe `http response` node should have `200` set as `Status code`, but don't worry about it, this is the default value as well.",
"x": 180,
"y": 343,
"wires": []
},
{
"id": "e2049b69.af9a9",
"type": "comment",
"z": "48504048.5a88a",
"name": "❓About This Path - Serving Up the Audio File",
"info": "If you have the audio file somewhere online, make sure it is in either MP3 or WAV format, take note of the URL where it's hosted and continue with the next path. Feel free to delete the one below.\n\nAnother option is serving it up from your computer. To do this, you need an `http` input node, a `file in`, a `change` and an `http response` node. \n\n### **`http in`**\nIn the `http` input node, select `GET` as a `Method` and fill in the `URL` field with something like `/filename.mp3`, so that you can find your audio file at _YOUR-URL/filename.mp3_.\n### **`file in`**\nNext, open up the `file in` node properties, provide the absolute local path to the audio file you're serving up in the `Filename` field and set the `Output` to `a single Buffer object`. This will read the contents of the file as a binary buffer.\n### **`change`**\nYou also need to specify what type of file you're serving up, and that's where the `change` node comes into play. Set `msg.headers` to `{}` and `msg.headers.content-type` to `audio/mp3`.\n\nNow after hitting **Deploy**, point your browser at `YOUR_URL/filename.mp3` and you should hear your audio file playing.",
"x": 210,
"y": 540,
"wires": []
},
{
"id": "4241cdee.10c564",
"type": "comment",
"z": "48504048.5a88a",
"name": "❓About This Path - Create a Nexmo Application",
"info": "Some of Nexmo’s APIs, including the Voice API, use Nexmo Applications to hold security and config information needed to connect to Nexmo endpoints. \n\nIn the Nexmo Node-RED palette, several nodes have the ability to create these applications: `getrecording`, `earmuff`, `mute`, `hangup`, `transfer`, `createcall`, `playaudio`, `playtts` and `playdtmf`.\nThis example uses the **`createcall`** node.\n\n### **`createcall`**\nNext to the `Nexmo Credentials`, select \"Add new nexmovoiceapp...\" from the drop-down menu and click the edit button. Fill in the details below and click `Create New Application`.\n\n| KEY | DESCRIPTION |\n| --------------- | --- |\n| `Name` | Choose a name for your Voice Application, for example `Stream audio`.\n| `API Key` | Your Nexmo API key, shown in your [account overview](https://dashboard.nexmo.com/getting-started-guide). |\n| `API Secret` | Your Nexmo API secret, shown in your [account overview](https://dashboard.nexmo.com/getting-started-guide). |\n| `Answer URL` | The URL that Nexmo makes a request to when handling [inbound calls](https://www.nexmo.com/blog/2019/05/09/receive-phone-calls-node-red-dr/). Set it to YOUR_URL/answer, you'll be hosting a Nexmo Call Control Object (NCCO) here. - more about this later on.\n| `Event URL` | Nexmo will send call events (e.g. ringing, answered) to this URL. If you’d like to receive events about the progress of your call, make sure your server is exposed to the internet, then use `YOUR_URL/event` for this field. Otherwise, feel free to use http://example.com - this will respond with 200 OK. You could also override this eventURL for a specific `createCall` node in its node properties. | \n\nNode-RED will then create a new Nexmo Application on your account and fill in the App ID and Private Key fields for you to save. Now you can find this application in your Nexmo Dashboard under _Voice_ > _[Your Applications](https://dashboard.nexmo.com/voice/your-applications)_.\n\nSelect `Phone` from the `Endpoint` drop-down menu. This will forward the call to a phone number, which you can specify in the text field next to the `Number{}` label. \nNote the `{}` sign, which means that [Mustache templating](https://mustache.github.io/) is supported for this field. You could hardcode a phone number in here, or pass it in dynamically using an **`inject`** node, and in this case, referencing it with `{{msg.payload}}`.\nNext, set one of your [virtual numbers](https://dashboard.nexmo.com/your-numbers) as the `From{}` number.\n\n### Linking Your Virtual Number\n\nNext you need to link your virtual number to the application created earlier by the **`createcall`** node.\n\nFind the Voice Application you've just created in your Nexmo Dashboard by navigating to _Voice_ > _[Your Applications](https://dashboard.nexmo.com/voice/your-applications)_.\nClick on the name of this application, then under the _Numbers_ tab click on the **Link** button next to the virtual number you've rented earlier.",
"x": 220,
"y": 725,
"wires": []
},
{
"id": "5b8fa5c4.8a0204",
"type": "comment",
"z": "48504048.5a88a",
"name": "❓About This Path - Building the Nexmo Call Control Object (NCCO)",
"info": "Nexmo calls are controlled using _Nexmo Call Control Objects_, also known as NCCOs. An NCCO defines a list of actions to be followed when a call is handled. There are lots of different actions available, find the corresponding nodes under the Nexmo palette in your Node-RED editor or check out the [NCCO Reference](https://developer.nexmo.com/api/voice/ncco) to find out more about them.\n\nWhen handling inbound calls, you need your NCCO hosted at an _Answer URL_, and for this you'll need a **`voice webhook`** input node, a **`stream`** node and a **`return NCCO`** output node.\n\n### **`voice webhook`**\nSelect `GET` as a method and type `/answer` in the answer URL field. ",
"x": 280,
"y": 860,
"wires": []
},
{
"id": "5d1691b0.1f7938",
"type": "voice webhook",
"z": "48504048.5a88a",
"name": "",
"url": "",
"method": "get",
"x": 150,
"y": 940,
"wires": [
[
"d75a8b3d.e0595"
]
]
},
{
"id": "e16d213a.4661c",
"type": "return ncco",
"z": "48504048.5a88a",
"name": "",
"x": 560,
"y": 940,
"wires": []
},
{
"id": "456974a8.23fa1c",
"type": "comment",
"z": "48504048.5a88a",
"name": "Now call your Nexmo number! ☎️",
"info": "",
"x": 170,
"y": 1020,
"wires": []
}
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment