Skip to content

GitHub Integration ​

Receive and route GitHub webhooks for repositories, organizations, and GitHub Apps.

Setup ​

1. Create a Source in WebhookRelay ​

bash
curl -X POST https://api.hookbase.app/api/organizations/{orgId}/sources \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "GitHub Production",
    "slug": "github",
    "verificationConfig": {
      "type": "github",
      "secret": "your-webhook-secret"
    }
  }'

Save your webhook URL:

https://api.hookbase.app/ingest/{orgSlug}/github

2. Configure GitHub Webhook ​

Repository Webhook ​

  1. Go to your repository on GitHub
  2. Navigate to Settings → Webhooks
  3. Click Add webhook
  4. Enter your WebhookRelay URL as the Payload URL
  5. Set Content type to application/json
  6. Enter your Secret (same as configured in the source)
  7. Select events or choose Send me everything
  8. Click Add webhook

Organization Webhook ​

  1. Go to your organization on GitHub
  2. Navigate to Settings → Webhooks
  3. Follow the same steps as repository webhook

GitHub App Webhook ​

  1. Go to your GitHub App settings
  2. Set the Webhook URL to your WebhookRelay URL
  3. Enter the Webhook secret
  4. Enable desired events

3. Create Destinations and Routes ​

bash
# Create a destination
curl -X POST https://api.hookbase.app/api/organizations/{orgId}/destinations \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -d '{"name": "My App", "url": "https://myapp.com/webhooks/github"}'

# Create a route
curl -X POST https://api.hookbase.app/api/organizations/{orgId}/routes \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -d '{"name": "GitHub to My App", "sourceId": "src_...", "destinationIds": ["dst_..."]}'

Signature Verification ​

GitHub signs webhooks with HMAC-SHA256. The signature is sent in the X-Hub-Signature-256 header:

X-Hub-Signature-256: sha256=abc123...

WebhookRelay automatically verifies this signature when you configure:

json
{
  "verificationConfig": {
    "type": "github",
    "secret": "your-webhook-secret"
  }
}

Common Events ​

Push Events ​

Triggered when code is pushed to a branch.

json
{
  "ref": "refs/heads/main",
  "before": "abc123",
  "after": "def456",
  "repository": {
    "id": 123456,
    "full_name": "owner/repo",
    "private": false
  },
  "pusher": {
    "name": "username",
    "email": "user@example.com"
  },
  "commits": [
    {
      "id": "def456",
      "message": "Update README",
      "author": {
        "name": "User",
        "email": "user@example.com"
      }
    }
  ]
}

Pull Request Events ​

Triggered for PR actions (opened, closed, merged, etc.).

json
{
  "action": "opened",
  "number": 42,
  "pull_request": {
    "id": 789,
    "title": "Add new feature",
    "state": "open",
    "head": {
      "ref": "feature-branch",
      "sha": "abc123"
    },
    "base": {
      "ref": "main",
      "sha": "def456"
    },
    "user": {
      "login": "username"
    }
  },
  "repository": {
    "full_name": "owner/repo"
  }
}

Issue Events ​

Triggered for issue actions.

json
{
  "action": "opened",
  "issue": {
    "id": 456,
    "number": 10,
    "title": "Bug report",
    "state": "open",
    "user": {
      "login": "reporter"
    },
    "labels": [
      {"name": "bug"}
    ]
  },
  "repository": {
    "full_name": "owner/repo"
  }
}

Transform Examples ​

Slack Notification for Push ​

javascript
function transform(payload) {
  const commits = payload.commits || [];
  const commitList = commits
    .slice(0, 5)
    .map(c => `• ${c.message.split('\n')[0]}`)
    .join('\n');

  return {
    blocks: [
      {
        type: "header",
        text: {
          type: "plain_text",
          text: `Push to ${payload.repository.full_name}`
        }
      },
      {
        type: "section",
        fields: [
          {
            type: "mrkdwn",
            text: `*Branch:*\n${payload.ref.replace('refs/heads/', '')}`
          },
          {
            type: "mrkdwn",
            text: `*Pusher:*\n${payload.pusher.name}`
          }
        ]
      },
      {
        type: "section",
        text: {
          type: "mrkdwn",
          text: `*Commits (${commits.length}):*\n${commitList}`
        }
      }
    ]
  };
}

Discord Notification for PR ​

javascript
function transform(payload) {
  const pr = payload.pull_request;
  const action = payload.action;

  const colors = {
    opened: 0x28a745,
    closed: 0xd73a49,
    merged: 0x6f42c1
  };

  return {
    embeds: [{
      title: `PR #${pr.number}: ${pr.title}`,
      url: pr.html_url,
      color: colors[action] || 0x586069,
      fields: [
        { name: "Action", value: action, inline: true },
        { name: "Author", value: pr.user.login, inline: true },
        { name: "Branch", value: `${pr.head.ref} → ${pr.base.ref}`, inline: true }
      ],
      timestamp: new Date().toISOString()
    }]
  };
}

Filter Examples ​

Only Push to Main ​

json
{
  "name": "Main Branch Pushes",
  "logic": "and",
  "conditions": [
    {
      "field": "ref",
      "operator": "equals",
      "value": "refs/heads/main"
    }
  ]
}

PR Opened or Merged ​

json
{
  "name": "PR Opened or Merged",
  "logic": "or",
  "conditions": [
    {
      "field": "action",
      "operator": "equals",
      "value": "opened"
    },
    {
      "field": "pull_request.merged",
      "operator": "equals",
      "value": "true"
    }
  ]
}

Exclude Bot Users ​

json
{
  "name": "Non-Bot Events",
  "logic": "and",
  "conditions": [
    {
      "field": "sender.type",
      "operator": "not_equals",
      "value": "Bot"
    }
  ]
}

Headers ​

GitHub sends these headers with webhooks:

HeaderDescription
X-GitHub-EventEvent type (push, pull_request, etc.)
X-GitHub-DeliveryUnique delivery ID
X-Hub-Signature-256HMAC-SHA256 signature
X-GitHub-Hook-IDWebhook configuration ID
X-GitHub-Hook-Installation-Target-IDInstallation target
X-GitHub-Hook-Installation-Target-TypeTarget type (repository, organization)

Troubleshooting ​

Webhook Not Triggering ​

  1. Check GitHub's webhook delivery logs in repository settings
  2. Verify the payload URL is correct
  3. Ensure the webhook is active (not disabled)

Signature Verification Failed ​

  1. Verify the secret matches exactly (no extra spaces)
  2. Check if you're using the correct secret for the environment
  3. Ensure the payload isn't being modified by proxies

Missing Events ​

  1. Check which events are selected in GitHub webhook settings
  2. Verify filters aren't blocking expected events
  3. Check if the repository/org has required permissions

Best Practices ​

  1. Use secrets: Always configure a webhook secret for security

  2. Select specific events: Only subscribe to events you need

  3. Use filters: Filter events to reduce unnecessary processing

  4. Monitor deliveries: Check GitHub's webhook logs for failures

  5. Separate by environment: Use different sources for prod/staging/dev

Released under the MIT License.