WP Manifestindependent plugin directory
manifest / integrations / action-schedular-

ThemeXpert Search Sync

Synchronizes WordPress posts with an external Meilisearch index and processes secure incoming webhooks.

by Mahbubur Rahman · github.com/mahbub-diu/action-schedular-

0stars
0forks

Install

No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:

wp plugin install https://github.com/mahbub-diu/action-schedular-/archive/refs/heads/master.zip

themexpert-interview-task

A WordPress plugin that synchronizes a custom Docs post type with an external Meilisearch index and securely processes incoming webhooks from an external SaaS application.


Features

  • Registers a custom Docs post type.
  • Synchronizes published and updated Docs posts to Meilisearch.
  • Uses Action Scheduler to process indexing and deletion requests asynchronously.
  • Normalizes document data before indexing.
  • Removes HTML tags and WordPress shortcodes from post content.
  • Exposes a secure REST API webhook endpoint.
  • Verifies incoming webhook requests using HMAC SHA-256 signatures.
  • Queues delete requests received from the webhook for background processing.

Plugin Structure

tx-search-sync.php
README.md
│
├── vendor/
│   └── action-scheduler/
│
└── includes/
    ├── Plugin.php
    ├── ApiClient.php
    ├── PostType.php
    ├── Queue.php
    ├── SyncService.php
    └── WebhookController.php

Architecture Overview

File Responsibility
tx-search-sync.php Plugin bootstrap file that loads dependencies and starts the plugin.
Plugin.php Initializes plugin services and registers WordPress hooks.
PostType.php Registers the Docs custom post type.
SyncService.php Normalizes post data and queues indexing jobs.
Queue.php Registers and processes Action Scheduler background jobs.
ApiClient.php Sends requests to the Meilisearch API.
WebhookController.php Registers the REST endpoint, validates webhook signatures, and queues deletion requests.

Background Queue

The plugin uses Action Scheduler to process all communication with the external search API asynchronously.

Why?

Sending HTTP requests while WordPress is saving a post can slow down the editor and may fail if the external service is temporarily unavailable.

Instead, the plugin queues work and processes it in the background.

Outgoing Sync

  1. A Docs post is published or updated.
  2. The post data is normalized.
  3. HTML tags and WordPress shortcodes are removed.
  4. A background job is queued.
  5. Action Scheduler sends the document to Meilisearch.

Incoming Webhook

  1. A webhook request is received.
  2. The HMAC SHA-256 signature is verified.
  3. If valid and the action is delete_indexed_post, a background deletion job is queued.
  4. Action Scheduler deletes the document from Meilisearch.

This approach keeps the WordPress request lifecycle fast and non-blocking.


Normalized Document Format

Before dispatching, each document is converted into the following JSON structure:

{
  "id": 42,
  "title": "Getting Started",
  "clean_content": "Install the CLI and run the init command to scaffold a project.",
  "author_name": "Jane Doe"
}

The clean_content field is generated by stripping HTML tags and WordPress shortcodes.


Search API

Base URL

https://search.thrivedesk.xyz

Authentication

Authorization: Bearer <API_KEY>

Add / Update Document

POST /indexes/docs/documents

The request body is sent as a JSON array, even when indexing a single document, as required by the Meilisearch API.

Delete Document

DELETE /indexes/docs/documents/{id}

Secure Webhook

Endpoint

POST /wp-json/myapp/v1/webhook

Signature Verification

Every request must include an X-Signature-Hash header.

The plugin verifies the HMAC SHA-256 signature against the raw request body using the shared secret before processing the request.

Responses:

  • 401 Unauthorized — Signature is missing or invalid.
  • 202 Accepted — Signature is valid and the deletion task has been queued.

Supported Payload

{
  "action": "delete_indexed_post",
  "post_id": 42
}

Testing the Webhook

Example:

SECRET='whsec_7Qm2Kx9Lp4Rv8Tn3Wj6Zc1Yb5Hd0Fg'

BODY='{"action":"delete_indexed_post","post_id":42}'

SIG=$(printf '%s' "$BODY" | openssl dgst -sha256 -hmac "$SECRET" | sed 's/^.*= //')

curl -i \
-X POST http://localhost/themexpert/wp-json/myapp/v1/webhook \
-H "Content-Type: application/json" \
-H "X-Signature-Hash: $SIG" \
--data-raw "$BODY"

Expected responses:

  • 401 Unauthorized — Missing or invalid signature.
  • 202 Accepted — Valid signature and the deletion request has been queued.

Requirements

  • WordPress 6.x+
  • PHP 8.1+
  • Action Scheduler (bundled with the plugin)

AI Disclosure

The following AI tool was used during development:

  • ChatGPT (OpenAI)

ChatGPT was used to assist with code explanations, debugging, documentation, and general implementation guidance. The plugin architecture, implementation strategy, design decisions, and final code were independently designed and implemented by the author.


Author

Mahbubur Rahman