Web push notification error with curl send message - php

I want to understand what is web-push and how can i use for my projects...
Have found this example https://mobiforge.com/design-development/web-push-notifications
But always getting an error when try to send notification via Firebase Cloud Messaging (FCM is the new version of GCM)
{"multicast_id":6440031216763605980,"success":0,"failure":1,"canonical_ids":0,"results":[{"error":"InvalidRegistration"}]}
What it means "InvalidRegistration"? What i'm doing wrong?
My php curl, but i am sure that there is no problem here
$link = "https://gcm-http.googleapis.com/gcm/send";
$header = array();
// $header[] = "Content-length: 0";
$header[] = "Content-type: application/json";
$header[] = "Authorization: key=AIzaSy...";
$contentArray = array(
"collapse_key" => "All",
"registration_ids" => array(
"gAAAAABX06BLKhA4n1yHNlsyzu02wxsDjZf89oxIljwM4ZdLpMZU7ty64TFEYahPQZaTmCeYlJo-WDWnfFHOKXzKURhNtRWmN0OgBgn9hJdmgatSGoiTkt69TeJpiD8F034WOr5HMEG2",
),
"data" => array(
"title" => "This is a Title",
"message" => "This is a GCM Topic Message!"
)
);
$jsonData = json_encode($contentArray);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $link);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonData);
$string = curl_exec($ch);
echo $string;
$data['curl'] = curl_errno($ch);
if(!curl_errno($ch) && !strpos($string, "503"))
$data = array_merge($data, explode("\n", $string));
curl_close($ch);
?><pre><? print_r($data); ?></pre><?
some from Cosole.log
ServiceWorker registration successful with scope: https://.../app/
PushSubscription { endpoint="https://updates.push.ser...rjYvTTapou7WcEDgu3V7IOY", options=PushSubscriptionOptions, getKey=getKey(), ...}
PushSubscription { endpoint="https://updates.push.ser...rjYvTTapou7WcEDgu3V7IOY", options=PushSubscriptionOptions, getKey=getKey(), ...}
gAAAAABX06OYvBIk4q2rRF3AsE6UwRYUpzpZ0jpuiWz6TRrSptb8_cBKjy8Ci-_u5UtAyiGfAYJ_ycYnJjoukSuez7BN6UnSX-GL_EWNAWzEpAVMhCT2wrjYvTTapou7WcEDgu3V7IOY

Please try checking the subscription ID that you used.
As mentioned in Check the response,
If the response shows an invalid registration error, check the subscription ID you used.
As discussed further in making a request to GCM, make sure to use your own API key and subscription ID when you run the cURL command.
For more information, please check the documentation on how to send a request from the command line for GCM to push a message.

It is not working. I have been trying a lot times. here below is how I tried in POSTMan

From my experience, the registration_id you are using seems to be from a subscription on a Firefox browser. But yet you're trying to send it to the Chrome push server.
A Chrome registration_id should look like that:
APA91bGdUldXgd4Eu9MD0qNmGd0K6fu0UvhhNGL9FipYzisrRWbc-qsXpKbxocgSXm7lQuaEOwsJcEWWadNYTyqN8OTMrvNA94shns_BfgFH14wmYw67KZGHsAg74sm1_H7MF2qoyRCwr6AsbTf5n7Cgp7ZqsBZwl8IXGovAuknubr5gaJWBnDc
It's a pretty new technology and earlier versions codes are still available on the google developer platform, so it's not really easy to understand what to do. I'm still experimenting with it.
Check this codelab it's a good example to understand the basics.

I would like to share my answer in this post too.
Check https://stackoverflow.com/a/40447040/4677062 for the same invalid registration id issue.
Its resolved. Works as expected.

Related

send a pageview event via Measurement Protocol to a GA4 property

How can I send a pageview event via Measurement Protocol to a GA4 property with PHP?
This is how I'm doing, but inside my Google Analytics 4 property I can't see any traffic.
$data = array(
'api_secret' => 'XXXX-YYYYY',
'measurement_id' => 'G-12345678',
'client_id' => gen_uuid(), // generates a random id
'events' => array(
'name' => 'page_view',
'params' => array(),
)
);
$url = 'https://www.google-analytics.com/mp/collect';
$content = http_build_query($data);
$content = utf8_encode($content);
$ch = curl_init();
curl_setopt($ch,CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_HTTPHEADER,array('Content-type: application/x-www-form-urlencoded'));
curl_setopt($ch,CURLOPT_HTTP_VERSION,CURL_HTTP_VERSION_1_1);
curl_setopt($ch,CURLOPT_POST, TRUE);
curl_setopt($ch,CURLOPT_POSTFIELDS, $content);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_exec($ch);
curl_close($ch);
I'm working on registering pageviews to track API usage right now, here's what I've found:
XTOTHEL is right about setting the content type to content/json above. In addition to specifying the content type you also have to send JSON data as the CURLOPT_POSTFIELDS data.
Also per their specification the api_secret and measurement_id need to be part of the URI: https://developers.google.com/analytics/devguides/collection/protocol/ga4/sending-events?client_type=gtag#required_parameters
Lastly, you can use debug mode to validate your responses and figure out what's going on now by simply changing the URL to google-analytics.com/debug/mp/collect
Here's the code I'm working with right now:
//retrieve or generate GA tracking id
if (empty($_COOKIE['_cid'])) {
setcookie('_cid', vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex(random_bytes(16)), 4)));
}
$data = '{"client_id":"'.$_COOKIE['_cid'].'","events":[{"name":"load_endpoint","params":{"page_location":"'.$request->fullUrl().'"}}]}';
echo '<pre>';
print_r($data);
$measurement_id = 'G-xxxxx';
$api_secret = 'xxxx';
$url = 'https://www.google-analytics.com/debug/mp/collect?api_secret='.$api_secret.'&measurement_id='.$measurement_id;
$ch = curl_init();
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
This works to a certain extent. Currently it's registering the page view as a custom event instead of an actual pageview though. I'm still trying to figure out how to get them to come through as page views.
Follow up
After a little more debugging I figured out page views are actually working, they just weren't showing up in some of the views. The fix for that was to add page_title into the params:
$data = '
{
"client_id": "'.$_COOKIE['_cid'].'",
"events": [
{
"name": "page_view",
"params": {
"page_location": "'.$request->fullUrl().'",
"page_title": "'.$request->path().'"
}
}
]
}
';
A few extra notes for whoever comes next:
Debug mode did return some useful validation errors for invalid top-level parameters (client_id, events) - but it didn't return errors for anything inside of the "params" for events. IE - i put "page_asdtitle" instead of "page_title" and it accepted it just fine.
None of the tests I sent through actually showed up in the debug panel while using debug mode. I suspect this is because of the data propagation delay, it's probably not loading realtime data.
Using a JSON validator can help. Make sure you use objects and arrays where GA tells you to.
If you get stuck figuring out why your PHP code doesn't work, write the code as a browser event in JavaScript and run it in your browser. There's tons of examples on how to do that. From there, you can use Dev Tools -> Network to inspect the request. If you right click on the google analytics request to the 'collect' endpoint you'll see an option to Copy Request as CURL. Put that into a text editor and compare it to what your PHP code is sending.
To ACTUALLY test this without the massive propagation delay you can login to Google Analytics, go to Reports -> Realtime, and you should see your data show up within 30-60 seconds if it's working. Realtime data will NOT show up if you're using the /debug/ endpoint though.

Firebase Cloud Message (FCM) : trying to send message to device from PHP (error: InvalidRegistration)

I'm trying to send push messages from PHP but I'm getting the following error message:
{"multicast_id":4832091122368281316,"success":0,"failure":1,"canonical_ids":0,"results":[{"error":"InvalidRegistration"}]}
I suppose there is a mismatch with the browser ID but I don't know which one I'm supposed to use.
When I register the push notification through JS, I receive the following payload on my PHP server:
{"endpoint":"https://fcm.googleapis.com/fcm/send/XXX:YYY","expirationTime":null,"keys":{"p256dh":"ZZZ","auth":"AAA"}}
To send the message in PHP, I have used the following code (found on stackexchange):
function sendnotification($to, $title, $message, $img = "", $datapayload = "")
{
$msg = urlencode($message);
$data = array(
'title'=>$title,
'sound' => "default",
'msg'=>$msg,
'data'=>$datapayload,
'body'=>$message,
'color' => "#79bc64"
);
if($img)
{
$data["image"] = $img;
$data["style"] = "picture";
$data["picture"] = $img;
}
$fields = array(
'to'=>$to,
'notification'=>$data,
'data'=>$datapayload,
"priority" => "high",
);
$headers = array(
'Authorization: key=MYSERVERKEY',
'Content-Type: application/json'
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://fcm.googleapis.com/fcm/send');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
$result = curl_exec($ch);
curl_close( $ch );
return $result;
I think I'm using the right server key, when I don't, I get a different error message.
For $to, I'm wondering what I should use. I thought I had to use XXX:YYY after the endpoint but it's not working (XXX is very short, YYY is very long). I have also tried ZZZ and AAA but it doesn't help either.
My questions:
What kind of ID should I be using to send the message to one specific browser ?
What should I do to send a notification to all registered browser?
Thanks!
Well you have to make sure store the token of your user browser, which you can only get when they allow on request prompt e.g.
On user Allow the request it generate the token which look like as below
This token you can use for send the message to specific browser.
So in your code where as your $to = it should be the device token.
i.e. "to": "<DEVICE_REGISTRATION_TOKEN>"

Why is the curl code not executed in PHP script? (WAMP Server)

I am trying to get a token to use the Microsoft Graph API (https://learn.microsoft.com/en-us/graph/auth-v2-user?context=graph%2Fapi%2F1.0&view=graph-rest-1.0) via Curl. I have set up a simple Php file with this function:
function getToken() {
echo "start gettoken";
var_dump(extension_loaded('curl'));
$jsonStr = http_build_query(Array(
"client_id" => "***",
"scope" => "https://graph.microsoft.com/.default",
"client_secret" => "***",
"grant_type" => "client_credentials"
));
$headers = Array("Content-Type: application/x-www-form-urlencoded", "Content-Length: " . strlen($jsonStr));
$ch = curl_init("https://login.microsoftonline.com/***.onmicrosoft.com/oauth2/v2.0/token");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonStr);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$token = curl_exec($ch);
echo "test after curl";
return $token;
curl_error($ch);
}
However, what I want to know is why the curl request is not working. Also the echo after the curl codeblock is not being executed, while 'start gettoken' is. PHP_curl is enabled in my WAMP. Why is this?
Are you sure CURL is enabled because that code you have posted is ok and giving echo response before and after curl execution.
you're sending the token request in a JSON-format, and then you're lying to the server saying it's application/x-www-form-urlencoded-encoded when it's actually application/json-encoded! since these 2 formats are completely incompatible, the server fails to parse it, and... ideally it should have responded HTTP 400 bad request (because your request can't be parsed as x-www-form-urlencoded)
anyhow, to actually send it in the application/x-www-form-urlencoded-format, replace json_encode() with http_build_query()
also get rid of the "Content-Length:"-header, it's easy to mess up (aka error-prone) if you're doing it manually (and indeed, you messed it up! there's supposed to be a space between the : and the number, you didn't add the space, but the usual error is supplying the wrong length), but if you don't do it manually, then curl will create the header for you automatically, which is not error-prone.

Create record in salesforce lightning API curl/php

I am trying to use the REST lightning API for salesforce. So far I can have it connect succesfully and get info on some things, however I am struggling to get it to actually create new records. Below is the code, I have excluding my connection code and getting my Bearer token, as both those work fine and don't impact the second half of creating a record.
<?php
$url = $instance_url.'/services/data/v20.0/sobjects/Account/';
$headers = array(
'Content-Type: application/json'
);
$data = array(
'Name' => "AccountHEX"
);
$ch2 = curl_init();
curl_setopt($ch2,CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch2,CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch2,CURLOPT_RETURNTRANSFER, true);
$head = 'Authorization: Bearer '.$access_token;
curl_setopt($ch2, CURLOPT_HTTPHEADER, array($head));
//execute post
$result = null;
$result = curl_exec($ch2);
echo $result;
?>
The result I get seems to be just the info on the account object:
{
"objectDescribe":{
"activateable":false,
"createable":true,
"custom":false,
"customSetting":false,
"deletable":true,
"deprecatedAndHidden":false,
"feedEnabled":true,
"keyPrefix":"001",
"label":"Account",
"labelPlural":"Accounts",
"layoutable":true,
"mergeable":true,
"name":"Account",
"queryable":true,
"replicateable":true,
"retrieveable":true,
"searchable":true,
"triggerable":true,
"undeletable":true,
"updateable":true,
"urls":{
"rowTemplate":"/services/data/v20.0/sobjects/Account/{ID}",
"describe":"/services/data/v20.0/sobjects/Account/describe",
"sobject":"/services/data/v20.0/sobjects/Account"
}
},
"recentItems":[
]
}
So it is treating it more as a query rather than a creation. I have tried a couple different $data arrangments. Incluidng just doing name right away, and putting it inside the fields array.
Trying to do this bassed on this:
https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/dome_sobject_create.htm
Any ideas how to get it to create the record?
What you're receiving is the Account sObject describe, which is the return value for a GET request. You need to make a POST request to create the sObject.
Your body data does not need to be nested in a fields key. Your JSON should look like the example from the documentation,
{
"Name" : "Express Logistics and Transport"
}
with all fields at the top level.
Lastly, API v20.0 is extremely old. I would recommend declaring the latest API version in your endpoint URL, v46.0. Using old API versions can result in unexpected behavior and in certain fields being unavailable to you.

Facebook Messenger Bot - PHP cURL messages

I've been fiddling around with Facebook Messenger Platform for the past couple days and have run into an issue. PHP has been the primary language.
Successfully, I've been able to implement a couple API's into the system, through plain text. (See image below)
This is what the system looks like:
$input = json_decode(file_get_contents('php://input'), true);
$senderId = $input['entry'][0]['messaging'][0]['sender']['id'];
$message = $input['entry'][0]['messaging'][0]['message']['text'];
$answer = "I don't understand that. Is that another language? Type 'hi' to get started.";
if($message == "hi") {
$answer = "Yo!";
}
All of this comes from the Facebook Messenger Getting Started if you're not familiar.
What I'm attempting to do now is pass an image through cURL onto JSON. This is something I'm unfamiliar with, but have found two great sources to help me with this task. POSTing JSON Data With PHP cURL and Create nested list from Multidimensional Array.
Here is the result:
if($message == "test") {
$data = array("message" => array("attachement" => array('"type" => "image"'),"payload" => array('"url" => "http://example.com"')));
$data_string = json_encode($data);
$ch = curl_init('https://graph.facebook.com/v2.6/me/messages?access_token=TOKEN_GOES_HERE');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($data_string))
);
$answer = curl_exec($ch);
}
Here is the response I receive:
I know for sure, that the parameters are not properly being picked up by cURL. Though, my limited knowledge on cuRL, suggests otherwise. My question is, how could I still achieve this? I want to be able to pass an image through JSON into messenger, using PHP.
I think your post request works fine, but due to the error, you didn't pass the whole json data.
Below is how a image generic message looks like, where did you put the recipient in your data?
{
"recipient":{
"id":"USER_ID"
},
"message":{
"attachment":{
"type":"image",
"payload":{
"url":"https://petersapparel.com/img/shirt.png"
}
}
}
}
reference: https://developers.facebook.com/docs/messenger-platform/send-api-reference#guidelines

Categories