agentsclimarketplace

Hermes feishu gateway

Skill TyrantLucifer/awesome-skills/skills/hermes-feishu-gateway

Operate and troubleshoot Hermes via Feishu (Lark): group authorization, pairing/allowlists, Gateway restarts, markdown rendering, and lark-cli setup.From its SKILL.md

Install
npx -y skills add TyrantLucifer/awesome-skills --skill hermes-feishu-gateway

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • 14 days oldThe repository was created 14 days ago. New is not bad, but a brand new repository carrying a familiar-sounding name is the shape a typosquat arrives in, and there has been no time for anyone else to find a problem with it.
  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

11.3 KB, ~2.7k tokens by cl100k_base, as published. Nobody here has run it

Hermes Feishu Gateway

How to operate Hermes effectively through the Feishu (Lark) messaging platform. Covers message formatting behavior, lark-cli integration, and known pitfalls.

Message Formatting (Critical)

How Feishu Outbound Messages Are Rendered

The Feishu adapter (plugins/platforms/feishu/adapter.py) has a three-way dispatch in _build_outbound_payload:

  1. Markdown table detected (_MARKDOWN_TABLE_RE) → ENTIRE message sent as plain text (no markdown at all)
  2. Markdown hints detected (_MARKDOWN_HINT_RE) → sent as post type with md tag elements (renders headings, bold, italic, code blocks, links, blockquotes)
  3. Neither → sent as plain text

⚠️ PITFALL: A single markdown table causes the ENTIRE message to degrade to plain text. All bold, headings, code blocks, links — everything loses formatting. This is because Feishu's post-type md elements cannot render tables.

What Renders in Post Mode (md tag)

FeatureRenders?
# Headings
**bold**
*italic*
`inline code`
```code blocks```✅ (isolated as separate fenced segments)
[links](url)
> blockquotes
--- horizontal rules
~~strikethrough~~
<u>underline</u>
| tables |❌ (triggers plain-text fallback for the whole message)

Workarounds for Tables

When you need to present tabular data in Feishu:

  • Use aligned plain text instead of markdown tables
  • Use bullet lists with key-value pairs
  • Split the message: send the table as a separate plain-text message, and the rest as markdown
  • Use Feishu interactive cards (msg_type=interactive) for structured layouts — the adapter supports this for exec approval prompts

Configuration

  • display.final_response_markdown controls CLI display only (render | strip | raw), NOT gateway output
  • Changing it to keep preserves markdown in CLI; does not affect Feishu rendering
  • The Feishu adapter decides format purely based on content pattern matching

Feishu CLI (lark-cli) Setup

Installation

# Install globally (use user prefix if no root access)
npm install -g @larksuite/cli --prefix ~/.local

# Install the CLI skills
npx -y skills add https://open.feishu.cn --skill -y

App Binding

Inside Hermes, lark-cli config init --new is blocked (prevents parallel app creation). Use:

# Bind to existing Hermes Feishu app
lark-cli config bind --source hermes --identity bot-only

# Or force a separate app (for more permissions)
lark-cli config init --new --force-init

--force-init gives a browser link for app selection. The CLI waits for completion — set adequate timeout (120s+).

User Identity Login

Bot identity can't access personal resources (calendar, mail, drive). Login as user:

lark-cli auth login --domain calendar    # calendar access
lark-cli auth login --domain im          # messaging access
lark-cli auth login                      # all domains

This also gives a browser link for OAuth authorization.

Permission Errors

When you get app_scope_not_applied errors, the error message includes:

  • console_url — direct link to the Feishu developer console with the required scopes pre-filled
  • missing_scopes — exact scope names needed

Share the console_url with the user so they can add scopes in the developer console.

Task & Calendar Queries

# Today's agenda (default)
lark-cli calendar +agenda --format pretty

# Custom date range
lark-cli calendar +agenda --start 2026-06-22 --end 2026-06-28 --format pretty

# My tasks
lark-cli task +get-my-tasks --format pretty

Note: Tasks may accumulate massively over time (200+). When summarizing, filter by date range and prioritize by deadline.

Feishu Document Creation via lark-cli

Create Feishu docs from local markdown files using lark-cli docs +create:

# Write content to local file first (avoids shell escaping issues)
# Then create doc from file
lark-cli docs +create --doc-format markdown --title "文档标题" --content @path/to/content.md

Update existing docs with lark-cli docs +update:

lark-cli docs +update --doc D0BBdowH7oJwU5xcGM2lwwcogzh --doc-format markdown --command overwrite --content @content.md

Key flags:

  • --doc (not --token) — document URL or token
  • --command overwrite — replaces entire document content
  • --command append — appends to end
  • --content @file.md — read from local file (relative path only, not absolute)
  • --doc-format markdown — use markdown format

Pitfall: @file only accepts relative paths from cwd. Write files in the working directory, not /tmp/. Absolute paths like @/tmp/file.md fail with unsafe file path.

Session Architecture

  • Session key format: agent:main:feishu:dm:{chat_id}
  • Same Feishu DM window = same session (persists across days until /new or /reset)
  • Session ID contains date timestamp but is NOT a routing mechanism
  • Different platforms (feishu/weixin/cli) have independent sessions
  • Gateway caches AIAgent instances per session_key for prompt caching

Group Authorization Troubleshooting

When the bot responds to the owner but silently ignores newly added group members, check authorization before investigating Feishu event subscriptions or mention parsing.

  • Unauthorized user: ou_xxx ... on feishu proves the event reached Hermes and was rejected by Gateway authorization.
  • FEISHU_GROUP_POLICY=open alone is insufficient: Gateway still requires pairing, FEISHU_ALLOWED_USERS, or explicit FEISHU_ALLOW_ALL_USERS=true.
  • Unauthorized group messages are silently dropped; pairing prompts are offered only in DMs.
  • Prefer per-user DM pairing or a fixed allowlist. Enabling FEISHU_ALLOW_ALL_USERS=true is platform-wide and can also expose DMs, not just the current group.
  • A config-file change is not active until the running Gateway reloads or restarts. Never report it as effective before that boundary.

For the complete diagnostic flow, safe repair options, restart constraints, and verification checklist, read references/feishu-group-authorization.md.

Cron Delivery from Feishu Topic Threads

A cron job created inside a Feishu topic may run successfully and create its document, yet fail delivery with:

[99992402] field validation failed

Diagnosis: inspect ~/.hermes/cron/output/<job_id>/ first. If the output contains the final document URL, generation succeeded and only message delivery failed. Then inspect ~/.hermes/cron/jobs.json: an origin containing thread_id: omt_... is the important signal.

Root cause in the affected adapter path: cron knows the Feishu thread_id but has no reply_to_message_id. The adapter's create fallback uses the topic ID as receive_id with receive_id_type=thread_id; Feishu rejects that request with code 99992402. A real in-topic reply requires an om_... message anchor and reply_in_thread=true.

Verified workaround: deliver scheduled results to the bare group chat instead of origin or an explicit topic target:

feishu:oc_<chat_id>

This posts to the group's main conversation. Verify both layers:

hermes send --json --to 'feishu:oc_<chat_id>' 'delivery test'

Then run a tiny one-shot no_agent cron job to the same bare target and confirm the log contains:

delivered to feishu:oc_<chat_id>

Do not claim the cron path is fixed based only on hermes send; direct send and cron delivery are separate verification boundaries. The old last_delivery_error remains in job state until the next successful full run, even after the target is updated.

Cron-generated document permissions

A Feishu user who creates a Hermes cron job does not automatically become the lark-cli document creator. lark-cli user OAuth is machine/profile scoped, so all jobs may create documents under one configured user. Posting that private link to a group does not grant access.

For document-producing group jobs, close permissions after every docs +create: dynamically list current human group members, grant each open_id the requested Drive permission in batches, validate the complete success ledger, and only then deliver the link. A small cron script can inject this policy into existing long prompts; cron script paths must be relative to ~/.hermes/scripts/.

Do not use bot document fetch as proof that openchat sharing works for human members: application identity may not inherit chat collaborator access. See references/feishu-cron-document-sharing.md for the full workflow, commands, verification criteria, and scaling options.

Upgrade regression: Feishu WebSocket fails with extra_ua_tags

Symptom after a Hermes upgrade:

[Feishu] Failed to connect: Client.__init__() got an unexpected keyword argument 'extra_ua_tags'

Cause: current Hermes constructs lark_oapi.ws.Client(..., extra_ua_tags=["channel"]), which requires the lazy dependency pin declared in tools/lazy_deps.py (lark-oapi==1.6.8 as of Hermes 0.19.0). The code can update while an older SDK such as 1.5.3 remains installed if hermes update logs platform.feishu failed to refresh: pip not available and ensurepip failed.

Diagnosis:

hermes gateway status
$HERMES_HOME/hermes-agent/venv/bin/python - <<'PY'
import inspect
from importlib.metadata import version
from lark_oapi.ws import Client
print(version("lark-oapi"))
print(inspect.signature(Client.__init__))
PY

Repair on Debian-style venvs that have no in-venv pip/ensurepip, but do have system pip with --python support:

cd "$HERMES_HOME/hermes-agent"
/usr/bin/pip --python venv/bin/python install --upgrade 'lark-oapi==1.6.8' 'qrcode==7.4.2'
# Prevent future lazy-backend refreshes from failing on the same venv:
/usr/bin/pip --python venv/bin/python install --upgrade pip
hermes gateway restart

Verify all boundaries:

  1. Client.__init__ contains extra_ua_tags.
  2. Gateway journal contains [Lark] ... connected to wss://msg-frontier.feishu.cn/... and no new extra_ua_tags exception.
  3. hermes send --json --to 'feishu:oc_<chat_id>' 'channel recovery test' returns success: true and a real om_... message ID.

Do not re-enter app credentials for this failure: configuration is already loaded; the SDK/API mismatch prevents WebSocket construction before authentication.

Common Pitfalls

  • npm install -g without --prefix ~/.local → EACCES on shared servers
  • config init --new blocked inside Hermes → use --force-init for separate app
  • Gateway cannot restart itself from a terminal/tool subprocess in its own cgroup. Ask the user to run hermes gateway restart from an independent server shell, or have an authorized user send /restart in chat; do not try to bypass the self-restart guard.
  • auth login --domain <domain> needs long timeout → use background + notify_on_complete
  • Tasks may accumulate massively (200+) → filter by date when summarizing

What ships with it: 2 files

7.4 KB alongside SKILL.md

Keep looking

Skills are one crate of 326,852. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.