Twilio doesn't call my TwiML instruction url - php

I'm using Twilio to send a verification code through voice call. I've used this tutorial to write the code:
https://www.twilio.com/blog/implement-account-verification-login-by-phone-laravel-php
So, that's basically the code. My phone rings and I get the "You have a test account, press any key to run your code" message, but when I press a key, it hangs up on me and my code is never called.
public function sendVerificationCodeThroughCall($mobile)
{
$code = $this->createMobileCode($mobile);
$client = new Client(config('services.twilio.sid'), config('services.twilio.auth_token'));
$client->calls->create(
$mobile,
config('services.twilio.phone_number'),
["url" => route('voice-code.build', $code)]
);
}
public function buildVoiceCode($code)
{
Log::debug('Twilio called to say: ' . $code);
$code = $this->splitCode($code);
$response = new VoiceResponse();
$response->say("Salaam. This is your verification code: {$code}. I repeat, {$code}.");
echo $response;
}
protected function splitCode($code)
{
return implode('.', str_split($code));
}

Related

WhatsApp chatbot with Twilio using Php

I am trying to create a chatbot using laravel php and Twilio Api. I am still in sandbox. This the code i currently have
public function commandHandler(Request $request){
$from = $request->input('From'); // phone number where the message is coming from
$body = $request->input('Body');// what user wrote
$client = new \GuzzleHttp\Client();
try {
$response = $client->request('GET', "https://api.github.com/users/$body"); //test if network is working
if ($response->getStatusCode() == 200) {
$message = "Welcome to System. \n";
$message .= "To Log In, Enter Email Address";
$this->sendWhatsAppMessage($message, $from);
} else {
$this->sendWhatsAppMessage("Error", $from);
}
} catch (RequestException $th) {
$response = json_decode($th->getResponse()->getBody());
$this->sendWhatsAppMessage($response->message, $from);
}
return;
}
I can get what user has typed from the variable $body and send user back a message through the function
$this->sendWhatsAppMessage($response->message, $from);
but the problem is when i want the user to enter password, it goes to the same url and does the same functions of which i would like for it to do different functions. Twilio only accepts one call-back url which i have to use that one function only. How do i use different functions for different messages sent to the user
this is what is in my api.php
Route::post('/chat', 'App\Http\Controllers\ChatBotController#listenToReplies');
and that is the url in the callback of the Twilio dashboard

Outgoing call from Twilio is not working in Laravel 5.5

I'm new to Twilio. I'm using Twilio for phone verification of my app. I'm using Laravel 5.5 for the backend & APIs. I've successfully sent the SMS to phone. I'm getting the call from Twilio but it says an application error. It doesn't read what I want to hear.
Below I'm giving every detail of my code.
Used composer require twilio/sdk for Twilio.
This is my Controller.
use Twilio\Rest\Client;
use Twilio\Twiml;
class AppUserController extends Controller{
private $account_sid;
private $auth_token;
private $twilio_number;
public function __construct(){
$this->account_sid = Config::get('envvalue.account_sid');
$this->auth_token = Config::get('envvalue.auth_token');
$this->twilio_number = Config::get('envvalue.twilio_number');
}
public function reVerification(Request $request){
$client = new Client($this->account_sid, $this->auth_token);
try {
$client->account->calls->create(
$receiverNumber,
$this->twilio_number,
array(
"url" => "http://demo.bitcanny.com/marine-admin/public/api/twiml/"
)
);
return response()->json([
'success' => true,
'statusCode' => '200',
'message' => 'Otp send again'
], 200);
}
catch (Exception $e) {
return $e->getMessage();
}
}
public function twiml(){
// A message for Twilio's TTS engine to repeat
$sayMessage = 'Hello.';
$twiml = new Twiml();
$twiml->say($sayMessage);
$response = Response::make($twiml, 200);
$response->header('Content-Type', 'text/xml');
return $response;
}
}
I found the solution. There's a silly mistake. I didn't use Response in the header of my controller.
use Response;

Twilio add incoming call to queue and call to the agent

I have run in the situation where i'm handling incoming call using PHP/laravel, so when client calls to the company number the response is this method :
public function respondToUser()
{
$response = new Twiml();
$audio_file_path = trans('ivr_file_paths.welcome');
$response->play($audio_file_path);
$response->redirect('/ivr/call/enqueue', ['method' => 'POST']);
return $response;
}
But what I want to achieve next is to put incoming call in queue and then run the music in background if the operator (one operator /agent only) is busy, if not then connect to him.
this is what it looks like now
public function enqueueCall(Request $request)
{
$please_wait_audio_file = trans('paths.please_wait');
$please_wait_audio_file = trans('ivr_file_paths.please_wait');
$response = new Twiml();
$dial = $response->dial();
$dial->number('+number');
$response->enqueue('support', ['waitUrl' => $please_wait_audio_file]);
Log::info($response);
echo $response;
}
I know there is no queue right now, but this method just ends up the call..
Any suggestions? Thank you very much!
Twilio developer evangelist here.
I recommend you start by looking at the <Enqueue> TwiML verb which queues a caller up, followed by <Queue> which you can use within <Dial> to pop the next user off from the queue and talk to them.
If you need anything more complicated than that, then start reading into TaskRouter.
edit some example code:
Enqueue the caller and dial your agent.
public function enqueueCall(Request $request)
{
// build up the TwiML
$please_wait_audio_file = trans('ivr_file_paths.please_wait');
$response = new Twiml();
$response->enqueue('support', ['waitUrl' => $please_wait_audio_file]);
// make the call to your agent
$client = new Client($yourTwilioAccountSid, $yourTwilioAuthToken);
$call = $client->calls->create(
$yourAgentNumber,
$yourTwilioNumber,
array("url" => "http://example.com/ivr/call/queue")
);
Log::info($response);
echo $response;
}
When the agent connects, dial the queue:
public function dialQueue(Request $request)
{
$response = new Twiml();
$dial = $response->dial();
$dial->queue('support');
echo $response;
}

Google always returns false verifying id token

I have the next code, got directly from google reference (https://developers.google.com/identity/sign-in/web/backend-auth)
public function verifyFromAndroid($idToken=null) {
if(empty($idToken)) {
$idToken = self::SAMPLE_ID_TOKEN;
}
$client = new Google_Client(['client_id' => self::CLIENT_ID]);
$payload = $client->verifyIdToken($idToken);
if ($payload) {
print_r($payload);
$userid = $payload['sub'];
// If request specified a G Suite domain:
//$domain = $payload['hd'];
} else {
var_dump($payload);
$this->lastError = "Invalid ID token";
return false;
}
}
But this method always returns false, even using a valid id token that is created and working using the oauthplayground online tool.
The next code works fine, using directly the GoogleAccessToken_Verify class. Can someone tell me why the official Google code doesn't work and yes my own code using the official Google-clien-php sdk?
try {
$verify = new Google_AccessToken_Verify();
$result = $verify->verifyIdToken($this->idToken);
if($result) {
print_r($result);
$friendlyData = $this->translateData($result, true);
if(!$friendlyData) {
return false;
}
return $friendlyData;
}
else {
$this->lastError = "Invalid token verification, no error code";
return false;
}
}
catch(UnexpectedValueException $ex) {
$this->lastError = "UnVaEx (Code {$ex->getCode()}): {$ex->getMessage()}";
return false;
}
try adding complete client ID
xxxxxxxxxxxxxx-xxxxx-yy-zz.apps.googleusercontent.com
while initiating the
$client = new Google_Client(['client_id' => self::CLIENT_ID]);
It should work i was also facing the same issue ...
Had a similar issue.Deleted my android app on firebase console and created a fresh app wirh debug key sha1.Then downloaded and replaced my google.json into my app.This fixed my issue.This has happened to me twice now. At times you just need to recreate the android app on firebase console.
Before you begin register your backend URL at https://developers.google.com/identity/sign-in/web/sign-in with Configure your project button and don't use any credidentials or api key in your code. After doing them your code should look like to this.
public function verifyFromAndroid($idToken=null) {
if(empty($idToken)) {
$idToken = self::SAMPLE_ID_TOKEN;
}
//As you notice we don't use any key as a parameters in Google_Client() API function
$client = new Google_Client();
$payload = $client->verifyIdToken($idToken);
if ($payload) {
print_r($payload);
$userid = $payload['sub'];
// If request specified a G Suite domain:
//$domain = $payload['hd'];
} else {
var_dump($payload);
$this->lastError = "Invalid ID token";
return false;
}
}
I hope it helps.
I faced the same issue. After checking different PHP versions, I found that the google client library is working in PHP7.4 but not with PHP8.0.
Please try the below code after downgrading the version of PHP to 7.4
require_once 'vendor/autoload.php';
$id_token = $_POST['credential'];
$client = new Google_Client(['client_id' => $CLIENT_ID]); // Specify the CLIENT_ID of the app that accesses the backend
$payload = $client->verifyIdToken($id_token);
if ($payload) {
$userid = $payload['sub'];
// If request specified a G Suite domain:
//$domain = $payload['hd'];
} else {
// Invalid ID token
}
Or For development and debugging, you can call google oauth2 tokeninfo validation endpoint.
https://oauth2.googleapis.com/tokeninfo?id_token=$id_token

How is this public key == private key

This is a part of a test with this wordpress plugin which is basically a license manager. I am trying to understand the internals of the system. Here is how it works.
Once the plugin is activated, it generates a private key 55d0ec3f9db414.02268045 using a simple function 'lic_verification_private_secret' => uniqid('', true). Now, when someone makes a purchase of an item eg. a wordpress plugin, a public license key 55d5d22ab70d2 is generated (using uniqid()). The public key is then sent to the customer's email id. The customer inputs that key into his site and sends a request to the license server. Below is a function about how the license manager plugin #server matches the private key with public key.
static function verify_secret_key() {
$slm_options = get_option('slm_plugin_options');
$private_secret_key = $slm_options['lic_verification_private_secret'];
$public_key = strip_tags($_REQUEST['secret_key']); //this is sent in the query string
if ($public_key == $private_secret_key) {
// send a message back to client saying the key is verified.
}
All this works, so basically where I am stumped is how the below equation is valid ? What part of the picture am I missing ?
55d5d22ab70d2 == 55d0ec3f9db414.02268045
Update - I have performed this test and it echoes false which i guess is obvious.
echo '55d0ec3f9db414.02268045' === '55d5d22ab70d2' ? 'true' : 'false';
Shared secret key:
function generate_signature($message, $secret) {
$serialized_message = serialize($message);
return md5($serialized_message . $secret);
}
$secret = "i like pie";
$content = array(
"i like" => "pie",
"pancakes" => "are also nice"
);
$message = serialize(array(
"signature" => generate_signature($content , $secret),
"content" => $content
));
// send the message
$message = unserialize($_POST["message"]);
$signature = generate_signature($message["content"], $secret);
if ($signature === $message["signature"]) {
echo "ok";
} else {
echo "you don't like pie?";
}
The secret key can be the license btw, since that's what you want to keep secret.

Categories