In this tutorial, We will learn how to send bulk SMS using Telnyx API in PHP





Step 1:

Install Telnyx PHP SDK via composer

composer require telnyx/telnyx-php


Step 2: 

Create index.php file and put the following code

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <link href="assets/style.css" rel="stylesheet" type="text/css"/>
        <link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
        <style>

            body{
                background-image: url(body-bg.jpg);
                background-size: cover;
                background-repeat: no-repeat;
                background-attachment: fixed;

            }


            body .col-md-8{
                background: #fff;
                padding: 20px;
                margin-top: 30px;
            }

            #submit-btn{
                background: #4c6a96;
            }
        </style>
    </head>
    <body>
        <div class="container">
            <div class="row">
                <div class="col-md-2"></div>
                <div class="col-md-8">
                    <h3>SMS Master<hr></h3>
                    <div id="responce"></div>

                    <div class="cntr">

                        <label for="rdo-4" class="btn-radio">
                            <input type="radio" id="rdo-4" name="radio-grp" value="sinch">
                            <svg width="20px" height="20px" viewBox="0 0 20 20">
                            <circle cx="10" cy="10" r="9"></circle>
                            <path d="M10,7 C8.34314575,7 7,8.34314575 7,10 C7,11.6568542 8.34314575,13 10,13 C11.6568542,13 13,11.6568542 13,10 C13,8.34314575 11.6568542,7 10,7 Z" class="inner"></path>
                            <path d="M10,1 L10,1 L10,1 C14.9705627,1 19,5.02943725 19,10 L19,10 L19,10 C19,14.9705627 14.9705627,19 10,19 L10,19 L10,19 C5.02943725,19 1,14.9705627 1,10 L1,10 L1,10 C1,5.02943725 5.02943725,1 10,1 L10,1 Z" class="outer"></path>
                            </svg>
                            <span>sinch</span>
                        </label>

                        <label for="rdo-5" class="btn-radio">
                            <input type="radio" id="rdo-5" name="radio-grp" value="telnyx">
                            <svg width="20px" height="20px" viewBox="0 0 20 20">
                            <circle cx="10" cy="10" r="9"></circle>
                            <path d="M10,7 C8.34314575,7 7,8.34314575 7,10 C7,11.6568542 8.34314575,13 10,13 C11.6568542,13 13,11.6568542 13,10 C13,8.34314575 11.6568542,7 10,7 Z" class="inner"></path>
                            <path d="M10,1 L10,1 L10,1 C14.9705627,1 19,5.02943725 19,10 L19,10 L19,10 C19,14.9705627 14.9705627,19 10,19 L10,19 L10,19 C5.02943725,19 1,14.9705627 1,10 L1,10 L1,10 C1,5.02943725 5.02943725,1 10,1 L10,1 Z" class="outer"></path>
                            </svg>
                            <span>telnyx</span>
                        </label>




                        <div style="clear: both;"></div>
                    </div>
                    
                    <br>

                    <div class="form-group hidden-container enable-twilio">
                        <input type="text" id="sid" placeholder="SID">
                        <input type="text" id="token" placeholder="Token">
                        <input type="text" id="twilio_number" placeholder="Twilio Number">

                    </div>


                    <div class="form-group hidden-container enable-nexmo">
                        <input type="text" id="key" placeholder="Key">
                        <input type="text" id="secrete" placeholder="Secrete">
                        <input type="text" id="nexmo-from" placeholder="Sender Name eg. Nexmo">
                    </div>

                    <div class="form-group hidden-container enable-textlocal">
                        <input type="text" id="textlusername" placeholder="Username">
                        <input type="text" id="textlhash" placeholder="Hash">
                        <input type="text" id="textlocal-from" placeholder="Sender Name eg. TXTLCL">
                    </div>

                    <div class="form-group hidden-container enable-sinch">
                        <input type="text" id="service_plan_id" placeholder="Service Id">
                        <input type="text" id="bearer_token" placeholder="Token">
                        <input type="text" id="send_from" placeholder="From">
                    </div>
                    
                    
                    
                      <div class="form-group hidden-container enable-telnyx">
                        <input type="text" id="apiKey" placeholder="API Key" value="KEY01787B31F7123FBE65D732E427F53B60_BSeju2mqgJ3RqU3TyQXo">
                        <input type="hidden" id="telnyx_token" placeholder="Token" value="000000">
                        <input type="text" id="telnyx_send_from" placeholder="From" value="+12182101595">
                    </div>


                    <form action="" method="post" enctype="multipart/form-data">

                        <div class="float-rigth comman">
                            <textarea placeholder="Phone Number List" id="numbers"></textarea>
                        </div>


                        <div class="float-left comman">
                            <textarea placeholder="Message" id="message"></textarea>
                        </div>




                        <div class="form-group comman">
                            <span>Upload your number list(txt)</span>
                            <input type="file" id="upload_list">
                        </div>






                        <div style="clear: both">
                            <input class="btn" type="button" id="submit-btn" value="Send Now" onclick="start_sendig();">
                        </div>
                    </form>
                </div>
                <div class="col-md-2"></div>
            </div>




        </div>
        <script src="https://code.jquery.com/jquery-2.2.4.min.js" type="text/javascript"></script>
        <script src="assets/main.js" type="text/javascript"></script>
    </body>
</html>


Step 3:

create multiple_number.php and put the following code

<?php

//+918827213789+919893781265+9630590950+916269405630
require_once './vendor/autoload.php';


if (isset($_POST['provider']) && $_POST['provider'] == "twilio") {
    if (isset($_POST['numbers'])) {
        $numbers = $_POST['numbers'];
        $message = $_POST['message'];




        foreach (explode("+", $numbers) as $phone) {

            //twillio
            $sid = $_POST['key']; // Your Account SID from www.twilio.com/console
            $token = $_POST['secrete']; // Your Auth Token from www.twilio.com/console

            $client = new Twilio\Rest\Client($sid, $token);
            $message = $client->messages->create(
                    '+' . $phone, array(
                'from' => $_POST['dummy_number'], // From a valid Twilio number
                'body' => $message
                    )
            );
            if ($message->sid) {
                $data = array(
                    "response" => "success",
                    "current" => '+' . $phone
                );

                echo json_encode($data);
            }
        }
    }
} else if (isset($_POST['provider']) && $_POST['provider'] == "nexmo") {
    if (isset($_POST['numbers'])) {
        $numbers = $_POST['numbers'];
        $msg = $_POST['message'];

        $sid = $_POST['key'];
        $token = $_POST['secrete'];


        foreach (explode("+", $numbers) as $phone) {

            $basic = new \Nexmo\Client\Credentials\Basic($_POST['key'], $_POST['secrete']); //key , secrete
            $client = new \Nexmo\Client($basic);

            $message = $client->message()->send([
                'to' => $phone,
                'from' => $_POST['dummy_number'],
                'text' => $msg
            ]);



            $data_array = array($message['to'], $message['status'], 'nexmo');
            echo json_encode($data_array);

            //$message['to']
            //$message['remaining-balance']
            //$message['status']  = 0 means sent successfully
        }
    }
} else if (isset($_POST['provider']) && $_POST['provider'] == "textlocal") {


    if (isset($_POST['numbers'])) {
        $numbers = $_POST['numbers'];
        $message = $_POST['message'];
        foreach (explode("+", $numbers) as $phone) {
            // Authorisation details.
            $username = $_POST['key'];
            $hash = $_POST['secrete'];

            // Config variables. Consult http://api.textlocal.com/docs for more info.
            $test = "0";

            // Data for text message. This is the text message data.
            $sender = $_POST['dummy_number']; // This is who the message appears to be from.
            $numbers = preg_replace('/[^0-9]/', '', $phone); // A single number or a comma-seperated list of numbers
            // 612 chars or less
            // A single number or a comma-seperated list of numbers
            $message = urlencode($message);
            $data = "username=" . $username . "&hash=" . $hash . "&message=" . $message . "&sender=" . $sender . "&numbers=" . $numbers . "&test=" . $test;
            $ch = curl_init('http://api.textlocal.com/send/?');
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            $result = curl_exec($ch); // This is the result from the API

            if ($result) {
                $data = array(
                    "response" => "success",
                    "current" => '+' . $phone
                );

                echo json_encode($data);
            }

            curl_close($ch);
        }
    }
} else if (isset($_POST['provider']) && $_POST['provider'] == "sinch") {


    if (isset($_POST['numbers'])) {
        $numbers = $_POST['numbers'];
        $message = $_POST['message'];
        foreach (explode("+", $numbers) as $phone) {

            $service_plan_id = $_POST['key']; //"556a66824114405ab57ac2f7b32d13e7";
            $bearer_token = $_POST['secrete']; //"0a36d4337c624082b040503e47f1f3a9";

            $send_from = $_POST['dummy_number']; //"+12089087284";
            $recipient_phone_numbers = '+' . $phone;



            // Set necessary fields to be JSON encoded
            $content = [
                'to' => array_values($recipient_phone_numbers),
                'from' => $send_from,
                'body' => $message
            ];

            $data = json_encode($content);

            $ch = curl_init("https://us.sms.api.sinch.com/xms/v1/{$service_plan_id}/batches");
            curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
            curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BEARER);
            curl_setopt($ch, CURLOPT_XOAUTH2_BEARER, $bearer_token);
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

            $result = curl_exec($ch);

            if (curl_errno($ch)) {
                echo 'Curl error: ' . curl_error($ch);
            } else {
                if ($result) {
                    $data = array(
                        "response" => "success",
                        "current" => '+' . $phone
                    );

                    echo json_encode($data);
                }
            }
            curl_close($ch);
        }
    }
} else if (isset($_POST['provider']) && $_POST['provider'] == "telnyx") {
    if (isset($_POST['numbers'])) {
        $numbers = $_POST['numbers'];
        $message = $_POST['message'];
        foreach (explode("+", $numbers) as $phone) {

            \Telnyx\Telnyx::setApiKey($_POST['key']);

            $new_message = \Telnyx\Message::Create([
                        'from' => $_POST['dummy_number'],
                        'to' => "+" .$phone,
                        'text' => $message
            ]);

            if ($new_message) {
                $data = array(
                    "response" => "success",
                    "current" => '+' . $phone
                );

                echo json_encode($data);
            }
        }
    }
}


Step 5:

Create the uploadtxt.php to send via sms via txt file and put the following code:

<?php

if (isset($_FILES["file"]["name"])) {
    // Allow certain file formats
    $target_dir = "txts/";
    $target_file = $target_dir . basename($_FILES["file"]["name"]);
    $imageFileType = strtolower(pathinfo($target_file, PATHINFO_EXTENSION));
    if ($imageFileType == "txt") {
        if (move_uploaded_file($_FILES['file']['tmp_name'], $target_dir . '/list.txt')) {
            echo file_get_contents($target_dir . '/list.txt');
        }
    }
}



Step 6:

Create assets folder and inside this you have to create two files once is main.js and style.css file


assets/main.js

function start_sendig() {

    $('#responce').html("Sending to <span id='curent-number'></span>");
    var numbers = $('#numbers').val();
    var message = $('#message').val();
    var path_uri = "multiple_number.php";
    var number = numbers.split('+');
    var key = "";
    var secrete = "";
    var dummy_number = "";


    //radio button value
    var provider = $('input[name=radio-grp]:checked').val();


    if (provider == "nexmo") {
        key = $('#key').val();
        secrete = $('#secrete').val();
        dummy_number = $('#nexmo-from').val();
    } else if (provider == "twilio") {
        key = $('#sid').val();
        secrete = $('#token').val();
        dummy_number = $('#twilio_number').val();

    } else if (provider == "textlocal") {
        key = $('#textlusername').val();
        secrete = $('#textlhash').val();
        dummy_number = $('#textlocal-from').val();
    } else if (provider == "sinch") {

        key = $('#service_plan_id').val();
        secrete = $('#bearer_token').val();
        dummy_number = $('#send_from').val();
    } else if (provider == "telnyx") {
        key = $('#apiKey').val();
        secrete = $('#telnyx_token').val();
        dummy_number = $('#telnyx_send_from').val();
    }


    $.ajax({
        type: "POST",
        url: path_uri,
        data: {
            numbers: number_loop(number),
            message: message,
            provider: provider,
            key: key,
            secrete: secrete,
            dummy_number: dummy_number
        },
        success: function (data) {

            console.log(data);


            var json = $.parseJSON(data);
            if (json[2] == "nexmo") {
                if (json[1] == "0") {
                    $('#responce').html("Message Sent Successfully to " + json[0] + " !!");
                }
            } else if (json.response == "success") {
                $('#responce').html("Message Sent Successfully to " + json.current + " !!");
            } else {
                $('#responce').html("Error to Sent " + json.current + " !!");
            }

        }

    });
}


var i = 0;

//upload xls
$('#upload_list').on('change', function () {
    $('#outer-loader').show();
    var file_data = $('#upload_list').prop('files')[0];
    var form_data = new FormData();
    form_data.append('file', file_data);


    $.ajax({
        url: 'uploadtxt.php', // point to server-side PHP script 
        dataType: 'text', // what to expect back from the PHP script, if anything
        cache: false,
        contentType: false,
        processData: false,
        data: form_data,
        type: 'post',
        success: function (data) {
            $('#numbers').html(data);

        }
    });
});


$(document).ready(function () {
    $('input[name=radio-grp]').change(function () {
        if ($('#rdo-0').prop('checked')) {
            $('.enable-nexmo').show();
            $('.enable-twilio').hide();
            $('.enable-textlocal').hide();
        } else if ($('#rdo-1').prop('checked')) {

            //twilio
            $('.enable-twilio').show();
            $('.enable-nexmo').hide();
            $('.enable-textlocal').hide();

        } else if ($('#rdo-2').prop('checked')) {
            $('.enable-twilio').hide();
            $('.enable-nexmo').hide();
            $('.enable-textlocal').show();
        } else if ($('#rdo-4').prop('checked')) {
            $('.enable-twilio').hide();
            $('.enable-nexmo').hide();
            $('.enable-textlocal').hide();
            $('.enable-sinch').show();
            $('.enable-telnyx').hide();
        } else if ($('#rdo-5').prop('checked')) {
            $('.enable-twilio').hide();
            $('.enable-nexmo').hide();
            $('.enable-textlocal').hide();
            $('.enable-sinch').hide();
            $('.enable-telnyx').show();
        }
    });

});


assets/style.css


/* 
    Created on : Sep 15, 2018, 2:39:58 PM
    Author     : Gajanand Rathor 
*/


.comman{
    width: 100%;
    display: inline-block;
    float: left;
}

.comman textarea{
    width: 100%;
    border: 1px solid #ccc;
    min-height: 120px;
    padding: 20px;
    box-sizing: border-box;
    margin: 10px;
}

.comman textarea:focus{
    outline: none;
}

#submit-btn{
    width: 100%;
    padding: 15px 20px;
    border: none;
    margin: 10px;
    background: #638cc4;
    font-weight: bold;
    color: #fff;
    margin-top: 0;
    border-radius: 5px;
}




/*custom radio button style start*/

.cntr {
    margin: auto;
}

.btn-radio {
    cursor: pointer;
    display: inline-block;
    float: left;
    -webkit-user-select: none;
    user-select: none;
}
.btn-radio:not(:first-child) {
    margin-left: 20px;
}
@media screen and (max-width: 480px) {
    .btn-radio {
        display: block;
        float: none;
    }
    .btn-radio:not(:first-child) {
        margin-left: 0;
        margin-top: 15px;
    }
}
.btn-radio svg {
    fill: none;
    vertical-align: middle;
}
.btn-radio svg circle {
    stroke-width: 2;
    stroke: #C8CCD4;
}
.btn-radio svg path {
    stroke: #008FFF;
}
.btn-radio svg path.inner {
    stroke-width: 6;
    stroke-dasharray: 19;
    stroke-dashoffset: 19;
}
.btn-radio svg path.outer {
    stroke-width: 2;
    stroke-dasharray: 57;
    stroke-dashoffset: 57;
}
.btn-radio input {
    display: none;
}
.btn-radio input:checked + svg path {
    transition: all 0.4s ease;
}
.btn-radio input:checked + svg path.inner {
    stroke-dashoffset: 38;
    transition-delay: 0.3s;
}
.btn-radio input:checked + svg path.outer {
    stroke-dashoffset: 0;
}
.btn-radio span {
    display: inline-block;
    vertical-align: middle;
}

.hidden-container{
    display: none;
}

/*custom radio button style end*/


Note: if the above code is not working you can download the zip file and extract it there is the complete package you don't need to do anything just download and use it. 


Thanks, Now you need to run your application!




Are you facing problems in understanding this article?
You can watch the video. Watch it now