use text to speech in making call on twilio php api - php

Good day,
Im creating reminder app that calls a number in certain time, currently I was using an uploaded mp3 file on my server:
here the code:
$sid = "ACxxxxxxxxxx";
$token = "2xxxxxxxxx";
$client = new Client($sid, $token);
$call = $client->calls->create(
"$phone_number_to","$phone_number_from",
array("url" =>
"https://xxxxx.com/asset/mp3/reminder.mp3")
);
$csid = $call->sid;
the above code works, but now I wanted to use the text to speech feature on twilio to have a more customized voicemail per reminder..
how do I do this using $client-> api? Im not really familiar on how TwiML works though, maybe thats why im confused.
thanks!

You change this line of your current code "url" => "https://xxxxx.com/asset/mp3/reminder.mp3" so that the URL points at the url hosting the script you want to use to generate your dynamic TwiML.
Then use the php TwiML library to generate the TwiML, it's pretty straightforward. We have a database with all out customers details in, I use code something along these lines to get their details based on caller ID and have Twilio greet them by first name:
$booked = SELECT * FROM table WHERE phone = $caller;
$name = explode(" ", $booked->name);
$firstname = $name[0];
$response->say("Hello $firstname. Thanks for calling......");
It's ok but it's a bit robotic. We ended up extracting the 50 most common first names from the database and having a voiceover artist record greetings for each one. For callers with one of those 50 names we serve a specific mp3 file, everyone else gets the robot.

Related

Google Sheets API with php - Find a cell value

I am using the Google Sheets API with PHP and reading a sheet, I need to find a row and update its content.
I am currently iterating over the rows, looking for the value, but as the sheet grows, this seems rather inefficient. Is there a way to search for a cell, to retrieve the row, so I can then update?
My code to iterate is as follows.
$spreadsheet = (new Google\Spreadsheet\SpreadsheetService)
->getSpreadsheetFeed()
->getById("xxx sheet id xxx");
$worksheets = $spreadsheet->getWorksheetFeed()->getEntries();
$worksheet = $worksheets[0];
$CellFeed = $worksheet->getCellFeed();
foreach ($CellFeed->getEntries() as $E)
{
$r = $E->getRow();
/* ...... */
}
I believe your goal as follows.
You want to search a value from the specific column in the Spreadsheet and want to retrieve the row numbers of searched rows.
You want to achieve this using PHP.
Issue and workaround:
In that case, unfortunately, when Sheets API is used, in the current stage, it is required to do the following flow.
Retrieve all values from the sheet you want to search.
Retrieve the row and column numbers from the retrieved values.
This might be the same with your current script. Because in the current stage, there are no methods for directly searching the values in Sheets API. So in this answer, as a workaround, I would like to propose to use Web Apps created by Google Apps Script. When Google Apps Script is used, the searched row numbers can be retrieved by the TextFinder which is the built-in method. And the process cost of TextFinder is low. So I proposed it.
Usage:
Please do the following flow.
1. Create new project of Google Apps Script.
Sample script of Web Apps is a Google Apps Script. So please create a project of Google Apps Script.
If you want to directly create it, please access to https://script.new/. In this case, if you are not logged in Google, the log in screen is opened. So please log in to Google. By this, the script editor of Google Apps Script is opened.
It is required to put this Google Apps Script project to the same Google Drive of the Spreadsheet you want to use.
2. Prepare script.
Please copy and paste the following script (Google Apps Script) to the script editor. This script is for the Web Apps.
function doGet(e) {
const sheet = SpreadsheetApp.openById(e.parameter.spreadsheetId).getSheetByName(e.parameter.sheetName);
const res = sheet.getRange(1, 2, sheet.getLastRow()).createTextFinder(e.parameter.searchValue).findAll().map(r => r.getRow());
return ContentService.createTextOutput(JSON.stringify({rowNumbers: res})).setMimeType(ContentService.MimeType.JSON);
}
3. Deploy Web Apps.
On the script editor, Open a dialog box by "Publish" -> "Deploy as web app".
Select "Me" for "Execute the app as:".
By this, the script is run as the owner.
Select "Anyone, even anonymous" for "Who has access to the app:".
In this case, no access token is required to be request. I think that I recommend this setting for testing this workaround.
Of course, you can also use the access token. When you use the access token, please include one of scopes for Drive API like https://www.googleapis.com/auth/drive.readonly.
And also, I think that a key value can be used as the query parameter instead of the access token.
Click "Deploy" button as new "Project version".
Automatically open a dialog box of "Authorization required".
Click "Review Permissions".
Select own account.
Click "Advanced" at "This app isn't verified".
Click "Go to ### project name ###(unsafe)"
Click "Allow" button.
Click "OK".
Copy the URL of Web Apps. It's like https://script.google.com/macros/s/###/exec.
When you modified the Google Apps Script, please redeploy as new version. By this, the modified script is reflected to Web Apps. Please be careful this.
4. Testing Web Apps using PHP script.
Please set the URL of your Web Apps to the following script. And, please set the spreadsheet ID, sheet name. From your replying, in this sample, the search value and column number are Pj/5678 and 2, respectively. 2 of searchColumn means the column "B".
<?php
$url = 'https://script.google.com/macros/s/###/exec'; // Please set the URL of Web Apps.
$q = array(
'spreadsheetId' => '###', // Please set the Spreadsheet ID.
'sheetName' => 'Sheet1',
'searchValue' => 'Pj/5678',
'searchColumn' => 2
);
$curl = curl_init();
$option = [
CURLOPT_URL => $url . '?' . http_build_query($q),
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_RETURNTRANSFER => true
];
curl_setopt_array($curl, $option);
$res = curl_exec($curl);
$obj = json_decode($res);
print_r($obj);
curl_close($curl);
?>
Result:
When above script is run, the following value is returned. The row numbers of searched rows are returned.
{"rowNumbers":[###, ###,,,]}
Note:
When you modified the script of Web Apps, please redeploy the Web Apps as new version. By this, the latest script is reflected to Web Apps. Please be careful this.
References:
Web Apps
Taking advantage of Web Apps with Google Apps Script
Class TextFinder

Getting campaign stats (e.g. Clicks, CTR, CPC, etc.) via AdWords API

What I'm trying to currently do is fetch Campaign statistics such as Clicks, Impressions, CTR, Average CPC and etc for a particular campaign. Unfortunately, I can't find how to do it via the AdWords API.
What I've found up till now is that,
Maybe, in an earlier version of the CampaignService, we were able to obtain stats by doing something like $campaign->campaignStats. Unluckily, I'm using V201506 and in it there is no campaignStats object/variable.
I probably can get these stats using the 'CAMPAIGN_PERFORMANCE_REPORT' but it needs to be downloaded and I don't want to download the report. I just want an array or something similar returned so that I can process it. Also, I don't want to give any time frame, I just want all time stats to be returned for that campaign. Is it even possible?
If any one could help me out, I would really appreciate it. Kind of been stuck here for a few hours, skimmed through the whole AdWords API documentation but couldn't understand what would be the best and easy approach to this.
Now, Adwords API allowing stats only By reporting service.
And stats can be get using two methods.
1) By using reporting service as described
here
2) You can use Adwords Query Language. See
this
i don't know if you still need this but the API V201806 I found a solution. In this version of API exist the function getAsString() which returns the data in String and not download file, I request data in format XML and in PHP transform the response into a XML Object.
This is code I used:
class DownloadCriteriaReportWithAwql {
public static function runExample(AdWordsSession $session, $reportFormat){
// Create report query to get the data for last 7 days.
$query = (new ReportQueryBuilder())
->select([
'CampaignId',
'AdGroupId',
'Id',
'Criteria',
'CriteriaType',
'Impressions',
'Clicks',
'Cost',
'Conversions'
])
->from(ReportDefinitionReportType::CRITERIA_PERFORMANCE_REPORT)
->where('Status')->in(['ENABLED'])
->duringDateRange(ReportDefinitionDateRangeType::LAST_7_DAYS)
->build();
// Download report as a string.
$reportDownloader = new ReportDownloader($session);
// Optional: If you need to adjust report settings just for this one
// request, you can create and supply the settings override here.
// Otherwise, default values from the configuration
// file (adsapi_php.ini) are used.
$reportSettingsOverride = (new ReportSettingsBuilder())->includeZeroImpressions(false)->build();
$reportDownloadResult = $reportDownloader->downloadReportWithAwql(
sprintf('%s', $query),
$reportFormat,
$reportSettingsOverride
);
//print "Report was downloaded and printed below:\n";
$datos = $reportDownloadResult->getAsString();
return ($datos);
}
public static function main(){
// Generate a refreshable OAuth2 credential for authentication.
$oAuth2Credential = (new OAuth2TokenBuilder())->fromFile()->build();
// See: AdWordsSessionBuilder for setting a client customer ID that is
// different from that specified in your adsapi_php.ini file.
// Construct an API session configured from a properties file and the
// OAuth2 credentials above.
$session = (new AdWordsSessionBuilder())
->fromFile()
->withOAuth2Credential($oAuth2Credential)
->build();
$string = self::runExample($session, DownloadFormat::XML);
$xml = new \SimpleXMLElement($string);
return $xml;}}
The question was asked in 2015, since then they renamed the API to Google Ads API. The current version is V6 where getting clicks, CTR, CPC and other metrics is relatively simple.
The documentation here states:
This page shows all metrics and segments that can be put in the same SELECT clause as the fields of campaign
Based on that the AWQL for getting campaign together with clicks will look like this (tested):
$query = "SELECT campaign.id, campaign.name, campaign.status, metrics.clicks FROM campaign ORDER BY campaign.name"
Example in PHP how to iterate through results:
$stream = $googleAdsServiceClient->searchStream($customerId, $query);
foreach ($stream->iterateAllElements() as $googleAdsRow) {
/** #var GoogleAdsRow $googleAdsRow */
$data['campaigns'][] = [
'id' => $googleAdsRow->getCampaign()->getId(),
'clicks' => $googleAdsRow->getMetrics()->getClicks(),
];
}

Pulling Bright Local API Data into my Ruby on Rails App - API Docs written in PHP

I'm trying to build a rails app that pulls data from several different SEO tool API's. For Bright Local (see their API docs here - http://apidocs.brightlocal.com/) all the API doc examples are written in PHP, which I can't read all that great.
So first, to ask a specific question, how would I write this batch request in Ruby:
<?php
use BrightLocal\Api;
use BrightLocal\Batches\V4 as BatchApi;
$api = new Api('[INSERT_API_KEY]', '[INSERT_API_SECRET]');
$batchApi = new BatchApi($api);
$result = $batchApi->create();
if ($result['success']) {
$batchId = $result['batch-id'];
}
Also, any suggestions for how I can bring myself up to snuff on using API's in my rails apps?
Our docs do currently only show PHP examples - although we are planning to expand on that and Ruby is one of the languages we'll be looking to add.
A simple command line CURL request for the above PHP code would look like this:
curl --data "api-key=<YOUR API KEY HERE>" https://tools.brightlocal.com/seo-tools/api/v4/batch
and would return a response like this:
{"success":true,"batch-id":<RETURNED BATCH ID>}
All our API endpoints respond to either POST, PUT, GET or DELETE. It's also important to note that whenever data is posted with POST or PUT it's passed like "param1=value1&param2=value2" in the body of the request rather than JSON encoded.
I don't know Ruby at all I'm afraid but something like this might make the request you want:
params = {"api-key" => "<YOUR API KEY>"}
Net::HTTP::Post.new("https://tools.brightlocal.com/seo-tools/api/v4/batch").set_form_data(params)
I'm also implementing brightlocal into my Rails app. I'm using the HTTParty gem. this is what I have so far and am able to make successful calls
this is to obtain your batch id:
api_key = YOUR_API_KEY
secret_key = YOUR_SECRET_KEY
request_url = "https://tools.brightlocal.com/seo-tools/api/v4/batch?api-key=#{api_key}"
response = HTTParty.post(request_url)
if response.code == 201
batch_id = response['batch-id']
end
this is an example of running one job in the batch (the query parameters go inside the body):
rank_url = "https://tools.brightlocal.com/seo-tools/api/v4/rankings/search"
response = HTTParty.post(rank_url, {
:body => {
"api-key" => api_key,
"batch-id" => batch_id,
"search-engine" => "google",
"country" => "USA",
"search-term" => "restaurant"
}
})
I have not tested this next part, but theoretically, this is how you would deal with signatures and expirations
expires = Time.now.to_i + 1800
string_to_sign = "#{api_key}.#{expires}"
binary_signature = OpenSSL::HMAC.digest('sha1', string_to_sign, secret_key)
url_safe_signature = CGI::escape(Base64.encode64(binary_signature).chomp)
All that would be left is to use a PUT request to commit the batch, and a GET request to retrieve the data inside the batch.
EDIT: Figured out how to correctly get a passing signature for the jobs that require one. (this example is for local search rank checker http://apidocs.brightlocal.com/#local-search-rank-checker)
expires = Time.now.to_i + 1800
concat = api_key + expires.to_s
sig = OpenSSL::HMAC.digest('sha1', secret_key, concat)
sig = CGI::escape(Base64.encode64(sig).chomp)
local_rank = "https://tools.brightlocal.com/seo-tools/api/v2/lsrc/add?api-key=#{api_key}&sig=#{sig}&expires=#{expires}"
response = HTTParty.post(local_rank, {
:body => {
"name" => "pizza hut",
"search-terms" => "restaurant"
}
})
Since you are using Ruby and not PHP you will have to implement everything yourself. The example you give shows the user of a PHP wrapper created by BrightLocal (and it seems they only have it in PHP).
Basically you will have to make calls to the endpoints yourself and manage the data yourself instead of using their wrapper.

How to get Twilio Recording file in PHP

I am using Twilio application. I want to get the path of my recording. I am using this code:
$client = new Services_Twilio($sid, $token, $version);
$calls = $client->account->calls->getIterator(0, 50, array(
));
$url = $call->subresource_uris->recordings;
in the variable $url /2010-04-01/Accounts/<acount id>/Calls/callerid/Recordings.json
But when i paste this url "https://api.twilio.com/2010-04-01/Accounts/<acount id>/Calls/callerid/Recordings.json" it gives me alert popup to enter user name and password.
Basically i want this file to save on my system
Twilio evangelist here.
The URL you are using is requesting a list of Recording resources from Twililo, not the actual audio files. Each resource contains a property called Url that represents that actual audio recording file.
If you want to download the audio, you will need to loop through that list of recordings and make a new HTTP GET request to the Url specified in the Url property.
Hope that helps.

Facebook PHP API not always returning event venue data

I have 3 events:
https://www.facebook.com/491594114271958 (Mad Haus)
https://www.facebook.com/569226999799343 (Deuglish)
539504962802119/ (Piffle)
All are being fetched via the PHP
$config = array();
$config['appId'] = $appId;
$config['secret'] = $secret;
$config['fileUpload'] = false; // optional
$facebook = new Facebook($config);
$ev = $facebook->api('/'.$id."?fields=cover,description,location,name,owner,venue",'GET');
print_r($ev);
For some reason Mad Haus and Piffle do not return venue data but Deuglish does. All events return basic data such as title, description and start time. When I run them through the Graph API explorer the venue data is returned as expected but not through the PHP API, any ideas? I can not for the life of me see the difference with these 3 events.
Thanks,
Caroline
Well, if you don't want to wait for the Facebook developers to fix the bug, you can try the same by making a simple GET request (of course along with an Access Token) to Graph API using PHP cURL. Since you are able to retrieve the venues while using the Graph API explorer, I'm pretty sure you'll be able to get them by making a simple GET request using PHP cURL.
This however involves an overhead of parsing the received JSON object and dealing with errors will be a little difficult here. But you can give it a shot.

Categories