Overview
The Webhook integration allows you to receive article data from GroMach and process it in your own backend system. When you publish an article, GroMach sends a POST request to your configured endpoint with the article content.
Step 1: Set Up Your Webhook Endpoint
Create an HTTPS endpoint on your server to receive webhook requests. The endpoint must:
- Accept POST requests: All webhook data is sent via POST
- Use HTTPS: For security, only HTTPS URLs are supported
- Return 2xx status: Return a success status code to confirm receipt
Step 2: Implement Signature Verification
GroMach signs all webhook requests using HMAC-SHA256. You should verify this signature to ensure requests are authentic.
Each request includes these headers:
- x-webhook-signature: HMAC-SHA256 signature of the request body
- x-webhook-timestamp: ISO 8601 timestamp of when the request was sent
- Content-Type: application/json
Here's an example of signature verification in Node.js:
const crypto = require('crypto');
function verifySignature(payload, signature, secret) {
const computedSignature = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature, 'hex'),
Buffer.from(computedSignature, 'hex')
);
}
// In your endpoint handler:
app.post('/webhook', (req, res) => {
const signature = req.headers['x-webhook-signature'];
const payload = JSON.stringify(req.body);
if (!verifySignature(payload, signature, YOUR_SECRET_KEY)) {
return res.status(401).json({ error: 'Invalid signature' });
}
// Process the webhook...
res.json({ success: true });
});Step 3: Webhook Payload Format
When an article is published, GroMach sends a payload with the following structure:
{
"event_type": "publish_articles",
"timestamp": "2024-01-15T10:30:00.000Z",
"data": {
"articles": [
{
"id": "article-uuid-123",
"slug": "my-article-slug",
"title": "Article Title",
"excerpt": "Brief description of the article...",
"content_format": "markdown",
"content": "# Full article content in markdown...",
"status": "published",
"published_at": "2024-01-15T10:30:00.000Z",
"author_name": "Admin",
"cover_image": "https://example.com/image.jpg",
"meta_title": "SEO Title",
"meta_description": "SEO meta description",
"tags": ["seo", "marketing"]
}
]
}
}Article Fields Reference
- id: Unique identifier for the article
- slug: URL-friendly identifier for the article
- title: Article title
- excerpt: Brief description or summary
- content_format: Either "markdown" or "html"
- content: Full article content
- status: Publication status (draft, published, archived)
- published_at: ISO 8601 publication timestamp
- author_name: Author display name
- cover_image: URL of the cover image (if available)
- meta_title: SEO title for search engines
- meta_description: SEO meta description
- tags: Array of tag strings
Step 4: Configure in GroMach
In the GroMach integrations page, fill in the following information:
- Name (Optional): A friendly name to identify this webhook
- Webhook URL: Your HTTPS endpoint URL (e.g., https://your-site.com/api/webhook)
- Secret Key: A secret string used to sign requests (keep this secure!)
- Publish Status: Choose whether articles are sent as "published" or "draft"
Important
Keep your Secret Key secure and never expose it in client-side code. Use environment variables to store it safely on your server.
Testing Your Webhook
Before creating the integration, you can test your webhook connection using the "Test Connection" button. GroMach will send a test request to verify your endpoint is properly configured.
Test Requirements
For the test to pass, your endpoint must:
- 1. Verify the signature: Use the secret key to verify the
X-Webhook-Signatureheader - 2. Return success response: Return a JSON response with
{ "success": true }
The test payload looks like:
{
"event_type": "test",
"timestamp": "2024-01-15T10:30:00.000Z",
"data": {
"message": "This is a test webhook from Gromach SEO",
"integration_name": "My Webhook"
}
}Here's a complete example of how your test endpoint should handle the request:
const crypto = require('crypto');
app.post('/webhook', (req, res) => {
const signature = req.headers['x-webhook-signature'];
const payload = JSON.stringify(req.body);
// Step 1: Verify the signature
const computedSignature = crypto
.createHmac('sha256', YOUR_SECRET_KEY)
.update(payload)
.digest('hex');
const isValid = crypto.timingSafeEqual(
Buffer.from(signature, 'hex'),
Buffer.from(computedSignature, 'hex')
);
if (!isValid) {
return res.status(401).json({
success: false,
error: 'Invalid signature'
});
}
// Step 2: Process based on event type
if (req.body.event_type === 'test') {
// Test connection - just return success
return res.json({ success: true });
}
if (req.body.event_type === 'publish_articles') {
// Process articles...
const articles = req.body.data.articles;
// Save to your database, etc.
return res.json({ success: true });
}
res.json({ success: true });
});Why signature verification is required
Signature verification ensures that the webhook requests are genuinely from GroMach and haven't been tampered with. This is a security best practice that protects your endpoint from unauthorized requests.
Troubleshooting
Connection test fails
- • Verify your endpoint URL is correct and uses HTTPS
- • Ensure your server is accessible from the internet
- • Check that your endpoint returns a 2xx status code
Signature verification fails
- • Make sure you're using the exact Secret Key from GroMach
- • Verify you're hashing the raw request body, not a parsed object
- • Use timing-safe comparison to prevent timing attacks
Articles not appearing
- • Check your server logs for any processing errors
- • Verify the article status matches your expected workflow
- • Ensure your database operations are completing successfully