Get your dream built 10x faster

How to integrate Feishu Bridge with OpenClaw

We build custom applications 5x faster and cheaper 🚀

Book a Free Consultation
4.9
Clutch rating 🌟
600+
Happy partners
17+
Countries served
190+
Team members
Matt Graham, CEO of Rapid Developers

Book a call with an Expert

Stuck on an error? Book a 30-minute call with an engineer and get a direct fix + next steps. No pressure, no commitment.

How to integrate Feishu Bridge with OpenClaw

Quick direct answer: Build a small, well-scoped OpenClaw skill that acts as a bridge: register a Feishu (Lark) app to get app credentials, implement Feishu authentication (tenant access token or OAuth as required), create a webhook endpoint that validates Feishu requests, store credentials securely in ClawHub (or an equivalent secret store) and environment variables, and have the skill invoke Feishu’s REST APIs to send messages or take actions. Keep long-lived state and scheduling outside the OpenClaw agent runtime, verify tokens/signatures on every request, and instrument logs and metrics so you can debug by inspecting API responses, scopes, and ClawHub invocation logs.

 

Preparation: Feishu app and credentials

 
  • Create a Feishu (Lark) app in the Feishu Developer Console. Choose the app type that matches your needs (internal app vs. open app). Note the App ID, App Secret, and any verification token or encrypt key the platform provides for webhook validation.
  • Decide authentication mode: For bot-to-tenant operations you’ll usually use Feishu’s tenant access token (app_id/app_secret → tenant_access_token). For per-user operations you may need OAuth flows. Pick the flow required for your use case and enable the correct API scopes for sending messages, reading users/chats, etc.
  • Record required API scopes so you can request only what you need. Missing scopes are a common cause of failures.

 

Authentication and token management

 
  • Token exchange: Implement the short exchange to get a tenant or user access token using Feishu’s REST endpoint (see Feishu docs for the exact URL and version you should use).
  • Token lifetime and refresh: Cache the token and its expiry time in a secure store (not as plain constants in code). Refresh proactively before expiry. The agent runtime should read the token from an environment variable or a secret the skill has access to at invocation time.
  • Where to store secrets: Use ClawHub’s secret manager (or equivalent) to configure App ID, App Secret, verification secrets, and any credentials. Expose them to the skill as environment variables at runtime—do not hardcode secrets into skill code or commit them to VCS.

 

Webhook setup and request validation

 
  • Register a webhook URL in Feishu: The webhook should point to an HTTPS endpoint you control that the OpenClaw skill or an external service exposes. If OpenClaw cannot host reliable public webhooks in your environment, run a small external webhook receiver (web server) and forward validated calls to the skill via ClawHub invocation APIs.
  • Validate every incoming webhook: Use the verification token or signature method described in Feishu docs (timestamp + signature or encrypt key). Do not trust payloads without validation. Log raw headers and payloads on first deployment so you can confirm header names and signature format.
  • Idempotency & replay protection: Check timestamps and unique event IDs to avoid processing duplicates from retries.

 

OpenClaw skill design and ClawHub configuration

 
  • Skill responsibility: Keep the skill code focused on mapping incoming Feishu events to actions and on calling Feishu APIs. Do not store important state inside the agent runtime if you need persistence across restarts—use an external DB or key-value store.
  • ClawHub configuration: Install and configure the skill in ClawHub (or the equivalent skill registry). During configuration, point the skill to the secret keys (App ID/Secret) and to any webhook URL you need. Ensure the skill’s runtime has the right environment variables and network egress to call Feishu endpoints.
  • Authentication in skill: When the skill starts or on first invocation, it should load credentials from the environment/secret store, request a tenant_access_token (or manage OAuth tokens), cache it, and refresh when needed.
  • Invocation model: Decide whether the skill is invoked by webhook forwarding (Feishu → webhook receiver → ClawHub → skill) or by the skill directly hosting a webhook. The safe, production pattern is to host the webhook receiver as a small external service and invoke the skill through ClawHub’s API to keep the agent lightweight.

 

Runtime separation of concerns

 
  • Agent vs external services: Use the agent (skill) for request/response work and stateless processing. Use external services for persistence, long-running jobs, scheduled tasks, and job queues.
  • Outbound calls: The skill should call Feishu’s REST APIs using the token and handle HTTP errors, 401/403 (re-auth), 429 (rate-limits), and transient 5xx errors with exponential backoff.
  • Logging and observability: Emit structured logs for requests, responses, authentication events, and webhook validations. Have the webhook receiver log raw request/response for debugging (securely and temporarily).

 

Error handling, retries, and debugging

 
  • Debugging checklist when something breaks: Validate App ID/Secret, token expiry, scopes, webhook verification, request/response bodies, and header names. Reproduce the failing API call with curl and the same token to inspect the provider error message.
  • Retries: Implement idempotent retry semantics where possible. Use the provider’s recommended rate-limit handling.
  • Instrumentation: Capture Feishu API response bodies and status codes in logs, but avoid logging secrets. Keep a correlation ID that flows from webhook → skill → Feishu call for easy tracing.

 

Minimal code example (token fetch + send message)

 
  • Notes before running: Replace placeholders with values from your Feishu app. Confirm the exact Feishu endpoints and payload shape from Feishu’s official docs; adjust the message payload as required by the API version you use.
// Node.js example using fetch-style API
// <b>//</b> Install node-fetch or use Node 18+ built-in fetch
const fetch = require('node-fetch');

const FEISHU_TOKEN_URL = 'https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal/'; 
const FEISHU_MESSAGE_URL = 'https://open.feishu.cn/open-apis/message/v4/send/';

const APP_ID = process.env.FEISHU_APP_ID;
const APP_SECRET = process.env.FEISHU_APP_SECRET;

async function getTenantToken() {
  // <b>//</b> Acquire tenant token using app_id/app_secret
  const resp = await fetch(FEISHU_TOKEN_URL, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ app_id: APP_ID, app_secret: APP_SECRET })
  });
  const body = await resp.json();
  if (!resp.ok) throw new Error('Token fetch failed: ' + JSON.stringify(body));
  // <b>//</b> body.tenant_access_token is the token field per Feishu docs versions
  return { token: body.tenant_access_token, expire: Date.now() + (body.expire || 3600) * 1000 };
}

async function sendTextMessage(tenantToken, receiveId, text) {
  // <b>//</b> Send a simple text message. Confirm payload shape (content often must be a JSON string).
  const payload = {
    receive_id: receiveId,
    msg_type: 'text',
    content: JSON.stringify({ text })
  };
  const resp = await fetch(FEISHU_MESSAGE_URL, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${tenantToken}`
    },
    body: JSON.stringify(payload)
  });
  const body = await resp.json();
  if (!resp.ok || body.code !== 0) {
    // <b>//</b> Log the full response for debugging
    throw new Error('Send failed: ' + JSON.stringify(body));
  }
  return body;
}

// <b>//</b> Example run (wrap in your skill invocation)
(async () => {
  try {
    const { token } = await getTenantToken();
    const result = await sendTextMessage(token, 'REPLACE_WITH_RECEIVE_ID', 'Hello from OpenClaw skill');
    console.log('Message sent', result);
  } catch (err) {
    console.error('Error', err);
  }
})();

 

Operational checklist before going live

 
  • Secrets: Ensure App ID/Secret and webhook secrets are in ClawHub secrets or an equivalent secure vault.
  • Scopes & permissions: Validate granted scopes match the APIs you call.
  • Webhook validation: Implement strict signature/timestamp checks and reject unsigned requests.
  • Rate limits: Add backoff and circuit-breaking for Feishu API errors.
  • Persistence: Move any persistent queues, audit logs, and retries to an external, durable store outside the agent.
  • Monitoring: Capture metrics for token fetch success, API latency, failure rates, and webhook validation failures.

Book Your Free 30‑Minute Migration Call

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.

Book a Free Consultation

Troubleshooting Feishu Bridge and OpenClaw Integration

1

Why does OpenClaw Feishu Bridge fail to obtain tenant_access_token using App ID and App Secret?

Direct answer: The Feishu Bridge most often fails to obtain a tenant_access_token because the flow/endpoint being used requires the app to be installed/authorized by the tenant (or a different auth flow) and you’re attempting to exchange only App ID/App Secret without that tenant authorization, or because the request uses the wrong endpoint/parameters or malformed credentials.

 

Troubleshooting

 
  • Check the API error — the response code/message tells the root cause.
  • Validate credentials — ensure App ID/Secret are exact and loaded into OpenClaw env vars.
  • Confirm installation/consent — tenant_access_token requires the app installed/authorized on that tenant.
  • Use correct flow/endpoint — third‑party vs internal flows differ; use the token endpoint the docs specify.
  • Inspect request — JSON body, Content-Type, clock skew, network/proxy and logs; reproduce with curl to isolate OpenClaw vs Feishu issues.

2

Why are Feishu webhook requests rejected by OpenClaw Bridge with X-Lark-Signature verification errors?

Feishu webhooks are rejected because the Bridge’s verifier computes a different signature than Feishu sent. Common causes: wrong app secret, the request body was changed (JSON parsed/pretty-printed or middleware consumed the raw stream), incorrect canonical string (Feishu uses timestamp + "\n" + body), encoding/base64 mismatches, or replay/timestamp checks failing.

 

Why it happens and how to fix

 

Checklist to resolve:

  • Use the app secret configured in the Bridge (env var/API credential).
  • Verify raw request body — don’t let JSON parsers alter whitespace or encoding before signature check.
  • Compute exactly base64(HMAC-SHA256(secret, timestamp + "\n" + rawBody)).
  • Check timestamp and clock skew.
// Node.js Express example: preserve raw body for verification
const crypto = require('crypto');
app.use(express.json({
  verify: (req, res, buf) => { req.rawBody = buf } // preserve raw bytes
}));

app.post('/webhook', (req, res) => {
  // // compute signature exactly as Feishu expects
  const timestamp = req.headers['x-lark-timestamp'];
  const secret = process.env.FEISHU_APP_SECRET;
  const base = `${timestamp}\n${req.rawBody}`;
  const sig = crypto.createHmac('sha256', secret).update(base).digest('base64');
  if (sig !== req.headers['x-lark-signature']) return res.status(401).end();
  // forward to OpenClaw Bridge runtime
  res.status(200).end();
});

3

Why do Feishu event payloads not map to the OpenClaw event schema and cause mapping/parsing errors in the bridge logs?

Direct answer: Feishu event payloads often fail to map because their JSON envelope, field names and nesting, optional encryption/signature wrapper, or content-type differ from the exact OpenClaw event schema the bridge expects. When required keys are missing or differently named, the bridge mapping step throws parsing errors.

 

Why and how to fix

 

Typical causes and practical checks:

  • Schema mismatch — Feishu uses a different structure/names; compare raw payload to the bridge schema.
  • Encrypted/envelope payloads — Feishu can wrap events; decrypt/unwrap before mapping.
  • Signature/headers — Wrong validation can drop or alter the body.
  • Content-Type/timestamp formats — Ensure JSON and expected timestamp shapes.
  • Fix — Log raw body, write a small adapter/transformation that normalizes fields to the OpenClaw schema, validate with sample events, and add tests in the bridge.

4

Why does OpenClaw Feishu Bridge hit 429 rate limits or timeouts when calling Feishu APIs or sending messages?

The Feishu Bridge hits 429s or timeouts because your agents/skills are sending more requests or concurrent connections than Feishu permits, or because retries and blocking code in the OpenClaw runtime create bursts. Missing backoff, shared credentials across many agents, lack of queuing, or slow network calls inside the agent runtime amplify the problem.

 

Root causes and practical fixes

 
  • Exceeding Feishu rate limits: throttle at source; add per-app rate limiter.
  • Retry storms: implement exponential backoff with jitter and inspect 429 headers for Retry-After.
  • Agent/runtime bursts: move batching/queues outside agents (worker/service), keep agents short-lived.
  • Auth/credential misuse: avoid sharing tokens widely; rotate and cache tokens properly.
  • Network/timeouts: set sane HTTP timeouts, log responses, and monitor metrics.
Book a Free Consultation

Still stuck?
Copy this prompt into ChatGPT and get a clear, personalized explanation.

This prompt helps an AI assistant understand your setup and guide you through the fix step by step, without assuming technical knowledge.

AI AI Prompt


Recognized by the best

Trusted by 600+ businesses globally

From startups to enterprises and everything in between, see for yourself our incredible impact.

RapidDev was an exceptional project management organization and the best development collaborators I've had the pleasure of working with.

They do complex work on extremely fast timelines and effectively manage the testing and pre-launch process to deliver the best possible product. I'm extremely impressed with their execution ability.

Arkady
CPO, Praction
Working with Matt was comparable to having another co-founder on the team, but without the commitment or cost.

He has a strategic mindset and willing to change the scope of the project in real time based on the needs of the client. A true strategic thought partner!

Donald Muir
Co-Founder, Arc
RapidDev are 10/10, excellent communicators - the best I've ever encountered in the tech dev space.

They always go the extra mile, they genuinely care, they respond quickly, they're flexible, adaptable and their enthusiasm is amazing.

Mat Westergreen-Thorne
Co-CEO, Grantify
RapidDev is an excellent developer for custom-code solutions.

We’ve had great success since launching the platform in November 2023. In a few months, we’ve gained over 1,000 new active users. We’ve also secured several dozen bookings on the platform and seen about 70% new user month-over-month growth since the launch.

Emmanuel Brown
Co-Founder, Church Real Estate Marketplace
Matt’s dedication to executing our vision and his commitment to the project deadline were impressive. 

This was such a specific project, and Matt really delivered. We worked with a really fast turnaround, and he always delivered. The site was a perfect prop for us!

Samantha Fekete
Production Manager, Media Production Company
The pSEO strategy executed by RapidDev is clearly driving meaningful results.

Working with RapidDev has delivered measurable, year-over-year growth. Comparing the same period, clicks increased by 129%, impressions grew by 196%, and average position improved by 14.6%. Most importantly, qualified contact form submissions rose 350%, excluding spam.

Appreciation as well to Matt Graham for championing the collaboration!

Michael W. Hammond
Principal Owner, OCD Tech

We put the rapid in RapidDev

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.Â