RankPill Logo

Integrations

Webhooks

What Are Webhooks?

Webhooks are a powerful tool for developers that allow you to send real-time data from one application to another whenever a specific event occurs. In RankPill, you can use a webhook to automatically send all the data for a newly published article to a URL of your choice.

This enables you to create custom integrations with any service that can receive an HTTP POST request, such as:

  • A Next.js, Hugo, or Jekyll site
  • A custom-built CMS
  • A Zapier or Make.com automation workflow
  • A serverless function (e.g., AWS Lambda, Vercel Functions)
  • A Discord or Slack notification channel

How to Set Up a Webhook

  1. Navigate to Webhook Settings: Go to Settings > Integrations in your RankPill dashboard and click on the "Webhooks" integration.

  2. Enter Your Webhook URL: In the input field, paste the public URL of the endpoint you've created to receive the webhook data. This URL must be able to accept a POST request with a JSON payload.

  3. Connect and Save: Click "Connect". RankPill will securely store your URL and generate a unique Secret Key.

  4. Copy Your Secret Key: The secret key is essential for verifying that the incoming requests are genuinely from RankPill. Copy this key and store it securely in your application's environment variables (e.g., as RANKPILL_WEBHOOK_SECRET).

Verifying the Signature

To ensure the security of your endpoint, you must verify the signature of every incoming webhook request. We include a signature in the X-RankPill-Signature header of each request.

The signature is a HMAC SHA-256 hash, created using your Secret Key and the raw JSON payload of the request.

Here's an example of how to verify the signature in a Next.js API route:

// /pages/api/rankpill-webhook.js
import crypto from 'crypto';

export default async function handler(req, res) {
  if (req.method !== 'POST') {
    return res.status(405).json({ message: 'Method Not Allowed' });
  }

  // 1. Get the signature from the headers
  const signature = req.headers['x-rankpill-signature'];
  if (!signature) {
    return res.status(401).json({ message: 'No signature provided.' });
  }

  // 2. Get the raw request body
  // Note: It's crucial to use the raw, unparsed body for the hash calculation.
  // The following line is specific to Next.js; your framework may differ.
  const rawBody = await getRawBody(req);
  
  // 3. Compute your own signature
  const secret = process.env.RANKPILL_WEBHOOK_SECRET;
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(rawBody)
    .digest('hex');

  // 4. Compare the signatures
  if (signature !== expectedSignature) {
    return res.status(401).json({ message: 'Invalid signature.' });
  }

  // If the signature is valid, process the article data
  const article = JSON.parse(rawBody);

  console.log('Successfully received article:', article.title);
  // TODO: Add your logic here to save the article, create a file, etc.

  res.status(200).json({ message: 'Webhook received successfully!' });
}

// Helper to get the raw body in Next.js
function getRawBody(req) {
  return new Promise((resolve, reject) => {
    const chunks = [];
    req.on('data', chunk => chunks.push(chunk));
    req.on('end', () => resolve(Buffer.concat(chunks)));
    req.on('error', reject);
  });
}

Payload Data Structure

The webhook will send a cleaned article object containing only the public content data as a JSON payload. Here is an example of the data you can expect to receive:

{
  "title": "How to Build Backlinks for Better SEO",
  "content_html": "<h1>How to Build Backlinks for Better SEO</h1><p>Building high-quality backlinks is one of the most important...</p>",
  "content_markdown": "# How to Build Backlinks for Better SEO\n\nBuilding high-quality backlinks is one of the most important...",
  "slug": "how-to-build-backlinks-for-better-seo",
  "meta_description": "Learn proven strategies to build high-quality backlinks that will improve your website's search engine rankings and drive more organic traffic.",
  "status": "published",
  "featured_image": "https://images.unsplash.com/photo-1516321318423-f06f85e504b3",
  "published_url": "https://yourblog.com/blog/how-to-build-backlinks-for-better-seo",
  "scheduled_date": null,
  "published_at": "2024-03-15T10:30:00Z"
}

By using this data, you can dynamically create pages, update your content, or trigger any other custom workflow you can imagine.