Play Custom Music to Caller

While an outbound call is being connected, you can customize the sound to be played to the caller. The sound is defined by a remote URL fetched with an HTTP POST request which must return only ‹Play›, ‹Wait› and/or ‹Speak› XML elements (all others are ignored). The sound indicated by the XML is played to the A-Leg party when the call is initiated/answered. You can also use the value 'real' which will play the real ringtone of the called party.

Prerequisites

  1. Sign up for a free Plivo trial account.
  2. Check out our Helper Libraries page and install the right helper based on the programming language you want to use.
  3. Buy a Plivo phone number. A phone number is required to receive calls. You can buy a Plivo phone number in over 20+ countries through the Buy Numbers tab on your Plivo account UI. Check the Voice API coverage page for all the supported countries.
  4. Use a web hosting service to host your web application. There are many inexpensive cloud hosting providers that you can use for just a few dollars a month. Follow the instructions of your hosting provider to host your web application.

Set up a Web Server

Let’s assume your web server is located at https://example.com. Below is some code to set up a route called /dial/ on your webserver. For this tutorial, this route will be the Answer URL of a Plivo application associated with a Plivo number where you can receive incoming calls; it also could be the Answer URL of an outbound call. When an HTTP request is sent to example.com/dial/, this route will return a Dial XML element to make an outbound call to another number and, while calling, custom music will be played to the caller. To setup that custom music, another route is defined, called /custom_tone/, which will return a Play XML element with the URL of the WAV or MP3 file you want to play.

Note: For PHP, the routes will be example.com/dial.php and example.com/custom_tone.php.

  1. Copy the relevant code below into a text file and save it. Lets call it, custom_music.
    Note: Make sure to use the appropriate file extention for your code (e.g., .py for Python).
  2. Change the phone number to dial for the B-Leg of the call and change the url of the addPlay function.
  3. Now that you have the code, you will need to expose your server to the public Internet. This way, Plivo will know where to find your app when a particular phone number is dialed. Moving forward, we will assume that your app is available at example.com.

Code

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
from flask import Flask, request, Response
import plivoxml

app=Flask(__name__)

@app.route('/dial/', methods=['GET','POST'])
def dial():
    response = plivoxml.Response()
    # When an outbound call is made to different number using a Dial element,
    # you can play a custom caller tone using the dialMusic attribute
    params = {
        'dialMusic' : "https://example.com/custom_tone/"
    }
    d = response.addDial(**params)
    d.addNumber("1111111111")
    print response.to_xml()
    return Response(str(response), mimetype='text/xml')

# Play XML is returned on the dialMusic URL
@app.route('/custom_tone/', methods=['POST'])
def custom_tone():
    response = plivoxml.Response()
    response.addPlay("https://s3.amazonaws.com/plivocloud/music.mp3")
    print response.to_xml()
    return Response(str(response), mimetype='text/xml')

if __name__ == "__main__":
    app.run(host='0.0.0.0', debug=True)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
require 'rubygems'
require 'sinatra'
require 'plivo'
include Plivo

get '/dial/' do
    r = Response.new()
    # When an outbound call is made to different number using a Dial element,
    # you can play a custom caller tone using the dialMusic attribute
    params = {
        'dialMusic' => "https://example.com/custom_tone/"
    }

    d = r.addDial(params)
    d.addumber("1111111111")
    puts r.to_xml()
    content_type 'text/xml'
    return r.to_s()
end

# Play XML is returned on the dialMusic URL
post '/custom_tone/' do
    r = Response.new()
    r.addPlay("https://s3.amazonaws.com/plivocloud/music.mp3")
    puts r.to_xml()
    content_type 'text/xml'
    return r.to_s()
end
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
var plivo = require('plivo');
var express = require('express');
var app = express();

app.set('port', (process.env.PORT || 5000));

app.all('/dial/', function(request, response) {
  var r = plivo.Response();
  // When an outbound call is made to different number using a Dial element,
  // you can play a custom caller tone using the dialMusic attribute
  var params = {
    'dialMusic' : "https://example.com/custom_tone/"
  };
  var d = response.addDial(params);
  d.addNumber("1111111111");
  console.log(r.toXML());
  response.set({'Content-Type': 'text/xml'});
  response.send(r.toXML());
});

// Play XML is returned on the dialMusic Url
app.post('/custom_tone/', function(request, response) {
  var r = plivo.Response();
  r.addPlay("https://s3.amazonaws.com/plivocloud/music.mp3");
  console.log(r.toXML());
  response.set({'Content-Type': 'text/xml'});
  response.send(r.toXML());
});

app.listen(app.get('port'), function() {
    console.log('Node app is running on port', app.get('port'));
});
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?php
    require 'vendor/autoload.php';
    use Plivo\Response;
    $r = new Response();
    $params = array(
        // Music to be played to the caller while the call is being connected.
        'dialMusic' => 'https://example.com/custom_tone.php'
    );
    // Add Dial tag
    $d = $r->addDial($params);
    $number = "1111111111";
    $d->addNumber($number);
    Header('Content-type: text/xml');
    echo($r->toXML());
?>

<!--custom_tone.php-->

<?php
    require 'vendor/autoload.php';
    use Plivo\Response;
    $r = new Response();
    $body = "https://s3.amazonaws.com/plivocloud/music.mp3";
    // Add Play tag
    $r->addPlay($body);
    Header('Content-type: text/xml');
    echo($r->toXML());
?>
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
// customTone.java
package plivoexample;

import java.io.IOException;

import com.plivo.helper.exception.PlivoException;
import com.plivo.helper.xml.elements.Dial;
import com.plivo.helper.xml.elements.Number;
import com.plivo.helper.xml.elements.PlivoResponse;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.plivo.helper.api.client.*;
import com.plivo.helper.api.response.call.Call;
import com.plivo.helper.exception.PlivoException;

import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;

public class customTone extends HttpServlet {
    private static final long serialVersionUID = 1L;
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {

        PlivoResponse response = new PlivoResponse();
        Dial dial = new Dial();
        dial.setDialMusic("https://example.com/custom_tone");
        Number num = new Number("1111111111");

        try {
            dial.append(num);
            response.append(dial);
            System.out.println(response.toXML());
            resp.addHeader("Content-Type", "text/xml");
            resp.getWriter().print(response.toXML());;
        } catch (PlivoException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws Exception {
        String port = System.getenv("PORT");
        if(port==null)
            port ="8000";
        Server server = new Server(Integer.valueOf(port));
        ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
        context.setContextPath("/");
        server.setHandler(context);
        context.addServlet(new ServletHolder(new customTone()),"/dial/");
        context.addServlet(new ServletHolder(new customTonePlay()),"/custom_tone/");
        server.start();
        server.join();
    }
}

// customTonePlay.java
package plivoexample;

import java.io.IOException;

import com.plivo.helper.exception.PlivoException;
import com.plivo.helper.xml.elements.Play;
import com.plivo.helper.xml.elements.PlivoResponse;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class customTonePlay extends HttpServlet {
    private static final long serialVersionUID = 1L;
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {

        PlivoResponse response = new PlivoResponse();
        Play play = new Play("https://s3.amazonaws.com/plivocloud/music.mp3");

        try {
            response.append(play);
            System.out.println(response.toXML());
            resp.addHeader("Content-Type", "text/xml");
            resp.getWriter().print(response.toXML());;
        } catch (PlivoException e) {
            e.printStackTrace();
        }
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
using System;
using System.Collections.Generic;
using System.Diagnostics;
using RestSharp;
using Plivo.XML;
using Nancy;

namespace custom_tone
{
    public class Program : NancyModule
    {
        public Program()
        {
            Get["/dial/"] = x =>
            {
                Plivo.XML.Response resp = new Plivo.XML.Response();

                // Generate Dial XML
                Plivo.XML.Dial dial = new Plivo.XML.Dial(new Dictionary<string, string>()
                {
                    {"dialMusic","http://example.com/custom_tone/"} // Music to be played to the caller while the call is being connected.
                });
                dial.AddNumber("1111111111", new Dictionary<string, string>() { });

                resp.Add(dial);
                Debug.WriteLine(resp.ToString());

                var output = resp.ToString();
                var res = (Nancy.Response)output;
                res.ContentType = "text/xml";
                return res;
            };

            Post["/custom_tone/"] = x =>
            {
                Plivo.XML.Response resp = new Plivo.XML.Response();

                // Add Play XML Tags
                resp.AddPlay("https://s3.amazonaws.com/plivocloud/music.mp3", new Dictionary<string, string>() { });

                Debug.WriteLine(resp.ToString());

                var output = resp.ToString();
                var res = (Nancy.Response)output;
                res.ContentType = "text/xml";
                return res;
            };
        }
    }
}

Create an Application

  1. Create an Application by visiting the Application Page and click on New Application or by using Plivo’s Application API.
  2. Give your application a name. Lets call it Custom Music. Enter your server URL (e.g., http://example.com/dial/) in the Answer URL field and set the method as POST. See our Application API docs to learn how to modify your application through our APIs.
  3. Click on Create to save your application.

Create Custom Music Application

Assign a Plivo number to your app

  1. Navigate to the Numbers page and select the phone number you want to use for this app.
  2. Select Custom Music (name of the app) from the Plivo App dropdown list.
  3. Click on ‘Update’ to save.

Create Custom Music Application

If you don’t have a number, go to the Buy Number page to purchase a Plivo phone number.

SMS Phone Number Search

Test it out

When you make a call to your Plivo number, the call will be answered by Plivo and the caller will hear music being played while an outbound call is being placed to the other number.

Sample XML

<Response>
    <Dial dialMusic="https://example.com/custom_tone">
        <Number>1111111111</Number>
    </Dial>
</Response>

<Response>
    <Play>https://s3.amazonaws.com/plivocloud/music.mp3</Play>
</Response>

Next Step

Learn how to Build an IVR Phone Menu.

  1. Make an Outbound Call
  2. Play a Text-to-speech Message
  3. Connect Call to a Second Person
  4. Greet Caller by Name
  5. Play MP3/WAV Audio to Caller
  6. Hangup Using API
  7. Receive Incoming Call
  8. Forward Incoming Call
  9. Record Using API
  10. Screen Incoming Call
  11. Reject incoming call
  12. Get Details of all Calls
  13. Get Details of a single Call
  14. Get Details of Live Calls
  15. Build an IVR Phone Menu
  16. Conference Call
  17. Call Forward
  18. SIP Endpoint (Direct-Dial)
  19. Inbound Trunk
  20. Outbound Trunk