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.
This integration is implemented by running a small external service that performs OAuth for Feishu (Evolver), receives and validates Feishu webhooks, exposes a stable API that the OpenClaw skill calls, and then registering/configuring that skill in ClawHub so the agent can invoke your service with the correct secrets and scopes. Keep state (tokens, refresh logic, event store) outside the agent runtime, validate webhooks with HMAC/keys, and ensure the skill is installed/authenticated before execution. Below are concrete, vendor-neutral steps, code samples, manifest examples, and debugging tips you can apply immediately.
<b>//</b> Example uses express and node-fetch. Install: npm install express node-fetch body-parser crypto
const express = require('express');
const fetch = require('node-fetch');
const bodyParser = require('body-parser');
const crypto = require('crypto');
const APP_CLIENT_ID = process.env.FEISHU_CLIENT_ID;
const APP_CLIENT_SECRET = process.env.FEISHU_CLIENT_SECRET;
const REDIRECT_URI = process.env.FEISHU_REDIRECT_URI;
const TOKEN_URL = process.env.FEISHU_TOKEN_URL; <b>//</b> e.g. https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal
const VERIFY_SECRET = process.env.FEISHU_WEBHOOK_SECRET; <b>//</b> webhook verification secret
const PORT = process.env.PORT || 3000;
const app = express();
app.use(bodyParser.json());
// <b>//</b> Step 1: OAuth callback
app.get('/oauth/callback', async (req, res) => {
const code = req.query.code;
if (!code) return res.status(400).send('missing code');
try {
// <b>//</b> Exchange code for token (replace TOKEN_URL with actual Feishu token endpoint)
const resp = await fetch(TOKEN_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
// <b>//</b> This JSON shape depends on Feishu token API. Adapt as needed.
grant_type: 'authorization_code',
code,
client_id: APP_CLIENT_ID,
client_secret: APP_CLIENT_SECRET,
redirect_uri: REDIRECT_URI
})
});
const data = await resp.json();
if (!resp.ok) return res.status(500).json({ error: data });
// <b>//</b> Persist tokens in DB keyed by user/tenant ID returned by Feishu
// saveTokensToDb(tenantId, data.access_token, data.refresh_token, data.expires_in)
return res.send('OAuth success; you can close this window.');
} catch (err) {
return res.status(500).json({ error: String(err) });
}
});
// <b>//</b> Step 2: Webhook receiver with signature verification
app.post('/webhook', (req, res) => {
const signature = req.headers['x-feishu-signature'] || req.headers['x-lark-signature'];
const bodyRaw = JSON.stringify(req.body);
if (!verifySignature(bodyRaw, signature, VERIFY_SECRET)) {
return res.status(401).send('invalid signature');
}
// <b>//</b> Process event asynchronously: push to job queue or DB
// enqueueEvent(req.body);
res.status(200).send({ challenge: req.body.challenge || 'ok' });
});
function verifySignature(payload, signature, secret) {
if (!signature || !secret) return false;
const hmac = crypto.createHmac('sha256', secret).update(payload).digest('base64');
return signature === hmac;
}
app.post('/api/evolver/run', async (req, res) => {
const { user_id, input } = req.body;
if (!user_id || !input) return res.status(400).send('missing fields');
// <b>//</b> Retrieve stored tokens for user_id
// const tokens = await getTokensFromDb(user_id);
// <b>//</b> Perform a call to Feishu Evolver endpoints using access_token
// const feishuResp = await fetch('https://open.feishu.cn/open-apis/evolver/v1/run', {
// method: 'POST',
// headers: { 'Authorization': `Bearer ${tokens.access_token}`, 'Content-Type': 'application/json' },
// body: JSON.stringify({ input })
// });
// const result = await feishuResp.json();
// <b>//</b> Return result back to caller (the OpenClaw skill)
// res.json(result);
res.json({ ok: true, message: 'stub — implement call to Feishu Evolver' });
});
app.listen(PORT, () => console.log(`Server listening ${PORT}`));
Example JSON manifest (generic, not OpenClaw-specific):
{
"name": "feishu-evolver-skill",
"description": "Calls external Feishu Evolver wrapper service",
"actions": {
"run": {
"method": "POST",
"url": "https://your-service.example.com/api/evolver/run",
"auth": { "type": "bearer", "headerName": "Authorization", "tokenSource": "SKILL_API_KEY" },
"input_schema": { "type": "object", "properties": { "user_id": { "type": "string" }, "input": { "type": "string" } }, "required": ["user_id","input"] }
}
}
}
This approach uses explicit REST APIs, standard OAuth, webhook validation, and clear separation of responsibilities: the OpenClaw skill invokes a stable external API and does not hold tokens or long-lived state.
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
Direct answer: A protobuf schema mismatch means the sender and receiver use incompatible .proto definitions (field numbers, types, reserved ranges, or enums). Fix by aligning .proto files or making only wire-compatible changes, regenerating code, and decoding problematic bytes to find unknown fields.
Steps to resolve:
#!/bin/sh
# Decode raw bytes for inspection
cat message.bin | protoc --decode_raw
2
Check credentials, token lifecycle, and skill permissions first: verify environment variables and secrets in ClawHub, confirm tokens aren’t expired, validate scopes and redirect URIs, and inspect API responses and logs for 401/403 details; refresh or re-run OAuth flows and ensure the OpenClaw skill is configured to use the correct credential mapping.
3
OpenClaw integrations work by explicit configuration: authenticate skills (env vars, API keys, OAuth), install/configure via ClawHub, run agents in the OpenClaw runtime, validate webhooks, and move state or scaling components outside the runtime. Debug by inspecting skill logs, API responses, and execution paths — nothing runs automatically without those steps.
// Node.js: check auth before skill call
if (!process.env.OPENCLAW_API_KEY) {
<b>//</b> missing key: abort
throw new Error('Missing OPENCLAW_API_KEY');
}
const apiKey = process.env.OPENCLAW_API_KEY;
// initialize SDK/client and call skill here
4
Direct answer: Configure a webhook endpoint in ClawHub/runtime, validate the provider signature using a secret stored in env vars, parse the provider event type, map it to the correct agent/skill with a routing table, then deliver the event to the agent runtime (or push to an external queue) so the skill can handle it with proper credentials and permissions; respond quickly and log for retries/idempotency.
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.Â