I'm creating a push, calendar-style push system. I need when I create a schedule for the user the system send a notification only to him, I created the system to manage this PHP, does anyone know how to help me?
If you're using OneSignal. You can send to that individual device with Playerid, you do however have to store the playerid serverside so that you know which device to send to. I personally do that in init state and do a http.post to my api to save the playerid into my database for that particular user.
You can of course achieve the same by using OneSignal's tags (useful if same person has multiple accounts in one device).
To send notification, use curl in php.
<?php
function sendMessage(){
$content = array(
"en" => 'English Message'
);
$fields = array(
'app_id' => "your-app-id",
'include_player_ids' => array("playerid-you-want-to-send-to"),
'data' => array("foo" => "bar"),
'contents' => $content
);
$fields = json_encode($fields);
print("\nJSON sent:\n");
print($fields);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://onesignal.com/api/v1/notifications");
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json; charset=utf-8'));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
$response = curl_exec($ch);
curl_close($ch);
return $response;
}
$response = sendMessage();
$return["allresponses"] = $response;
$return = json_encode( $return);
print("\n\nJSON received:\n");
print($return);
print("\n");
?>
In Flutter, get the package, import it and:
void oneSignal() {
OneSignal.shared.init("app-id");
OneSignal.shared.setNotificationReceivedHandler((OSNotification notification)
{
//do what you need to do with upcoming notification, get title for example
print(notification.payload.title);
}
}
I'm far from an expert on mobile apps, so somebody should correct / confirm this.
To accomplish push notification in your app you could use a 'live' connection (websocket for instance) or you could use polling.
I don't know much about websockets and I don't think that's possible with CakePHP (not sure). EDIT: Definitely not possible out-of-the-box, but plugins exist.
When you are using polling you repeat a GET request every so often (once per hour, once per minute, depending on needs) and check if there is new info.
For instance, your CakePHP page could be an action taking a lastUpdated argument, which returns new information since that timestamp. The app then requests this page every x minutes, each time setting the lastUpdated parameter. When there is new info, the response will be not empty and the app can process it.
This does mean the app needs to always run in the background and the number of requests can become sizeable (depending on the polling interval).
Related
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.
I've got an online store and I make use of an online accounting software where I manually post orders to. The online accounting software has a very big api and I would like to send orders over automatically when a customer places an order.
Once an order is completed the customer lands up on the Success Page, i.e. successpage.php
In this page I've got the following:
$sendOrder = file_get_contents("https://myonlinestore.com/sendorder.php?order=1234");
On sendorder.php, I receive the $_GET parameter "order" which is the order number, and the I process several SQL requests to retrieve data of the order from the database.
Once I've got all this data, I then initiate a CURL post to send the data using the API of the accounting system.
Here is a watered-down version of my code that contains the essential parts:
$orderNum = htmlspecialchars($_GET["order"]) // SENT OVER FILE_GET_CONTENTS
// bOf process SQL here and get order info stored in various variables
// EXECUTE SQL HERE
// eOf process SQL here and get order info stored in various variables
$invoice = array(
'customer_id' => $custaccount,
'estimate_number' => $orderRef,
'reference_number' => $orderNum
// MANY OTHER VARIABLES ENTERED HERE, BUT LEFT OUT TO KEEP THINGS SHORT
);
$jsonInvoice = json_encode($invoice);
$url = 'https://ACCOUTINGAPP.com/api/v2/orders';
$data = array(
'authtoken' => '***********',
'JSONString' => $jsonInvoice,
'company_id' => '***********'
);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/x-www-form-urlencoded") );
$response = false;
$response = curl_exec($ch);
curl_close($ch);
// TEST RESPONSE
if($response !== false) {
var_dump($response);
}
else
{
echo "oops error hehehe";
}
MY MAIN CONCERN:
I expect the user to immediately close the tab or page once they're on successpage.php.
But I would like to ensure that the successpage.php's $sendOrder = file_get_contents() and the code that it executes on sendorder.php continues running regardless of user connection.
So my question is, where would I put:
ignore_user_abort(TRUE);
Also, should I use output buffering? I'm only asking because I read a post about this on some other website and it advised this.
And lastly, should I include:
set_time_limit(0);
Call ignore_user_abort(TRUE); as soon as you can. And you do not need output buffering as noone is going to see your output once browser tab is closed anywyay, so you just need to ensure your script continues if it was already doing anything.
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.
I'm trying to setup a server to send push notifications.
I'm trying to send push notification toward user of an specified package e.g. something like com.mysite.android (This options is available in Firebase console).
Checking answers like this I could not understand how to set to parameter to send push notifications to user of an specified package. I can find sample which send notification to specific devices by their ids or news topics.
Clarification: I'm the owner of application which I want sent push notifications.
If it helps here is my code:
<?php
/*
Parameter Example
$data = array('post_id'=>'12345','post_title'=>'A Blog post');
$target = 'single tocken id or topic name';
or
$target = array('token1','token2','...'); // up to 1000 in one request
*/
echo "Start<br/>";
$result = sendMessage('{"id":"hello"}',null);
var_dump($result);
function sendMessage($data,$target){
//FCM api URL
$url = 'https://fcm.googleapis.com/fcm/send';
//api_key available in Firebase Console -> Project Settings -> CLOUD MESSAGING -> Server key
$server_key = 'xxxxxxxxxxxxxxxxxxxkeyxxxxxxxxxxxxxxxxxxxxxxxx';
$fields = array();
$fields['data'] = $data;
$fields['restricted_package_name']='com.mysite.android ';
$fields['dry_run']=true;
if (isset($target)){
if(is_array($target)){
$fields['registration_ids'] = $target;
}else{
$fields['to'] = $target;
}
}
//header with content_type api key
$headers = array(
'Content-Type:application/json',
'Authorization:key='.$server_key
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
$result = curl_exec($ch);
if ($result === FALSE) {
die('FCM Send Error: ' . curl_error($ch));
}
curl_close($ch);
return $result;
}
?>
Notice: I removed my server_key intentionally.
You cannot send push notifications to any external app except the apps you own, simply the user device token and your server key are linked under one project so you must use a server key and valid device tokens for "X" app
This is manageable. However, for you to be able to send a Notification to an app, you first need to be a valid Sender.
By that, usually (if you are the app owner), all you have to do is Add the App to your Firebase Project, generate the google-services.json file and add it to your Android Project.
If you're not the app owner and you don't want to add the app via your Firebase Project, this can be overridden by simply modifying the google-services.json that is used in the app, adding your SenderID in it. But I highly doubt that you'd be given access to modify an app that isn't yours in the first place.
Note: It is not advisable to modify your google-services.json though.
If you were able to set your peoject as a valid sender, you will have to make use of Topic Messaging and subscribe the devices to a topic name that is their app package name.
Then when sending to the topic, simply use the name of the package in the to parameter like so:
"to": "/topics/<app_package_name_here>"
I am building a CMS/CRM and want to let users install this software on their server using their databases.
I would like to track some of the data from that installation, like version, so I can send updates to that installation if it is out of date. Like when Wordpress tells you a new version is available.
I also want to be able to track the number of users to be able to charge for the installation.
I am using PHP, MySQL(PDO).
Can you let me know what this process is called and any references to this process would be fantastic.
In your application you may have an array of data you'd like to track; something like this
$data = array(
'domain' => 'http://example.com',
'version' => '1.4.35',
'date_added' => '2014-08-20',
'last_update' => '2014-08-22'
);
Then you could send a request to your server to see if is anything new out there; using cURL or any other method for sending an HTTP request
$curl = curl_init("http://your-server.com/your-service/");
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, array("Content-type: application/json"));
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data)); // convert it to JSON format
$json = curl_exec($curl);
curl_close($curl);
// this is your feedback, in JSON format
$response = json_decode($json, true);
It would be good to check the status, like this, but before the curl_close() call
$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if($status == 201){
// ... all fine
}else{
// otherwise, do something but don't use exit() or die() in this case
}
The $response value, after decoding, could look something like this
array(
'some_key' => 'some_value',
'another_key' => 'another_value'
...
);
Now, according to the response, echo a message to the user, like this
if(isset($response['some_key']) && $response['some_key'] == 'some_value')){
echo "An update is out there, Check it out";
}