Friday, August 4, 2017

Asterisk Call Originate Action Using Pami

asterisk

What is Asterisk?

Asterisk is an open source framework for building communications applications. Asterisk turns an ordinary computer into a communications server. Asterisk powers IP PBX systems, VoIP gateways, conference servers and other custom solutions. It is used by small businesses, large businesses, call centers, carriers and government agencies, worldwide. Asterisk is free and open source.

About PAMI

PAMI means PHP Asterisk Manager Interface. It is an OOP client for the Asterisk Manager Protocol, implemented in PHP.

About PAMI Features

  • TCP and TLS connections.
  • Event Driven (the framework will dispatch events to your listener).
  • Lightweight, easy of use, and useful.
  • Supports synchronous and asynchronous events (Actions with Responses, and 
  • Responses with Events associated).
  • Supports SMS via VGMS boards.

{
"require": {
"marcelog/pami": "dev-master",
"educoder/pest": "1.0.0",
"react/zmq": "0.2.*|0.3.*"
}
}
view raw composer.json hosted with ❤ by GitHub
require_once 'vendor/autoload.php';
require_once 'configlocal.php';
use PAMI\Client\Impl\ClientImpl;
use PAMI\Listener\IEventListener;
use PAMI\Message\Event\EventMessage;
use PAMI\Message\Action\OriginateAction;
use PAMI\Message\Action\StatusAction;
class PamiEventListener implements IEventListener
{
public function __construct($cli)
{
$this->cli = $cli;
}
/**
* To Handle the All Pami Events
* @param EventMessage $event
*/
public function handle(EventMessage $event)
{
echo $strevt = $event->getKeys()['event'];
$this->var_error_log($event->getKeys());
if ($strevt == 'DialBegin') {
echo "DialBegin event --- \n";
}
if ($strevt == 'DialEnd') {
echo "Dial end event --- \n";
}
if ($strevt == 'Hangup') {
echo "Hangup event --- \n";
}
}
public function var_error_log($object = null)
{
$datetime = date("Y-m-d h:i:s a");
$contents = PHP_EOL . $datetime . " :";
ob_start(); // start buffer capture
var_dump($object); // dump the values
$contents .= ob_get_contents(); // put the buffer into a variable
ob_end_clean(); // end capture
//create the log file if not exist
$log_file_path = "log.txt";
if (file_exists($log_file_path) == false) {
fopen($log_file_path, "w");
}
error_log($contents, 3, $log_file_path);
}
}
////////////////////////////////////////////////////////////////////////////////
// Code STARTS.
////////////////////////////////////////////////////////////////////////////////
error_reporting(E_ALL);
ini_set('display_errors', 1);
try {
$options = array(
'host' => 122.111.111.222,
'scheme' => 'tcp://',
'port' => 5038,
'username' => 'testuser',
'secret' => '#######',
'connect_timeout' => 10,
'read_timeout' => 10000000
);
$phonenumber=1000;
$sipNumber=20000;
$a = new ClientImpl($options);
$eventListener = new PamiEventListener($a);
$a->registerEventListener($eventListener);
$a->open();
$time = time();
while (true) {
//(time() - $time) < 60) // Wait for events.
usleep(1000); // 1ms delay
//check the Avilable Agents status
$actionid = md5(uniqid());
$response = $a->send(new StatusAction());
$originateMsg = new OriginateAction('SIP/' . $phonenumber . "@voipgw");
$originateMsg->setContext('dialer');
$originateMsg->setPriority('1');
$originateMsg->setExtension($sipNumber);
$originateMsg->setCallerId($sipNumber);
$originateMsg->setAsync(false);
$originateMsg->setActionID($actionid);
$orgresp = $a->send($originateMsg);
$orgStatus = $orgresp->getKeys()['response'];
// Since we declare(ticks=1) at the top, the following line is not necessary
$a->process();
}
$a->close(); // send logoff and close the connection.
} catch (Exception $e) {
echo $e->getMessage() . "\n";
}
view raw index.php hosted with ❤ by GitHub

Tuesday, July 18, 2017

Getting Started with Redis in PHP

What is Redis?

Redis created by Salvatore Sanfilippo is an open source, in-memory data structure server with advanced key-value cache and store, often referred to as a NoSQL database. It is also referred to as a data structure server, since it can store strings, hashes, lists, sets, sorted sets, and more.

The essence of a key-value store is the ability to store some data, called a value inside a key. This data can later be retrieved only if we know the exact key used to store it.

Usage of Redis

  • Caching can be used in the same manner as memcached.
  • Leaderboards or related problems.
  • Counting stuff.
  • Real time analysis.
  • Deletion and filtering.
  • Show latest item listings in your home page.

Install on Windows

Now, let us check how to set up Redis PHP driver.

You need to download the phpredis from github repository https://github.com/nicolasff/phpredis. Once you’ve downloaded it, extract the files to phpredis directory.

extension = redis.so

Connect to Redis Server

<?php
//echo phpinfo();exit;
//Connecting to Redis server on localhost
$redis = new Redis();
$status=$redis->connect('XXX.XXXX.XXX.XXX', $portnumber);
echo "<pre>";
echo "Connection to server sucessfully";
//check whether server is running or not
echo "Server is running: ".$redis->ping();
//creating the key
$key="Key_Name";
$redis->set($key, 'MAK Key Venki');
//Retreving the specified key value
echo $redis->get($key);
// Get the stored keys and print it
$arList = $redis->keys("*");
echo "Stored keys in redis:: " ;
print_r($arList);
?>
view raw redis.php hosted with ❤ by GitHub

Monday, July 17, 2017

Inter Process Communication Using PHP ,ZeroMQ AND React/ZMQ

push the external changes to existing web pages

The above diagram shows the any external php file or database layer changes has happen should be notify to all our web client. We can able to achieve this using React/ZMQ

Requirements

ZeroMQ

All Our client web pages will be listening to port 8080 for incoming WebSocket connections...but how will it also get updates from another PHP script or another server process event. Enter ZeroMQ. We could use raw sockets, like the ones Ratchet is built on, but ZeroMQ is a library that just makes sockets easier. install zmq

React/ZMQ

Ratchet is a WebSocket library built on top of a socket library called React. React handles connections and the raw I/O for Ratchet. In addition to React, which comes with Ratchet, we need another library that is part of the React suite: React/ZMQ. This library will bind ZeroMQ sockets to the Reactor core enabling us to handle both WebSockets and ZeroMQ sockets. To install, your composer.json file should look like this:

{
"autoload": {
"psr-0": {
"MyApp": "src"
}
},
"require": {
"cboden/ratchet": "0.3.*",
"react/zmq": "0.2.*|0.3.*"
}
}
view raw composer.json hosted with ❤ by GitHub
<?php
require dirname(__DIR__) . '/vendor/autoload.php';
$loop = React\EventLoop\Factory::create();
$pusher = new MyApp\Pusher;
// Listen for the web server to make a ZeroMQ push after an ajax request
$context = new React\ZMQ\Context($loop);
$pull = $context->getSocket(ZMQ::SOCKET_PULL);
$pull->bind('tcp://127.0.0.1:55556'); // Binding to 127.0.0.1 means the only client that can connect is itself
$pull->on('message', array($pusher, 'onBlogEntry'));
// Set up our WebSocket server for clients wanting real-time updates
$webSock = new React\Socket\Server($loop);
$webSock->listen(8080, '0.0.0.0'); // Binding to 0.0.0.0 means remotes can connect
$webServer = new Ratchet\Server\IoServer(
new Ratchet\Http\HttpServer(
new Ratchet\WebSocket\WsServer(
new Ratchet\Wamp\WampServer(
$pusher
)
)
),
$webSock
);
$loop->run();
<?php
namespace MyApp;
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
class Chat implements MessageComponentInterface {
protected $clients;
public function __construct() {
$this->clients = new \SplObjectStorage;
}
public function onOpen(ConnectionInterface $conn) {
// Store the new connection to send messages to later
$this->clients->attach($conn);
echo "New connection! ({$conn->resourceId})\n";
}
public function onMessage(ConnectionInterface $from, $msg) {
$numRecv = count($this->clients) - 1;
echo sprintf('Connection %d sending message "%s" to %d other connection%s' . "\n"
, $from->resourceId, $msg, $numRecv, $numRecv == 1 ? '' : 's');
foreach ($this->clients as $client) {
if ($from !== $client) {
// The sender is not the receiver, send to each client connected
$client->send($msg);
}
}
}
public function onClose(ConnectionInterface $conn) {
// The connection is closed, remove it, as we can no longer send it messages
$this->clients->detach($conn);
echo "Connection {$conn->resourceId} has disconnected\n";
}
public function onError(ConnectionInterface $conn, \Exception $e) {
echo "An error has occurred: {$e->getMessage()}\n";
$conn->close();
}
}
<html>
<head>
<title>Testing</title>
<script src="autobahn.js"></script>
<script>
var conn = new ab.Session('ws://localhost:8080',function() {
conn.subscribe('kittensCategory', function(topic, data) {
// This is where you would add the new article to the DOM (beyond the scope of this tutorial)
console.log('New article published to category "' + topic + '" : ' + data.title);
});
},
function() {
console.warn('WebSocket connection closed');
},
{'skipSubprotocolCheck': true}
);
</script>
</head>
<body>
<h1> Sample Client web page </h1>
</body>
</html>
<?php
// post.php ???
// This all was here before ;)
$entryData = array(
'category' =>"kittensCategory"
, 'title' => "Ces Dialer"
, 'article' => "First Articale"
, 'when' => time()
);
// This is our new stuff
$context = new ZMQContext();
$socket = $context->getSocket(ZMQ::SOCKET_PUSH, 'my pusher');
$socket->connect("tcp://localhost:55556");
$socket->send(json_encode($entryData));
<?php
namespace MyApp;
use Ratchet\ConnectionInterface;
use Ratchet\Wamp\WampServerInterface;
class Pusher implements WampServerInterface {
/**
* A lookup of all the topics clients have subscribed to
*/
protected $subscribedTopics = array();
public function onSubscribe(ConnectionInterface $conn, $topic) {
echo "subscribe\n";
print_r($topic->getId());
$this->subscribedTopics[$topic->getId()] = $topic;
}
public function onUnSubscribe(ConnectionInterface $conn, $topic) {
}
public function onOpen(ConnectionInterface $conn) {
}
public function onClose(ConnectionInterface $conn) {
}
public function onCall(ConnectionInterface $conn, $id, $topic, array $params) {
// In this application if clients send data it's because the user hacked around in console
$conn->callError($id, $topic, 'You are not allowed to make calls')->close();
}
public function onPublish(ConnectionInterface $conn, $topic, $event, array $exclude, array $eligible) {
// In this application if clients send data it's because the user hacked around in console
$conn->close();
}
public function onError(ConnectionInterface $conn, \Exception $e) {
}
/**
* @param string JSON'ified string we'll receive from ZeroMQ
*/
public function onBlogEntry($entry) {
$entryData = json_decode($entry, true);
print_r($entryData);
// If the lookup topic object isn't set there is no one to publish to
if (!array_key_exists($entryData['category'], $this->subscribedTopics)) {
return;
}
$topic = $this->subscribedTopics[$entryData['category']];
// re-send the data to all the clients subscribed to that category
$topic->broadcast($entryData);
}
}
To Run the above application go to root directory "push" run below command to run the web socket connection on server side
php bin/push-server.php
Run the : "push\src\MyApp\clientwebpage.html" which connect to web socket listen to the specified category

PHP ZMQ extension Installation in Apache 2.4 & php 5.6


PHP ZMQ extension we will look at how you can easily distribute work to background processes, provide flexible service brokering for your next service oriented architecture, and manage caches efficiently and easily with just PHP and the ZeroMQ libraries. Whether the problem is asynchronous communication, message distribution, process management or just about anything, ZeroMQ can help you build an architecture that is more resilient, more scalable and more flexible, without introducing unnecessary overhead or requiring a heavyweight queue manager node..

Installing ZMQ in Windows

Required Softwares Apache 2.4 & PHP 5.6
  1. Download the zmq php extension from following url depends up on the installed php version
    url: ZMq Download Url
  2. Extract the folder
  3. Copy the php_zmq.dll to php/ext directory
  4. Then copy the libzmq.dll to the php/ root directory
  5. Add below line in php.ini file : extension=php_zmq.dll

Friday, April 7, 2017

Defining a HTML template to append using JQuery

Append Dynamic content to html template using Jquery

If we want to append the dynamic content to html template using jquery below will be the simple solution
<!DOCTYPE html>
<html>
<head>
<title>Modular Design Pattern</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div>TODO write content
<input type="button" name="button" value="buttonclick" id="buttonclick"/>
<div id="target"></div>
</div>
</body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script>
$(document).ready(function () {
//Clone the template
var template = $('#hidden-template').html();
$('#buttonclick').click(function () {
//Clone the template
var item = $(template).clone();
//Find the
$(item).find('.first').html("First");
//Change 'bar' to '-Bar'
$(item).find('#bar').html("-Bar");
//Append to the source
$('#target').append(item);
});
});
</script>
<script id="hidden-template" type="text/x-custom-template">
<tr>
<td class="first">Foo</td>
<td id="bar">Bar</td>
<tr>
</script>
</html>
view raw index.html hosted with ❤ by GitHub

Wednesday, April 5, 2017

Iframe communication or Accessing a cross-origin frame

Accessing a cross-origin frame.

window.postMessage allows you to send messages not only across frames (regular frame or iframe) but also across domains. This post showed interaction from parent to child. Even when we keep the iframe domain url is different for the main page url.
With out using the window.postMessage will gives us below error message in console

SecurityError: Blocked a frame with origin from accessing a cross-origin frame

You can't access an iframe with Javascript, it would be a huge security flaw if you could do it.
For the same-origin policy browsers block scripts trying to access a frame with a different origin.
Origin is considered different if at least one of the following parts of the address isn't maintained: ://:/path/to/page.html Protocol, hostname and port must be the same of your domain, if you want to access a frame.


Examples
Here's what would happen trying to access the following URLs from http://www.example.com/home/index.html

URL RESULT
http://www.example.com/home/other.html -> Success
http://www.example.com/dir/inner/another.php -> Success
http://www.example.com:80 -> Success (default port for HTTP)
http://www.example.com:2251 -> Failure: different port
http://data.example.com/dir/other.html -> Failure: different hostname
https://www.example.com/home/index.html.html -> Failure: different protocol
ftp://www.example.com:21 -> Failure: different protocol & port
https://google.com/search?q=james+bond -> Failure: different hostname & protocol
Workaround
<!DOCTYPE html>
<html>
<head>
<title>My Iframe</title>
</head>
<body>
<button>Button</button>
<div id="childdiv"> </div>
<script type="text/javascript">
//To Recive the parent frame message
document.querySelector('button').onclick = function () {
parent.postMessage("myevent", "*")
};
</script>
</body>
</html>
view raw iframe.html hosted with ❤ by GitHub
<!DOCTYPE html>
<html>
<head>
<title>Index</title>
</head>
<body>
<iframe src="iframe.html" id="iframe" width="300" height="300"></iframe>
<script type="text/javascript">
var eventMethod = window.addEventListener
? "addEventListener"
: "attachEvent";
var eventer = window[eventMethod];
var messageEvent = eventMethod === "attachEvent"
? "onmessage"
: "message";
eventer(messageEvent, function (e) {
alert('Message from iframe just came!');
console.log(e);
});
//send message to child window
window.onload = function () {
document.getElementById("iframe").contentWindow.postMessage(
'test message',
"*"
);
};
</script>
</body>
</html>
view raw index.html hosted with ❤ by GitHub

Monday, April 3, 2017

Get Google contacts with Javascript using Google Contacts API and OAUTH 2.0

To get the Google Contacts with Javascript using Google Contacts Api

To Pull the google contacts we need to create a project in google developer console

Create a Google application in Google Developers Console for obtaining your Client id and Client secret

  • Go to Google Google Developers Console and login with your google account.
  • create one a project by clicking Create Project Button
  • Go into the newly created project
  • Click On the Menu icon and select the Api Manager Link
  • Search for “Contacts API” and click on it
  • Enable the “Contacts API” by hitting the “Enable API” button
Below is the code to pull the contacts from google relplace client id with newly created client id
<html>
<head>
<title>Google Contacts</title>
</head>
<body>
Body .....
<div id="con"> </div>
<button onclick="auth();">GET CONTACTS FEED</button>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://apis.google.com/js/client.js"></script>
<script type="text/javascript">
function auth() {
var config = {
'client_id': "client_id",
'scope': 'https://www.googleapis.com/auth/contacts.readonly'
};
gapi.auth.authorize(config, function() {
fetch(gapi.auth.getToken());
});
}
function fetch(token) {
$.ajax({
url: "https://www.google.com/m8/feeds/contacts/default/full?access_token=" + token.access_token + "&alt=json",
dataType: "jsonp",
success:function(data) {
// display all your data in console
// console.log(JSON.stringify(data));
// $("#con").html(data);
var data=data;
var entry=data.feed.entry;
$( entry ).each(function( index,vaule ) {
var phone="";
if(vaule.gd$phoneNumber){
phone=" Phone No:"+vaule.gd$phoneNumber[0].$t;
}
var cont="<div> <span>"+index+" </span>"+ vaule.title.$t+phone+"</div>";
$("#con").append(cont);
});
}
});
}
</script>
</body>
</html>
view raw google-contacts hosted with ❤ by GitHub