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.
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.
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.
> <?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.
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…
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…