Friday, March 18, 2016

Twilio Voice call integration using PHP and JS


First step is to signup on twilio using a valid mobile number - which will get a verification code which is used to verify the mobile number.

Selection_120.png

www.twilio.com/try-twilio

On clicking the Get Your First Twilio Phone Number, a sample phone number will be provided by twilio which will be used to generate calls (From number).

Selection_121.png

Download the sdk and setup the code to autoload the sdk in the project.
Go to Dashboard www.twilio.com/user/account/voice/dashboard click on ‘view API credentials’ to get the id and token.

Now go to www.twilio.com/user/account/voice/dev-tools/twiml-apps and create a sample TwiML app. On the voice section provide an accessible url from which twilio will be fetching the from and to numbers for connecting (will explain in detail below).
E.g. http://DOMAIN/twilioCall.php

Generate required files for initiating calls.

demoCall.php : Display the dial-er page.

<?php
include 'Services/Twilio/Capability.php';
 
// put your Twilio API credentials here
// https://www.twilio.com/user/account/settings
$accountSid = 'AccountId';
$authToken  = 'token';
 
// put your Twilio Application Sid here
// https://www.twilio.com/user/account/voice/dev-tools/twiml-apps and select an app to get the app id
$appSid     = 'TwiMLAppID';
 
$capability = new Services_Twilio_Capability($accountSid, $authToken);
$capability->allowClientOutgoing($appSid);
$capability->allowClientIncoming('incommingTest');
$token = $capability->generateToken();
?>

<!DOCTYPE html>
<html>
  <head>
    <title>Call Demo</title>
    <script type="text/javascript"
      src="//media.twiliocdn.com/sdk/js/client/v1.3/twilio.min.js"></script>
    <script type="text/javascript"
      src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js">
    </script>
    <link href="//static0.twilio.com/resources/quickstart/client.css"
      type="text/css" rel="stylesheet" />
    <script type="text/javascript">

      Twilio.Device.setup("<?php echo $token; ?>");

      Twilio.Device.ready(function (device) {
        $("#log").text("Ready");
      });

      Twilio.Device.error(function (error) {
        $("#log").text("Error: " + error.message);
      });

      Twilio.Device.connect(function (conn) {
        $("#log").text("Successfully established call");
      });

      Twilio.Device.disconnect(function (conn) {
        $("#log").text("Call ended");
      });

      Twilio.Device.incoming(function (conn) {
        $("#log").text("Incoming connection from " + conn.parameters.From);
        // accept the incoming connection and start two-way audio
        conn.accept();
      });

      function call() {
        // get the phone number to connect the call to
        params = {"PhoneNumber": $("#number").val()};
        Twilio.Device.connect(params);
      }

      function hangup() {
        Twilio.Device.disconnectAll();
      }
    </script>
  </head>
  <body>
    <button class="call" onclick="call();">
      Call
    </button>

    <button class="hangup" onclick="hangup();">
      Hangup
    </button>

    <input type="text" id="number" name="number" placeholder="Enter a phone number to call"/>
    <div id="log">Loading ...</div>
  </body>
</html>

twilioCall.php

<?php
header('Content-type: text/xml');
if (isset($_REQUEST['PhoneNumber'])) {
    $number = htmlspecialchars($_REQUEST['PhoneNumber']);
}?>

<Response>
    <Dial callerId="<?php echo $callerId ?>">
 <Number>"<?php echo $number ?>"</Number>
    </Dial>
</Response>

Key elements required for connection are Account SId, Token (www.twilio.com/user/account/settings) and appId (www.twilio.com/user/account/voice/dev-tools/twiml-apps and select an app to get the app id).

Now its ready to be tested. Note that since this is a demo account from and to numbers cannot be changed (From should be the number provided by Twilio during signup and to should be the verified number on the account).

Logs will be available over here : www.twilio.com/user/account/log/calls , on clicking the timestamp it will direct to the details of request and response.

www.twilio.com/user/account/monitor/alerts, this one provide alerts created during our test failures.

Selection_123.png

Alert logs
Selection_122.png

Wednesday, March 9, 2016

Sample application with AngularJS, PHP and Mysql

AngularJS sample application with PHP and MYSQL

Lets start by creating a sample database and a table to have some values which can be used for listing the data.

AngularJS PHP MYSQL



CREATE TABLE `movies` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `title` VARCHAR(255) NOT NULL, `director` VARCHAR(15) NOT NULL, `year` int(10) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=INNODB DEFAULT CHARSET=utf8;


Then some default entries to the table

INSERT INTO `movies` (`id`, `title`, `director`, `year`) VALUES (1, 'Mad Max: Fury Road', 'George Miller', '2015'), (2, 'Captain Phillips', 'Paul Greengrass', '2013'), (3, 'Room', 'Lenny Abrahamson', '2015') , (4, 'London Has Fallen', 'Babak Najafi', '2016') , (5, 'Deadpool', 'Tim Miller', '2016');


Now we have the database ready to be used, shall start from building the html pages, js and relative php file.

index.html

<!DOCTYPE html>

<html ng-app="customMovApp">

<head>

 <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.min.js"></script>

 <script type="text/javascript" src="js/app.js"></script>

</head>

        <body ng-controller="movieController">

                <div ng-include src=" 'views/movie.html' "></div>

        </body>

</html>

In angularjs based applications we use attribute names with ng keyword. As you can see in the html tag we have an attribute ng-app been set to a value 'customMovApp' and this is to initialize the html page with anuglarjs app which we will be defining on the app.js file. Within the body tag we have also initialized to controller to be used for this page with ng-controller attribute. Then we have a content loading div section which uses another view to be included when the index page is loaded. Here, note that the source url used within the ng-include attribute is enclosed within single quotes.

Now we shall define the app.js file which will be having the core of angular js application.

app.js

var app = angular.module('customMovApp',[]);

app.controller('movieController',  function($scope, $http) {

 getMovie();

 function getMovie() {

  $http.post("getMovie.php").success(function(data) {

   console.log(data);

   $scope.movies = data;

  });

 }

});


Here from the 1st line angular module is been initialized as 'customMovApp' and then with that we have created a new controller named 'movieController' and it has a function 'getMovie' which is in turn defined to call the php file getMovie.php and set the returned json object to 'movies' variable.

We already have a database and a table with some sample entries, we have the php script to connect to the database and returns the response as json object. For this we have a sample script which can be used.

getMovie.php

// mysqli connection object initialization
$mysqli = new mysqli('host', 'username', 'password', 'dbname');

$query = "select * from movies";
$result = $mysqli->query($query) or die($mysqli->error.__LINE__);
$arr     = array();

if($result->num_rows > 0) {
        while($row = $result->fetch_assoc()) {
                $arr[] = $row;
        }

}

// JSON-encoded response
echo $json_response = json_encode($arr);


Now we need a view page to render the response from the controller action of angular module.

movie.html

<table ng-controller="movieController">

<thead><tr><th>Title</th><th>Director</th><th>Released Year</th></tr></thead>

<tbody>
 <tr ng-repeat="movie in movies">

 <td>{{movie.title}}</td>
 <td>{{movie.director}}</td>
 <td>
    <div ng-if="movie.year == '2016'"> <span>Current Year</span> </div>
 <div ng-if="movie.year != '2016'"> <span>{{movie.year}}</span> </div>
 </td>

 </tr>

</tbody> </table>

Here we are using ng-repeat to loop through all the movie records from the response object.

Thursday, July 9, 2015

Sugarcrm connection to mysql DB with SSL - Amazon RDS with SSL - using ca-cert file

This is based on Sugarcrm CE 6.5, and by default the MysqliManager.php doesnt support ssl connection to mysql db's, even if we set the 'ssl' flag on 'dboptions' of config.php file. To make the DBManager work, we need to update the MysqliManager code.

First, we need to have the ssl flag on and the file path to the ca-cert file, for that we can have these details on config_override.php
$sugar_config['dbconfigoption']['ssl'] = true;
$sugar_config['dbconfigoption']['ca_cert'] = '/home/user/ca-cert-rds.pem';

Then, update the MysqliManger.php file inside include/database folder.

            $link = FALSE;

            $configDbOptions = $this->getOptions();

            if ($configDbOptions['ssl'] === TRUE) {

                $this->database = mysqli_init();

                mysqli_options($this->database, MYSQLI_OPT_SSL_VERIFY_SERVER_CERT, true);

                $this->database->ssl_set(NULL,NULL,$configDbOptions['ca_cert'],NULL,NULL);

                $link = $this->database->real_connect($dbhost, $configOptions['db_user_name'], $configOptions['db_password'], isset($configOptions['db_name'])?$configOptions['db_name']:'', $dbport, NULL, MYSQLI_CLIENT_SSL);

            } else {

                $this->database = mysqli_connect($dbhost,$configOptions['db_user_name'],$configOptions['db_password'],isset($configOptions['db_name'])?$configOptions['db_name']:'',$dbport);

                $link = TRUE;

            }



            if($link === FALSE) {

                $GLOBALS['log']->fatal("Could not connect to DB server ".$dbhost." as ".$configOptions['db_user_name'].". port " .$dbport . ": " . mysqli_connect_error());

                if($dieOnError) {

                    if(isset($GLOBALS['app_strings']['ERR_NO_DB'])) {

                        sugar_die($GLOBALS['app_strings']['ERR_NO_DB']);

                    } else {

                        sugar_die("Could not connect to the database. Please refer to sugarcrm.log for details.");

                    }

                } else {

                    return false;

                }

            }

Wednesday, December 3, 2014

Copy all the lines from a file using vim to another

First open the file using 'vim'.

e.g. vim testfile.txt

Then to copy use "ggVGy" or ":%y a", now the content is in the clipboard.

Open a new terminal and open a new file with 'vim' where you are going to paste it.

Then use "p" or "P" to put the content in the file from the clipboard.

Thursday, November 13, 2014

Instagram user profile details by username or userid

There are actually 3 methods to get profile details of a specific instagram user.

Method 1

Condition : you need to have the user id and the users access token to get the profile details

call the url with user id and access token. 
'https://api.instagram.com/v1/users/USER_ID?access_token=ACCESS_TOKEN'


Method 2

Condition : you need a client id (which can be created from : http://instagram.com/developer/clients/register/) & user id

call the url with user id and client id. 
'https://api.instagram.com/v1/users/USER_ID?client_id=CLIENT_ID'


Method 3

There are some private profiles which cannot be directly accessed using the above 2 methods, for that you can use the search endpoint with the client id to get the matching results and then get the respective user details.

Condition : you need a client id (which can be created from : http://instagram.com/developer/clients/register/) & user id

call the url with user name and client id to search the user. 
'https://api.instagram.com/v1/users/search?q=USER_NAME&client_id=CLIENT_ID'

Friday, March 22, 2013

How to override an attribute name in yii model ?

In model add an override function for checking the errors generated on validation.

public function getErrors($attribute=null)
{
        $errors = parent::getErrors($attribute);
        if ($attribute == null) {
            // Ok We get a collection of errors
            if (isset($errors['attribute_to_be_replaces'])) {
                $error = $errors['attribute_to_be_replaces'];
                unset($errors['attribute_to_be_replaces']);
                $errors['replaced_attribute_name'] = $error;
            }
        }
        return $errors;
 }

Thursday, February 28, 2013

Delete a remote tag

First delete it from local
git tag -d tag_name

Then push the change to remote
git push origin :refs/tags/tag_name