Handling SWML From Code
In Making and Receiving Phone Calls we learned how to use SWML Scripts to handle incoming calls serverlessly.
Handling calls from code gives us more flexibility. Instead of serving a static SWML Script, we can use a custom web server to decide the content of the YAML/JSON depending on the incoming call.
In this guide, we will show how to recreate the same setup so you can leverage your preferred programming language to create SWML dynamically.
Setting up the environment
If your preferred language allows you to write YAML/JSON (it probably does), then all you really need is to use your preferred library to spin up a web server:
- Node.js
npm install express
Serving SWML
We'd like to set up an endpoint (our own "dynamic" SWML Script) which emits a valid SWML document, like this one:
- YAML
- JSON
version: 1.0.0
sections:
main:
- play: say:Hello from SignalWire!
{
"version": "1.0.0",
"sections": {
"main": [
{
"play": "say:Hello from SignalWire!"
}
]
}
}
We prefer YAML for its readability, so we're going to use it instead of JSON in this example. The YAML will be sent back to the client as a response to their request. Let's see how to set up a web server to serve valid SWML.
Setting up a web server
How you set up the web server is mostly specific to the language and framework of your choosing. A basic skeleton might be the following:
- Node.js
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.post('/start', async (req, res) => {
let instructions = `
sections:
main:
- play: say:Hello from SignalWire!
`
res.send(instructions)
})
app.listen(3000);
Try running the application, which will listen on port 3000:
- Node.js
node index.js
Since you are likely behind a NAT, to test this application on your local machine you need a public IP address that SignalWire can reach. We suggest using ngrok: refer to our guide on ngrok for more information.
In short, while the application is up and listening on port 3000, run ngrok from a new terminal like this:
ngrok http 3000
You'll get a public random URL (such as https://983f-93-41-16-193.ngrok.io/
) that you can use to access your local application.
Configuring the number
Now that the code is ready and the HTTP endpoint is reachable from the web, we need to configure our SignalWire number to access it.
If you don't have a phone number yet, make sure to buy one. You will need at least one number to receive calls.
Then, open the settings for the number. Under "Voice Settings", choose to
handle messages using "a SWML Script". Set "Handle calls using" to "a SWML Script", then check the "Use External URL for SWML Script handler?" checkbox. Finally, paste the public ngrok URL which connects to your application, making sure to add /start
at the end.
Try calling the phone number: SignalWire will ask your server for the instructions to run and say "Hello from SignalWire!", but you can make SignalWire say/do whatever you like.
Conclusion
We have shown how to handle incoming calls from code, by emitting SWML instructions that say something on a call, but it can do so much more! For more advanced applications, you'll want to check out SWML's Technical Reference.