Conference Calls

    A conferencing app is where 2 or more people can chat at the same time. It can be as simple as connecting two or more people in a conference bridge or involve many different users and or moderators.

    1. Plivo simultaneously calls all 3 phone numbers that were inserted by the user into the conference app.
    2. Plivo responds with the following message when any of the 3 calls are answered, “You will now be placed into a demo conference. This is brought to you by Plivo. To know more visit us at plivo.com”.
    3. Plivo connects all answered calls into a conference call.
    4. If no calls are answered, Plivo hangs up.

    Prerequisites

    1. Sign up for a free Plivo trial account.
    2. Check out our server-side SDKs 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 example.com. Below is a snippet to set up a route on your webserver. Let’s call it response/conference. Now when we send an HTTP request to example.com/response/conference this route will be invoked. You will now have to configure this URL as the Answer URL in your code. To place the calls into a conference, we need to use the Conference XML. In this route we added a message using the Speak XML and then created a Conference called ‘demo’.

    Note: For PHP, the route will be `example.com/conference.php`.

    Copy the relevant code below into a text file and save it. Let’s call it conferenceXML.

    Code

    Outbound API Call to Conference Participants

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    import plivo
    
    client = plivo.RestClient()
    response = client.calls.create(
        from_='+14151234567',
        to_='+15671234567<+15671234863<+15671234864',
        answer_url='https://example.com/conference',
        answer_method='GET', )
    print(response)
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    
    #
    # Example for Call Create
    #
    require 'rubygems'
    require 'plivo'
    
    include Plivo
    include Plivo::Exceptions
    
    api = RestClient.new("YOUR_AUTH_ID", "YOUR_AUTH_TOKEN")
    
    begin
      response = api.calls.create(
        '+14151234567',
        ['+15671234567','+15671234863','+15671234864'],
        'https://example.com/conference/'
      )
      puts response
    rescue PlivoRESTError => e
      puts 'Exception: ' + e.message
    end
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    
    // Example for Call create
    
    var plivo = require('plivo');
    
    (function main() {
        'use strict';
        
        // As the auth_id and auth_token are unspecified, Plivo will fetch them from the PLIVO_AUTH_ID and PLIVO_AUTH_TOKEN environment variables.
        var client = new plivo.Client();
        client.calls.create(
            "+14151234567", // from
            "+15671234567<+15671234863<+15671234864", // to
            "http://foo.com/conference", // answer url
            {
                answerMethod: "POST",
            },
        ).then(function (response) {
            console.log(response);
        }, function (err) {
            console.error(err);
        });
    })();
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    
    <?php
    /**
     * Example for Call create
     */
    require 'vendor/autoload.php';
    use Plivo\RestClient;
    use Plivo\Exceptions\PlivoRestException;
    $client = new RestClient("YOUR_AUTH_ID", "YOUR_AUTH_TOKEN");
    try {
        $response = $client->calls->create(
            '+14151234567',
            ['+15671234567<+15671234863<+15671234864'],
            'http://foo.com/conference/',
            'POST',
        );
        print_r($response);
    }
    catch (PlivoRestException $ex) {
        print_r($ex);
    }
    
    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
    
    package com.plivo.api.samples.call;
    
    import java.io.IOException;
    import java.util.Collections;
    
    import com.plivo.api.Plivo;
    import com.plivo.api.exceptions.PlivoRestException;
    import com.plivo.api.models.call.Call;
    import com.plivo.api.models.call.CallCreateResponse;
    
    /**
    * Example for Call create
    */
    class CallCreate {
        public static void main(String [] args) {
            Plivo.init();
            try {
                CallCreateResponse response = Call.creator("+14151234567", Collections.singletonList("+15671234567<+15671234863<+15671234864"), "http://foo.com/conference")
                    .answerMethod("POST")
                    .create();
    
                System.out.println(response);
            } catch (PlivoRestException | IOException 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
    
    // Example for Call create
    package main
    
    import "fmt"
    import "github.com/plivo/plivo-go"
     
    func main() {
    	client, err := plivo.NewClient("YOUR_AUTH_ID", "YOUR_AUTH_TOKEN", &plivo.ClientOptions{})
    	if err != nil {
    		panic(err)
    	}
    	response, err := client.Calls.Create(
    		plivo.CallCreateParams{
    			From: "+14151234567",
    			To: "+15671234567<+15671234863<+15671234864",
    			AnswerURL: "http://foo.com/conference/",
    			AnswerMethod: "POST",
    		},
    	)
    	if err != nil {
    		panic(err)
    	}
    	fmt.Printf("Response: %#v\n", response)
    }
    
    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
    
    /**
     * Example for Call Create
     */
    using System;
    using System.Collections.Generic;
    using Plivo;
    using Plivo.Exception;
    
    namespace PlivoExamples
    {
        internal class Program
        {
            public static void Main(string[] args)
            {
                var api = new PlivoApi("YOUR_AUTH_ID", "YOUR_AUTH_TOKEN");
                try
                {
                    var response = api.Call.Create(
                        to:new List<String>{"+15671234567","+15671234863","+15671234864"},
                        from:"+14151234567",
                        answerMethod:"GET",
                        answerUrl:"http://foo.com/conference/"
                    );
                    Console.WriteLine(response);
                }
                catch (PlivoRestException e)
                {
                    Console.WriteLine("Exception: " + e.Message);
                }
            }
        }
    }
    

    Conference XML and Callbacks

    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
    
    from flask import Flask, Response, request, make_response
    from plivo import plivoxml
    
    app=Flask(__name__)
    
    @app.route('/conference/', methods=['GET','POST'])
    def conference():
        response = plivoxml.ResponseElement()
        response.add(plivoxml.SpeakElement('You will now be placed into a demo conference. This is brought to you by Plivo. To know more visit us at plivo.com'))
        response.add(plivoxml.ConferenceElement('My Room',
            action='https://example.com/conference/action/',
            method='POST',
            callback_url='https://example.com/conference/callback/',
            callback_method='POST',
            enter_sound='beep:2',
            start_conference_on_enter=True,
            end_conference_on_exit=True))
        return Response(response.to_string(), mimetype='application/xml')
    
    # Action URL Example
    
    @app.route('/conference/action/', methods=['GET','POST'])
    def action():
        conf_name = request.values.get('ConferenceName')
        conf_uuid = request.values.get('ConferenceUUID')
        conf_mem_id = request.values.get('ConferenceMemberID')
        record_url = request.values.get('RecordUrl')
        record_id = request.values.get('RecordingID')
        response = make_response('OK')
        response.headers['Content-type'] = 'text/plain'
        print "Conference Name : %s " % (conf_name)
        print "Conference UUID : %s " % (conf_uuid)
        print "Conference Member ID : %s " % (conf_mem_id)
        print "Record URL : %s " % (record_url)
        print "Recording ID : %s " % (record_id)
        return response
    
    # Callback URL Example
    
    @app.route('/conference/callback/', methods=['GET','POST'])
    def callback():
        conf_action = request.values.get('ConferenceAction')
        conf_name = request.values.get('ConferenceName')
        conf_uuid = request.values.get('ConferenceUUID')
        conf_mem_id = request.values.get('ConferenceMemberID')
        call_uuid = request.values.get('CallUUID')
        record_url = request.values.get('RecordUrl')
        record_id = request.values.get('RecordingID')
        response = make_response('OK')
        response.headers['Content-type'] = 'text/plain'
        print "Conference Name : %s " % (conf_name)
        print "Conference UUID : %s " % (conf_uuid)
        print "Conference Member ID : %s " % (conf_mem_id)
        print "Record URL : %s " % (record_url)
        print "Recording ID : %s " % (record_id)
        return response
    
    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
    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
    
    require 'rubygems'
    require 'sinatra'
    require 'plivo'
    
    include Plivo
    include Plivo::XML
    
    get '/conference' do
    
        r = Response.new()
        r.addSpeak("You will now be placed into a demo conference. This is brought to you by Plivo. To know more visit us at plivo.com")
        params = {
            'enterSound' => "beep:2", # Used to play a sound when a member enters the conference
            'record' => "true", # Option to record the call
            'action' => "https://example.com/conference/action/", # URL to which the API can send back parameters
            'method' => "GET", # method to invoke the action Url
            'record' => "true", # Option to record the call
            'callbackUrl' => "https://example.com/conference/callback/", # If specified, information is sent back to this URL
            'callbackMethod' => "GET", # Method used to notify callbackUrl
            'startConferenceOnEnter' => "true", # When a member joins the conference with this attribute set to true, the conference is started.
                                               # If a member joins a conference that has not yet started, with this attribute value set to false,
                                               # the member is muted and hears background music until another member joins the conference
            'endConferenceOnExit' => "true" # If a member with this attribute set to true leaves the conference, the conference ends and all
                                           # other members are automatically removed from the conference.
        }
        conference_name = "demo"
        r.addConference(conference_name,params)
    
        xml = PlivoXML.new(r)
        content_type "application/xml"
        return xml.to_s()
    end
    
    get '/action/' do
        conf_name = params[:ConferenceName]
        conf_uuid = params[:ConferenceUUID]
        conf_mem_id = params[:ConferenceMemberID]
        record_url = params[:RecordUrl]
        record_id = params[:RecordingID]
    
        puts ("Conference Name : #{conf_name}, Conference UUID : #{conf_uuid}, Member ID : #{conf_mem_id}, Record URL : #{record_url}, Record ID : #{record_id}")
    
    end
    
    get '/callback/' do
        conf_action = params[:ConferenceAction]
        conf_name = params[:ConferenceName]
        conf_uuid = params[:ConferenceUUID]
        conf_mem_id = params[:ConferenceMemberID]
        call_uuid = params[:CallUUID]
        record_url = params[:RecordUrl]
        record_id = params[:RecordingID]
    
        puts ("Conference Action : #{conf_action}, Conference Name : #{conf_name}, Conference UUID : #{conf_uuid}, Member ID : #{conf_mem_id}, Call UUID : #{call_uuid}, Record URL : #{record_url}, Record ID : #{record_id}")
    
    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
    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
    
    var plivo = require('plivo');
    var express = require('express');
    var app = express();
    
    app.set('port', (process.env.PORT || 5000));
    app.use(express.static(__dirname + '/public'));
    
    app.all('/conference/', function(request, response) {
        // Generates a Conference XML
        var r = plivo.Response();
        r.addSpeak("You will now be placed into a demo conference. This is brought to you by Plivo. To know more visit us at plivo.com");
        var params = {
            'enterSound' : "beep:2", // Used to play a sound when a member enters the conference
            'record' : "true", // Option to record the call
            'action' : "http://foo.com/conference/action/", // URL to which the API can send back parameters
            'method' : "POST", // method to invoke the action Url
            'callbackUrl' : "http://foo.com/conference/callback/", // If specified, information is sent back to this URL
            'callbackMethod' : "POST", // Method used to notify callbackUrl
            'startConferenceOnEnter' : "true", // When a member joins the conference with this attribute set to true, the conference is started.
                                               // If a member joins a conference that has not yet started, with this attribute value set to false,
                                               // the member is muted and hears background music until another member joins the conference
            'endConferenceOnExit' : "true" // If a member with this attribute set to true leaves the conference, the conference ends and all
                                           // other members are automatically removed from the conference.
        };
    
        var conference_name = "demo"; // Conference Room name
        r.addConference(conference_name, params);
        console.log (r.toXML());
    
        response.set({
            'Content-Type': 'text/xml'
        });
        response.end(r.toXML());
    
    });
    
    app.all('/conference/action/', function(request, response) {
        var conf_name = request.param('ConferenceName');
        var conf_uuid = request.param('ConferenceUUID');
        var conf_mem_id = request.param('ConferenceMemberID');
        var record_url = request.param('RecordUrl');
        var record_id = request.param('RecordingID');
    
        console.log ('Conference Name : ' + conf_name + ' Conference UUID  : ' + conf_uuid + ' Conference Member ID : ' + conf_mem_id + ' Record Url : '
            + record_url + ' Record ID : ' + record_id);
    });
    
    app.all('/conference/callback/', function(request, response) {
        var conf_action = request.param('ConferenceAction')
        var conf_name = request.param('ConferenceName');
        var conf_uuid = request.param('ConferenceUUID');
        var conf_mem_id = request.param('ConferenceMemberID');
        var call_uuid = request.param('CallUUID')
        var record_url = request.param('RecordUrl');
        var record_id = request.param('RecordingID');
    
        console.log ('Conference Action : ' + conf_action + ' Conference Name : ' + conf_name + ' Conference UUID  : ' + conf_uuid
            + ' Conference Member ID : ' + conf_mem_id + ' Call UUID : ' + call_uuid + ' Record Url : ' + record_url + ' Record ID : ' + record_id);
    });
    
    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
    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
    
    <!--conference.php-->
    
    <?php
        require 'vendor/autoload.php';
        use Plivo\XML\Response;
        $r = new Response();
        $body = "You will now be placed into a demo conference. This is brought to you by Plivo. To know more visit us at plivo.com";
        $r->addSpeak($body);
        $params = array(
                'enterSound' => "beep:2", # Used to play a sound when a member enters the conference
                'record' => "true", # Option to record the call
                'action' => "https://example.com/action.php", # URL to which the API can send back parameters
                'method' => "GET", # method to invoke the action Url
                'callbackUrl' => "https://example.com/callback.php", # If specified, information is sent back to this URL
                'callbackMethod' => "GET", # Method used to notify callbackUrl
                # For moderated conference
                'startConferenceOnEnter' => "true", # When a member joins the conference with this attribute set to true, the conference is started.
                                       # If a member joins a conference that has not yet started, with this attribute value set to false,
                                       # the member is muted and hears background music until another member joins the conference
                'endConferenceOnExit' => "true" # If a member with this attribute set to true leaves the conference, the conference ends and all
                                   # other members are automatically removed from the conference.
            );
    
        $conference_name = "demo";
        $r->addConference($conference_name, $params);
        Header('Content-type: text/xml');
        echo($r->toXML());
    ?>
    
    <!--action.php-->
    
    <?php
        $conf_name = $_REQUEST['ConferenceName'];
        $conf_uuid = $_REQUEST['ConferenceUUID'];
        $conf_mem_id = $_REQUEST['ConferenceMemberID'];
        $record_url = $_REQUEST['RecordUrl'];
        $record_id = $_REQUEST['RecordingID'];
        error_log("Conference Name : $conf_name, Conference UUID : conf_uuid, Conference Member ID : conf_mem_id, Record URL : $record_url, Record ID : $record_id");
        echo "Conference Name : $conf_name, Conference UUID : conf_uuid, Conference Member ID : conf_mem_id, Record URL : $record_url, Record ID : $record_id";
    ?>
    
    <!--callback.php-->
    
    <?php
        $conf_action = $_REQUEST['ConferenceAction'];
        $conf_name = $_REQUEST['ConferenceName'];
        $conf_uuid = $_REQUEST['ConferenceUUID'];
        $conf_mem_id = $_REQUEST['ConferenceMemberID'];
        $call_uuid = $_REQUEST['CallUUID'];
        $record_url = $_REQUEST['RecordUrl'];
        $record_id = $_REQUEST['RecordingID'];
        error_log("Conference Action : $conf_action, Conference Name : $conf_name, Conference UUID : conf_uuid,
            Conference Member ID : conf_mem_id, Call UUID : $call_uuid, Record URL : $record_url, Record ID : $record_id");
        echo "Conference Action : $conf_action, Conference Name : $conf_name, Conference UUID : conf_uuid,
            Conference Member ID : conf_mem_id, Call UUID : $call_uuid, Record URL : $record_url, Record ID : $record_id";
    ?>
    
    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
    
    import static spark.Spark.*;
    import com.plivo.api.xml.Conference;
    import com.plivo.api.xml.Speak;
    import com.plivo.api.xml.Response;
    
    public class conferencecall {
        public static void main(String[] args) {
            post("/conference", (request, response) -> {
                response.type("application/xml");
                Response resp = new Response();
                resp.children(new Speak("You will now be placed into a demo conference. This is brought to you by Plivo. To know more visit us at plivo.com"));
                resp.children(
                        new Conference("My Room")
                        .action("http://foo.com/conference/action")
                        .method("POST")
                        .callbackMethod("POST")
                        .callbackUrl("http://foo.com/conference/callback")
                        .enterSound("beep:2")
                        .record(true)
                        .startConferenceOnEnter(true)
                        .endConferenceOnExit(true)
                );
                return resp.toXmlString();
            });
            post("/conference/action", (request, response) -> {
                String conf_name = request.queryParams("ConferenceName");
                String conf_uuid = request.queryParams("ConferenceUUID");
                String conf_mem_id = request.queryParams("ConferenceMemberID");
                String record_url = request.queryParams("RecordUrl");
                String record_id = request.queryParams("RecordingID");
                System.out.println("Conference Name : " + conf_name + " Conference UUID : " + conf_uuid + " Conference Member ID : " + conf_mem_id +
                        " Record URL : " + record_url + " Record ID : " + record_id);
                response.raw().getWriter().print("Conference Name : " + conf_name + " Conference UUID : " + conf_uuid + " Conference Member ID : " + conf_mem_id +
                        " Record URL : " + record_url + " Record ID : " + record_id);
                return "done";
            });
            post("/conference/callback", (request, response) -> {
                String conf_action = request.queryParams("ConferenceAction");
                String conf_name = request.queryParams("ConferenceName");
                String conf_uuid = request.queryParams("ConferenceUUID");
                String conf_mem_id = request.queryParams("ConferenceMemberID");
                String call_uuid = request.queryParams("CallUUID");
                String record_url = request.queryParams("RecordUrl");
                String record_id = request.queryParams("RecordingID");
                System.out.println("Conference Action : " + conf_action + " Conference Name : " + conf_name + " Conference UUID : " + conf_uuid + " Conference Member ID : " + conf_mem_id +
                        " Call UUID : " + call_uuid + " Record URL : " + record_url + " Record ID : " + record_id);
                response.raw().getWriter().print("Conference Action : " + conf_action + "Conference Name : " + conf_name + " Conference UUID : " + conf_uuid + " Conference Member ID : " + conf_mem_id +
                        " Call UUID : " + call_uuid + " Record URL : " + record_url + " Record ID : " + record_id);
                return "done";
            });
        }
    }
    
    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
    
    package main
    
    import (
    	"github.com/go-martini/martini"
    	"github.com/plivo/plivo-go/xml"
    	"net/http"
    )
    
    func main() {
    	m := martini.Classic()
    	m.Post("/conference", func(w http.ResponseWriter, r *http.Request) string {
    		w.Header().Set("Content-Type", "application/xml")
    		response := xml.ResponseElement{
    			Contents: []interface{}{
    				new(xml.SpeakElement).
    					SetContents("You will now be placed into a demo conference. This is brought to you by Plivo. To know more visit us at plivo.com"),
    				new(xml.ConferenceElement).
    					SetAction("http://foo.com/conference/action").
    					SetMethod("POST").
    					SetCallbackMethod("POST").
    					SetCallbackUrl("http://foo.com/conference/callback").
    					SetContents("My Room"),
    			},
    		}
    		return response.String()
    	})
    	m.Post("/conference/action", func(w http.ResponseWriter, r *http.Request) string {
    		conferenceName := r.FormValue("ConferenceName")
    		conferenceUUID := r.FormValue("ConferenceUUID")
    		conferenceMemberID := r.FormValue("ConferenceMemberID")
    		recordUrl := r.FormValue("RecordUrl")
    		recordingID := r.FormValue("RecordingID")
    		result := conferenceName + " " + conferenceUUID + " " + conferenceMemberID + " " + recordUrl + " " + recordingID
    		return result
    	})
    	m.Post("/conference/callback", func(w http.ResponseWriter, r *http.Request) string {
    		conf_action := r.FormValue("ConferenceAction");
        conf_name := r.FormValue("ConferenceName");
        conf_uuid := r.FormValue("ConferenceUUID");
        conf_mem_id := r.FormValue("ConferenceMemberID");
        call_uuid := r.FormValue("CallUUID");
        record_url := r.FormValue("RecordUrl");
        record_id := r.FormValue("RecordingID");
    		result := conf_action + " " + conf_name + " " + conf_uuid + " " + conf_mem_id + " " + call_uuid + " " + record_url + " " + record_id
    		return result
    	})
    	m.Run()
    }
    
    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
    
    using System;
    using System.Collections.Generic;
    using Plivo.XML;
    using Microsoft.AspNetCore.Mvc;
    
    namespace Conferencecall.Controllers
    {
        public class ConferenceController : Controller
        {
            // GET: /<controller>/
            public IActionResult Index()
            {
                Plivo.XML.Response resp = new Plivo.XML.Response();
                resp.AddSpeak("You will now be placed into a demo conference. This is brought to you by Plivo. To know more, visit us at Plivo.com",
                 new Dictionary<string, string>() { });
                resp.AddConference("My room",
                   new Dictionary<string, string>() {
                       {"action", "http://foo.com/conference/action/"},
                       {"method", "GET" },
                       {"callbackUrl", "http://foo.com/conference/callback/"},
                       {"callbackMethod", "POST"},
                       {"enterSound", "beep:2"},
                       {"record", "true"},
                       {"startConferenceOnEnter", "true"},
                       {"endConferenceOnExit", "true"}
                   });
                var output = resp.ToString();
                return this.Content(output, "text/xml");
            }
            //Action URL
            public String Action()
            {
                var conf_name = Request.Query["ConferenceName"];
                var conf_uuid = Request.Query["ConferenceUUID"];
                var conf_mem_id = Request.Query["ConferenceMemberID"];
                var record_url = Request.Query["RecordUrl"];
                var record_id = Request.Query["RecordingID"];
                var result = conf_name + " " + conf_uuid + " " + conf_mem_id + " " + record_url + " " + record_id;
                return result;
            }
            //Callback URL
            public String Callback()
            {
                var conf_action = Request.Query["ConferenceAction"];
                var conf_name = Request.Query["ConferenceName"];
                var conf_uuid = Request.Query["ConferenceUUID"];
                var conf_mem_id = Request.Query["ConferenceMemberID"];
                var call_uuid = Request.Query["CallUUID"];
                var record_url = Request.Query["RecordUrl"];
                var record_id = Request.Query["RecordingID"];
                var result = conf_action + " " + conf_name + " " + conf_uuid + " " + conf_mem_id + " " + call_uuid + " " + record_url + " " + record_id;
                return result;
            }
        }
    }
    
    1. To make the outbound calls, copy the last code sample into a text editor and save it as conference.py
    2. Add your ‘from’ (source) phone number. This will show up as your Caller ID. Be sure that all phone numbers include country code, area code, and phone number without spaces or dashes (e.g. 14153336666).
    3. Add your ‘to’ (destination) phone numbers. These are the phone numbers you wish to call to. To place calls in bulk, separate your destination phone numbers with the “<” character (e.g. 14156667777<14157778888<14158889999). Be sure that all phone numbers include country code, area code, and phone number without spaces or dashes (e.g. 14153336666).
    4. Change the answer_url to example.com/response/conference which was created previously.

    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. Let’s call it Conference Call. Enter your server URL (e.g., http://www.example.com/response/conference) 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 Record Call 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 Conference Call (name of the app) from the Plivo App dropdown list.
    3. Click on ‘Update’ to save.

    Assign Conference Application

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

    Voice Phone Number Search

    Test and validate

    Whe you make a call to your Plivo number, you will hear the message and then you will be place into a conference.

    Sample XML

    <Response>
        <Speak>You will now be placed into a demo conference. This is brought to you by Plivo. To know more visit us at plivo.com</Speak>
        <Conference action="https://www.example.com/response/action/" callbackMethod="GET"
            callbackUrl="https://www.example.com/response/callback/" enterSound="beep:2" method="GET" record="true"
            startConferenceOnEnter="true" endConferenceOnExit="true">demo
        </Conference>
    </Response>

    Sample output for action URL

    Conference Name : demo
    Conference UUID : 1edcce24-94a6-11e4-a29c-498d468c930b
    Conference Member ID : 4387
    Record URL : http://s3.amazonaws.com/recordings_2000/00000000-1111-2222-3333-4444b5555684.mp3
    Recording ID : 1e9eca52-94a6-11e4-b499-0026b92f9684

    Sample output for Callback URL

    Conference Action : enter
    Conference Name : demo
    Conference UUID : 1edcce24-94a6-11e4-a29c-498d468c930b
    Conference Member ID : 4387
    Call UUID : a59bc002-94a9-11e4-ad11-3f7813869e0a
    Record URL : http://s3.amazonaws.com/recordings_2000/00000000-1111-2222-3333-4444b5555684.mp3
    Recording ID : 1e9eca52-94a6-11e4-b499-0026b92f9684