Skip to content

Commit

Permalink
feat: add notifications feature
Browse files Browse the repository at this point in the history
  • Loading branch information
davisshaver committed Dec 13, 2024
1 parent 3e24b9b commit af61b4a
Show file tree
Hide file tree
Showing 16 changed files with 767 additions and 18 deletions.
4 changes: 2 additions & 2 deletions farcaster-wp.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
* Plugin Name: Farcaster WP
* Plugin URI: https://farcaster-wp.davisshaver.com/
* Description: Farcaster WP connects your WordPress site to Farcaster.
* Version: 0.0.16
* Version: 0.0.17
* Author: Davis Shaver
* Author URI: https://davisshaver.com/
* License: GPL v2 or later
Expand All @@ -22,7 +22,7 @@

defined( 'ABSPATH' ) || exit;

define( 'FARCASTER_WP_VERSION', '0.0.16' );
define( 'FARCASTER_WP_VERSION', '0.0.17' );

define( 'FARCASTER_WP_API_NAMESPACE', 'farcaster-wp/v1' );
define( 'FARCASTER_WP_API_URL', get_site_url() . '/wp-json/' . FARCASTER_WP_API_NAMESPACE );
Expand Down
15 changes: 10 additions & 5 deletions includes/api/class-manifest-controller.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php
/**
* Manifest API endpoints
* Manifest API endpoint
*
* @package Farcaster_WP\API
*/
Expand All @@ -11,11 +11,12 @@
use WP_Error;
use WP_REST_Response;
use Farcaster_WP\Frames;
use Farcaster_WP\Notifications;

defined( 'ABSPATH' ) || exit;

/**
* REST API endpoints for Farcastermanifest.
* REST API endpoints for Farcaster manifest.
*/
class Manifest_Controller extends WP_REST_Controller {

Expand Down Expand Up @@ -86,6 +87,7 @@ public function get_manifest() {
$signature = $domain_manifest['signature'];
}


$manifest = [
'accountAssociation' => [
'header' => $header,
Expand All @@ -99,11 +101,14 @@ public function get_manifest() {
'iconUrl' => get_site_icon_url(),
'splashImageUrl' => $splash_image_url,
'splashBackgroundColor' => $splash_background_color,
// @TODO: Add API endpoint for webhook to do... something?
// 'webhookUrl' => '',

],
];

if ( Notifications::are_enabled() ) {
$manifest['frame']['webhookUrl'] = get_rest_url( null, FARCASTER_WP_API_NAMESPACE . '/webhook' );
}

return new WP_REST_Response( $manifest );
}

Expand All @@ -112,7 +117,7 @@ public function get_manifest() {
*
* @return array
*/
public function get_app_config_schema() {
public function get_manifest_schema() {
return [
'$schema' => 'http://json-schema.org/draft-04/schema#',
'title' => $this->resource_name,
Expand Down
133 changes: 133 additions & 0 deletions includes/api/class-webhook-controller.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
<?php
/**
* Webhook API endpoint
*
* @package Farcaster_WP\API
*/

namespace Farcaster_WP\API;

use WP_REST_Controller;
use WP_Error;
use WP_REST_Response;
use WP_REST_Request;
use Farcaster_WP\Notifications;

defined( 'ABSPATH' ) || exit;

/**
* REST API endpoints for Farcaster notifications webhook.
*/
class Webhook_Controller extends WP_REST_Controller {

/**
* Endpoint namespace.
*
* @var string
*/
protected $namespace = FARCASTER_WP_API_NAMESPACE;

/**
* Endpoint resource.
*
* @var string
*/
protected $resource_name = 'webhook';

/**
* Register the routes.
*/
public function register_routes() {
// Register farcaster-wp/v1/webhook endpoint.
register_rest_route(
$this->namespace,
'/' . $this->resource_name,
[
[
'methods' => 'POST',
'callback' => [ $this, 'process_webhook' ],
'validate_callback' => [ $this, 'validate_webhook' ],
],
'schema' => [ $this, 'get_webhook_schema' ],
]
);
}

/**
* Process the webhook.
*
* @param WP_REST_Request $request The request object.
* @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
*/
public function process_webhook( $request ) {
$body = $request->get_body();
$data = json_decode( $body, true );
$header = json_decode( base64_decode( $data['header'] ), true );
$payload = json_decode( base64_decode( $data['payload'] ), true );
$response = Notifications::process_webhook( $header, $payload );
return new WP_REST_Response( $response );
}

/**
* Validate the webhook.
*
* @param WP_REST_Request $request The request object.
* @return bool True if the webhook is valid, false otherwise.
*/
public function validate_webhook( $request ) {
$body = $request->get_body();
$data = json_decode( $body, true );

if ( empty( $data['header'] ) || empty( $data['payload'] ) || empty( $data['signature'] ) ) {
return new WP_Error( 'invalid_webhook_parameters', 'Invalid webhook parameters', [ 'status' => 400 ] );
}

$header = json_decode( base64_decode( $data['header'] ), true );
$payload = json_decode( base64_decode( $data['payload'] ), true );

if ( empty( $header['fid'] ) || empty( $header['type'] ) || empty( $header['key'] ) ) {
return new WP_Error( 'invalid_webhook_header', 'Invalid webhook header', [ 'status' => 400 ] );
}

if ( empty( $payload['event'] ) || ! in_array( $payload['event'], [ 'frame_added', 'frame_removed', 'notifications_disabled', 'notifications_enabled' ] ) ) {
return new WP_Error( 'invalid_webhook_payload', 'Invalid webhook payload', [ 'status' => 400 ] );
}

// We are only handling frame_added and notifications_enabled events if they have notificationDetails.
if (
in_array( $payload['event'], [ 'frame_added', 'notifications_enabled' ] ) &&
( empty( $payload['notificationDetails'] ) || empty( $payload['notificationDetails']['url'] ) || empty( $payload['notificationDetails']['token'] ) )
) {
return new WP_Error( 'invalid_notification_details', 'Invalid notification details', [ 'status' => 400 ] );
}

return true;
}

/**
* Get the REST schema for the endpoints.
*
* @return array
*/
public function get_webhook_schema() {
return [
'$schema' => 'http://json-schema.org/draft-04/schema#',
'title' => $this->resource_name,
'type' => 'object',
'properties' => [
'header' => [
'required' => true,
'type' => 'string',
],
'payload' => [
'required' => true,
'type' => 'string',
],
'signature' => [
'required' => true,
'type' => 'string',
],
],
];
}
}
4 changes: 4 additions & 0 deletions includes/class-admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -114,13 +114,17 @@ public static function action_init() {
'url' => '',
),
'domain_manifest' => '',
'notifications_enabled' => false,
);
$schema = array(
'type' => 'object',
'properties' => array(
'frames_enabled' => array(
'type' => 'boolean',
),
'notifications_enabled' => array(
'type' => 'boolean',
),
'splash_background_color' => array(
'type' => 'string',
),
Expand Down
7 changes: 7 additions & 0 deletions includes/class-api.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
namespace Farcaster_WP;

use Farcaster_WP\API\Manifest_Controller;
use Farcaster_WP\API\Webhook_Controller;

defined( 'ABSPATH' ) || exit;

Expand All @@ -23,5 +24,11 @@ public static function init() {
include_once 'api/class-manifest-controller.php';
$manifest_api = new Manifest_Controller();
add_action( 'rest_api_init', [ $manifest_api, 'register_routes' ] );

if ( Notifications::are_enabled() ) {
include_once 'api/class-webhook-controller.php';
$webhook_api = new Webhook_Controller();
add_action( 'rest_api_init', [ $webhook_api, 'register_routes' ] );
}
}
}
12 changes: 10 additions & 2 deletions includes/class-frames.php
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,9 @@ public static function action_wp_head() {
* Enqueue scripts.
*/
public static function action_enqueue_scripts() {
$options = get_option( 'farcaster_wp', array() );

$options = get_option( 'farcaster_wp', array() );
$notifications_enabled = $options['notifications_enabled'] ?? false;

// Only enqueue if frames are enabled in settings.
if ( ! empty( $options['frames_enabled'] ) ) {
wp_enqueue_script(
Expand All @@ -144,6 +145,13 @@ public static function action_enqueue_scripts() {
'strategy' => 'defer',
)
);
wp_localize_script(
'farcaster-frame-sdk',
'farcasterWP',
array(
'notificationsEnabled' => $notifications_enabled,
)
);
}
}
}
1 change: 1 addition & 0 deletions includes/class-initializer.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,6 @@ public static function init() {
Admin::init();
API::init();
Frames::init();
Notifications::init();
}
}
Loading

0 comments on commit af61b4a

Please sign in to comment.