CRM initiate outgoing call on physical Desk Phone?

Hello,
I’m looking to start using a CRM in our organization.

Do you see a way that a CRM can initiate a call from a physical desk phone?

Say one of our users is on the desktop website of the CRM, and they want to call a Customer-007.
Our user clicks the CRM website’s call button, and via “API piping”, have our FreePBX system initiate the call on the user’s physical phone on his desk.

Do you see this as possible?

My rough idea system development sketch is:
0- CRM initiates call and its API [0] hits our server (intermediary server).
1- Intermediary server receives API hit/call (preferably with user name).
2- Intermediary server then further makes API call to our FreePBX system.
3- From FreePBX system then off to the physical desk phone.

Assuming point [0] that the CRM does in fact have such an API facility.

What are your thoughts?

Why do it this way? Because asking our users to use the physical desk phone for one thing, and then the CRM’s softphone for another is insane.

All thoughts and opinions are greatly welcomed!

Thanks
– AJ

Generally by any AMI or ARI interface your crm supports , in that absence have it generate a ‘call-file’

1 Like

Not for a while, but I have done it through software that creates a TAPI on the user computer and that will communicate over 5038 using a manager user. It essentially will allow you click-to-dial from your CRM, if it integrates with it.

1 Like

@dicko thanks.
Pardon, yet can you expand a little bit on the AMI or ARI interface?

I take this this is different than an API endpoint.

How are you imagining the flow? From CRM to FreePBX endpoint?

or

CRM --> intermediate machine --> FreePBX

?

Thank you for your help… I’m happy to know it is possible, even if 20 things need to be piped together.

AMI needs a manager account that your crm would use to open a tcp connection on port 5038. After that you will need to RTFM’s

ARI does much the same thing over http(s)

The new API in FreePBX 15 does not yet (last time I checked) support initiating a call. I know it is on the radar of features.

In the mean time you have to work around it with AMI or ARI. Have your CRM hit a URL on your PBX with the users extension and the number to dial. Then have that page make AMI/ARI generate the call appropriately.

Here’s a PHP script that works to do this put it in your /var/www/html dir name it CallInit.php or whatever

You will also need to modify the handful of strings for your system settings then call it via
http://Your.PBX.FQDN/CallInit.php?ExtraSecurity=COMPLEXGIBBERISHSTRINGHERE&exten=PHONEEXTVAR&number=NUMBERTOCALL&contact=URLENCODEDCONTACT

> <?php
> error_reporting(E_ALL);
> ini_set('display_errors', 1);
> 
> $strUser = "AMI USERNAME"; #specify the asterisk manager username you want to login with
> $strSecret = "AMI PASSWORD"; #specify the password for the above user
> 
> $securityString = "SECURITY STRING HERE";
> 
> if(isset($_GET['ExtraSecurity'])){
> 	if($_GET['ExtraSecurity'] != $securityString){
> 		//echo "Security Key Invalid";
> 		http_response_code(404);
> 		exit();
> 	}
> }else{
> 	http_response_code(404);
> 	exit();
> }
> 
> 
> //Get Contact
> $contactname = $_GET['contact'];
> 
> $strHost = "127.0.0.1";
> //Clean up EXT
> $ext = $_GET['exten'];
> $ext = filter_var($ext, FILTER_SANITIZE_NUMBER_INT);
> $ext = preg_replace("/[^0-9,.]/", "", $ext);
> 
> $strChannel = "PJSIP/".$ext;
> $strContext = "from-internal";
> $strWaitTime = "30"; #Wait Time before hanging up
> $strPriority = "1";
> $strMaxRetry = "2"; #maximum amount of retries
> 
> if(isset($_GET['number'])){
> 	$number=strtolower($_GET['number']);}
> elseif(isset($_GET['phone'])){
> 	$number=strtolower($_GET['phone']);
> }
> //Clean up number
> $number = filter_var($number, FILTER_SANITIZE_NUMBER_INT);
> $number = preg_replace("/[^0-9,.]/", "", $number);
> 
> 
> //The following line adds a 1 before the number if its not there already... You can remove this if you already added this into your outbound route or you dont need a 1.
> //if(substr($number,0,1) != 1){$number = "1".$number;}
> 
> $pos=strpos($number, "local");
> if ($number == null) :
> 	exit() ;
> endif ;
> if ($pos===false) :
> 	$errno=0 ;
> $errstr=0 ;
> 
> //OPEN CNAM LOOKUP
> $callerid = $callerid = "Web Call to $contactname";
> $strCallerId = $callerid." <$number>";
> 
> $oSocket = fsockopen("localhost", 5038, $errno, $errstr, 20);
> if (!$oSocket) {
> 	echo "$errstr ($errno)<br>\n";
> } else {
> 	fputs($oSocket, "Action: login\r\n");
> 	fputs($oSocket, "Events: off\r\n");
> 	fputs($oSocket, "Username: $strUser\r\n");
> 	fputs($oSocket, "Secret: $strSecret\r\n\r\n");
> 	fputs($oSocket, "Action: originate\r\n");
> 	fputs($oSocket, "Channel: $strChannel\r\n");
> 	fputs($oSocket, "WaitTime: $strWaitTime\r\n");
> 	fputs($oSocket, "CallerId: $strCallerId\r\n");
> 	fputs($oSocket, "Exten: $number\r\n");
> 	fputs($oSocket, "Context: $strContext\r\n");
> 	fputs($oSocket, "Variable: _SIPADDHEADER=Alert-Info: \;info=int-transfer\r\n");
> 	fputs($oSocket, "Priority: $strPriority\r\n\r\n");
> 	fputs($oSocket, "Action: Logoff\r\n\r\n");
> 	sleep(2);
> 	fclose($oSocket);
> }
> echo "Extension $ext should be calling $number." ;
> else :
> 	exit() ;
> endif ;
> ?>
> 
> <script type="text/javascript">
> 	window.open('','_self').close();
> </script>

If your extensions are chan sip instead of PJSIP you will need to change the $strChannel var.

I didn’t write the original script. I apologize I don’t remember who did. I’ve modified it a bit and integrated it into the software for two companies in my office.

1 Like

Please don’t do this…

  1. This thing is a security nightmare
  2. This makes a lot of assumptions
  3. Security

If you don’t care about 1 and 3 because you have too much money and nothing to spend it on I could recommend a few charitable organizations.

Seriously though… This is a good example of why you shouldn’t just copy and paste off of the internet. If I do a scan and find this file I can own the box in under 5 seconds.

In my case there is another firewall sitting in front of the box that allows access to SIP signaling from our providers IPs and unfettered access from the office IP, my home IP and http access from our web server that needs to make the curl request.

So I did some googling and found a copy of this with credit given to an Elastix post that doesn’t exist any more. I would clean it up but there is no license so I am pretty much hands off.

Remember kids license your code!!!

Notes:

With FreePBX you can add bootstrapping

<?php
include '/etc/freepbx.conf';
$freepbx = FreePBX::Create();

Which allows you to take advantage of all the plumbing allowing you to be more secure…

$extensionData = $freepbx->Core->getDevice($_GET['exten']);
if(empty($extensionData)){
   exit();
} 

Then use the data for your call…

$strChannel = $extensionData['dial'];
$strContext = $extensionData['context'];

You can also use libraries with this…

$phoneUtil = \libphonenumber\PhoneNumberUtil::getInstance();
$phoneNumber = $phoneUtil->parse($_GET['phone'], "US");
if(!$phoneUtil->isValidNumber($phoneNumber)){
      exit();
}

While the javascript is clever I would just move this all to POST so opening a browser doesn’t do anything. Also with GET your security is in plain text to the network even with ssl

Finally bootstrapping avoids the need to store the ami stuff because you can just use the plumbing…

$astman->Originate($channel, $exten, $context, $priority, $timeout, $callerid);

This topic was automatically closed 31 days after the last reply. New replies are no longer allowed.