I'm creating a sample application that will post alerts to the website in the event of a hurricane or service outage. I'm not using Laravel.
I set the URL of the page in my account settings. The first time I sent a message I received a HTTP error that it had timed out without being given a reponse. I edited the XML and tried again.
I'm not getting anything in the database and I'm not getting the response. I also wrote a sample page that posts a value to see if it would work and it did. It posted it into the database and showed correctly formatted XML.
<?php
$response = 'This number cannot handle automated replies...';
$twiml1 = '<response><sms>';
$twiml2 = '</sms></response>';
require_once '../settings/db.php';
if (isset($_POST['body'])) {
$body = strip_tags($_POST['body']);
$sql = "INSERT INTO alerts (message) VALUES ('$body')";
$result = $db->query($sql);
if ($result) {
$response = 'Thanks. Your message was posted on the website.';
} else {
$response = 'There was a query error.';
}
}
header('Content-type: application/xml');
echo $twiml1;
echo $response;
echo $twiml2;
Twilio developer evangelist here.
Parameters that are sent via webhooks from Twilio are case sensitive and start with a capital letter. The text for an incoming message is sent as the Body parameter so checking for $_POST['body'] won't work.
I'd update your conditional to:
if (isset($_POST['Body'])) {
$body = strip_tags($_POST['Body']);
// The rest
}
Also, just to note, the <Sms> element has been deprecated. I'd use the <Message> element instead. The tags are case sensitive too, so I'd update the TwiML section to this:
$twiml1 = '<Response><Message>';
$twiml2 = '</Message></Response>';
Let me know if that helps at all.
Related
I have integrated Twilio and it works fine. Now I want to capture all the intermediate message statuses. I referred to Sending Messages.
My code looks like -
require __DIR__ . '/vendor/autoload.php';
// Use the REST API Client to make requests to the Twilio REST API
use Twilio\Rest\Client;
// Your Account SID and Auth Token from twilio.com/console
$sid = '****************';
$token = '*****************';
$client = new Client($sid, $token);
// send message
$message = $client->messages->create(
// the number you'd like to send the message to
'+1xxxxxxxxx',
array(
'from' => '+1xxxxxxxx',
'body' => 'Test web hook message '.date('h:i'),
'statusCallback' => "https://xxxxxx/xxxx.php",
)
);
But the output/response returned to statusCallback is different as -
"{\"SmsSid\":\"SM72478c1ea61f467dbc33338123c0ad0\",\"SmsStatus\":\"sent\",\"MessageStatus\":\"sent\",\"To\":\"+1xxxxxxxx\",\"MessageSid\":\"SM72478c1ea612222dbc3b7858123c0ad0\",\"AccountSid\":\"ACb655a10c1c2222e4af158c5395d64beb\",\"From\":\"+1xxxxxxx\",\"ApiVersion\":\"2010-04-01\"}"
But I need the response as it is defined at Sending Messages
EDIT
If checked at Sending Messages, we can see the fields returned in the output are - account_sid, api_version, body, num_segments, num_media, date_created, date_sent, date_updated, direction, error_code, error_message, from, price, sid, status, to and uri.
But I receive fields as - SmsSid, SmsStatus, MessageStatus, To, MessageSid, AccountSid, From and ApiVersion.
For me, the fields - num_segments, date_sent, direction, error_code, error_message are important which I am not receiving. Do I need to use another API of TWILIO to retrieve this information ?
Why am I getting different response ?
Twilio developer evangelist here.
When you send a message and set a statusCallback URL the sending messages documentation says:
Twilio will POST the MessageSid along with the other standard request parameters as well as MessageStatus and ErrorCode.
The standard request parameters are:
MessageSid
SmsSid
AccountSid
MessagingServiceSid
From
To
Body
NumMedia
as well as some others specifically about media or geographic data based on the two numbers.
If you need to find out those other attributes of the message, you will need to look up the message using the REST API.
Let me know if that helps at all.
What does your code for your callback url script look like?
What you have is just an escaped JSON string, so to match what you see on the documentation you just have to do this:
$json = '{\"SmsSid\":\"SM72478c1ea61f467dbc33338123c0ad0\",\"SmsStatus\":\"sent\",\"MessageStatus\":\"sent\",\"To\":\"+1xxxxxxxx\",\"MessageSid\":\"SM72478c1ea612222dbc3b7858123c0ad0\",\"AccountSid\":\"ACb655a10c1c2222e4af158c5395d64beb\",\"From\":\"+1xxxxxxx\",\"ApiVersion\":\"2010-04-01\"}';
echo stripslashes($json);
We are attempting to create a workflow that will ultimately connect a lead from a contact form, with a business owner.
The workflow is as follows:
1) Lead fills in contact form
2) Using Stamplay integration with Unbounce, the lead receives a text asking them if they wanted to be contacted "Now", or "Later".
Let's go with lead says "Now"
3) Lead says "Now", which will access a webhook URL to decide on what to do next.
In this particular case, saying "Now", will trigger a TWIML bin to dial the business owner. If the business owner doesn't pick up/busy, then we send a text to the lead asking them to send a follow-up text with a 'name' and 'date/time'.
4) The lead replies with a text with this information, and then both the business owner and lead receive separate notifications about the appointment.
I have been able to successfully go through this whole workflow when a user directly dials the Twilio number (not programatically with keywords yet, which is where I need help).
When a call comes in -> TWIML bin
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Pause length="4"/>
<Say>Please hold, while I connect your call.</Say>
<Pause length="4"/>
<Dial timeout="10"> business owner number </Dial>
<Pause length="4"/>
<Sms>I am currently unavailable. If you'd like me to get in touch, pls reply back with your name, and a time that would work best for you. Thanks, Adam</Sms>
</Response>
When a SMS is received -> webhook URL
<?php
// Require the bundled autoload file - the path may need to change
// based on where you downloaded and unzipped the SDK
require __DIR__ . '/twilio-php-master/Twilio/autoload.php';
// Use the REST API Client to make requests to the Twilio REST API
use Twilio\Rest\Client;
// Your Account SID and Auth Token from twilio.com/console
$sid = 'xyz';
$token = 'xyz';
$client = new Client($sid, $token);
$number = $_POST['From'];
$body = $_POST['Body'];
//Sends a message to the owner
$sms = $client->account->messages->create(
// Cell of owner
'12345',
array(
// A Twilio phone number you purchased at twilio.com/console
'from' => "78900",
// Lead's reply sent to owner asNotification
'body' => "Hi <name>. You have a new lead. The information for this lead is: $body. You can contact them at $number"
)
);
//Sends a message to the lead
$sms = $client->account->messages->create(
// Cell of Lead
$number,
array(
// A Twilio phone number you purchased at twilio.com/console
'from' => "78900",
// Notification Message sent to Lead
'body' => "This is a confirmation that I have received your information, and will be in contact with you soon. Thanks, <name>."
)
);
Where I am encountering issues is having the lead text "Now", to trigger a phone call between the business owner and lead.
This is the code that I have been attempting to use, except that I have been receiving 11200- HTTP retrieval failure non-stop. I have also attempted to use $client->account->calls->create, as that's what I used to successfully send messages.
// Read TwiML at this URL when a call connects (attempt to connect to owner)
$call = $client->calls->create(
'lead-number', // Call this number
'78900', // From a valid Twilio number
array(
'url' => TWIML Bin of Interest
)
);
Anyone have any idea what I could do?
Check out the example of creating a dynamic response:
<?php
// Get the PHP helper library from twilio.com/docs/php/install
require_once '/path/to/vendor/autoload.php'; // Loads the library
use Twilio\Twiml;
$response = new Twiml;
$body = $_REQUEST['Body'];
if( $body == 'hello' ){
$response->message('Hi!');
}else if( $body == 'bye' ){
$response->message('Goodbye');
}
print $response;
In your case you'll modify for if "now" is in the $body you can create the call which your code looks fine for.
$call = $client->calls->create(
"+1415XXXXXXX", "+1415XXXXXXX",
array("url" => "link_to_twiml_bin")
);
In regards to the 11200 HTTP retrieval error, take a look at the possible solutions here especially:
Make sure your web server allows HTTP POST requests to static
resources (if the URL refers to .xml or .html files)
I have a website that uses Twilio to allow people to use our temporary numbers to receive SMS messages received during verification processes etc. It is becomming more common that companies are switching to audio verification instead so I want to start recording all calls received and displaying them in the existing HTML table using the HTML5 <audio> tag.
Here is the existing code:
<tbody>
<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
// Get the PHP helper library from twilio.com/docs/php/install
require_once('twilio/Services/Twilio.php'); // Loads the library
// Your Account Sid and Auth Token from twilio.com/user/account
$sid = "";
$token = "";
$client = new Services_Twilio($sid, $token);
$messages = $client->account->messages->getIterator(0, 50, array(
'To' => $_SERVER['QUERY_STRING'] // this is the number
));
foreach ($messages as $message) {
echo "<tr><td>" . $message->from . "</td><td>" . $message->date_sent . "</td><td>" . $message->body . "</td></tr>";
}
?>
</tbody>
</table>
How can I build in to that the recorded calls received? I want to keep it in date/time order within the eixsting SMS messages, if that makes sense.
Twilio developer evangelist here.
You can absolutely record calls with Twilio.
When you create a call, you just need to include the parameter Record=true in the REST API request to create a call. Then, if you include a statusCallback parameter that points to a URL on your server, then you will receive a webhook to that URL when the call is complete that includes a link to the recording.
You can also fetch the latest recordings from the API. You can get recordings in wav or mp3 format, which you can then use in the HTML <audio> element.
I'm not sure how you have set up your date ordered SMS table, but hopefully this helps. Let me know if there is anything else I can help with.
I am new to Twilio. To learn the basics, I followed the instructions here:
https://www.twilio.com/docs/howto/walkthrough/click-to-call/php/laravel#12
At first, my phone would ring, and I would receive a generic message. Impressed, I upgraded my account. Now I receive a call where a voice says "We're sorry an application error has occurred."
I checked my Alerts in Twilio, and found Error: 12100 - Document parse failure
So I checked the url of my outbound.php and realized that there is a PHP error here. The error is
Fatal error: Class 'Response' not found in
/home/......./outbound.php on line 16
After some searching, I can't find anyone else discussing this same problem. Finally, the worst part, I can't even find any reference to a Response class in the Twilio Helper Library.
Here is my entire code block for the page in question.
<?php
error_reporting(E_ALL);
require_once 'twilio-library/Services/Twilio.php';
// A message for Twilio's TTS engine to repeat
$sayMessage = 'Thanks for contacting our sales department. If this were a
real click to call application, we would redirect your call to our
sales team right now using the Dial tag.';
$twiml = new Services_Twilio_Twiml();
$twiml->say($sayMessage, array('voice' => 'alice'));
// $response->dial('+12345675309');
$response = Response::make($twiml, 200);
$response->header('Content-Type', 'text/xml');
return $response;
?>
If I change this file to static, well formatted XML then the error stops.
Twilio developer evangelist here.
The tutorial you were following was based within the Laravel framework, which is where the Response class was expecting to come from.
If you are using the PHP TwiML builder in just a plain PHP file, you should be able to just print the $twiml. I'd probably add a Content-Type of text/xml as well, just to be safe. Like this:
<?php
error_reporting(E_ALL);
require_once 'twilio-library/Services/Twilio.php';
// A message for Twilio's TTS engine to repeat
$sayMessage = 'Thanks for contacting our sales department. If this were a
real click to call application, we would redirect your call to our
sales team right now using the Dial tag.';
$twiml = new Services_Twilio_Twiml();
$twiml->say($sayMessage, array('voice' => 'alice'));
// $twiml->dial('+12345675309');
header('Content-type: application/xml');
print $twiml;
?>
Let me know if this helps at all!
I am working on a website that allows the user to search for the top ten twitter trends in a city or country. At first I was only relying on Twitter's Rest API, but I was having a lot of rate limit issues (at school my rate limit disappears faster than I have a chance to use it). I know that authenticating my API calls will help me to better deal with this issue (Authenticated API calls are charged to the authenticating user’s limit while unauthenticated API calls are deducted from the calling IP address’ allotment).
I implemented #abraham's PHP library (https://github.com/abraham/twitteroauth), unfortunately my API calls aren't being authenticated. I know I have implemented #abraham's PHP library, because it prints out my user information at the end like it should. I have my twitter trend search underneath it but the API call isn't being authenticated. I am not sure how to fix this, and any help would really be appreciated!
This is what I use to get the top ten trends by country:
function showContent(){
// we're going to point to Yahoo's APIs
$BASE_URL = "https://query.yahooapis.com/v1/public/yql";
// the following code should only run if we've submitted a form
if(isset($_REQUEST['location']))
{
// set a variable named "location" to whatever we passed from the form
$location = $_REQUEST['location'];
// Form YQL query and build URI to YQL Web service in two steps:
// first, we show the query
$yql_query = "select woeid from geo.places where text='$location'";
// then we combine the $BASE_URL and query (urlencoded) together
$yql_query_url = $BASE_URL . "?q=" . urlencode($yql_query) . "&format=json";
//var_dump($location);
// show what we're calling
// echo $yql_query_url;
// Make call with cURL (curl pulls webpages - it's very common)
$session = curl_init($yql_query_url);
curl_setopt($session, CURLOPT_RETURNTRANSFER,true);
$json = curl_exec($session);
// Convert JSON to PHP object
$phpObj = json_decode($json);
// Confirm that results were returned before parsing
if(!is_null($phpObj->query->results)){
// Parse results and extract data to display
foreach($phpObj->query->results as $result){
//var_dump($result);
$woeid = $result[0]->woeid;
if (is_numeric ($location))
{
echo "<span style='color:red; padding-left: 245px;'>Please enter a city or a country</span>";
}
else if(empty($result)){
echo "No results found";
}
else {
/* echo "The woeid of $location is $woeid <br />"; */
}
}
}
$jsontrends=file_get_contents("http://api.twitter.com/1/trends/".$woeid.".json");
$phpObj2 = json_decode($jsontrends, true);
echo "<h3 style='margin-top:20px'>TRENDS: ".$phpObj2[0]['locations'][0]['name']."</h3> \r\n";
$data = $phpObj2[0]['trends'];
foreach ($data as $item) {
echo "<br />".$item['name']."\r\n";
echo "<br /> \r\n";
}
if(empty($item)){
echo "No results found";
}
}
}
I then add it to #abraham's html.inc file (along with some php to see the rate limit status) and html.inc is included in the index.php:
<h1>Top Twitter Trends</h1>
<form name='mainForm' method="get">
<input name='location' id='location' type='text'/><br/>
<button id='lookUpTrends'>Submit</button>
</form>
<?php showContent();
$ratelimit = file_get_contents("http://api.twitter.com/1/account/rate_limit_status.json");
echo $ratelimit;
?>
</div>
#abraham's index.php file has some example calls, and since my call doesn't look like this I think that is probably why it isn't being authenticated.
/* Some example calls */
//$connection->post('statuses/update', array('status' => date(DATE_RFC822)));
//$connection->post('statuses/destroy', array('id' => 5437877770));
//$connection->post('friendships/create', array('id' => 9436992));
//$connection->post('friendships/destroy', array('id' => 9436992));
Please help me find what I need to fix so that my API calls are authenticated.
update 10-21
I think in order to make an authenticated API call I need to include something like this is my code:
$connection->get('trends/place', array('id' => $woeid));
It didn't fix my problem, but maybe it is on the right track?
First off, you'll find that keeping your PHP and HTML separate will really help streamline your code and keep logical concerns separate (aggregating the data and displaying it are two different concerns)(many PHPers like MVC).
The code you have shared appears to be correct. My guess is that the issue lies in the creation of the OAuth connection, which should look something like:
<?php
/* Create TwitteroAuth object with app key/secret and token key/secret from default phase */
$connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET, $token,$secret);
Where CONSUMER_KEY and CONSUMER_SECRET are from your Trends Test app and $token and $secret are from the user signing in to twitter and allowing your app permission. Are all these values showing up when you create the TwitterOAuth object?
Also, be sure you update the config items in the twitteroauth.php file (specifically line 21 should be set to use the 1.1 API and line 29 should be set to 'json').