WP Email Ticketing is a demo WordPress plugin for support ticket management. It automatically converts inbound emails into support tickets and allows agents to reply directly from WordPress. Built with Postmark integration for reliable email processing.
Ticket Listing View
Ticket Detail View
- The support email (e.g., support@yourcompany.com) is connected to Postmark.
- Postmark parses incoming emails and sends structured JSON data to your WordPress webhook endpoint.
- The plugin converts email data into custom post type "Tickets" with proper metadata and attachments.
- Support agents can manage tickets through a React-powered dashboard.
- Agent responses are sent to customers.
- Customer replies containing ticket IDs are automatically threaded to existing tickets.
- PHP 8.0+
- Composer
- Node.js (for frontend development)
Download the latest plugin zip file from the GitHub Releases page and install it through the WordPress admin:
- Go to Plugins > Add New in your WordPress admin
- Click Upload Plugin
- Choose the downloaded zip file and click Install Now
- Activate the plugin
For local installation:
git clone https://github.com/jessy-p/wp-email-ticketing.git
cd wp-email-ticketing
composer install
cd client && npm install && npm run build
-
Event-Driven Email Processing - Real-time email processing via webhooks without polling or cron jobs for instant ticket creation.
-
WordPress Integration Patterns
- Leverages Custom Post Types for Tickets
- Replies stored as WordPress comments
- Email attachments handled via the WordPress Media Library
- Custom taxonomies for ticket status and priority management
- Structured metadata storage for efficient retrieval
-
PSR-4 Autoloading - Proper namespace organization for maintainable and scalable code.
-
Interface-Driven Design -
EmailProviderInterfaceabstracts email provider logic for extensibility, can easily swap Postmark with SendGrid, Mailgun, or custom code that parses email to JSON. -
Separation of Concerns
- Controllers handle HTTP requests and routing
- DTOs provide structured data validation and transfer
- Providers abstract email service logic
- Clean namespace organization with single-responsibility classes
-
WordPress REST API Endpoints
- Webhook URL authentication using Application Password
- Authorization based on Editor role capabilities
-
Input Validation & Security - Email validation, content length limits, and sanitization for secure webhook payload processing.
-
Frontend Stack - React with TypeScript, using Vite for fast dev builds.
-
Code Quality Standards - PHP CodeSniffer with PSR-12 standards for consistent PHP code style.
- Create Postmark Account: Sign up at https://postmarkapp.com/ and create a new inbound server.
- Point Your Email to Postmark:
- Follow Postmark's email setup guide to route your support email to Postmark.
- This allows Postmark to receive emails sent to your support address (e.g., support@yourcompany.com) and parse them to JSON.
- Connect Postmark to your WordPress site:
- In WordPress, create a user with "Editor" role or higher (needs "Edit Others' Posts" capability)
- Generate an application password for this user (Users → Profile → Application Passwords)
- In your Postmark server settings, set the webhook URL to
https://username:applicationpassword@yoursite.com/wp-json/ticketing/v1/webhook - This tells Postmark where to send the parsed email data when emails arrive.
- Send a Test Email: Send an email to your configured support address.
- Verify Ticket Creation: A new ticket should appear under "Tickets".
- Test Agent Reply : Reply to the ticket from the Ticketing dashboard and the customer should receive your response via email (via wp_mail).
- Test Customer Reply: Customer reply to the agent response should appear as an update to the existing ticket.
To test locally without Postmark, use curl to simulate the parsed email JSON arriving at the webhook URL from PostMark
- Create a ticket
curl -X POST 'https://<user>:<applicationpassword>@<yoursite>/wp-json/ticketing/v1/webhook' \
-H 'Content-Type: application/json' \
-d '{
"Subject": "Mobile App Crashes",
"FromName": "John Doe",
"From": "john@example.com",
"HtmlBody": "<p>The mobile app keeps crashing every time I try to upload photos.</p>",
"TextBody": "The mobile app keeps crashing every time I try to upload photos.",
"Attachments": []
}'
- Create a reply to ticket
curl -X POST 'https://<user>:<applicationpassword>@<yoursite>/wp-json/ticketing/v1/webhook' \
-H 'Content-Type: application/json' \
-d '{
"Subject": "[Ticket #19] Re: Mobile App Crashes",
"FromName": "John Doe",
"From": "john@example.com",
"HtmlBody": "<p>More information about the crashing app.</p>",
"TextBody": "More information about the crashing app",
"Attachments": [],
"is_reply": true,
"ticket_id": 19
}'
Frontend API Endpoints:
GET /wp-json/ticketing/v1/tickets- List tickets with filtering and paginationGET /wp-json/ticketing/v1/ticket/{id}- Get ticket details with full conversation threadPOST /wp-json/ticketing/v1/ticket/{id}/status- Update ticket statusPOST /wp-json/ticketing/v1/ticket/{id}/reply- Send agent reply and notify customer
Webhook Endpoint:
POST /wp-json/ticketing/v1/webhook- Accepts inbound email JSON
All endpoints require authentication and Editor-level permissions.
This demonstration plugin focuses on core functionality. Production-ready features would include:
Features:
- Real-time updates on the dashboard
- Ticket sorting and filtering on the dashboard
- Pagination for ticket listing
- Search capabilities to find tickets
- Implement and leverage Priority taxonomy (added in backend but not used)
- Email templates for agent responses
- SLA tracking and notifications on dashboard.
- Settings screen for configuring support email and provider
Technical:
- Error logging.
- Unit and integration testing suite
- Custom roles and capabilities (currently using built-in Editor role)
- Full Postmark API integration. To send emails to customer, we are currently using wp_mail due to Postmark test account limitation.
- Webhook IP and Signature verification.
- Rate limiting and more robust security checks on Webhook payload.
This code is licensed under GPL v2 or later license. See LICENSE.

