一键导入
nyx-lark
Lark/Feishu integration via NyxID proxy. Replaces lark-cli — call Lark OpenAPI directly through nyxid proxy request with automatic credential injection.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Lark/Feishu integration via NyxID proxy. Replaces lark-cli — call Lark OpenAPI directly through nyxid proxy request with automatic credential injection.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
| name | nyx-lark |
| description | Lark/Feishu integration via NyxID proxy. Replaces lark-cli — call Lark OpenAPI directly through nyxid proxy request with automatic credential injection. |
| version | 1.0.0 |
| metadata | {"category":"plain","tag":["nyxid","lark","feishu","messaging","calendar","drive"],"requires":{"bins":["nyxid"]}} |
This skill replaces all 20 lark-cli skills. Instead of lark-cli <service> +<shortcut>, use nyxid proxy request <slug> <path>. NyxID handles tenant token exchange (bot) and OAuth token injection (user) automatically.
Two NyxID services for Lark, matching lark-cli's --as bot / --as user:
| Service | Identity | Auth Method | Base URL | Path Convention |
|---|---|---|---|---|
api-lark-bot | Bot (tenant_access_token) | Token exchange | https://open.larksuite.com | Paths start with /open-apis/ |
api-lark | User (user_access_token) | OAuth | https://open.larksuite.com/open-apis | Paths start with / (no /open-apis/ prefix) |
Same API, different service — the base URL already contains the prefix for user.
The key difference: api-lark-bot base URL ends at the domain, so you must include /open-apis/ in every path. api-lark base URL already includes /open-apis, so paths start directly with the API version segment.
# Bot: list chats — note the /open-apis/ prefix
nyxid proxy request api-lark-bot /open-apis/im/v1/chats
# User: list chats — no /open-apis/ prefix needed
nyxid proxy request api-lark /im/v1/chats
# Bot: send message — POST with JSON body
nyxid proxy request api-lark-bot "/open-apis/im/v1/messages?receive_id_type=chat_id" \
-m POST -d '{"receive_id":"oc_xxx","msg_type":"text","content":"{\"text\":\"hello\"}"}'
# User: get primary calendar
nyxid proxy request api-lark /calendar/v4/calendars/primary
If you accidentally double the prefix (e.g., api-lark /open-apis/im/v1/chats), the downstream URL becomes /open-apis/open-apis/... and returns 404.
Which service to use for each Lark API domain:
| Domain | Service | Reason |
|---|---|---|
| IM — bot messages, list chats | api-lark-bot | Org-level, bot identity |
| IM — send as user | api-lark | Needs user_access_token |
| Calendar — agenda, events, free/busy | api-lark | Personal calendar data |
| Contact — user lookup, search | api-lark-bot | User OAuth scope hard to obtain |
| Drive — upload, download, list files | api-lark-bot | drive scope only on bot |
| Doc — create, read, write documents | api-lark | docx scope available on user |
| Wiki — spaces, nodes | api-lark-bot | wiki scope only on bot |
| Task — CRUD, subtasks, tasklists | api-lark-bot | task scope only on bot |
| Sheets — read, write, append | api-lark-bot | sheets scope on bot |
| Base (Bitable) — tables, records | api-lark-bot | bitable scope on bot |
| Mail — send, reply, drafts | api-lark | Personal mailbox |
| Approval — instances, tasks | api-lark-bot | Org-level |
| VC / Minutes — meetings, transcripts | api-lark-bot | Org-level |
See references/identity.md for complete scope mapping.
nyxid service add api-lark-bot
# Prompted for JSON credential:
# app_id: your Lark app ID (e.g., cli_a940e30bf3b89eea)
# app_secret: your Lark app secret
# Get these from: https://open.larksuite.com/app → your app → Credentials
nyxid service add api-lark --oauth --scope "\
contact:user.base:readonly,\
calendar:calendar.event:read,calendar:calendar.event:create,\
calendar:calendar.event:update,calendar:calendar.free_busy:read,\
calendar:calendar:read,\
docx:document,docx:document:readonly,docx:document:create,\
im:chat:read,im:message,im:message.send_as_user,\
im:message:readonly,im:message.group_msg:get_as_user,\
sheets:spreadsheet:readonly,\
approval:task:read,approval:instance:read,\
drive:drive:readonly,wiki:wiki:readonly,\
task:task:read,task:task:write,\
mail:mailbox:readonly,bitable:bitable:readonly"
# Bot: should return a JSON object with data.items[] containing chat_id, name, etc.
nyxid proxy request api-lark-bot /open-apis/im/v1/chats
# User: should return a JSON object with data.calendar_list[] containing calendar_id, summary, etc.
nyxid proxy request api-lark /calendar/v4/calendars
If either returns a scope error, see Section 6 (Scope Troubleshooting).
These are the most common multi-step tasks. Follow in order.
# Step 1: Find their open_id (list all org users from root department)
nyxid proxy request api-lark-bot "/open-apis/contact/v3/users?user_id_type=open_id&department_id=0&page_size=50"
# → scan data.items[] for the target name, extract open_id (ou_xxx)
# Step 2: Send DM using open_id
nyxid proxy request api-lark-bot "/open-apis/im/v1/messages?receive_id_type=open_id" \
-m POST -d '{"receive_id":"ou_xxx","msg_type":"text","content":"{\"text\":\"hello\"}"}'
Do NOT use /contact/v3/users/me for "send to myself" — it fails on scope. Use the department list above and match by name.
# Step 1: Get primary calendar ID
nyxid proxy request api-lark /calendar/v4/calendars
# → find the primary calendar in data.calendar_list[], extract calendar_id
# Step 2: List today's events (replace timestamps — Unix seconds)
# Example: 2026-04-13 00:00 SGT = 1776182400, 23:59 = 1776268799
nyxid proxy request api-lark "/calendar/v4/calendars/CALENDAR_ID/events?start_time=1776182400&end_time=1776268799"
# Step 1: Find the chat_id
nyxid proxy request api-lark-bot /open-apis/im/v1/chats
# → scan data.items[] for the target group name, extract chat_id (oc_xxx)
# Step 2: Send message
nyxid proxy request api-lark-bot "/open-apis/im/v1/messages?receive_id_type=chat_id" \
-m POST -d '{"receive_id":"oc_xxx","msg_type":"text","content":"{\"text\":\"hello\"}"}'
The content field is double-encoded JSON — a JSON string containing JSON.
nyxid proxy request api-lark-bot "/open-apis/im/v1/messages?receive_id_type=open_id" \
-m POST -d '{"receive_id":"ou_xxx","msg_type":"post","content":"{\"zh_cn\":{\"title\":\"Title\",\"content\":[[{\"tag\":\"text\",\"text\":\"Body text\"}]]}}"}'
content double-encodingThe content field in message send is always a JSON string, not a JSON object:
"content": {"text": "hello"}"content": "{\"text\":\"hello\"}"This applies to all msg_types (text, post, image, file, interactive card).
Top 10 most common operations, showing lark-cli vs NyxID equivalent.
# lark-cli
lark-cli im +messages-send --as bot --chat-id oc_xxx --msg-type text --data '{"text":"hello"}'
# nyx
nyxid proxy request api-lark-bot "/open-apis/im/v1/messages?receive_id_type=chat_id" \
-m POST -d '{"receive_id":"oc_xxx","msg_type":"text","content":"{\"text\":\"hello\"}"}'
# lark-cli
lark-cli im +chat-search --as bot
# nyx
nyxid proxy request api-lark-bot /open-apis/im/v1/chats
# lark-cli
lark-cli calendar +agenda --as user
# nyx (replace CALENDAR_ID and timestamps)
nyxid proxy request api-lark "/calendar/v4/calendars/CALENDAR_ID/events?\
start_time=START_UNIX&end_time=END_UNIX"
nyxid proxy request api-lark "/calendar/v4/calendars/CALENDAR_ID/events" \
-m POST -d '{"summary":"Meeting","start_time":{"timestamp":"1718280000"},"end_time":{"timestamp":"1718283600"}}'
# lark-cli
lark-cli contact +get-user --as bot --user-id ou_xxx
# nyx
nyxid proxy request api-lark-bot /open-apis/contact/v3/users/ou_xxx
nyxid proxy request api-lark-bot /open-apis/drive/v1/files
nyxid proxy request api-lark /docx/v1/documents \
-m POST -d '{"title":"New Doc","folder_token":"fldcniHf40Vcv1"}'
nyxid proxy request api-lark-bot /open-apis/task/v2/tasks \
-m POST -d '{"summary":"My task"}'
nyxid proxy request api-lark "/im/v1/messages/search?query=keyword" \
-m POST -d '{"query":"search term"}'
nyxid proxy request api-lark "/calendar/v4/freebusy/list" \
-m POST -d '{"time_min":"1718280000","time_max":"1718366400","user_id":{"user_id":"ou_xxx","id_type":"open_id"}}'
# Lark error includes helps[].url — open it to add the scope
open "https://open.larksuite.com/app/cli_a940e30bf3b89eea/auth?q=im:chat:readonly&op_from=openapi"
# Bot scopes take effect immediately after adding
# 1. Delete all old OAuth credentials (they share a refresh token)
nyxid external-key list # find Lark OAuth entries
nyxid external-key delete <id> # delete each one
# 2. Re-add with correct scopes
nyxid service add api-lark --oauth --scope "new,scopes,here"
contact:contact.base:readonly vs contact:user.base:readonly). Always check the Lark API docs for the correct scope variant.Most Lark list endpoints return paginated results. The pattern is consistent across all APIs:
# First page
nyxid proxy request api-lark-bot /open-apis/im/v1/chats
# Response includes: "page_token": "xxx", "has_more": true
# Next page
nyxid proxy request api-lark-bot "/open-apis/im/v1/chats?page_token=xxx&page_size=50"
Default page size is 20. Maximum is typically 50 or 100 depending on the endpoint. Check the specific API reference for limits.
| File | Description |
|---|---|
references/identity.md | Complete bot vs user routing + scope mapping |
references/im.md | Messages, chats, threads, reactions |
references/calendar.md | Events, free/busy, RSVP, suggestions |
references/contact.md | User lookup, org structure |
references/drive.md | Files, folders, comments, permissions |
references/doc.md | Document CRUD, media upload |
references/wiki.md | Knowledge base spaces, nodes |
references/task.md | Tasks, subtasks, tasklists |
references/sheets.md | Spreadsheet cells, rows, filters |
references/base.md | Bitable tables, fields, records, views |
references/mail.md | Email send, reply, drafts, folders |
references/approval.md | Approval instances, tasks |
references/vc.md | Meetings, minutes, transcripts |