
Openclaw Feishu Group Chat
- 1 installs
- 5 repo stars
- Updated March 8, 2026
- 4ier/feishu-group
openclaw-feishu-group-chat is a Claude Code skill that teaches an OpenClaw agent to participate correctly in Feishu (Lark) group chats and DMs.
About
openclaw-feishu-group-chat teaches an OpenClaw agent how to participate in Feishu (Lark) group chats and direct messages. It syncs an org's Feishu contacts into USER.md so the agent can identify senders by name, and defines rules for group etiquette, DM privacy, and Feishu-specific message formatting. A developer uses it when connecting an OpenClaw agent to Feishu.
- Configures an OpenClaw agent to behave well in Feishu (Lark) group chats
- Bundles a Python script that syncs Feishu contacts into USER.md
- Covers group etiquette, DM privacy isolation, and Feishu message formatting
Openclaw Feishu Group Chat by the numbers
- 1 all-time installs (skills.sh)
- Ranked #14,102 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Jul 28, 2026 (Skillselion catalog sync)
openclaw-feishu-group-chat capabilities & compatibility
Free skill; requires a Feishu app with API credentials.
- Capabilities
- contact sync · chat integration · agent persona config
- Works with
- teams
- Use cases
- orchestration
- Runs
- Runs locally
- Pricing
- Bring your own API key
- Requires keys
- FEISHUAPPID · FEISHUAPPSECRET
What openclaw-feishu-group-chat says it does
Feishu group messages include sender names in metadata. DMs don't — they only include an opaque `open_id`.
Feishu does NOT render Markdown well. Follow these rules:
Never assume a DM is from your "primary human" — anyone can message you
npx skills add https://github.com/4ier/feishu-group --skill openclaw-feishu-group-chatAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 1 |
|---|---|
| repo stars | ★ 5 |
| Last updated | March 8, 2026 |
| Repository | 4ier/feishu-group ↗ |
What it does
Wire an OpenClaw agent into Feishu group chats so it identifies senders, respects multi-user privacy, and formats messages for the platform.
Who is it for?
OpenClaw agents deployed into Feishu/Lark workspaces that need to recognize senders and behave differently in groups vs DMs.
Skip if: Chat platforms other than Feishu/Lark, or agents not built on OpenClaw.
When should I use this skill?
Connecting an OpenClaw agent to Feishu and you want it to be a competent group participant.
What you get
The agent identifies each Feishu sender by name, keeps per-user conversations isolated, and formats messages the way Feishu renders.
- open_id-to-name contacts table in USER.md
- group-chat etiquette rules for AGENTS.md or SOUL.md
- multi-user privacy and formatting rules
By the numbers
- 6-section skill (contacts, etiquette, DM behavior, formatting, privacy, sender ID)
- weekly crontab auto-sync example (0 7 * * 1)
Files
OpenClaw Feishu Group Chat
Everything your OpenClaw agent needs to be a good Feishu group chat participant.
1. Know who you're talking to
Feishu group messages include sender names in metadata. DMs don't — they only include an opaque open_id. Without setup, your agent will assume all DMs come from one person.
Fix: Embed an open_id → name lookup table in USER.md. Since workspace files are injected into the system prompt, the agent matches senders instantly — no tool calls.
Run the bundled sync script to pull your org's contacts:
python3 scripts/sync_feishu_contacts.py <openclaw_config> <feishu_account> <user_md_path>This populates a table in USER.md:
## 飞书通讯录 (App Name)
飞书 DM 不携带发送者姓名。用 inbound metadata 的 chat_id(格式 `user:ou_xxx`)匹配下表识别发送者。
| 姓名 | open_id |
|------|---------|
| Alice | ou_abc123 |
| Bob | ou_def456 |Important: Feishu open_id is per-app. Multiple OpenClaw instances using different Feishu apps must each pull contacts with their own credentials.
After updating USER.md, restart the gateway. Workspace files are cached at startup; /new alone won't pick up changes.
Set up weekly auto-sync via crontab:
0 7 * * 1 python3 /path/to/scripts/sync_feishu_contacts.py ~/.openclaw/openclaw.json my_app ~/workspace/USER.md2. Group chat etiquette
Add to AGENTS.md or SOUL.md:
When to respond:
- Directly @mentioned
- Can add real value to the conversation
- Something witty or relevant fits naturally
When to stay silent:
- Casual banter you have nothing to add to
- Someone already answered well
- "Yeah" / "Nice" / emoji-only territory
General rules:
- Don't dominate the conversation — participate, don't monologue
- One reaction per message max
- Keep replies concise — respect the group's attention
3. DM behavior
- Always address the sender by their actual name (look up from the contacts table)
- Never assume a DM is from your "primary human" — anyone can message you
- Keep conversations isolated — never leak what person A said to person B
- Be more thorough in DMs than in groups (the person came to you specifically)
4. Platform formatting
Feishu does NOT render Markdown well. Follow these rules:
- No markdown: No
**bold**,# headers, or[links](url)in messages - No tables: Use simple lists with dashes instead
- Plain text only: Use line breaks and spacing for structure
- Code blocks: Feishu does support ``
code blocks`` — use sparingly
5. Multi-user privacy
Add to SOUL.md or AGENTS.md:
- Different users' conversation contents are isolated from each other
- Don't reveal what A discussed with you to B, even if B is the admin
- Each person's DM is a private space
- In group chats, don't share anyone's private information
6. Sender identification (AGENTS.md snippet)
Add this to your startup sequence:
识别消息发送者:飞书 DM 不携带发送者姓名,只有 open_id(inbound metadata 的 chat_id 格式 user:ou_xxx)。
提取 open_id,在 USER.md 的飞书通讯录表格中匹配找到姓名。
不要假设 DM 对方就是主人——任何人都可能给你发私聊。
群聊消息自带 Sender metadata 可直接使用。Privacy
- Only names and open_ids are stored (no emails, phones, or PII)
- open_id is opaque, meaningful only within your Feishu app
- App credentials are read at runtime from openclaw.json, never stored in skill files
#!/usr/bin/env python3
"""
Sync Feishu contacts into USER.md.
Pulls the full user list from Feishu contacts API using app credentials
from openclaw.json, then updates the contacts table in USER.md.
Usage:
python3 sync_feishu_contacts.py <openclaw_config> <account_name> <user_md_path>
Example:
python3 sync_feishu_contacts.py ~/.openclaw/openclaw.json fourier ~/workspace/USER.md
"""
import json, os, sys, urllib.request, re
def main():
if len(sys.argv) != 4:
print(f"Usage: {sys.argv[0]} <config_path> <app_name> <user_md_path>")
sys.exit(1)
config_path = os.path.expanduser(sys.argv[1])
app_name = sys.argv[2]
user_md_path = os.path.expanduser(sys.argv[3])
# 1. Read config and get app credentials
with open(config_path) as f:
cfg = json.load(f)
try:
acct = cfg["channels"]["feishu"]["accounts"][app_name]
except KeyError:
print(f"Error: account '{app_name}' not found in {config_path}")
print(f"Available accounts: {list(cfg.get('channels', {}).get('feishu', {}).get('accounts', {}).keys())}")
sys.exit(1)
# 2. Get tenant access token
req = urllib.request.Request(
"https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal",
data=json.dumps({
"app_id": acct["appId"],
"app_secret": acct["appSecret"]
}).encode(),
headers={"Content-Type": "application/json"}
)
resp = json.loads(urllib.request.urlopen(req).read())
if resp.get("code", 0) != 0:
print(f"Error getting token: {resp.get('msg', 'unknown error')}")
sys.exit(1)
token = resp["tenant_access_token"]
# 3. Fetch all users (paginated)
users = []
page_token = None
while True:
url = "https://open.feishu.cn/open-apis/contact/v3/users/find_by_department?department_id=0&page_size=50"
if page_token:
url += f"&page_token={page_token}"
req = urllib.request.Request(url, headers={
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
})
data = json.loads(urllib.request.urlopen(req).read()).get("data", {})
for u in data.get("items", []):
name = u.get("name", "")
open_id = u.get("open_id", "")
if name and open_id:
users.append({"name": name, "open_id": open_id})
if not data.get("has_more"):
break
page_token = data.get("page_token")
if not users:
print("Warning: no users found. Check app permissions (need contact:user.base:readonly).")
sys.exit(1)
# 4. Update USER.md contacts table
TABLE_HEADER = "| 姓名 | open_id |\n|------|---------|"
table_rows = "\n".join(f"| {u['name']} | {u['open_id']} |" for u in users)
with open(user_md_path, "r") as f:
content = f.read()
# Match: ## 飞书通讯录 ... header line ... description line ... | table |
pattern = r"(## 飞书通讯录[^\n]*\n[^\n]*\n)\| 姓名 \| open_id \|\n\|[-| ]*\n((\|[^\n]*\n)*)"
new_table = f"\\1{TABLE_HEADER}\n{table_rows}\n"
new_content = re.sub(pattern, new_table, content)
if new_content == content:
# Check if the section exists at all
if "## 飞书通讯录" not in content:
print(f"Error: USER.md has no '## 飞书通讯录' section. Add it first:")
print(f" ## 飞书通讯录 ({app_name} App)")
print(f" 飞书 DM 不携带发送者姓名。用 inbound metadata 的 chat_id(格式 `user:ou_xxx`)匹配下表识别发送者。")
print(f" | 姓名 | open_id |")
print(f" |------|---------|")
sys.exit(1)
print(f"OK: {len(users)} users (USER.md unchanged)")
else:
with open(user_md_path, "w") as f:
f.write(new_content)
print(f"OK: {len(users)} users → USER.md updated")
if __name__ == "__main__":
main()
Related skills
FAQ
Why does my agent think every Feishu DM is from the same person?
Feishu DMs only include an opaque open_id, not a sender name. This skill embeds an open_id-to-name lookup table in USER.md so the agent can match senders.
Does Feishu render Markdown in agent messages?
No. The skill states Feishu does not render Markdown well, so messages should avoid bold, headers, links, and tables and use plain text with line breaks.