We build custom applications 5x faster and cheaper 🚀
Book a Free Consultation
Stuck on an error? Book a 30-minute call with an engineer and get a direct fix + next steps. No pressure, no commitment.
OpenClaw can integrate with GitHub by treating GitHub as an external service: register an OAuth app or use a personal/access token on GitHub, configure those credentials as secrets for your OpenClaw skill in ClawHub, implement the OAuth token exchange or token storage on a reliable external service (web server or secret store), receive GitHub webhooks on an external HTTPS endpoint (validate signatures), and have the OpenClaw agent call GitHub’s REST APIs (authenticated requests) for operations like creating issues, commenting, or triggering workflows. Keep persistent/stateful pieces (webhook receiver, OAuth redirect handler, token refresh/storage, job queues) outside the agent runtime; use the agent to run short, authenticated API calls and business logic only after confirming credentials and scopes.
https://github.com/login/oauth/authorize?client_id=<CLIENT_ID>&scope=repo,workflow&state=<RANDOM>// include scopes you need (e.g., repo, workflow, repo:status, read:org)
POST https://github.com/login/oauth/access\_token Accept: application/json{
"client_id":"<CLIENT_ID>",
"client_secret":"<CLIENT_SECRET>",
"code":"<CODE>"
}
const express = require('express');
const crypto = require('crypto');
const app = express();
app.use(express.raw({type: '_/_'}));
// Use raw body to compute signature exactly as GitHub sends
const WEBHOOK_SECRET = process.env.WEBHOOK_SECRET;
function verifySignature(req) {
const signature = req.headers['x-hub-signature-256'] || '';
const hmac = crypto.createHmac('sha256', WEBHOOK_SECRET);
hmac.update(req.body);
const digest = 'sha256=' + hmac.digest('hex');
const sigBuffer = Buffer.from(signature);
const digestBuffer = Buffer.from(digest);
if (sigBuffer.length !== digestBuffer.length) {
return false;
}
return crypto.timingSafeEqual(sigBuffer, digestBuffer);
}
app.post('/webhook', (req, res) => {
if (!verifySignature(req)) {
return res.status(401).send('invalid signature');
}
const event = req.headers['x-github-event'];
const payload = JSON.parse(req.body.toString());
// Process event: persist or enqueue for agent processing
console.log('received event', event, payload.repository && payload.repository.full_name);
res.status(200).send('ok');
});
app.listen(3000);
const axios = require('axios');
async function createIssue(token, owner, repo, title, body) {
const url = https://api.github.com/repos/${owner}/${repo}/issues;
const resp = await axios.post(url, {
title,
body
}, {
headers: {
'Authorization': token ${token},
'Accept': 'application/vnd.github+json',
'User-Agent': 'openclaw-integration'
}
});
return resp.data;
}
/* usage:
const token = process.env.GH_TOKEN;
createIssue(token, 'owner', 'repo', 'Issue title', 'Body text')
.then(i => console.log('Created', i.html_url))
.catch(e => console.error(e.response && e.response.data || e));
*/
curl -X POST "https://github.com/login/oauth/access\_token" \\ -H "Accept: application/json" \\ -d client_id="<CLIENT_ID>" \\ -d client_secret="<CLIENT_SECRET>" \\ -d code="<CODE>"
Speak one‑on‑one with a senior engineer about your no‑code app, migration goals, and budget. In just half an hour you’ll leave with clear, actionable next steps—no strings attached.
1
Short answer: confirm the GitHub webhook secret stored in your GitHub repo matches the secret your OpenClaw webhook receiver (skill) uses, compute the HMAC-SHA256 over the raw HTTP request body and compare it to the X-Hub-Signature-256 header using a constant-time compare, and ensure your runtime delivers the raw body to the skill (disable JSON body-parsing that consumes the stream).
2
Start by ensuring your connector uses three authenticated pieces: the GitHub App ID, the Installation ID, and a JWT signed with the App private key. Generate a short-lived JWT (RS256) from the private key, POST it to GitHub’s /app/installations/{installation_id}/access_tokens to get an installation access token, then use that token in Authorization: Bearer for API calls. Store App ID, Installation ID and private key in environment variables and refresh tokens before expiry to avoid 401s.
Keep env vars: APP_ID, INSTALLATION_ID, PRIVATE_KEY. Ensure JWT iat/exp within clock skew and exp ≤10min. Exchange JWT for installation token and use that token for connector requests.
3
Short answer: detect GitHub 403/secondary-rate-limit responses in your OpenClaw sync job, read headers (Retry-After, X-RateLimit-Reset, X-RateLimit-Remaining), apply exponential backoff with jitter, switch to conditional requests (ETag/If-None-Match), prefer webhooks/incremental syncs, and use GitHub App installation tokens to raise limits. Log and surface rate-limit metadata so the runtime can delay or reschedule jobs.
Actions to implement in the connector/skill:
// Minimal retry example
async function fetchWithRateLimit(url, opts, attempt=0){
const res = await fetch(url, opts);
if(res.status===403 || res.status===429){
const ra = res.headers.get('Retry-After') || (res.headers.get('X-RateLimit-Reset')? (parseInt(res.headers.get('X-RateLimit-Reset'))-Date.now()/1000):null);
const wait = ra ? Math.max(1, parseInt(ra)) : Math.min(60, 2**attempt + Math.random());
// schedule retry via OpenClaw job delay or setTimeout
throw {type:'rate_limited', wait};
}
return res;
}
4
Grant the GitHub App these repository permissions: Issues (Read & Write) to sync issues and labels; Pull requests (Read & Write) to sync PRs; Contents (Read) to read refs/files; Checks / Commit statuses (Read & Write) to report status; Repository hooks (Read & Write) to install/manage webhooks; and Metadata (Read) to discover accessible repos. For OAuth/PAT fallbacks grant repo, repo:status, and admin:repo_hook.
This prompt helps an AI assistant understand your setup and guide you through the fix step by step, without assuming technical knowledge.
From startups to enterprises and everything in between, see for yourself our incredible impact.
Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We’ll discuss your project and provide a custom quote at no cost.Â