Send FCM message to open deeplink in my android application by Laravel - laravel

How can i send Firebase cloud token to my android app to open my app deeplink?
I implemented deeplink and its worked
Then config my firebase FCM and my laravel send notification to my android device. with this library
https://github.com/brozot/Laravel-FCM
i cant find any method to send link but
function sendNotification($user_id, $type)
{
$message = getNotificationMessage($type);
try {
$fcm_tokens = ClientInfo::where('user_id', $user_id)->all();
foreach ($fcm_tokens as $key => $fcm_token) {
$optionBuilder = new OptionsBuilder();
$optionBuilder->setTimeToLive(60 * 20);
$notificationBuilder = new PayloadNotificationBuilder();
$notificationBuilder->setBody($message)
->setSound('default')
->setClickAction('bazarshahr://customer.app/order');
$dataBuilder = new PayloadDataBuilder();
$dataBuilder->addData(['deeplink' => 'bazarshahr://customer.app/product/39']);
$option = $optionBuilder->build();
$notification = $notificationBuilder->build();
$data = $dataBuilder->build();
$token = $fcm_token['firebase_token'];
$downstreamResponse = FCM::sendTo($token, $option, $notification, $data);
$downstreamResponse->numberSuccess();
$downstreamResponse->numberFailure();
$downstreamResponse->numberModification();
// return Array - you must remove all this tokens in your database
$downstreamResponse->tokensToDelete();
// return Array (key : oldToken, value : new token - you must change the token in your database)
$downstreamResponse->tokensToModify();
// return Array - you should try to resend the message to the tokens in the array
$downstreamResponse->tokensToRetry();
// return Array (key:token, value:error) - in production you should remove from your database the tokens
$downstreamResponse->tokensWithError();
}
} catch (Exception $e) {
SystemLog::error(sprintf("[helpers.sendNotif] Can't send Nofication: %s (%d)", $e->getMessage(), $e->getCode()));
return false;
}
return true;
}

This feature is not mentioned in Fcm documentation but i tried some sort of tests on my own and figured out the solution: as we replied here
Instead of click_action we need to put link:
https://fcm.googleapis.com/fcm/send
Content-Type: application/json
Authorization: key={SERVER_KEY}
{
"to" : "{Firebase client token}",
"collapse_key" : "type_a",
"notification" : {
"body" : "Body of Your Notification",
"title": "Title of Your Notification"
"link": "example://my.app/products" <<-- Here is the solution
}
}

Related

Stripe PHP Best way to debug an SignatureVerificationException with Stripe-cli

I created a webhook to get informations about checkout sessions :
public function stripeWebhookCheckout(Request $request)
{
\Stripe\Stripe::setApiKey(env("STRIPE_SECRET"));
// You can find your endpoint's secret in your webhook settings
$endpoint_secret = 'whsec_fVBkAmCztUTacQKZiyjmcq6QQrl8lKL1';
$payload = #file_get_contents('php://input');
$sig_header = $_SERVER['HTTP_STRIPE_SIGNATURE'];
$event = null;
try {
$event = \Stripe\Webhook::constructEvent(
$payload,
$sig_header,
$endpoint_secret
);
} catch (\UnexpectedValueException $e) {
// Invalid payload
http_response_code(400);
exit();
} catch (\Stripe\Exception\SignatureVerificationException $e) {
// Invalid signature
http_response_code(400);
exit();
}
// Handle the checkout.session.completed event
if ($event->type == 'checkout.session.completed') {
$session = $event->data->object;
// Fulfill the purchase...
handle_checkout_session($session);
$stripeSessionId = $session['id'];
if (isset($stripeSessionId)) {
$payment = Payment::where('stripe_sessioncheckout_id', '=', $stripeSessionId)->first();
$payment->status = "success";
$payment->data = $session;
$payment->save();
}
}
http_response_code(200);
}
I use stripe-cli to test my webhook in local. And i have this kind of result
$ stripe listen --forward-to jvlb.test/api/stripe/webhook/checkout
> Ready! Your webhook signing secret is whsec_sc9Gh9A6zx3IOfBpH62F9DdPYIhSUYtw (^C to quit)
2019-11-28 16:19:06 --> charge.succeeded [evt_1FjsW5FIYszmshR0eGSB9GDo]
2019-11-28 16:19:06 <-- [400] GET https://jvlb.test/api/stripe/webhook/checkout [evt_1FjsW5FIYszmshR0eGSB9GDo]
To debug it i changes the http_response_code(400) and I realised it generate a SignatureVerificationException.
My question is, how can i debug this ? Is it the $_SERVER['HTTP_STRIPE_SIGNATURE'] who is wrong ?
Thanks
i found a solution, if it can help people in the future :
I made a mistake in the way i use stripe-cli, i forgot "https://".
The good way is :
stripe listen --forward-to https://jvlb.test/api/stripe/webhook/checkout
And then i had few error of code to manage. I just used the tail command on my log file
tail -f storage/logs/laravel-2019-11-29.log

Gsuite reseller API for create admin user for our customers using PHP

I am using google API client service to perform all GSuite API like customer creation, customer subscription, and customer admin user creation.
So using the API i could able to create customer, subscription and list users of customers. But only thing i couldn't able to do, ie., customer admin user creation.
Seems like that needs some scope "https://www.googleapis.com/auth/admin.directory.user".
But after many try I have enabled the scope "https://www.googleapis.com/auth/admin.directory.user.readonly". But I couldn't remember how it was enabled by me ,only I have remember when I try to use API console I have chosen all directory API to authorize, even this also "https://www.googleapis.com/auth/admin.directory.user".
So now the problem is that creation of admin user using the API. I am getting the error "Insufficient Permission: Request had insufficient authentication scopes."
I have done all this by referring the below URLs only.
https://developers.google.com/admin-sdk/reseller/v1/quickstart/php
https://developers.google.com/admin-sdk/directory/v1/quickstart/php
So please help me to give permission to access "https://www.googleapis.com/auth/admin.directory.user" to create admin user for my application.
I have used below script to do that.
<?php
require __DIR__ . '/vendor/autoload.php';
if (php_sapi_name() != 'cli') {
throw new Exception('This application must be run on the command line.');
}
function getClient()
{
$OAUTH2_SCOPES = [
Google_Service_Reseller::APPS_ORDER,
Google_Service_SiteVerification::SITEVERIFICATION,
Google_Service_Directory::ADMIN_DIRECTORY_USER,
];
$client = new Google_Client();
$client->setApplicationName('G Suite Reseller API PHP Quickstart');
$client->setScopes(Google_Service_Reseller::APPS_ORDER);
$client->setAuthConfig('credentials.json');
$client->setAccessType('offline');
$client->setPrompt('select_account consent');
$tokenPath = 'token.json';
if (file_exists($tokenPath)) {
$accessToken = json_decode(file_get_contents($tokenPath), true);
$client->setAccessToken($accessToken);
}
if ($client->isAccessTokenExpired()) {
if ($client->getRefreshToken()) {
$client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
} else {
$authUrl = $client->createAuthUrl();
printf("Open the following link in your browser:\n%s\n", $authUrl);
print 'Enter verification code: ';
$authCode = trim(fgets(STDIN));
$accessToken = $client->fetchAccessTokenWithAuthCode($authCode);
$client->setAccessToken($accessToken);
if (array_key_exists('error', $accessToken)) {
throw new Exception(join(', ', $accessToken));
}
}
if (!file_exists(dirname($tokenPath))) {
mkdir(dirname($tokenPath), 0700, true);
}
file_put_contents($tokenPath, json_encode($client->getAccessToken()));
}
return $client;
}
$client = getClient();
$user = new Google_Service_Directory_User($client);
$service = new Google_Service_Directory($client);
$names = new Google_Service_Directory_UserName($client);
$customerId = $cusomter_id;
$email_id = $admin_email_id;
$fname = $fname;
$lname = $lname;
$kind = "admin#directory#user";
$user->setKind($kind);
$user->setChangePasswordAtNextLogin(true);
$user->setprimaryEmail($email_id);
$user->setCustomerId($customerId);
$user->setIsAdmin(true);
$names->setFamilyName($fname);
$names->setFullName($fname);
$user->setName($names);
$user->setPassword($password);
$setEmails = array("address"=>$email_id, "type"=>"work", "primary"=>true,"isAdmin"=>true);
$user->setEmails($setEmails);
$results = $service->users->insert($user);
print_r($results);
?>
Response Error
PHP Fatal error: Uncaught exception 'Google_Service_Exception' with message '{
"error": {
"errors": [
{
"domain": "global",
"reason": "insufficientPermissions",
"message": "Insufficient Permission: Request had insufficient authentication scopes."
}
],
"code": 403,
"message": "Insufficient Permission: Request had insufficient authentication scopes."
}
}
' in google-gsuite-api/google-api-php-client-2.2.3/src/Google/Http/REST.php:118
Stack trace:
#0 google-gsuite-api/google-api-php-client-2.2.3/src/Google/Http/REST.php(94): Google_Http_REST::decodeHttpResponse(Object(GuzzleHttp\Psr7\Response), Object(GuzzleHttp\Psr7\Request), 'Google_Service_...')
#1 [internal function]: Google_Http_REST::doExecute(Object(GuzzleHttp\Client), Object(GuzzleHttp\Psr7\Request), 'Google_Service_...')
#2 google-gsuite-api/google-api-php-client-2.2.3/src/Google/Task/Runner.php(176): call_user_func_ in google-gsuite-api/google-api-php-client-2.2.3/src/Google/Http/REST.php on line 118

Laravel issue Credentials are required to create a Client

I need to test send SMS to mobile I get Credentials are required to create a Client error for My Code Here
.env
TWILIO_ACCOUNT_SID=AC15...................
TWILIO_AUTH_TOKEN=c3...................
TWILIO_NUMBER=+1111...
Config\App
'twilio' => [
'TWILIO_AUTH_TOKEN' => env('TWILIO_AUTH_TOKEN'),
'TWILIO_ACCOUNT_SID' => env('TWILIO_ACCOUNT_SID'),
'TWILIO_NUMBER' => env('TWILIO_NUMBER')
],
Controller
$accountSid = env('TWILIO_ACCOUNT_SID');
$authToken = env('TWILIO_AUTH_TOKEN');
$twilioNumber = env('TWILIO_NUMBER');
$client = new Client($accountSid, $authToken);
try {
$client->messages->create(
'0020109.....',
[
"body" => 'test',
"from" => $twilioNumber
// On US phone numbers, you could send an image as well!
// 'mediaUrl' => $imageUrl
]
);
Log::info('Message sent to ' . $twilioNumber);
} catch (TwilioException $e) {
Log::error(
'Could not send SMS notification.' .
' Twilio replied with: ' . $e
);
}
Twilio developer evangelist here.
A quick read over the environment config for Laravel suggests to me that you can use the env method within your config files, as you are doing, but it's not necessarily available in application code. Since you are committing your environment variables to the config object, I think you need to use the config method instead.
$accountSid = config('TWILIO_ACCOUNT_SID');
$authToken = config('TWILIO_AUTH_TOKEN');
$twilioNumber = config('TWILIO_NUMBER');
Let me know if that helps at all.

New Caller Insert to Database with Codeigniter using the Twilio API

Below is the function to receive all incoming calls in my Controller
public function call_incoming()
{
$blocklist = $this->call_log_model->get_blocklist($_REQUEST['From']);
$tenantNum = $this->call_log_model->get_called_tenant($_REQUEST['From']);
$tenantInfoByNumber = $this->account_model->getTenantInfoByNumber($tenantNum->to_tenant);
$officeStatus = $this->check_office_hours($tenantInfoByNumber->start_office_hours, $tenantInfoByNumber->end_office_hours);
$calldisposition = $this->calldisp_model->get_call_disposition($tenantInfoByNumber->user_id);
$response = new Services_Twilio_Twiml;
if($blocklist == 0)
{
if($officeStatus == "open")
{
if($_POST['Called'] != AGENTPOOL_NUM)
{
$data = array(
'caller'=>$_REQUEST['From'],
'to_tenant'=>$_POST['Called'],
'date_created'=>date('Y-m-d H:i:s')
);
$this->call_log_model->insert_caller_to_tenant($data);
$dial = $response->dial(NULL, array('callerId' => $_REQUEST['From']));
$dial->number(AGENTPOOL_NUM);
print $response;
}
else
{
$gather = $response->gather(array('numDigits' => 1, 'action'=>HTTP_BASE_URL.'agent/call_controls/call_incoming_pressed', 'timeout'=>'5' , 'method'=>'POST'));
$ctr = 1;
foreach($calldisposition as $val )
{
$gather->say('To go to '.$val->disposition_name.', press '.$ctr, array('voice' => 'alice'));
$gather->pause("");
$ctr++;
}
print $response;
}
}
else
{
$response->say('Thank you for calling. Please be advise that our office hours is from '.$tenantInfoByNumber->start_office_hours.' to '.$tenantInfoByNumber->end_office_hours);
$response->hangup();
print $response;
}
}
else
{
$response->say('This number is blocked. Goodbye!');
$response->hangup();
print $response;
}
}
Please advise if I need to post the model...
Here is whats happening everytime an unknown number calls in, the caller will hear an application error has occurred error message and when checking the Twilio console the error it is giving me is
A PHP Error was encountered
Severity: Notice
Message: Trying to get property of non-object
Filename: agent/Call_controls.php
Line Number: 357
Please be advised that this error only occurs when the caller is a number not in our database yet. When the call comes from a number already saved in our databse, this codes works...
Thank you for the help...
if($tenantNum) {
$tenantInfoByNumber = $this->account_model->getTenantInfoByNumber($tenantNum->to_t‌​enant);
} else {
$tenantInfoByNumber = ""; // fill this in with relevant fill data
}
This should fix your issue, as there is no TenantNum returned, there is no data, so make it yourself for unknown numbers.

Ratchet WAMP onpublish always publish to all clients include the publish caller or not?

I have just made a chat hello world for the Ratchet WAMP + autobahn version 1.
full source code here if you want to see
The JavaScript client send chat message:
function click_send_btn() {
var json_data = {
"message": $.trim($("#input_message").val())
};
sess.publish("send_message", json_data, true);
}
The PHP Ratchet server publish the message:
public function onPublish(\Ratchet\ConnectionInterface $conn, $topic, $event, array $exclude, array $eligible) {
switch ($topic) {
case 'http://localhost/enter_room':
$foundChater = $this->allChater[$conn];
$newChaterName = $event['username'];
$foundChater->setChatName($newChaterName);
break;
case 'send_message':
$foundChater = $this->allChater[$conn];
$event['username']=$foundChater->getChatName();
break;
}
$topic->broadcast($event);
echo "onPublish {$conn->resourceId}\n";
}
I don't understand why publish with excludeme not working.
In the above 2 firefox, right firefox said: I am bar. The message should not display at himself, but it is.
doc ref: autobahn version 1 javascript publish with excludeme
doc ref: ratchet onpublish
doc ref: ratchet topic broadcast
I have just fix it.
What a fool I am. I had not handle the parameter "array $exclude"
and I also used the $topic->broadcast($event) to force broadcast to all.
Now I create a function
/**
* check whitelist and blacklist
*
* #param array of sessionId $exclude -- blacklist
* #param array of sessionId $eligible -- whitelist
* #return array of \Ratchet\ConnectionInterface
*/
private function getPublishFinalList(array $exclude, array $eligible) {
//array of sessionId
$allSessionId = array();
$this->allChater->rewind();
while ($this->allChater->valid()) {
array_push($allSessionId, $this->allChater->current()->WAMP->sessionId);
$this->allChater->next();
}
//if whitelist exist, use whitelist to filter
if (count($eligible) > 0) {
$allSessionId = array_intersect($allSessionId, $eligible);
}
//then if blacklist exist, use blacklist to filter
if (count($exclude) > 0) {
$allSessionId = array_diff($allSessionId, $exclude);
}
//return array of connection
$result = array();
$this->allChater->rewind();
while ($this->allChater->valid()) {
$currentConn = $this->allChater->current();
if (in_array($currentConn->WAMP->sessionId, $allSessionId)) {
array_push($result, $currentConn);
}
$this->allChater->next();
}
return $result;
}
in the onPublish, I not use the $topic->broadcast($event) anymore.
$conn2PublishArray = $this->getPublishFinalList($exclude, $eligible);
foreach ($conn2PublishArray as $conn2Publish) {
$conn2Publish->event($topic, $new_event);
}
connection class has a method 'even', which can send message to the 'subscriber' directly.
Ratchet.Wamp.WampConnection event method

Resources