I'm trying to figure out about sending push notification using PHP.
The problem is, how to register service worker in browser and send notification directly from PHP.
I got sample of code for back-end part:
<?php
define( 'API_ACCESS_KEY', 'SOME KEY' );
$registrationIds = array('fK_LVMivilI:APA91bHCXawEoNXc0Avwk4F6iYsshn4mmWX6jysrg8gC9PGA6_AlqWtr1HXhIMonCCUj8syOlsDGTFJVu_T3aPqdMNynqy7SY5L9OBlgolu-7L2a5pwZrB7kN_bdnUPeZHJQ1HT2i2ed');
$msg = array
(
'message' => 'here is a message. message',
'title' => 'This is a title. title',
'subtitle' => 'This is a subtitle. subtitle',
'tickerText' => 'Ticker text here...Ticker text here...Ticker text here',
'vibrate' => 1,
'sound' => 1,
'largeIcon' => 'large_icon',
'smallIcon' => 'small_icon'
);
$fields = array
(
'registration_ids' => $registrationIds,
'data' => $msg
);
$headers = array
(
'Authorization: key=' . API_ACCESS_KEY,
'Content-Type: application/json'
);
$ch = curl_init();
curl_setopt( $ch,CURLOPT_URL, 'https://android.googleapis.com/gcm/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 );
echo $result;
When I'm trying to run this script, I'm getting the following error:
{"multicast_id":7003820144951503575,"success":0,"failure":1,"canonical_ids":0,"results":[{"error":"NotRegistered"}]}
I guess it's because there are no service workers registered in the browser.
So, I need some solution to send notification with dynamic content using PHP and javascript if needed.
Any advice appricated.
Check this documentation on how to register a Service Worker in implementing Push Messaging. It is stated here that there is a dependency of having a service worker to implement push messages for the web. The reason for this is that when a push message is received, the browser can start up a service worker, which runs in the background without a page being open, and dispatch an event so that you can decide how to handle that push message.
This is the sample code use for this.
var isPushEnabled = false;
…
window.addEventListener('load', function() {
var pushButton = document.querySelector('.js-push-button');
pushButton.addEventListener('click', function() {
if (isPushEnabled) {
unsubscribe();
} else {
subscribe();
}
});
// Check that service workers are supported, if so, progressively
// enhance and add push messaging support, otherwise continue without it.
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/service-worker.js')
.then(initialiseState);
} else {
console.warn('Service workers aren\'t supported in this browser.');
}
});
For more information about Service Worker, check this tutorials:
PUSH NOTIFICATIONS ON THE WEB - GOOGLE CHROME
WEB PUSH NOTIFICATION WITH SERVICE WORKER
mybb-gcm-push-notifications/service-worker.js.php
Related
I am trying to integrate a Stripe payment method in a web application. I am stuck: payment_init.php does not load, when I am redirected to the page. I get 403 Forbidden error code ("Forbidden. You don't have permission to access this resource.
Additionally, a 400 Bad Request error was encountered while trying to use an ErrorDocument to handle the request").
Here is my payment_init.php file's code:
<?php
// Include the Stripe PHP library
require_once 'stripe-php/init.php';
// Include the configuration file
require_once 'config.php';
$chosenService = $_POST['submitService'];
printf($chosenService);
// Product Details
if ($chosenService === "1") {
$productName = "Hajvágás (6900 HUF)";
$productID = "hc001";
$productPrice = 6900;
} elseif ($chosenService === "2") {
$productName = 'Hajvágás + Szakáll (9900 HUF)';
$productID = "hc002";
$productPrice = 9900;
};
$currency = "huf";
$description = "20% előleg Mobil Barber";
printf($productName);
// Set API key
\Stripe\Stripe::setApiKey(STRIPE_API_KEY);
$response = array(
'status' => 0,
'error' => array(
'message' => 'Invalid Request!'
)
);
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$input = file_get_contents('php://input');
$request = json_decode($input);
}
if (json_last_error() !== JSON_ERROR_NONE) {
http_response_code(400);
echo json_encode($response);
exit;
}
if (!empty($request->createCheckoutSession)) {
printf($productName);
// Convert product price to cent
$stripeAmount = round($productPrice * 100, 2);
// Create new Checkout Session for the order
try {
printf($productName);
$checkout_session = \Stripe\Checkout\Session::create([
'line_items' => [[
'price_data' => [
'currency' => $currency,
'unit_amount' => $productPrice,
'product_data' => [
'name' => $productName,
'description' => $description,
],
],
'quantity' => 1,
]],
'mode' => 'payment',
'success_url' => STRIPE_SUCCESS_URL . '?session_id={CHECKOUT_SESSION_ID}',
'cancel_url' => STRIPE_CANCEL_URL,
]);
} catch (Exception $e) {
$api_error = $e->getMessage();
}
if (empty($api_error) && $checkout_session) {
$response = array(
'status' => 1,
'message' => 'Checkout Session created successfully!',
'sessionId' => $checkout_session->id
);
} else {
$response = array(
'status' => 0,
'error' => array(
'message' => 'Checkout Session creation failed! ' . $api_error
)
);
}
}
// Return response
echo json_encode($response);
When I print $chosenService and $productName variables outside the "if (!empty($request->createCheckoutSession)) {...}" condition, I get the parameters, so they are not NULL. But inside the condition I do not get anything back, neither NULL (does this mean that the $request is empty?). I even checked the Logs in Stripe dashboard, this is the err message there:
"parameter_missing - line_items[0][price_data][product_data][name]
Looks like you are missing the name field tied to a given line item's product_data.
This field is required in that it contains the name that will show up on associated invoice line item descriptions."
I would be really grateful, if someone could help me with this. Thank you in advance.
I don't think your problem is the $productName. I tested out the code you provided and it looks like the issue has to do with the price value. You convert the $productPrice to $stripeAmount but then you don't use it. Without the conversion the amounts for either of the services are less than the $0.50 threshold (with the USD = HUF conversion).
As their docs point out, Stripe requires your charge amounts to be valued between $0.50 and $999,999.00
I don't think this impacted your attempt here but it might also be worth updating the way in which you are invoking/using the Stripe PHP library to conform to the current standard: https://github.com/stripe/stripe-php#getting-started
It will mean you can more easily use the code snippets displayed in the API docs
I'm using Minishlink/WebPush package to send a push notification from my server to my client but I'm getting this error:
array(3) {
["success"]=>
bool(false)
["endpoint"]=>
string(188) "***"
["message"]=>
string(179) "cURL error 77: error setting certificate verify locations:
CAfile: C:\xampp\apache\bin\curl-ca-bundle.crt
CApath: none (see https://curl.haxx.se/libcurl/c/libcurl-errors.html)"
}
This is my code:
require __DIR__ . '../../../vendor/autoload.php';
use Minishlink\WebPush\WebPush;
$vapidAuth = array(
'VAPID' => array(
'subject' => 'https://github.com/Minishlink/web-push-php-example/',
'publicKey' => '***',
'privateKey' => '***'
)
);
$webPush = new WebPush($vapidAuth);
$res = $webPush->sendNotification(
$subscription['ius_endpoint'],
'hello world!',
$subscription['ius_p256dh'],
$subscription['ius_auth'],
true
);
My sw code on my client is working because I've tried to manually push a notification using javascript to my registered sw.
I found out an answer here
Download the certificate from: https://curl.haxx.se/ca/cacert.pem
Rename the cacert.pem file into curl-ca-bundle.crt
Copy the file into path/to/xampp/apache/bin
Restart apache
I have written a custom calendar module for use with Beaver Builder.
I want to fetch posts from a custom post_type of 'event' to populate the calendar.
In my beaver builder module I have the following:
wp_enqueue_script( 'axios', 'https://unpkg.com/axios/dist/axios.min.js');
wp_enqueue_script( 'qs', 'https://unpkg.com/qs/dist/qs.js');
function get_ajax_event_calendar_posts() {
// Query Arguments
$args = array(
'post_type' => array('event'),
'post_status' => array('publish'),
'posts_per_page' => 40,
'nopaging' => true,
'order' => 'DESC',
'orderby' => 'date',
'cat' => 1,
);
// The Query
$ajaxposts = get_posts( $args ); // changed to get_posts from wp_query, because `get_posts` returns an array
echo json_encode( $ajaxposts );
wp_die(); // this is required to terminate immediately and return a proper response
}
// Fire AJAX action for both logged in and non-logged in users
add_action('wp_ajax_get_ajax_event_calendar_posts','get_ajax_event_calendar_posts');
add_action('wp_ajax_nopriv_get_ajax_event_calendar_posts', 'get_ajax_event_calendar_posts');
and in my modules JavaScript (frontend.php) I have:
var data = { action: "get_ajax_event_calendar_posts" };
axios.post("<?php echo admin_url('admin-ajax.php');?>", Qs.stringify(data))
.then(function(response) {
console.log(JSON.stringify(response.data));
})
.catch(function(error) {
console.log(error);
});
I have one post in 'event'. In the browser, I test the endpoint by visiting xxx.flywheelsites.com/wp-admin/admin-ajax.php?action=get_ajax_event_calendar_posts and receive an empty array []. I expect to receive a single event. I've looked in the admin and can see the post.
When clicking on the button in my module to make the Ajax request, I receive a 400 error
Checking the logs, I receive the following error message:
(MISSING)127.0.0.1 - 04/Jan/2020:16:41:40 +0000 "POST /.wordpress/wp-admin/admin-ajax.php" 400 /www/.wordpress/wp-admin/admin-ajax.php 64263000 4103576 709.963 4096 35.21%!
This error message doesn't really tell me anything. I also altered my axios method to use a GET - however, I receive the same error.
Any advice on how I can debug this would be really helpful. Thanks!
Wordpress, Astra Theme, Beaver Builder, hosted on flywheel.
** Edit **
To test, in my get_ajax_event_calendar_posts method I am echo'ing out 'hello world'
function get_ajax_event_calendar_posts() {
// Query Arguments
$args = array(
'post_type' => array('event'),
'post_status' => array('publish'),
'posts_per_page' => 40,
'nopaging' => true,
'order' => 'DESC',
'orderby' => 'date',
'cat' => 1,
);
// The Query
$ajaxposts = get_posts( $args ); // changed to get_posts from wp_query, because `get_posts` returns an array
echo 'hello world'; //json_encode( $ajaxposts );
wp_die(); // this is required to terminate immediately and return a proper response
}
I visit the url in my browser and see 'hello world' - so it seems there might be a problem in querying the data? The logs don't contain anything useful. However, from this I can see I can hit the route and get a response from it.
** Edit **
I can now view the posts when hitting the url directly. Appears to be an issue of cacheing.... I have updated my JS - yet the old files persist. I'm hopeful this is just a cacheing issue...
Using Beaver Builder, I had to clear Beaver Builders cache. To clear it, go into settings -> beaver-builder -> tools and click the clear cache button.
I am trying to use PHP + GCM + Service Workers to send push notifications to users of my website (not app).
//service-worker.js
self.addEventListener('push', function(event) {
console.log('Received a push message');
console.log(event.data.text());
});
When I go to the Chrome Console >> Application >> Service Workers >> Push the console shows the following:
Received a push message
Test push message from DevTools.
I am trying to accomplish the same thing using a PHP script:
$msg = array
(
'message' => 'here is a message. message',
'title' => 'This is a title. title',
'subtitle' => 'This is a subtitle. subtitle',
'tickerText' => 'Ticker text here...Ticker text here...Ticker text here',
'vibrate' => 1,
'sound' => 1,
'largeIcon' => 'large_icon',
'smallIcon' => 'small_icon'
);
$fields = array
(
'registration_ids' => $ids,
'data' => $msg,
);
$headers = array
(
'Authorization: key=' . $apiKey,
'Content-Type: application/json'
);
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 );
The push notification comes through, however, I get the following:
Received a push message
Uncaught TypeError: Cannot read property 'text' of null
I've tried digging through other properties of event with no luck. Most of the help articles I have read are for Android and not for web development. What am I missing?
I am Implementing push notification in ionic using this tutorial: http://devdactic.com/ionic-push-notifications/
I have succesfully done using this.
I got device token: like:
Got token: DEV-f30dac7a-d761-4a4c-a579-01918b9662ad none
When I use this in following php script:
<?php
// API access key from Google API's Console
define( 'API_ACCESS_KEY', 'apikey' );
$registrationIds = array( 'f30dac7a-d761-4a4c-a579-01918b9662ad' );
// prep the bundle
$msg = array
(
'message' => 'here is a message. message',
'title' => 'This is a title. title',
'subtitle' => 'This is a subtitle. subtitle',
'tickerText' => 'Ticker text here...Ticker text here...Ticker text here',
'vibrate' => 1,
'sound' => 1,
'largeIcon' => 'large_icon',
'smallIcon' => 'small_icon'
);
$fields = array
(
'registration_ids' => $registrationIds,
'data' => $msg
);
$headers = array
(
'Authorization: key=' . API_ACCESS_KEY,
'Content-Type: application/json'
);
$ch = curl_init();
curl_setopt( $ch,CURLOPT_URL, 'https://android.googleapis.com/gcm/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 );
echo $result;
I got error like:
{`"multicast_id":6920644147476475688,"success":0,"failure":1,"canonical_ids":0,"results":[{"error":"InvalidRegistration"}]}`
I dont Know where I am wrong.Please Help
The error says that your app is not registred. Make sure you put your GCM API key in 'apikey'.
The token is DEV-f30dac7a-d761-4a4c-a579-01918b9662ad, and not f30dac7a-d761-4a4c-a579-01918b9662ad as you put in $registrationIds.