Wipple CPaaS
Menu
Guide / Getting started

Getting started

This page takes you from an empty project to a working voice application in five steps. By the end you will have received an inbound call, responded with Functions, and placed an outbound call through the REST API.

Prerequisites

  • A Wipple CPaaS account with an API key.
  • A phone number provisioned on the account.
  • An application on the account, with the phone number routed to it.
  • A publicly reachable HTTPS endpoint for your code. During development a tunnelling tool that exposes a local port over HTTPS is sufficient.

Throughout this page {API_ENDPOINT} is the API host name assigned to you and {yourserver} is the public host name of your application.

Step 1: Write a call hook

The call hook is the URL that Wipple CPaaS requests when a new call arrives. It must respond with a JSON array of Functions.

Node.js (Express)

import express from 'express';

const app = express();
app.use(express.json());

app.post('/call', (req, res) => {
  const { from, to, call_sid } = req.body;
  console.log(`incoming call ${call_sid} from ${from} to ${to}`);

  res.json([
    {
      verb: 'say',
      text: 'Thank you for calling Miraicom. Please leave a message after the tone.'
    },
    {
      verb: 'listen',
      actionHook: '/voicemail',
      url: 'wss://{yourserver}/audio',
      playBeep: true,
      timeout: 30,
      finishOnKey: '#'
    },
    {
      verb: 'say',
      text: 'Thank you. Goodbye.'
    }
  ]);
});

app.post('/voicemail', (req, res) => {
  console.log('recording finished', req.body);
  res.json([]);
});

app.listen(3000);

Python (Flask)

from flask import Flask, jsonify, request

app = Flask(__name__)

@app.post("/call")
def call_hook():
    body = request.get_json()
    print("incoming call", body["call_sid"], body["from"], body["to"])
    return jsonify([
        {
            "verb": "say",
            "text": "Thank you for calling Miraicom. Please leave a message after the tone."
        },
        {
            "verb": "listen",
            "actionHook": "/voicemail",
            "url": "wss://{yourserver}/audio",
            "playBeep": True,
            "timeout": 30,
            "finishOnKey": "#"
        },
        {"verb": "say", "text": "Thank you. Goodbye."}
    ])

@app.post("/voicemail")
def voicemail():
    print("recording finished", request.get_json())
    return jsonify([])

The actionHook value /voicemail is a relative URL. Wipple CPaaS resolves relative hook URLs against the URL of the call hook, so it will POST to https://{yourserver}/voicemail.

Step 2: Configure the application

Set the call hook URL of your application to https://{yourserver}/call and, if you want status events, set the call status hook to a URL such as https://{yourserver}/status. Choose the default text-to-speech vendor, language and voice; Functions such as say use these defaults unless you override them.

Step 3: Receive a call

Call the phone number attached to the application. Wipple CPaaS sends a request to https://{yourserver}/call whose body looks like this:

{
  "call_sid": "d2515c3b-b79a-41a2-971a-445e769c823c",
  "application_sid": "72c5c38f-9bba-40ce-aa83-aaa6be55e1b5",
  "account_sid": "bad98250-b34d-459d-9e90-f97dfb9bc519",
  "direction": "inbound",
  "from": "+815099990001",
  "to": "+815099990002",
  "caller_name": "Miraicom Taro",
  "call_status": "trying",
  "sip_status": 100
}

The full list of properties is documented in New Call (POST). Your application returns the Functions from Step 1, the caller hears the greeting and the beep, and the recording is streamed to your WebSocket endpoint.

Step 4: Place an outbound call

Use the REST API to originate a call. The call_hook tells Wipple CPaaS which URL to request once the called party answers.

curl -X POST "https://{API_ENDPOINT}/v1/Accounts/{AccountSid}/Calls" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "from": "+815099990001",
    "to": { "type": "phone", "number": "+815099990002" },
    "call_hook": { "url": "https://{yourserver}/outbound", "method": "POST" },
    "call_status_hook": { "url": "https://{yourserver}/status", "method": "POST" }
  }'

The response contains the sid of the new call:

{
  "sid": "2531329f-fb09-4ef7-887e-84e648214436"
}

When the call is answered, Wipple CPaaS requests https://{yourserver}/outbound, and your application replies with Functions in exactly the same way as for an inbound call. See Create a call for every option, including answering machine detection and SIP targets.

Step 5: Track call status

The call status hook receives a request each time the call changes state (trying, ringing, in-progress, completed, and so on). Your handler should respond with HTTP 200 and an empty body; no Functions are expected.

app.post('/status', (req, res) => {
  const { call_sid, call_status, duration } = req.body;
  console.log(`call ${call_sid} is now ${call_status}`, duration ?? '');
  res.sendStatus(200);
});

Next steps