Current Manual Update to HTTP v1 from FCM APIS
-
I’ve adapted the existing code to work with the new http v1 firebase api. All you need to do is:
1.) copy the entire code below
2.) go to menu Plugins -> Plugin File Editor -> Select plugin to edit: FCM Push Notification from WP -> select file fcm-dp-push-notification.php and replace all the code with the code below
3.) Adjust function fcmdpplgpn_notification with your firebase data. The info below is needed. Then save and enjoy.
“project_id”: “your-project-id”,
“private_key_id”: “your-private-key-id”,
“private_key”: “—–BEGIN PRIVATE KEY—–\nYOUR_PRIVATE_KEY\n—–END PRIVATE KEY—–\n”,
“client_email”: “your-client-email@your-project-id.iam.gserviceaccount.com”,
“client_id”: “your-client-id”,
<?php
/*
Plugin Name:FCM Push Notification from WP
Description:Notify your app users using Firebase Cloud Messaging (FCM) when content is published or updated
Version:1.9.1
Author:dprogrammer
Author URI:https://www.buymeacoffee.com/dprogrammer
License:GPL2
License URI:https://www.gnu.org/licenses/gpl-2.0.html
*/
/*
FCM Push Notification from WP is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
any later version.
FCM Push Notification from WP is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with MV Slider. If not, see https://www.gnu.org/licenses/gpl-2.0.html.
*/
if (!defined('ABSPATH')) {
exit;
}
if (!defined("FCMDPPLGPN_VERSION_CURRENT")) define("FCMDPPLGPN_VERSION_CURRENT", '1');
if (!defined("FCMDPPLGPN_URL")) define("FCMDPPLGPN_URL", plugin_dir_url( __FILE__ ) );
if (!defined("FCMDPPLGPN_PLUGIN_DIR")) define("FCMDPPLGPN_PLUGIN_DIR", plugin_dir_path(__FILE__));
if (!defined("FCMDPPLGPN_PLUGIN_NM")) define("FCMDPPLGPN_PLUGIN_NM", 'FCM Push Notification from WP');
if (!defined("FCMDPPLGPN_TRANSLATION")) define("FCMDPPLGPN_TRANSLATION", 'fcmdpplgpn_translation');
/* FCMDPPLGPN -> FCM DP(dprogrammer) PLG(plugin) PN(Push Notification) */
Class FCMDPPLGPN_Push_Notification
{
public function __construct()
{
// Installation and uninstallation hooks
register_activation_hook(__FILE__, array($this, 'fcmdpplgpn_activate'));
register_deactivation_hook(__FILE__, array($this, 'fcmdpplgpn_deactivate'));
add_action('admin_menu', array($this, 'fcmdpplgpn_setup_admin_menu'));
add_action('admin_init', array($this, 'fcmdpplgpn_settings'));
add_action('add_meta_boxes', array($this, 'fcmdpplgpn_featured_meta'), 1);
add_action('save_post', array($this, 'fcmdpplgpn_meta_save'),1,1);
//https://codex.wordpress.org/Post_Status_Transitions
add_action('future_to_publish', array($this, 'fcmdpplgpn_future_to_publish'), 10, 1);
//https://davidwalsh.name/wordpress-publish-post-hook
//add_action('transition_post_status', array($this, 'fcmdpplgpn_send_new_post'), 10, 3);
add_filter('plugin_action_links_fcm-push-notification-from-wp/fcm-dp-push-notification.php', array($this, 'fcmdpplgpn_settings_link') );
}
function fcmdpplgpn_featured_meta() {
//add_meta_box( 'fcmdpplgpn_ckmeta_send_notification', __( 'Push Notification', FCMDPPLGPN_TRANSLATION ), array($this, 'fcmdpplgpn_meta_callback'), 'post', 'side', 'high', null );
/* set meta box to a post type */
$args = array(
'public' => true,
);
$post_types = get_post_types( $args, 'objects' );
if ( $post_types ) { // If there are any custom public post types.
foreach ( $post_types as $post_type ) {
if ($post_type->name != 'attachment'){
if ($this->get_options_posttype($post_type->name)) {
add_meta_box( 'fcmdpplgpn_ckmeta_send_notification', esc_attr(__( 'Push Notification', FCMDPPLGPN_TRANSLATION )), array($this, 'fcmdpplgpn_meta_callback'), $post_type->name, 'side', 'high', null );
}
}
}
}
}
function fcmdpplgpn_meta_callback( $post ) {
global $pagenow;
wp_nonce_field( basename( __FILE__ ), 'fcmdpplgpn_nonce' );
$fcmdpplgpn_stored_meta = get_post_meta( $post->ID );
$checked = get_option('fcmdpplgpn_disable') != 1;//$fcmdpplgpn_stored_meta['send-fcm-checkbox'][0];
//$this->write_log('fcmdpplgpn_meta_callback: $checked: ' . $checked);
//$this->write_log('fcmdpplgpn_meta_callback: $post->post_status: ' . $post->post_status);
?>
<p>
<span class="fcm-row-title"><?php echo esc_html(__( 'Check if send a push notification: ', FCMDPPLGPN_TRANSLATION ));?></span>
<div class="fcm-row-content">
<label for="send-fcm-checkbox">
<?php if (in_array( $pagenow, array( 'post-new.php' ) ) || $post->post_status == 'future') { ?>
<input type="checkbox" name="send-fcm-checkbox" id="send-fcm-checkbox" value="1" <?php if ( isset ( $fcmdpplgpn_stored_meta['send-fcm-checkbox'] ) ) checked( $checked, '1' ); ?> />
<?php } else { ?>
<input type="checkbox" name="send-fcm-checkbox" id="send-fcm-checkbox" value="1"/>
<?php } ?>
<?php echo esc_attr(__( 'Send Push Notification', FCMDPPLGPN_TRANSLATION ));?>
</label>
</div>
</p>
<?php
}
/**
* Saves the custom meta input
*/
function fcmdpplgpn_meta_save( $post_id ) {
// Checks save status - overcome autosave, etc.
$is_autosave = wp_is_post_autosave( $post_id );
$is_revision = wp_is_post_revision( $post_id );
$is_valid_nonce = ( isset( $_POST[ 'fcmdpplgpn_nonce' ] ) && wp_verify_nonce( $_POST[ 'fcmdpplgpn_nonce' ], basename( __FILE__ ) ) ) ? 'true' : 'false';
//$this->write_log('fcmdpplgpn_meta_save');
// Exits script depending on save status
if ( $is_autosave || $is_revision || !$is_valid_nonce ) {
return;
}
//$this->write_log('remove_action: wp_insert_post');
remove_action('wp_insert_post', array($this, 'fcmdpplgpn_on_post_save'),10);
if( isset( $_POST[ 'send-fcm-checkbox' ] ) ) {
update_post_meta( $post_id, 'send-fcm-checkbox', '1' );
//$this->write_log('add_action: send-fcm-checkbox 1');
} else {
//$this->write_log('add_action: send-fcm-checkbox 0');
update_post_meta( $post_id, 'send-fcm-checkbox', '0' );
}
//$this->write_log('add_action: wp_insert_post');
add_action('wp_insert_post', array($this, 'fcmdpplgpn_on_post_save'),10, 3);
}
function fcmdpplgpn_future_to_publish($post) {
//$this->write_log('fcmdpplgpn_future_to_publish: CHAMOU EVENTO');
$this->fcmdpplgpn_send_notification_on_save($post, true);
}
// Listen for publishing of a new post
/*
function fcmdpplgpn_send_new_post($new_status, $old_status, $post) {
//$this->write_log('fcmdpplgpn_send_new_post: CHAMOU EVENTO - ' . $new_status . ' - ' . $old_status);
//if('publish' === $new_status && 'future' == $old_status && $post->post_type === 'post') {
if('publish' === $new_status && 'future' == $old_status) {
$this->write_log('fcmdpplgpn_send_new_post: CHAMOU EVENTO IF ALOU - ' . $new_status . ' - ' . $old_status);
$this->fcmdpplgpn_send_notification_on_save($post, true);
}
}
*/
// função utilizada no evento ao salvar e quando um post que foi agendado, é publicado
function fcmdpplgpn_on_post_save($post_id, $post, $update) {
$this->fcmdpplgpn_send_notification_on_save($post, $update);
}
// utilizada na função ao salvar e na função ao mudar de status de agendado para movo post
private function fcmdpplgpn_send_notification_on_save($post, $update){
//$this->write_log('fcmdpplgpn_on_post_save: CHAMOU EVENTO');
if(get_option('fcmdpplgpn_api') && get_option('fcmdpplgpn_topic')) {
//$this->write_log('fcmdpplgpn_on_post_save: ENTROU NO TESTE');
//new post/page
if (isset($post->post_status)) {
//$this->write_log('fcmdpplgpn_on_post_save: ENTROU NO IF - ' . $post->post_status);
if ($update && ($post->post_status == 'publish')) {
//$this->write_log('fcmdpplgpn_on_post_save: ENTROU NO SEGUNDO IF - ' . $post->post_status);
$send_fcmdpplgpn_checkbox = get_post_meta( $post->ID, 'send-fcm-checkbox', true );
//$this->write_log('send_fcmdpplgpn_checkbox: ' . $send_fcmdpplgpn_checkbox);
if ($send_fcmdpplgpn_checkbox) {
//$this->write_log('fcmdpplgpn_on_post_save: ENTROU NO SEGUNDO IF - ' . $post->post_status);
if ($this->get_options_posttype($post->post_type)) {
//($post, $sendOnlyData, $showLocalNotification, $command)
$result = $this->fcmdpplgpn_notification($post, false, false, '');
//$this->write_log('post updated: ' . $post_title);
} elseif ($this->get_options_posttype($post->post_type)) {
$result = $this->fcmdpplgpn_notification($post, false, false, '');
//$this->write_log('page updated: ' . $post_title);
}
update_post_meta( $post->ID, 'send-fcm-checkbox', '0' );
}
}
}
}
}
public function write_log($log) {
if (true === WP_DEBUG) {
if (is_array($log) || is_object($log)) {
error_log(print_r($log, true));
} else {
error_log($log);
}
}
}
public function get_options_posttype($post_type) {
return get_option('fcmdpplgpn_posttype_' . $post_type) == 1;
}
public function fcmdpplgpn_setup_admin_menu()
{
add_submenu_page('options-general.php', __('Firebase Push Notification', FCMDPPLGPN_TRANSLATION), FCMDPPLGPN_PLUGIN_NM, 'manage_options', 'fcmdpplgpn_push_notification', array($this, 'fcmdpplgpn_admin_page'));
add_submenu_page(null
, __('Test Push Notification', FCMDPPLGPN_TRANSLATION)
, 'Test Notification'
, 'administrator'
, 'test_push_notification'
, array($this, 'fcmdpplgpn_send_test_notification')
);
}
public function fcmdpplgpn_admin_page()
{
include(plugin_dir_path(__FILE__) . 'fcm-dp-admin-panel.php');
}
public function fcmdpplgpn_activate()
{
}
public function fcmdpplgpn_deactivate()
{
}
function fcmdpplgpn_settings()
{
register_setting('fcmdpplgpn_group', 'fcmdpplgpn_api');
register_setting('fcmdpplgpn_group', 'fcmdpplgpn_topic');
register_setting('fcmdpplgpn_group', 'fcmdpplgpn_disable');
register_setting('fcmdpplgpn_group', 'fcmdpplgpn_page_disable');
register_setting('fcmdpplgpn_group', 'fcmdpplgpn_channel');
register_setting('fcmdpplgpn_group', 'fcmdpplgpn_default_image');
/* 30/04/2021 - Included notification sound setting */
register_setting('fcmdpplgpn_group', 'fcmdpplgpn_sound');
// 1.9.0 31/12/2021 - Included to enter custom field names
// Suggestion of @ibrahimelshamy
register_setting('fcmdpplgpn_group', 'fcmdpplgpn_custom_fields');
/* set checkboxs post types */
$args = array(
'public' => true,
);
$post_types = get_post_types( $args, 'objects' );
if ( $post_types ) { // If there are any custom public post types.
foreach ( $post_types as $post_type ) {
//$this->write_log('add action 4: ' . $post_type->name);
if ($post_type->name != 'attachment'){
register_setting('fcmdpplgpn_group', 'fcmdpplgpn_posttype_' . $post_type->name);
}
}
}
}
function fcmdpplgpn_send_test_notification(){
$test = new FCMDPPLGPNTestSendPushNotification;
$test->post_type = "test";
$test->ID = 0;
$test->post_title = "Teste Push Notification";
$test->post_content = "Test from Firebase Push Notification Plugin";
$test->post_excerpt = "Test from Firebase Push Notification Plugin";
$test->post_url = "https://dprogrammer.net";
$result = $this->fcmdpplgpn_notification($test, false, false, '');
echo '<div class="row">';
echo '<div><h2>API Return</h2>';
echo '<pre>';
printf($result);
echo '</pre>';
echo '<p><a href="'. admin_url('admin.php').'?page=test_push_notification">Send again</a></p>';
echo '<p><a href="'. admin_url('admin.php').'?page=fcmdpplgpn_push_notification">FCM Options</a></p>';
echo '</div>';
}
function fcmdpplgpn_notification($post, $sendOnlyData, $showLocalNotification, $command) {
// $admin_email = get_option('admin_email');
$from = get_bloginfo('name');
$post_type = esc_attr($post->post_type);
$post_id = esc_attr($post->ID);
$post_title = $post->post_title;
$content = esc_html(wp_strip_all_tags(preg_replace("/\r|\n/", " ", $post->post_content)));
$content = wp_specialchars_decode($content, ENT_QUOTES);
$resume = wp_specialchars_decode(esc_attr($post->post_excerpt), ENT_QUOTES);
$post_url = esc_url(get_the_permalink($post->ID));
$thumb_id = get_post_thumbnail_id($post_id);
$thumb_url = wp_get_attachment_image_src($thumb_id, 'full');
$image = $thumb_url ? esc_url($thumb_url[0]) : get_option('fcmdpplgpn_default_image');
$sound = esc_attr(get_option('fcmdpplgpn_sound'));
$topic = esc_attr(get_option('fcmdpplgpn_topic'));
$channel = esc_attr(get_option('fcmdpplgpn_channel'));
$customFields = esc_attr(get_option('fcmdpplgpn_custom_fields'));
$arrCustomFieldsValues = [];
if (_mb_strlen($customFields) > 0) {
$arrCustomFields = explode("|", $customFields);
foreach($arrCustomFields as $customField) {
$arrCustomFieldsValues[$customField] = (string)esc_attr(get_post_meta($post_id, $customField, TRUE)); // Ensure value is a string
}
}
// JSON string with service account details
$jsonString = '{
"type": "service_account",
"project_id": "your-project-id",
"private_key_id": "your-private-key-id",
"private_key": "-----BEGIN PRIVATE KEY-----\nYOUR_PRIVATE_KEY\n-----END PRIVATE KEY-----\n",
"client_email": "your-client-email@your-project-id.iam.gserviceaccount.com",
"client_id": "your-client-id",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/your-client-email@your-project-id.iam.gserviceaccount.com"
}';
$authConfig = json_decode($jsonString);
if ($authConfig === null) {
// wp_mail($admin_email, 'FCM Notification Error', 'Failed to decode JSON for Firebase service account.');
return;
}
$token = $this->generate_firebase_jwt($authConfig);
if ($token) {
$url = "https://fcm.googleapis.com/v1/projects/{$authConfig->project_id}/messages:send";
$notification_data = [
'message' => [
'topic' => $topic,
'notification' => [
'title' => $post_title,
'body' => _mb_strlen($resume) == 0 ? _mb_substr(wp_strip_all_tags($content), 0, 55) . '...' : $resume,
'image' => $image,
],
'data' => [
'click_action' => 'FLUTTER_NOTIFICATION_CLICK',
'post_type' => $post_type,
'post_id' => (string)$post_id, // Convert to string
'url' => $post_url,
'show_in_notification' => $showLocalNotification ? 'true' : 'false', // Convert to string
'command' => $command,
'dialog_title' => $post_title,
'dialog_text' => _mb_strlen($resume) == 0 ? _mb_substr(wp_strip_all_tags($content), 0, 100) . '...' : $resume,
'dialog_image' => $image,
'sound' => _mb_strlen($sound) == 0 ? 'default' : $sound,
'custom_fields' => json_encode($arrCustomFieldsValues) // Convert array to JSON string
],
'apns' => [
'payload' => [
'aps' => [
'sound' => 'default'
]
]
],
'android' => [
'notification' => [
'icon' => 'assets/icon.png',
'color' => '#32DE8A',
'channel_id' => $channel
]
]
]
];
$fields = json_encode($notification_data);
$headers = [
'Authorization: Bearer ' . $token,
'Content-Type: application/json'
];
$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_POSTFIELDS, $fields);
$result = curl_exec($ch);
curl_close($ch);
if ($result === false) {
// wp_mail($admin_email, 'FCM Notification Error', 'Error occurred while sending push notification.');
} else {
// wp_mail($admin_email, 'FCM Notification Success', 'Push notification sent successfully. Result: ' . $result);
}
} else {
// wp_mail($admin_email, 'FCM Notification Error', 'Failed to obtain Firebase access token.');
}
}
private function generate_firebase_jwt($authConfig) {
error_log('Generating JWT...');
$header = json_encode([
'typ' => 'JWT',
'alg' => 'RS256'
]);
$time = time();
$payload = json_encode([
"iss" => $authConfig->client_email,
"scope" => "https://www.googleapis.com/auth/firebase.messaging",
"aud" => "https://oauth2.googleapis.com/token",
"exp" => $time + 3600,
"iat" => $time
]);
$base64UrlHeader = $this->base64UrlEncode($header);
$base64UrlPayload = $this->base64UrlEncode($payload);
$secret = openssl_get_privatekey($authConfig->private_key);
if ($secret === false) {
error_log('Failed to read private key.');
return null;
}
openssl_sign($base64UrlHeader . "." . $base64UrlPayload, $signature, $secret, OPENSSL_ALGO_SHA256);
if ($signature === false) {
error_log('Failed to sign JWT.');
return null;
}
$base64UrlSignature = $this->base64UrlEncode($signature);
$jwt = $base64UrlHeader . "." . $base64UrlPayload . "." . $base64UrlSignature;
// Request token
$options = array('http' => array(
'method' => 'POST',
'content' => 'grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=' . $jwt,
'header' => "Content-Type: application/x-www-form-urlencoded"
));
$context = stream_context_create($options);
$responseText = file_get_contents("https://oauth2.googleapis.com/token", false, $context);
if ($responseText === false) {
error_log('Failed to get a response from Google OAuth.');
return null;
}
$response = json_decode($responseText);
return $response->access_token ?? null;
}
private function base64UrlEncode($text) {
return str_replace(
['+', '/', '='],
['-', '_', ''],
base64_encode($text)
);
}
function fcmdpplgpn_settings_link( $links ) {
// Build and escape the URL.
$url = esc_url( add_query_arg(
'page',
'fcmdpplgpn_push_notification',
get_admin_url() . 'admin.php'
) );
// Create the link.
$settings_link = "<a href='$url'>" . __( 'Settings' ) . '</a>';
// Adds the link to the end of the array.
array_push(
$links,
$settings_link
);
return $links;
}//end nc_settings_link()
}
/* to test a send notification */
class FCMDPPLGPNTestSendPushNotification
{
public $ID;
public $post_type;
public $post_content;
public $post_excerpt;
public $post_url;
}
$FCMDPPLGPN_Push_Notification_OBJ = new FCMDPPLGPN_Push_Notification();
- You must be logged in to reply to this topic.