Skip to main content

  • Login | Forgot Password?
Ribbit Developer logo

Sending a recorded voice message in an outbound call

  • Login or register to post comments
12 replies [Last post]
Thu, 2009-12-03 06:33
ionatec
User offline. Last seen 1 week 6 hours ago. Offline
Joined: 2009-11-24
Hi I am trying to write a simple application in which the user can use an mp3 or wav file to be played in an outbound call to a number he/she types. I am considering that the file is already on the server. I make a call I try to play the file, as follows: $domain= $ribbit->getConfig()->getDomain();\ try{ $rmf = $ribbit->Media(); $file = $rmf->getFile("test","offer.wav",$domain); $call_id = $ribbit->Calls()->createCall($toAddrs); $_SESSION["last_call_id"] = $call_id; $media = new RibbitCallPlayMedia(RibbitCall::MEDIA_TYPE_FILE, $file,0,-1); $play = new RibbitCallPlayRequest(array($media) ,null, "1", true); $ribbit->Calls()->playMediaToCall($call_id,RibbitCall::ANNOUNCE_EN_US_CLASSIC,$play); $ribbit->Calls()->hangupCall($call_id); } catch(RibbitException $e){ $result = "A ". $e->getStatus() ." error occured - " . $e->getMessage(); } where $toAddrs is the receipt of the call. It is pretty obvious what is happening: as soon as the call is started the hangupCall is called and the call is finished. The questions here are: 1. What do I have to change in the code to be able to access the file? I am getting the following error message: "A 406 error occured - The request was not acceptable". If I type a file that does not exist the error message says that the file does not exist. Thefore, I conclude that the file was found, but do not know what that "not acceptable" means. 2. Since PHP does not have event handlig, how can I start playing the file only after the call is answered and how can I set the hangupCall method to be executed only after the whole file is played? Thanks for the help! Best regards, Guillermo
Top
  • Login or register to post comments
Mon, 2010-06-21 04:26
#1
rajbhatiya
User offline. Last seen 10 weeks 4 days ago. Offline
Joined: 2010-06-19
  Things have changed

 

Things have changed so drastically over the course of the past decade. Just a few years ago, ecommerce was at its infancy and now that is what drives businesses. Earlier, businesses had to target customers through traditional advertising media such as newspapers, hoardings etc. They also had no choice but to reveal the location where the company is based. The telephone number and the address gave it away. The inbound call handling technology was also at its rudimentary stages. So the customers could always estimate how big or small the company’s operations were.
Now things have changed for the better. With 0800 numbers, 0845 numbers, 0844 numbers, 0871 numbers and other similar number ranges, a host of advanced call management features are bundled along with the service package. The telephone numbers do not reveal the location of the company and they can be used to build a national or even international presence. With advanced call management features, even small companies with limited staff can handle inbound telephone calls in an extremely professional manner that rivals big corporations. Inbound calls can be routed to any location in the world. A customer calling a national number will intuitively attribute a bigger presence to the company.
By using a combination of smart number choices and handling inbound calls professionally, businesses can truly set themselves apart.

Top
  • Login or register to post comments
Thu, 2009-12-03 08:19
#2
san1t1
User offline. Last seen 9 weeks 3 days ago. Offline
Joined: 2009-04-07
Managing state of calls.

Wow you/ve done a good job with your code so far, nice to see you getting stuck into the PHP API.

The first thing to be aware of is that the createCall() method does not block. In other words, it's really a request to create a call, and you get back a call id, and your php code doesn't hang waiting.

In order to play media to a call there must be at least one answered leg. There are two ways to determine whether a call has been answered.

1. Poll the call using getCall(callId). You need to keep your PHP code running for this, so may be tricky in a web application.
2. Register your application to receive http notifications, and wait for a CallLegAnsweredNotification for that call, and tie the notification POSTed by Ribbit to your session - this does require some marshalling of state, and the PHP session is possibly not the best way to handle this.

So far we haven't really provided any samples of how to set up your application for http notifications, but the code on a "listener.php" script, called by Ribbit, might look a bit like this:

<?php
require_once ("ribbit/Ribbit.php");

$ribbit = Ribbit::getInstance();
$callback = $ribbit->getCallbackNotification();

if ($callback instanceof RibbitCallLegAnsweredNotification){
    //do something
}

elseif ($callback instanceof RibbitPlayAnnouncementCompleteNotification){
    //media has finished playing
}
//etc

?>

Please let us know if this helps, and watch this site for more examples of how to handle this type of scenario.

Cheers
Tim

Top
  • Login or register to post comments
Mon, 2009-12-07 06:57
#3
ionatec
User offline. Last seen 1 week 6 hours ago. Offline
Joined: 2009-11-24
Not playing the audio file yet
Dear Tim I tried to write the code as you told me, but the file is still not being played. My source code looks like this: $call_id = $ribbit->Calls()->createCall($toAddrs); $_SESSION["last_call_id"] = $call_id; $called = true; //If the call is done, then play the file if($called){ if ($callback instanceof RibbitCallLegAnsweredNotification){ //construct a new RibbitCallPlayRequest $media = new RibbitCallPlayMedia(RibbitCall::MEDIA_TYPE_FILE,"https://rest.ribbit.com/rest/1.0/media/comercial@ionatec.com.br/files/".$file,0,-1); $play = new RibbitCallPlayRequest(array($media) ,null, "1", true); $ribbit->Calls()->playMediaToCall($call_id,RibbitCall::ANNOUNCE_EN_US_CLASSIC,$play); } elseif ($callback instanceof RibbitPlayAnnouncementCompleteNotification){\ //media has finished playing $ribbit->Calls()->hangupCall($call_id); } } What am I doing wrong? How can I be sure that the file is in the ribbit server and I am accessing it? Thank you again. Best regards, Guillermo
Top
  • Login or register to post comments
Tue, 2009-12-08 02:54
#4
san1t1
User offline. Last seen 9 weeks 3 days ago. Offline
Joined: 2009-04-07
I sent you example code, not

I sent you example code, not a finished app!

Have you uploaded the file? You can either record a file over the phone, using the recordCall method, or There is an upload method, and when you have uploaded the path to your file will be https://rest.ribbit.com/rest/1.0/media/comercial@ionatec.com.br/folder/filename.wav

You won't get callback notifications to the same script - REST will make a brand new HTTP request each time there is a change of state of the call, and you must also register your application for notifications (which you can do using the updateApplication method.

$_SESSION is not a safe place to store call_ids when you use callback notifications

Simple rule of thumb. Don't play media to calls in the same script as the one in which you start the call. unless you are prepared to do something like the below and let your script "hang" until the first leg on the call is answered. The createCall method doesn't wait for legs to be answered

while ($ribbit->Calls()->getCall(callId).legs[0].status !="ANSWERED){
     sleep(1000);
}

$ribbit->Calls()->playMediaToCall( etc... )

Cheers

Tim

Top
  • Login or register to post comments
Tue, 2009-12-08 07:07
#5
ionatec
User offline. Last seen 1 week 6 hours ago. Offline
Joined: 2009-11-24
Now I am lost
Thank you for the help Tim, but now I am totally lost. - Yes, the file is uploaded. If I check for the content of the folder (iterate inside a foleder using $rmf->getFolder(folder_name)), where rmf is an instance of $ribbit->Media() ) i can see the file and its details. The weird thing is if I try to use the $rmf->getFile($folder_name,$file_name,$domain) a "request not acceptable" exception is thrown. Why? - I updated my application using the $ribbit->Applications->updateApplication($url) method. The url I provided is another php file I called VoiceMessageEH.php. Is this correct? This file is in the same directory as the VoiceMessage.php file, which is the main application file. - In the VoiceMessageEH.php file the code is like this: require_once ("ribbit/Ribbit.php"); $ribbit = Ribbit::getInstance(); $callback = $ribbit->getCallbackNotification(); //If the call is done, then play the file if ($callback instanceof RibbitCallLegAnsweredNotification){ //construct a new RibbitCallPlayRequest echo "play"; } elseif ($callback instanceof RibbitPlayAnnouncementCompleteNotification){ //media has finished playing $ribbit->Calls()->hangupCall($call_id); echo "hang up"; } However, the VoiceMessageEH.php is not being called. This is the point where I am lost. What should I do? Thanks again, Guillermo
Top
  • Login or register to post comments
Tue, 2009-12-08 09:42
#6
san1t1
User offline. Last seen 9 weeks 3 days ago. Offline
Joined: 2009-04-07
When you set up your callback

When you set up your callback url, using the updateApplication method, did you make this absolute? eg "http://www.yourdomain.com/yourdirectory/VoiceMessageEH.php"

If you specifiy this as relative then REST has no idea where it is.

Top
  • Login or register to post comments
Wed, 2009-12-09 07:15
#7
ionatec
User offline. Last seen 1 week 6 hours ago. Offline
Joined: 2009-11-24
Application Updated, notifications set, and now?
Thanks again for the help. I changed the URL in the updateApplication method to "http://localhost/ionatec/MessageCentral/VoiceMessageEH.php". Checked the application details ($robbit->getApplication() method) and there is set this URL. In the VoiceMessageEH.php file I have the following lines: require_once ("ribbit/Ribbit.php"); $ribbit = Ribbit::getInstance(); $callback = $ribbit->getCallbackNotification(); if ($callback instanceof RibbitCallAnsweredNotification){ echo "play"; } The "play" message should be displayed when I pick up the phone to answer the call, right? However, still nothing happens when I make a call and it is anwered. I do not know what else to do. Thanks again, Guillermo
Top
  • Login or register to post comments
Wed, 2009-12-09 09:31
#8
san1t1
User offline. Last seen 9 weeks 3 days ago. Offline
Joined: 2009-04-07
don't use localhost

As far as REST is concerned, when it's sending notifications, localhost is REST itself.

You can only send notifications to a URL that is addressable on the internet. Not to 127.0.0.1, not to a private network.

Top
  • Login or register to post comments
Fri, 2009-12-11 05:21
#9
ionatec
User offline. Last seen 1 week 6 hours ago. Offline
Joined: 2009-11-24
Almost there (I think)

Tim

As I can test the application only using the localhost, I decided to use some "sleep(sec)" to play the file.

I believe the file is uploaded, because when I instantiate a RibbitCallPlayMedia object and read its content, the path where I put the file is retrieved. I just do not really know what is there. If is an "empty" file or if the file is actually there. How can I be sure the file is there?

$media = new RibbitCallPlayMedia (RibbitCall::MEDIA_TYPE_FILE, $filePath,0,-1);

When I instantiate a RibbitCallPlayRequest object and use the playMediaToCall method to play it, nothing happens.

$play = new RibbitCallPlayRequest(array($media) ,null, "1", true);
$ribbit->Calls()->playMediaToCall($call_id, RibbitCall::ANNOUNCE_EN_US_CLASSIC,$play);

However, if instead of playing a file I play a text, like
$media = new RibbitCallPlayMedia(RibbitCall:: MEDIA_TYPE_SPELL,"Hello world",0,-1);
the text is said correctly in the call.

Any ideas?
Thank you again.
Best regards,

Guillermo
Top
  • Login or register to post comments
Fri, 2009-12-11 07:03
#10
san1t1
User offline. Last seen 9 weeks 3 days ago. Offline
Joined: 2009-04-07
Using sleep is ok for

Using sleep is ok for testing.

To improve this, instead of just doing sleep you could do:

while ($ribbit->Calls().getCall($call_id).legs[0].status !="ANSWERED"){
    sleep(1000);
}

This will then wait until the call is answered before attempting to play. Just a bit safer.

Try downloading the file again, and playing back what you get. I only ask as  there are issues with uploading mp3s on our platform which we are hoping to resolve soon. You get best results with audio that you have recorded through $ribbit->Calls()->recordCall() or by uploading a suitable 8bit CCIT ulaw wav file - the format that the telephone network likes. Hopefully our transcribing problem will get fixed soon, it's a bit of a pain.

Top
  • Login or register to post comments
Fri, 2009-12-11 13:07
#11
ionatec
User offline. Last seen 1 week 6 hours ago. Offline
Joined: 2009-11-24
It works (at least part of it)

Finally I managed to play an audio in an outbound call. Thank you!

Unfortunately the

   while ($ribbit->Calls()->getCall($call_id)->legs[0].status !="ANSWERED"){
    sleep(1000);
}

does not work. If I try to read the value of the status "variable", it is never "ANSWERED". Actually, I got "status"

.

The audio I could play was one I recorded in ribbits databse through a call. With files uploaded to ribbit server it was not possible. Even if I convert them to 8 Bit and 8KHz.

I think the problem is with the file upload. I do not know what to put in the base_65 parameter of the uploadFile method:

   $rmf = $ribbit->Media(); 
   $filePath = $rmf->uploadFile($base64_data,"files",$file,$domain);

What can be an acceptable value for the base64_data parameter?

Thanks again


Guillermo
Top
  • Login or register to post comments
Tue, 2009-12-15 04:39
#12
san1t1
User offline. Last seen 9 weeks 3 days ago. Offline
Joined: 2009-04-07
base64 data is a string that

base64 data is a string that is a base64 encoded file - ie base64_encode(file_get_contents($filename));

The next version of the PHP SDK makes this easier by allowing you to just specify a filename instead. Of course that must be readable by your web app.

Top
  • Login or register to post comments
  • Login or register to post comments
sales@ribbit.com
(619) 916-2565
 Talk to Us!
Get Started
     Ribbit Idea Wall
Industry Solutions

  • Digital Agencies
  • Hosted Call Centers
  • Systems Integrators
  • Carriers/ISPs
  • Company
    • Corporate Site
    • About Us
    • Careers
    • Contact Us
    • LegalPrivacy
    • News
    • Media Kit
  • Products
    • Platform
    • Mobile
    • Salesforce
    • Oracle
  • Solutions
    • Digital Agencies
    • Carriers
    • Systems Integrators
    • Hosted Contact Centers
  • Community
    • Corporate Blog
    • Developer Blog
    • CRM Blog
    • Moble Blog
    • Idea Wall
    • Events Calendar
  • Support
    • Developer Help
    • Ribbit for Salesforce Help
    • Ribbit for Oracle Help
    • Ribbit Mobile Help
    • Feedback
    • Developer Forums
    • Ribbit Mobile Forum
  • Developers
    • Developer Center
    • Develop for Ribbit Mobile
    • Register
    • Ribbit Labs

© 2010 Ribbit Corporation. All Rights Reserved.