Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

WeChat iLink Typing Indicator API — undocumented but works #1553

btxro3han-code started this conversation in Show and tell
Discussion options

TL;DR

You can show the native "对方正在输入..." (typing indicator) in WeChat using the iLink bot API. This is undocumented but fully functional. We implemented it in our WeChat bot and it works great — much better than sending a temporary "thinking..." message.

The API

Step 1: Get a typing_ticket

POST {baseUrl}/ilink/bot/getconfig
Headers:
 Content-Type: application/json
 AuthorizationType: ilink_bot_token
 Authorization: Bearer {bot_token}
 X-WECHAT-UIN: {base64(randomUint32())}
Body:
{
 "ilink_user_id": "{user_id}", // ⚠️ REQUIRED — omitting this returns ret:-2
 "base_info": { "channel_version": "2.0.1" }
}
Response:
{
 "ret": 0,
 "typing_ticket": "AARTBK8FAAAB..."
}

The ticket can be cached for ~20 hours.

Step 2: Send/cancel typing status

POST {baseUrl}/ilink/bot/sendtyping
Body:
{
 "ilink_user_id": "{user_id}", // ⚠️ REQUIRED here too
 "to_user_id": "{user_id}",
 "typing_ticket": "{ticket}",
 "command": 1, // 1 = show typing, 2 = cancel
 "base_info": { "channel_version": "2.0.1" }
}
Response:
{ "ret": 0 }

Key Gotcha

Both getconfig and sendtyping require the ilink_user_id field. Without it you get {"ret":-2,"errmsg":"ilink_user_id required"}. This is not documented anywhere we could find — we discovered it by trial and error.

TypeScript Implementation

// Typing ticket cache
let typingTicket: string | null = null;
let typingTicketExpiry = 0;
async function ensureTypingTicket(
 baseUrl: string, token: string, userId: string
): Promise<string | null> {
 if (typingTicket && Date.now() < typingTicketExpiry) return typingTicket;
 const res = await fetch(`${baseUrl}/ilink/bot/getconfig`, {
 method: 'POST',
 headers: buildIlinkHeaders(token),
 body: JSON.stringify({
 ilink_user_id: userId,
 base_info: { channel_version: '2.0.1' },
 }),
 });
 const data = await res.json();
 if (data.typing_ticket) {
 typingTicket = data.typing_ticket;
 typingTicketExpiry = Date.now() + 20 * 3600_000;
 return typingTicket;
 }
 return null;
}
async function sendTyping(
 baseUrl: string, token: string, userId: string, command: 1 | 2 = 1
) {
 const ticket = await ensureTypingTicket(baseUrl, token, userId);
 if (!ticket) return;
 await fetch(`${baseUrl}/ilink/bot/sendtyping`, {
 method: 'POST',
 headers: buildIlinkHeaders(token),
 body: JSON.stringify({
 ilink_user_id: userId,
 to_user_id: userId,
 typing_ticket: ticket,
 command,
 base_info: { channel_version: '2.0.1' },
 }),
 });
}

Usage Pattern

// When a message arrives:
await sendTyping(baseUrl, token, userId, 1); // Show typing
// Process with AI...
const response = await queryAI(message);
await sendTyping(baseUrl, token, userId, 2); // Cancel typing
await sendMessage(baseUrl, token, userId, response);

Why This Matters

Most WeChat bots either:

  • Show no feedback while processing (user wonders if bot is alive)
  • Send a temporary "thinking..." message (creates noise in chat history)

The native typing indicator solves both — user sees the bot is working, no extra messages.

Hope this helps anyone building WeChat bots with iLink! 🎉

You must be logged in to vote

Replies: 0 comments

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
1 participant

AltStyle によって変換されたページ (->オリジナル) /