Get your dream built 10x faster

How to integrate Feishu Evolver Wrapper 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 Evolver Wrapper with OpenClaw

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.

 

High-level architecture

 
  • External service (your server): Hosts OAuth callbacks, stores tokens and user mapping in a durable store, validates webhooks from Feishu, and exposes an authenticated REST API that performs the Evolver actions.
  • OpenClaw skill: A thin declarative configuration and runtime integration that calls your external service’s REST API. The skill does not store tokens or run a public HTTP server; it invokes your API using credentials set in ClawHub / environment variables.
  • Persistence and queues: Place token storage, DB, retry queues, and long-running tasks outside the agent runtime (e.g., Postgres, Redis, job worker). The agent should be stateless.

 

Prerequisites

 
  • Feishu (Lark) application credentials: client_id, client_secret, redirect\_uri, and any required app verification keys for webhook validation.
  • Hosting + HTTPS: A public HTTPS endpoint for OAuth callback and webhooks (required by Feishu).
  • Persistent datastore: To store access/refresh tokens and installation mappings.
  • ClawHub access: Ability to register/configure the skill, provide environment variables/secrets, and set required API scopes for the skill to call your external API.

 

Design decisions to follow

 
  • Keep state outside the agent: Access tokens and refresh logic must live on your external service, not inside the agent’s ephemeral runtime.
  • Explicit authentication: Use OAuth flows and API keys. Install/configure credentials explicitly in ClawHub or the environment the agent uses.
  • Webhook security: Validate incoming events via HMAC or the verification mechanism Feishu provides; reject unverified events before processing.
  • API contract: Define and document a small REST API that the OpenClaw skill calls (e.g., POST /evolver/run with body { user\_id, input }).
  • Retry and idempotency: Implement idempotency keys for actions that may be retried by the agent or Feishu.

 

OAuth flow (conceptual) and token handling

 
  • Redirect user to Feishu authorization URL with your client_id and redirect_uri and requested scopes.
  • Feishu redirects back to your /oauth/callback with an authorization code.
  • Your server exchanges the code at Feishu’s token endpoint for an access_token and refresh_token, stores them in your DB associated with the user or tenant, and returns a confirmation page.
  • When the access_token expires, your server uses the refresh_token to obtain a new access\_token; the OpenClaw agent should call your service’s endpoints which handle refresh transparently.

 

Example: minimal Node.js OAuth + webhook service

 
<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}`));

 

Skill contract and manifest (vendor-neutral example)

 
  • Declare endpoints: The skill should declare a single action endpoint (e.g., POST /api/evolver/run) which the agent will call when the skill is invoked.
  • Declare auth type: In ClawHub, set the skill to use an API key or service credential that your external service expects (e.g., an OpenClaw-provided header or a static secret injected into environment variables available to the agent).
  • Scopes: Document which Feishu scopes are required (message.send, events.\*, etc.) so the OAuth flow requests them.

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"] }
    }
  }
}

 

What runs inside the agent vs externally

 
  • Agent runtime (inside OpenClaw): Lightweight orchestration code that calls your external service endpoint and returns responses to the user or next agent step. No long-lived sockets, no token storage.
  • External service: OAuth flows, token storage/refresh, webhook endpoints, retry logic, background workers, DBs, and any heavy processing (evolver transforms, model calls, rate-limiting).

 

Security and secrets

 
  • Secrets in ClawHub: Store the skill-to-service API key and any agent-level secrets in ClawHub’s secret store (or your secret manager). Don’t hardcode secrets in code or skill manifests.
  • Least privilege: Request only the Feishu scopes you need. If possible, use tenant-level (app) credentials instead of user-scoped tokens for background tasks.
  • Webhook validation: Always validate signatures and reject requests that don’t validate.
  • Rotate secrets: Implement token rotation and ability to update secrets from ClawHub or your CI/CD pipeline without downtime.

 

Testing and verification

 
  • Use a staging Feishu app and a staging instance of your service with a public URL (ngrok during dev is fine) to complete OAuth and webhook verification.
  • Verify that tokens are stored and refresh flows work by simulating expiry.
  • Call your /api/evolver/run endpoint directly with a test API key to confirm behavior before wiring it to the OpenClaw skill.
  • Install the skill in a test agent instance and verify the agent gets success/error responses and handles them predictably.

 

Debugging checklist when something breaks

 
  • Check logs: External service logs for OAuth exchanges, token refresh, webhook receipts, and errors. Agent logs for outgoing HTTP calls to your service and error responses.
  • Inspect HTTP responses: Capture headers, response bodies, and status codes from token endpoints, Evolver API, and your wrapper endpoints.
  • Confirm credentials/scopes: Ensure client_id/client_secret are correct, redirect\_uri matches, and the granted scopes include the ones your code expects.
  • Webhook validation: Confirm the signature algorithm and secret used by Feishu match your verification code; mismatched encodings (utf8 vs buffer) are a common failure point.
  • Confirm skill invocation: Ensure the OpenClaw skill is configured to call the correct URL, with the expected auth header or API key, and that network routing from the agent environment to your service is allowed.

 

Operational suggestions

 
  • Monitoring: Track 4xx/5xx rates for your wrapper and token exchange endpoints, and instrument latency for the Evolver calls.
  • Retry/backoff: Implement exponential backoff for transient errors and a dead-letter queue for events that fail repeatedly.
  • Idempotency: Use idempotency keys for operations that might be re-submitted by the agent.
  • Graceful degradation: Return clear error shapes so the agent can display a friendly message rather than failing silently.

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.

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 Evolver Wrapper and OpenClaw Integration

1

protobuf schema mismatch

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.

 

Diagnose and fix

 

Steps to resolve:

  • Compare .proto files (field numbers/types, reserved).
  • Use protoc --decode_raw on captured bytes to see unknown fields.
  • Regenerate client/server bindings and redeploy.
  • Keep changes wire-compatible: add fields with new numbers, avoid renaming types or changing scalar kinds.
#!/bin/sh
# Decode raw bytes for inspection
cat message.bin | protoc --decode_raw

2

authentication failures

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.

 

Debug checklist

 

  • Env & credentials: confirm API keys, client_id/secret, and secrets loaded into the agent runtime.
  • Token & scopes: check expiry, refresh tokens, and requested scopes match API requirements.
  • Requests: capture failing HTTP responses, headers (Authorization), and body for error codes.
  • Clock skew: ensure system time is correct.
  • Permissions: verify ClawHub skill permission mappings and runtime role grants.

3

register as ClawPlugin

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.

 

Checklist

 
  • Auth: env vars, OAuth tokens, service creds.
  • Deploy: install skills in ClawHub, grant permissions.
  • Runtime: run agents in OpenClaw, offload stateful services.
  • Debug: logs, HTTP responses, webhook signatures.

 

Example

 
// 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

webhook event routing

 

Webhook event routing

 

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.

  • Steps: validate signature → parse → route by event-type or path → enqueue/deliver to runtime → ack provider.
  • Best practices: store secrets in env vars, make handlers idempotent, move long/stateful work outside runtime, log full request/skill execution path for debugging.
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.Â