pin_message
Pin or unpin a message in a chat to control message visibility. Use this to emphasize important announcements or reduce clutter.
Instructions
[Official API] Pin or unpin a message in a chat.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| message_id | Yes | Message ID | |
| pinned | No | true to pin, false to unpin |
Implementation Reference
- src/tools/messaging-bot.js:68-79 (schema)Input schema definition for the pin_message tool. Specifies message_id (required) and pinned (optional boolean, defaults true).
{ name: 'pin_message', description: '[Official API] Pin or unpin a message in a chat.', inputSchema: { type: 'object', properties: { message_id: { type: 'string', description: 'Message ID' }, pinned: { type: 'boolean', description: 'true to pin, false to unpin', default: true }, }, required: ['message_id'], }, }, - src/tools/messaging-bot.js:139-141 (handler)Handler function that executes the pin_message tool logic. Calls ctx.getOfficialClient().pinMessage() with message_id and pinned flag.
async pin_message(args, ctx) { return json(await ctx.getOfficialClient().pinMessage(args.message_id, args.pinned !== false)); }, - src/server.js:47-47 (registration)Tool modules registered in server.js. messaging-bot.js is loaded as one of the tool modules; its schemas and handlers are aggregated into TOOLS and HANDLERS.
require('./tools/messaging-bot'), - src/clients/official/im.js:213-230 (helper)Official API client method pinMessage that calls Feishu SDK im.pin.create (to pin) or im.pin.delete (to unpin). Handles both operations.
async pinMessage(messageId, pinned = true) { if (pinned) { const res = await this._safeSDKCall( () => this.client.im.pin.create({ data: { message_id: messageId } }), 'pinMessage' ); return { pin: res.data.pin }; } // Feishu unpin is DELETE /pins/{message_id} — path param only, no body. // SDK's pin.delete expects `path: {message_id}`. Sending `data: {message_id}` // (the previous shape) yielded a 400 with "message_id is required" because // the message_id never made it onto the URL. await this._safeSDKCall( () => this.client.im.pin.delete({ path: { message_id: messageId } }), 'unpinMessage' ); return { unpinned: true }; }, - src/tools/_registry.js:1-32 (helper)Response helper functions used by the pin_message handler. 'json' serializes the result to JSON text, 'text' wraps a plain string response.
// src/tools/_registry.js — shared infrastructure for tool modules. // // Every src/tools/<domain>.js exports: // { schemas: [<MCP tool schema objects>], handlers: { [name]: async (args, ctx) => MCPResponse } } // // The ctx object that handlers receive is built in src/server.js (or, during // the v1.3.7 phase A migration, temporarily in src/index.js) and provides: // - getUserClient(): Promise<LarkUserClient> // - getOfficialClient(): LarkOfficialClient // - getEventBuffer(): EventBuffer | null — null when WS isn't running // - resolveDocId(x): Promise<string> — wiki-node / URL → native token // - listProfiles(): string[] — names from LARK_PROFILES_JSON + 'default' // - getActiveProfile():string // - setActiveProfile(name): void — invalidates cached clients // // Response builders below are imported directly by each tool module — they're // not on ctx because they're pure functions with no state. const text = (s) => ({ content: [{ type: 'text', text: s }] }); // `json` will lift any `fallbackWarning` field to the top of the rendered // response so users see the warning before the structured payload. Preserved // from index.js v1.3.5 behaviour. const json = (o) => { const warn = o && typeof o === 'object' && o.fallbackWarning ? `${o.fallbackWarning}\n\n` : ''; return text(warn + JSON.stringify(o, null, 2)); }; const sendResult = (r, desc) => text(r.success ? desc : `Send failed (status: ${r.status})`); module.exports = { text, json, sendResult };