feat(im): support generating AppLinks to open chat directly to thread / thread sidepanel (im +applink & thread_app_link)
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 17.3k
- Forks
- 1.4k
- Avg merge
- 2d 4h
- Merged PRs (30d)
- 105
Description
Problem Statement / Background
In Feishu / Lark, discussions in group chats and direct messages (P2P) frequently happen in threads (reply in thread / 话题回复). In the desktop and mobile clients, threads in standard chats (chat_mode: normal / group / p2p) open in a sidepanel (右侧边栏) alongside the chat stream, while topic chats (chat_mode: topic) open the thread in a dedicated view.
When AI agents or automated workflows interact with Lark/Feishu using lark-cli, a critical need is generating a clickable AppLink that directs the user:
- Directly to a specific thread in a chat (opening the thread in the chat sidepanel or scrolling to it).
- Directly to a joined chat at a specific message or thread anchor.
Currently, lark-cli has several limitations in this regard:
- No Standalone AppLink Generation Command / Shortcut:
- There is no command like
lark-cli im +applinkto generate/assemble AppLinks on demand from knownchat_id,thread_id, andmessage_id. - AppLinks are only generated as incidental read fields (
chat_app_link,message_app_link) during query commands (+chat-list,+chat-messages-list, etc.).
- There is no command like
- Missing
thread_app_linkin Thread Operations:lark-cli im +threads-messages-list --thread <om_xxx>returns{ "thread_id": "...", "messages": [...] }without a top-levelthread_app_linkfor the thread container itself.lark-cli im +messages-reply --reply-in-threadreturns only{ "message_id": "...", "chat_id": "...", "create_time": "..." }, omittingthread_id,message_app_link, andthread_app_link.
- Fragile Thread AppLink Assembly (
assembleMessageAppLink):- In
shortcuts/im/convert_lib/content_convert.go:if threadID != "" && chatID != "" && okThreadPos { // Generates https://<domain>/client/thread/open?openthreadid=...&openchatid=... }thread_message_positionis strictly required for/client/thread/open. If position metadata is missing (common across various OpenAPI payloads or when only thread root is known), it falls back to chat or returns nothing.
- In
- No Direct Support for Sidepanel Navigation in Group/Private Chats:
/client/thread/openis designed for topic-group streams. In normal group chats and P2P chats, users expect threads to open in the sidepanel (/client/chat/openwith thread/message focus or position) rather than a separate topic window.
Proposed Solution & CLI Design
1. New Shortcut: lark-cli im +applink
Provide a dedicated shortcut to compute/assemble AppLinks deterministically (offline or lightweight):
# Generate link to chat
lark-cli im +applink --chat-id oc_xxx
# Generate link to thread (with sidepanel & topic link variants)
lark-cli im +applink --chat-id oc_xxx --thread-id om_xxx
# Generate link directly from a message ID (optionally resolves container via API if needed)
lark-cli im +applink --message-id om_xxx
Output payload:
{
"chat_app_link": "https://applink.feishu.cn/client/chat/open?openChatId=oc_xxx",
"thread_app_link": "https://applink.feishu.cn/client/thread/open?openthreadid=om_xxx&openchatid=oc_xxx&open_thread_id=om_xxx&open_chat_id=oc_xxx",
"sidepanel_app_link": "https://applink.feishu.cn/client/chat/open?openChatId=oc_xxx&position=12",
"message_app_link": "https://applink.feishu.cn/client/chat/open?openChatId=oc_xxx&position=12"
}
2. Enrich +threads-messages-list and +messages-reply
im +threads-messages-list: addthread_app_linkat the root of the output envelope.im +messages-reply: when replying (especially--reply-in-thread), includethread_app_linkandmessage_app_linkin the output so the caller immediately receives a clickable link to share with users.
3. Make assembleThreadAppLink resilient
- Remove the strict
okThreadPosprerequisite: ifthreadIDandchatIDare present, assemble/client/thread/openeven withoutthread_message_position. - When available, also provide the chat-level navigation AppLink pointing to the root message position.
Compatibility
- Fully backward-compatible: existing fields and envelopes remain unchanged.
- Multi-brand: respects
core.ResolveEndpoints(brand).AppLink(applink.feishu.cnfor Feishu,applink.larksuite.comfor Lark).
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with shortcuts/im/convert_lib/content_convert.go, especially assembleMessageAppLink and the thread-position handling described in the issue. Then trace the existing IM shortcuts for +threads-messages-list and +messages-reply to understand their output envelopes. Done means +applink and the enriched thread/reply outputs provide the requested links while preserving existing fields and endpoint resolution.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- cli
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100