botmsg 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/config/loader.ts","../src/config/schema.ts","../src/errors.ts","../src/logger.ts","../src/platforms/dingtalk.ts","../src/platforms/base.ts","../src/platforms/wecom.ts","../src/platforms/feishu.ts","../src/platforms/lark.ts","../src/platforms/slack.ts","../src/platforms/discord.ts","../src/platforms/telegram.ts","../src/platforms/registry.ts","../src/queue/rate-limiter.ts","../src/audit/logger.ts","../src/templates/engine.ts","../src/tools/send-message.ts","../src/tools/send-file.ts","../src/tools/send-broadcast.ts","../src/tools/send-batch.ts","../src/tools/list-bots.ts","../src/tools/message-status.ts","../src/tools/render-template.ts","../src/tools/index.ts"],"sourcesContent":["/**\n * botmsg - MCP Server for multi-platform bot messaging\n *\n * Entry point: sets up MCP server, loads config, registers tools\n * Transport: stdio (compatible with Claude Desktop, VS Code, Cursor, etc.)\n */\n\nimport { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n} from \"@modelcontextprotocol/sdk/types.js\";\n\nimport { loadConfig } from \"./config/loader.js\";\nimport { PlatformRegistry } from \"./platforms/registry.js\";\nimport { RateLimiterManager } from \"./queue/rate-limiter.js\";\nimport { AuditLogger } from \"./audit/logger.js\";\nimport { toolDefinitions, createToolHandlers } from \"./tools/index.js\";\nimport { logger } from \"./logger.js\";\nimport { BotMsgError } from \"./errors.js\";\n\nconst VERSION = \"0.1.0\";\n\nasync function main(): Promise<void> {\n // ── Load configuration ──────────────────────────────────────────\n logger.info(\"botmsg starting...\", { version: VERSION });\n\n const config = loadConfig();\n logger.setLevel(config.settings.log_level);\n\n if (Object.keys(config.bots).length === 0) {\n logger.warn(\"No bots configured. Use env vars or a config file. See README for details.\");\n }\n\n // ── Initialize modules ──────────────────────────────────────────\n const registry = new PlatformRegistry();\n registry.loadConfig(config);\n\n const rateLimiter = new RateLimiterManager({\n maxRetries: config.settings.max_retries,\n });\n\n const auditLogger = new AuditLogger({\n filePath: config.settings.audit_log,\n });\n\n const dryRun = config.settings.dry_run;\n if (dryRun) {\n logger.info(\"DRY RUN mode enabled - no messages will be sent\");\n }\n\n // ── Create tool handlers ────────────────────────────────────────\n const handlers = createToolHandlers(registry, rateLimiter, auditLogger, dryRun);\n\n // ── Set up MCP server ───────────────────────────────────────────\n const server = new Server(\n { name: \"botmsg\", version: VERSION },\n { capabilities: { tools: {} } },\n );\n\n // List available tools\n server.setRequestHandler(ListToolsRequestSchema, async () => ({\n tools: toolDefinitions.map((td) => ({\n name: td.name,\n description: td.description,\n inputSchema: td.inputSchema,\n })),\n }));\n\n // Handle tool calls\n server.setRequestHandler(CallToolRequestSchema, async (request) => {\n const { name, arguments: args } = request.params;\n const startTime = Date.now();\n\n try {\n logger.debug(`Tool call: ${name}`, { args: JSON.stringify(args).slice(0, 200) });\n\n const handler = (handlers as Record<string, Function>)[name];\n if (!handler) {\n return {\n content: [{ type: \"text\", text: `Error: Unknown tool \"${name}\"` }],\n isError: true,\n };\n }\n\n const result = await handler(args || {});\n const latencyMs = Date.now() - startTime;\n logger.info(`Tool ${name} completed`, { latencyMs });\n\n return {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n };\n } catch (error) {\n const latencyMs = Date.now() - startTime;\n let message: string;\n\n if (error instanceof BotMsgError) {\n message = `[${error.code}] ${error.message}`;\n if (error.platform) message = `[${error.platform}] ${message}`;\n } else if (error instanceof Error) {\n message = error.message;\n } else {\n message = \"An unexpected error occurred\";\n }\n\n logger.error(`Tool ${name} failed`, { latencyMs, error: message });\n\n return {\n content: [{ type: \"text\", text: `Error: ${message}` }],\n isError: true,\n };\n }\n });\n\n // ── Connect transport ───────────────────────────────────────────\n const transport = new StdioServerTransport();\n await server.connect(transport);\n logger.info(\"botmsg MCP server running on stdio\", {\n bots: Object.keys(config.bots).length,\n dryRun,\n });\n\n // ── Graceful shutdown ───────────────────────────────────────────\n const shutdown = async (signal: string): Promise<void> => {\n logger.info(`Received ${signal}, shutting down...`);\n await rateLimiter.disconnect();\n await server.close();\n process.exit(0);\n };\n\n process.on(\"SIGINT\", () => shutdown(\"SIGINT\"));\n process.on(\"SIGTERM\", () => shutdown(\"SIGTERM\"));\n process.on(\"uncaughtException\", (error) => {\n logger.error(\"Uncaught exception\", { error: error.message, stack: error.stack });\n process.exit(1);\n });\n process.on(\"unhandledRejection\", (reason) => {\n logger.error(\"Unhandled rejection\", {\n reason: reason instanceof Error ? reason.message : String(reason),\n });\n process.exit(1);\n });\n}\n\nmain().catch((error) => {\n logger.error(\"Fatal error during startup\", {\n error: error instanceof Error ? error.message : String(error),\n });\n process.exit(1);\n});\n","/**\n * Configuration loader - supports env vars and external config files\n *\n * Priority:\n * 1. BOTMSG_CONFIG -> external YAML/JSON file\n * 2. BOTMSG_{PLATFORM}_{INSTANCE}_{FIELD} env vars\n * 3. Both can be mixed (file first, env supplements)\n */\n\nimport { readFileSync, existsSync } from \"node:fs\";\nimport { extname } from \"node:path\";\nimport YAML from \"yaml\";\nimport {\n FullConfigSchema,\n BotConfigSchema,\n SettingsSchema,\n type BotConfig,\n type FullConfig,\n type Platform,\n} from \"./schema.js\";\nimport { ConfigError } from \"../errors.js\";\nimport { logger } from \"../logger.js\";\n\nconst PLATFORM_NAMES = [\n \"dingtalk\",\n \"wecom\",\n \"feishu\",\n \"lark\",\n \"slack\",\n \"discord\",\n \"telegram\",\n] as const;\n\n/**\n * Parse bot configs from environment variables\n * Pattern: BOTMSG_{PLATFORM}_{INSTANCE}_{FIELD}\n */\nfunction parseEnvBots(): Record<string, BotConfig> {\n const bots: Record<string, Record<string, string>> = {};\n\n for (const [key, value] of Object.entries(process.env)) {\n if (!key.startsWith(\"BOTMSG_\") || !value) continue;\n\n const parts = key.slice(\"BOTMSG_\".length).split(\"_\");\n if (parts.length < 3) continue;\n\n const platform = parts[0].toLowerCase();\n if (!PLATFORM_NAMES.includes(platform as (typeof PLATFORM_NAMES)[number])) continue;\n\n // Skip global settings\n if ([\"LOG\", \"AUDIT\", \"CONFIG\", \"DRY\", \"MAX\"].includes(parts[0])) continue;\n\n const instance = parts[1].toLowerCase();\n const field = parts.slice(2).join(\"_\").toLowerCase();\n const botName = `${platform}-${instance}`;\n\n if (!bots[botName]) bots[botName] = {};\n bots[botName].platform = platform;\n bots[botName][field] = value;\n }\n\n const result: Record<string, BotConfig> = {};\n\n for (const [name, raw] of Object.entries(bots)) {\n try {\n // Special handling for telegram which uses token + chat_id instead of webhook\n const parsed = BotConfigSchema.parse(raw);\n result[name] = parsed;\n } catch (err) {\n logger.warn(`Skipping invalid bot config for \"${name}\"`, {\n error: err instanceof Error ? err.message : String(err),\n raw,\n });\n }\n }\n\n return result;\n}\n\n/**\n * Parse settings from environment variables\n */\nfunction parseEnvSettings(): Record<string, unknown> {\n const settings: Record<string, unknown> = {};\n\n if (process.env.BOTMSG_LOG_LEVEL) {\n settings.log_level = process.env.BOTMSG_LOG_LEVEL;\n }\n if (process.env.BOTMSG_AUDIT_LOG) {\n settings.audit_log = process.env.BOTMSG_AUDIT_LOG;\n }\n if (process.env.BOTMSG_MAX_RETRIES) {\n settings.max_retries = parseInt(process.env.BOTMSG_MAX_RETRIES, 10);\n }\n if (process.env.BOTMSG_DRY_RUN) {\n settings.dry_run = process.env.BOTMSG_DRY_RUN === \"true\";\n }\n\n return settings;\n}\n\n/**\n * Load config from external file (YAML or JSON)\n */\nfunction loadConfigFile(filePath: string): FullConfig {\n if (!existsSync(filePath)) {\n throw new ConfigError(`Config file not found: ${filePath}`);\n }\n\n const content = readFileSync(filePath, \"utf-8\");\n const ext = extname(filePath).toLowerCase();\n\n let raw: unknown;\n if (ext === \".yaml\" || ext === \".yml\") {\n raw = YAML.parse(content);\n } else if (ext === \".json\") {\n raw = JSON.parse(content);\n } else {\n throw new ConfigError(`Unsupported config file format: ${ext}`);\n }\n\n return FullConfigSchema.parse(raw);\n}\n\n/**\n * Load full configuration with dual-mode support\n */\nexport function loadConfig(): FullConfig {\n // Mode B: External config file\n const configPath = process.env.BOTMSG_CONFIG;\n if (configPath) {\n try {\n const fileConfig = loadConfigFile(configPath);\n logger.info(`Loaded config from file: ${configPath}`, {\n botCount: Object.keys(fileConfig.bots).length,\n });\n\n // Merge env vars as supplements\n const envBots = parseEnvBots();\n const mergedBots = { ...envBots, ...fileConfig.bots };\n\n const envSettings = parseEnvSettings();\n const mergedSettings = SettingsSchema.parse({\n ...envSettings,\n ...fileConfig.settings,\n });\n\n return { bots: mergedBots, settings: mergedSettings };\n } catch (err) {\n if (err instanceof ConfigError) throw err;\n logger.warn(`Failed to parse config file, falling back to env vars`, {\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }\n\n // Mode A: Environment variables only\n const bots = parseEnvBots();\n const settings = SettingsSchema.parse(parseEnvSettings());\n\n logger.info(`Loaded config from environment variables`, {\n botCount: Object.keys(bots).length,\n });\n\n return { bots, settings };\n}\n","/**\n * zod schemas for botmsg configuration\n */\n\nimport { z } from \"zod\";\n\n// ── Platform identifiers ────────────────────────────────────────────\n\nexport const PlatformEnum = z.enum([\n \"dingtalk\",\n \"wecom\",\n \"feishu\",\n \"lark\",\n \"slack\",\n \"discord\",\n \"telegram\",\n]);\nexport type Platform = z.infer<typeof PlatformEnum>;\n\n// ── Per-platform bot config ─────────────────────────────────────────\n\nexport const DingTalkBotSchema = z.object({\n platform: z.literal(\"dingtalk\"),\n webhook: z.string().url(),\n secret: z.string().optional(),\n security: z.enum([\"keyword\", \"ip\", \"sign\"]).default(\"keyword\"),\n});\n\nexport const WeComBotSchema = z.object({\n platform: z.literal(\"wecom\"),\n webhook: z.string().url(),\n});\n\nexport const FeishuBotSchema = z.object({\n platform: z.literal(\"feishu\"),\n webhook: z.string().url(),\n secret: z.string().optional(),\n});\n\nexport const LarkBotSchema = z.object({\n platform: z.literal(\"lark\"),\n webhook: z.string().url(),\n secret: z.string().optional(),\n});\n\nexport const SlackBotSchema = z.object({\n platform: z.literal(\"slack\"),\n webhook: z.string().url(),\n});\n\nexport const DiscordBotSchema = z.object({\n platform: z.literal(\"discord\"),\n webhook: z.string().url(),\n username: z.string().optional(),\n avatar_url: z.string().url().optional(),\n});\n\nexport const TelegramBotSchema = z.object({\n platform: z.literal(\"telegram\"),\n token: z.string(),\n chat_id: z.string(),\n parse_mode: z.enum([\"MarkdownV2\", \"HTML\", \"\"]).default(\"\"),\n});\n\nexport const BotConfigSchema = z.discriminatedUnion(\"platform\", [\n DingTalkBotSchema,\n WeComBotSchema,\n FeishuBotSchema,\n LarkBotSchema,\n SlackBotSchema,\n DiscordBotSchema,\n TelegramBotSchema,\n]);\nexport type BotConfig = z.infer<typeof BotConfigSchema>;\n\n// ── Global settings ─────────────────────────────────────────────────\n\nexport const SettingsSchema = z.object({\n log_level: z.enum([\"debug\", \"info\", \"warn\", \"error\"]).default(\"info\"),\n audit_log: z.string().optional(),\n max_retries: z.number().int().min(0).max(10).default(3),\n dry_run: z.boolean().default(false),\n});\nexport type Settings = z.infer<typeof SettingsSchema>;\n\n// ── Full config (file mode) ─────────────────────────────────────────\n\nexport const FullConfigSchema = z.object({\n bots: z.record(z.string(), BotConfigSchema),\n settings: SettingsSchema.default({}),\n});\nexport type FullConfig = z.infer<typeof FullConfigSchema>;\n\n// ── Message types ───────────────────────────────────────────────────\n\nexport const MessageTypeEnum = z.enum([\n \"text\",\n \"markdown\",\n \"link\",\n \"image\",\n \"card\",\n \"news\",\n \"file\",\n]);\nexport type MessageType = z.infer<typeof MessageTypeEnum>;\n\nexport const AtSchema = z.object({\n users: z.array(z.string()).optional(),\n mobiles: z.array(z.string()).optional(),\n all: z.boolean().default(false),\n});\nexport type AtConfig = z.infer<typeof AtSchema>;\n\nexport const LinkContentSchema = z.object({\n title: z.string(),\n text: z.string(),\n url: z.string().url(),\n pic_url: z.string().url().optional(),\n});\n\nexport const CardButtonSchema = z.object({\n title: z.string(),\n url: z.string().url(),\n});\n\nexport const CardContentSchema = z.object({\n title: z.string(),\n text: z.string(),\n buttons: z.array(CardButtonSchema).optional(),\n single_button_text: z.string().optional(),\n single_button_url: z.string().url().optional(),\n});\n\nexport const NewsItemSchema = z.object({\n title: z.string(),\n description: z.string().optional(),\n url: z.string().url(),\n pic_url: z.string().url().optional(),\n});\n","/**\n * botmsg error hierarchy\n */\n\nexport class BotMsgError extends Error {\n constructor(\n message: string,\n public code: string,\n public platform?: string,\n public details?: Record<string, unknown>,\n ) {\n super(message);\n this.name = \"BotMsgError\";\n }\n}\n\nexport class ValidationError extends BotMsgError {\n constructor(message: string, details?: Record<string, unknown>) {\n super(message, \"VALIDATION_ERROR\", undefined, details);\n this.name = \"ValidationError\";\n }\n}\n\nexport class ConfigError extends BotMsgError {\n constructor(message: string) {\n super(message, \"CONFIG_ERROR\");\n this.name = \"ConfigError\";\n }\n}\n\nexport class PlatformError extends BotMsgError {\n constructor(\n message: string,\n platform: string,\n details?: Record<string, unknown>,\n ) {\n super(message, \"PLATFORM_ERROR\", platform, details);\n this.name = \"PlatformError\";\n }\n}\n\nexport class RateLimitError extends BotMsgError {\n constructor(\n message: string,\n platform: string,\n public retryAfterMs?: number,\n ) {\n super(message, \"RATE_LIMIT_ERROR\", platform);\n this.name = \"RateLimitError\";\n }\n}\n\nexport class BotNotFoundError extends BotMsgError {\n constructor(botName: string) {\n super(`Bot \"${botName}\" not found in configuration`, \"BOT_NOT_FOUND\");\n this.name = \"BotNotFoundError\";\n }\n}\n","/**\n * stderr-only structured logger\n * stdout is reserved for MCP JSON-RPC protocol\n */\n\nexport type LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\";\n\nconst LOG_LEVELS: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n};\n\nclass Logger {\n private level: number;\n\n constructor(level: LogLevel = \"info\") {\n this.level = LOG_LEVELS[level];\n }\n\n setLevel(level: LogLevel): void {\n this.level = LOG_LEVELS[level];\n }\n\n private log(level: LogLevel, message: string, ctx?: Record<string, unknown>): void {\n if (LOG_LEVELS[level] < this.level) return;\n const entry = {\n timestamp: new Date().toISOString(),\n level: level.toUpperCase(),\n message,\n ...ctx,\n };\n console.error(JSON.stringify(entry));\n }\n\n debug(message: string, ctx?: Record<string, unknown>): void {\n this.log(\"debug\", message, ctx);\n }\n\n info(message: string, ctx?: Record<string, unknown>): void {\n this.log(\"info\", message, ctx);\n }\n\n warn(message: string, ctx?: Record<string, unknown>): void {\n this.log(\"warn\", message, ctx);\n }\n\n error(message: string, ctx?: Record<string, unknown>): void {\n this.log(\"error\", message, ctx);\n }\n}\n\nexport const logger = new Logger(\n (process.env.BOTMSG_LOG_LEVEL as LogLevel) || \"info\",\n);\n","/**\n * DingTalk (钉钉) custom robot adapter\n *\n * Supports: text, markdown, link, actionCard, feedCard\n * Security: keyword / IP whitelist / HMAC-SHA256 signing\n * Rate limit: 20 messages/minute\n *\n * Docs: https://open.dingtalk.com/document/orgapp/custom-robots-send-group-messages\n */\n\nimport { createHmac } from \"node:crypto\";\nimport { PlatformAdapter, type SendOptions, type SendResult } from \"./base.js\";\nimport type { BotConfig } from \"../config/schema.js\";\nimport { PlatformError } from \"../errors.js\";\n\ninterface DingTalkConfig extends BotConfig {\n platform: \"dingtalk\";\n webhook: string;\n secret?: string;\n security: \"keyword\" | \"ip\" | \"sign\";\n}\n\nexport class DingTalkAdapter extends PlatformAdapter {\n get platformName(): string {\n return \"dingtalk\";\n }\n\n private get cfg(): DingTalkConfig {\n return this.config as DingTalkConfig;\n }\n\n /**\n * Build signed webhook URL if HMAC-SHA256 security is enabled\n */\n private getSignedUrl(): string {\n const { webhook, secret, security } = this.cfg;\n\n if (security === \"sign\" && secret) {\n const timestamp = Date.now();\n const stringToSign = `${timestamp}\\n${secret}`;\n const hmac = createHmac(\"sha256\", secret).update(stringToSign).digest(\"base64\");\n const sign = encodeURIComponent(hmac);\n return `${webhook}&timestamp=${timestamp}&sign=${sign}`;\n }\n\n return webhook;\n }\n\n buildPayload(options: SendOptions): Record<string, unknown> {\n const at = this.buildAt(options.at);\n\n switch (options.type) {\n case \"text\":\n return {\n msgtype: \"text\",\n text: { content: options.content },\n ...(Object.keys(at).length > 0 ? { at } : {}),\n };\n\n case \"markdown\":\n return {\n msgtype: \"markdown\",\n markdown: {\n title: options.title || \"Message\",\n text: options.content,\n },\n ...(Object.keys(at).length > 0 ? { at } : {}),\n };\n\n case \"link\":\n return {\n msgtype: \"link\",\n link: {\n title: options.title || \"Link\",\n text: options.content,\n messageUrl: options.linkUrl || \"\",\n picUrl: options.picUrl || \"\",\n },\n };\n\n case \"card\": {\n const hasButtons = options.buttons && options.buttons.length > 0;\n if (hasButtons) {\n return {\n msgtype: \"actionCard\",\n actionCard: {\n title: options.title || \"Card\",\n text: options.content,\n btnOrientation: \"0\",\n btns: options.buttons!.map((btn) => ({\n title: btn.title,\n actionURL: btn.url,\n })),\n },\n };\n }\n return {\n msgtype: \"actionCard\",\n actionCard: {\n title: options.title || \"Card\",\n text: options.content,\n singleTitle: options.singleButtonText || \"View\",\n singleURL: options.singleButtonUrl || \"\",\n },\n };\n }\n\n case \"news\":\n return {\n msgtype: \"feedCard\",\n feedCard: {\n links: (options.newsItems || []).map((item) => ({\n title: item.title,\n messageURL: item.url,\n picURL: item.picUrl || \"\",\n })),\n },\n };\n\n case \"image\":\n // DingTalk doesn't natively support image messages via webhook,\n // fall back to markdown with image syntax\n return {\n msgtype: \"markdown\",\n markdown: {\n title: options.title || \"Image\",\n text: `![image](${options.imageUrl || options.content})`,\n },\n };\n\n case \"file\":\n // DingTalk webhook doesn't support file upload, degrade to link\n return {\n msgtype: \"link\",\n link: {\n title: options.title || \"File\",\n text: options.content || \"A file was shared\",\n messageUrl: options.linkUrl || \"\",\n picUrl: \"\",\n },\n };\n\n default:\n return {\n msgtype: \"text\",\n text: { content: options.content },\n };\n }\n }\n\n async send(options: SendOptions): Promise<SendResult> {\n return this.withTiming(async () => {\n const url = this.getSignedUrl();\n const payload = this.buildPayload(options);\n\n const { status, data } = await this.httpPost(url, payload);\n const result = data as Record<string, unknown>;\n\n if (status === 200 && result.errcode === 0) {\n return { success: true, messageId: this.generateMessageId(), raw: result };\n }\n\n return {\n success: false,\n error: `DingTalk error [${result.errcode}]: ${result.errmsg}`,\n raw: result,\n };\n });\n }\n\n async sendFile(filePath: string, _caption?: string): Promise<SendResult> {\n // DingTalk webhook doesn't support file uploads\n return {\n success: false,\n platform: \"dingtalk\",\n bot: this.botName,\n latencyMs: 0,\n error: \"DingTalk webhook does not support file uploads. Use link type instead.\",\n };\n }\n\n private buildAt(at?: SendOptions[\"at\"]): Record<string, unknown> {\n if (!at) return {};\n const result: Record<string, unknown> = {};\n if (at.all) result.isAtAll = true;\n if (at.mobiles && at.mobiles.length > 0) result.atMobiles = at.mobiles;\n if (at.users && at.users.length > 0) result.atUserIds = at.users;\n return result;\n }\n}\n","/**\n * Abstract base class for all platform adapters\n */\n\nimport type { BotConfig, MessageType, AtConfig } from \"../config/schema.js\";\nimport { PlatformError } from \"../errors.js\";\n\nexport interface SendOptions {\n type: MessageType;\n content: string;\n title?: string;\n at?: AtConfig;\n // Link type\n linkUrl?: string;\n picUrl?: string;\n // Card type\n buttons?: Array<{ title: string; url: string }>;\n singleButtonText?: string;\n singleButtonUrl?: string;\n // News type\n newsItems?: Array<{\n title: string;\n description?: string;\n url: string;\n picUrl?: string;\n }>;\n // Image type\n imageUrl?: string;\n imageBase64?: string;\n // File type\n filePath?: string;\n fileMediaId?: string;\n}\n\nexport interface SendResult {\n success: boolean;\n messageId?: string;\n platform: string;\n bot: string;\n raw?: unknown;\n error?: string;\n latencyMs: number;\n}\n\nexport abstract class PlatformAdapter {\n readonly config: BotConfig;\n readonly botName: string;\n\n constructor(botName: string, config: BotConfig) {\n this.botName = botName;\n this.config = config;\n }\n\n abstract get platformName(): string;\n\n /**\n * Send a message through this platform's bot\n */\n abstract send(options: SendOptions): Promise<SendResult>;\n\n /**\n * Send a file through this platform's bot (if supported)\n */\n abstract sendFile(\n filePath: string,\n caption?: string,\n ): Promise<SendResult>;\n\n /**\n * Build the platform-specific payload from unified SendOptions\n */\n abstract buildPayload(options: SendOptions): Record<string, unknown>;\n\n /**\n * Execute HTTP POST with error handling\n */\n protected async httpPost(\n url: string,\n body: Record<string, unknown>,\n headers?: Record<string, string>,\n ): Promise<{ status: number; data: unknown }> {\n const startTime = Date.now();\n try {\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...headers,\n },\n body: JSON.stringify(body),\n });\n\n const text = await response.text();\n let data: unknown;\n try {\n data = JSON.parse(text);\n } catch {\n data = text;\n }\n\n return { status: response.status, data };\n } catch (err) {\n const latencyMs = Date.now() - startTime;\n throw new PlatformError(\n `HTTP request failed: ${err instanceof Error ? err.message : String(err)}`,\n this.platformName,\n { latencyMs },\n );\n }\n }\n\n /**\n * Generate a unique message ID for audit tracking\n */\n protected generateMessageId(): string {\n const ts = Date.now().toString(36);\n const rand = Math.random().toString(36).slice(2, 8);\n return `msg_${ts}_${rand}`;\n }\n\n /**\n * Wrap send with timing and result normalization\n */\n protected async withTiming(\n sendFn: () => Promise<{ success: boolean; raw?: unknown; error?: string; messageId?: string }>,\n ): Promise<SendResult> {\n const startTime = Date.now();\n try {\n const result = await sendFn();\n return {\n ...result,\n platform: this.platformName,\n bot: this.botName,\n latencyMs: Date.now() - startTime,\n };\n } catch (err) {\n return {\n success: false,\n platform: this.platformName,\n bot: this.botName,\n latencyMs: Date.now() - startTime,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n }\n}\n","/**\n * WeCom (企业微信) group robot adapter\n *\n * Supports: text, markdown, image, news, file, template_card\n * Security: webhook key\n * Rate limit: 20 messages/minute\n *\n * Docs: https://developer.work.weixin.qq.com/document/path/99110\n */\n\nimport { readFileSync } from \"node:fs\";\nimport { createHash } from \"node:crypto\";\nimport { PlatformAdapter, type SendOptions, type SendResult } from \"./base.js\";\nimport type { BotConfig } from \"../config/schema.js\";\nimport { PlatformError } from \"../errors.js\";\n\ninterface WeComConfig extends BotConfig {\n platform: \"wecom\";\n webhook: string;\n}\n\nexport class WeComAdapter extends PlatformAdapter {\n get platformName(): string {\n return \"wecom\";\n }\n\n private get cfg(): WeComConfig {\n return this.config as WeComConfig;\n }\n\n /**\n * Extract the webhook key from URL for file upload\n */\n private getWebhookKey(): string {\n const url = new URL(this.cfg.webhook);\n return url.searchParams.get(\"key\") || \"\";\n }\n\n /**\n * Upload file to get media_id (for file messages)\n */\n async uploadFile(filePath: string): Promise<string> {\n const key = this.getWebhookKey();\n const uploadUrl = `https://qyapi.weixin.qq.com/cgi-bin/webhook/upload_media?key=${key}&type=file`;\n\n const fileBuffer = readFileSync(filePath);\n const fileName = filePath.split(/[/\\\\]/).pop() || \"file\";\n\n const formData = new FormData();\n formData.append(\"media\", new Blob([fileBuffer]), fileName);\n\n const response = await fetch(uploadUrl, {\n method: \"POST\",\n body: formData,\n });\n\n const data = (await response.json()) as Record<string, unknown>;\n if (data.errcode !== 0) {\n throw new PlatformError(\n `WeCom file upload failed: [${data.errcode}] ${data.errmsg}`,\n \"wecom\",\n );\n }\n\n return data.media_id as string;\n }\n\n buildPayload(options: SendOptions): Record<string, unknown> {\n switch (options.type) {\n case \"text\":\n return {\n msgtype: \"text\",\n text: {\n content: options.content,\n ...(this.buildMention(options.at)),\n },\n };\n\n case \"markdown\":\n return {\n msgtype: \"markdown\",\n markdown: {\n content: options.content,\n },\n };\n\n case \"image\": {\n if (options.imageBase64) {\n const md5 = createHash(\"md5\")\n .update(Buffer.from(options.imageBase64, \"base64\"))\n .digest(\"hex\");\n return {\n msgtype: \"image\",\n image: {\n base64: options.imageBase64,\n md5,\n },\n };\n }\n // If URL provided, send as news with single item\n return {\n msgtype: \"news\",\n news: {\n articles: [\n {\n title: options.title || \"Image\",\n description: options.content || \"\",\n url: options.imageUrl || options.content,\n picurl: options.imageUrl || options.content,\n },\n ],\n },\n };\n }\n\n case \"link\":\n return {\n msgtype: \"news\",\n news: {\n articles: [\n {\n title: options.title || \"Link\",\n description: options.content,\n url: options.linkUrl || \"\",\n picurl: options.picUrl || \"\",\n },\n ],\n },\n };\n\n case \"news\":\n return {\n msgtype: \"news\",\n news: {\n articles: (options.newsItems || []).map((item) => ({\n title: item.title,\n description: item.description || \"\",\n url: item.url,\n picurl: item.picUrl || \"\",\n })),\n },\n };\n\n case \"file\":\n return {\n msgtype: \"file\",\n file: {\n media_id: options.fileMediaId || \"\",\n },\n };\n\n case \"card\":\n return {\n msgtype: \"template_card\",\n template_card: {\n card_type: \"text_notice\",\n main_title: {\n title: options.title || \"Card\",\n },\n emphasis_content: {\n title: options.content.split(\"\\n\")[0] || \"\",\n desc: options.content,\n },\n jump_list: (options.buttons || []).map((btn) => ({\n type: 1,\n url: btn.url,\n title: btn.title,\n })),\n card_action: options.singleButtonUrl\n ? { type: 1, url: options.singleButtonUrl }\n : options.buttons?.[0]\n ? { type: 1, url: options.buttons[0].url }\n : undefined,\n },\n };\n\n default:\n return {\n msgtype: \"text\",\n text: { content: options.content },\n };\n }\n }\n\n async send(options: SendOptions): Promise<SendResult> {\n return this.withTiming(async () => {\n const payload = this.buildPayload(options);\n\n const { status, data } = await this.httpPost(this.cfg.webhook, payload);\n const result = data as Record<string, unknown>;\n\n if (status === 200 && result.errcode === 0) {\n return { success: true, messageId: this.generateMessageId(), raw: result };\n }\n\n return {\n success: false,\n error: `WeCom error [${result.errcode}]: ${result.errmsg}`,\n raw: result,\n };\n });\n }\n\n async sendFile(filePath: string, _caption?: string): Promise<SendResult> {\n return this.withTiming(async () => {\n try {\n const mediaId = await this.uploadFile(filePath);\n const payload = {\n msgtype: \"file\",\n file: { media_id: mediaId },\n };\n\n const { status, data } = await this.httpPost(this.cfg.webhook, payload);\n const result = data as Record<string, unknown>;\n\n if (status === 200 && result.errcode === 0) {\n return { success: true, messageId: this.generateMessageId(), raw: result };\n }\n\n return {\n success: false,\n error: `WeCom send file failed: [${result.errcode}] ${result.errmsg}`,\n raw: result,\n };\n } catch (err) {\n return {\n success: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n });\n }\n\n private buildMention(at?: SendOptions[\"at\"]): Record<string, unknown> {\n if (!at) return {};\n const result: Record<string, unknown> = {};\n if (at.users && at.users.length > 0) {\n result.mentioned_list = at.all ? [\"@all\"] : at.users;\n } else if (at.all) {\n result.mentioned_list = [\"@all\"];\n }\n if (at.mobiles && at.mobiles.length > 0) {\n result.mentioned_mobile_list = at.mobiles;\n }\n return result;\n }\n}\n","/**\n * Feishu (飞书) custom robot adapter\n *\n * Supports: text, post (rich text), image, interactive card\n * Security: keyword / IP whitelist / HMAC-SHA256 signing\n * Rate limit: 100 messages/minute, 5 messages/second\n * Payload max: 20KB\n *\n * Docs: https://open.feishu.cn/document/uktmuktmuktm/uctm5yjl3eto24ynxkjn\n */\n\nimport { createHmac } from \"node:crypto\";\nimport { PlatformAdapter, type SendOptions, type SendResult } from \"./base.js\";\nimport type { BotConfig } from \"../config/schema.js\";\n\ninterface FeishuConfig extends BotConfig {\n platform: \"feishu\";\n webhook: string;\n secret?: string;\n}\n\nexport class FeishuAdapter extends PlatformAdapter {\n protected baseUrl = \"https://open.feishu.cn\";\n\n get platformName(): string {\n return \"feishu\";\n }\n\n private get cfg(): FeishuConfig {\n return this.config as FeishuConfig;\n }\n\n /**\n * Generate HMAC-SHA256 signature for Feishu\n * Note: Feishu uses string_to_sign as KEY and empty string as DATA\n */\n protected generateSign(): { timestamp: string; sign: string } | null {\n const { secret } = this.cfg;\n if (!secret) return null;\n\n const timestamp = Math.floor(Date.now() / 1000).toString();\n const stringToSign = `${timestamp}\\n${secret}`;\n const sign = createHmac(\"sha256\", stringToSign).update(\"\").digest(\"base64\");\n\n return { timestamp, sign };\n }\n\n /**\n * Add signature fields to payload if security is enabled\n */\n protected addSignature(payload: Record<string, unknown>): Record<string, unknown> {\n const signData = this.generateSign();\n if (signData) {\n payload.timestamp = signData.timestamp;\n payload.sign = signData.sign;\n }\n return payload;\n }\n\n buildPayload(options: SendOptions): Record<string, unknown> {\n let payload: Record<string, unknown>;\n\n switch (options.type) {\n case \"text\": {\n let textContent = options.content;\n // Handle @mentions via <at> tags in text\n if (options.at) {\n if (options.at.all) {\n textContent += '\\n<at user_id=\"all\">所有人</at>';\n }\n if (options.at.users) {\n for (const userId of options.at.users) {\n textContent += `\\n<at user_id=\"${userId}\">${userId}</at>`;\n }\n }\n }\n payload = {\n msg_type: \"text\",\n content: { text: textContent },\n };\n break;\n }\n\n case \"markdown\": {\n // Feishu uses interactive card for markdown rendering\n payload = {\n msg_type: \"interactive\",\n card: {\n schema: \"2.0\",\n header: {\n title: {\n tag: \"plain_text\",\n content: options.title || \"Message\",\n },\n template: \"blue\",\n },\n body: {\n elements: [\n {\n tag: \"markdown\",\n content: options.content,\n },\n ],\n },\n },\n };\n break;\n }\n\n case \"link\":\n payload = {\n msg_type: \"post\",\n content: {\n post: {\n zh_cn: {\n title: options.title || \"Link\",\n content: [\n [\n { tag: \"text\", text: options.content + \"\\n\" },\n {\n tag: \"a\",\n text: options.linkUrl || \"Open Link\",\n href: options.linkUrl || \"\",\n },\n ],\n ],\n },\n },\n },\n };\n break;\n\n case \"image\":\n payload = {\n msg_type: \"image\",\n content: {\n image_key: options.content, // For Feishu, content should be image_key\n },\n };\n break;\n\n case \"card\": {\n const elements: Array<Record<string, unknown>> = [\n { tag: \"markdown\", content: options.content },\n ];\n\n if (options.buttons && options.buttons.length > 0) {\n elements.push({\n tag: \"action\",\n actions: options.buttons.map((btn) => ({\n tag: \"button\",\n text: { tag: \"plain_text\", content: btn.title },\n type: \"primary\",\n behaviors: [\n { type: \"open_url\", default_url: btn.url },\n ],\n })),\n });\n }\n\n payload = {\n msg_type: \"interactive\",\n card: {\n schema: \"2.0\",\n header: {\n title: {\n tag: \"plain_text\",\n content: options.title || \"Card\",\n },\n template: \"blue\",\n },\n body: { elements },\n },\n };\n break;\n }\n\n case \"news\": {\n const contentRows = (options.newsItems || []).map((item) => [\n { tag: \"a\", text: item.title, href: item.url },\n ]);\n payload = {\n msg_type: \"post\",\n content: {\n post: {\n zh_cn: {\n title: options.title || \"News\",\n content: contentRows,\n },\n },\n },\n };\n break;\n }\n\n case \"file\":\n // Feishu webhook doesn't support file upload directly\n // Degrade to text with a note\n payload = {\n msg_type: \"text\",\n content: {\n text: options.content || `[File: ${options.filePath || \"unknown\"}]`,\n },\n };\n break;\n\n default:\n payload = {\n msg_type: \"text\",\n content: { text: options.content },\n };\n }\n\n return this.addSignature(payload);\n }\n\n async send(options: SendOptions): Promise<SendResult> {\n return this.withTiming(async () => {\n const payload = this.buildPayload(options);\n\n const { status, data } = await this.httpPost(this.cfg.webhook, payload);\n const result = data as Record<string, unknown>;\n\n if (status === 200 && result.code === 0) {\n return { success: true, messageId: this.generateMessageId(), raw: result };\n }\n\n return {\n success: false,\n error: `Feishu error [${result.code}]: ${result.msg}`,\n raw: result,\n };\n });\n }\n\n async sendFile(filePath: string, _caption?: string): Promise<SendResult> {\n return {\n success: false,\n platform: \"feishu\",\n bot: this.botName,\n latencyMs: 0,\n error: \"Feishu webhook does not support file uploads. Use image_key or share_chat instead.\",\n };\n }\n}\n","/**\n * Lark (International Feishu) adapter\n *\n * Identical to Feishu but with a different base URL:\n * - Feishu: https://open.feishu.cn\n * - Lark: https://open.larksuite.com\n *\n * Docs: https://open.larksuite.com/document/client-docs/bot-v3/add-custom-bot\n */\n\nimport { FeishuAdapter } from \"./feishu.js\";\nimport type { BotConfig } from \"../config/schema.js\";\n\nexport class LarkAdapter extends FeishuAdapter {\n protected override baseUrl = \"https://open.larksuite.com\";\n\n override get platformName(): string {\n return \"lark\";\n }\n}\n","/**\n * Slack incoming webhook adapter\n *\n * Supports: text, Block Kit, attachments (legacy)\n * Security: URL is the credential\n * Rate limit: ~1 message/second per webhook\n *\n * Docs: https://docs.slack.dev/messaging/sending-messages-using-incoming-webhooks\n */\n\nimport { PlatformAdapter, type SendOptions, type SendResult } from \"./base.js\";\nimport type { BotConfig } from \"../config/schema.js\";\n\ninterface SlackConfig extends BotConfig {\n platform: \"slack\";\n webhook: string;\n}\n\nexport class SlackAdapter extends PlatformAdapter {\n get platformName(): string {\n return \"slack\";\n }\n\n private get cfg(): SlackConfig {\n return this.config as SlackConfig;\n }\n\n buildPayload(options: SendOptions): Record<string, unknown> {\n switch (options.type) {\n case \"text\":\n return { text: options.content };\n\n case \"markdown\": {\n const blocks: Array<Record<string, unknown>> = [];\n\n if (options.title) {\n blocks.push({\n type: \"header\",\n text: { type: \"plain_text\", text: options.title },\n });\n }\n\n blocks.push({\n type: \"section\",\n text: { type: \"mrkdwn\", text: options.content },\n });\n\n return {\n text: options.title || options.content.slice(0, 100),\n blocks,\n };\n }\n\n case \"link\": {\n const blocks: Array<Record<string, unknown>> = [\n {\n type: \"section\",\n text: {\n type: \"mrkdwn\",\n text: `*${options.title || \"Link\"}*\\n${options.content}`,\n },\n accessory: options.picUrl\n ? {\n type: \"image\",\n image_url: options.picUrl,\n alt_text: options.title || \"image\",\n }\n : undefined,\n },\n ];\n\n if (options.linkUrl) {\n blocks.push({\n type: \"actions\",\n elements: [\n {\n type: \"button\",\n text: { type: \"plain_text\", text: \"Open Link\" },\n url: options.linkUrl,\n },\n ],\n });\n }\n\n return {\n text: `${options.title || \"Link\"}: ${options.linkUrl || \"\"}`,\n blocks,\n };\n }\n\n case \"image\": {\n const imageUrl = options.imageUrl || options.content;\n return {\n text: options.title || \"Image\",\n blocks: [\n {\n type: \"image\",\n image_url: imageUrl,\n alt_text: options.title || \"image\",\n },\n ],\n };\n }\n\n case \"card\": {\n const blocks: Array<Record<string, unknown>> = [];\n\n if (options.title) {\n blocks.push({\n type: \"header\",\n text: { type: \"plain_text\", text: options.title },\n });\n }\n\n blocks.push({\n type: \"section\",\n text: { type: \"mrkdwn\", text: options.content },\n });\n\n if (options.buttons && options.buttons.length > 0) {\n blocks.push({\n type: \"actions\",\n elements: options.buttons.map((btn) => ({\n type: \"button\",\n text: { type: \"plain_text\", text: btn.title },\n url: btn.url,\n })),\n });\n }\n\n return {\n text: options.title || options.content.slice(0, 100),\n blocks,\n };\n }\n\n case \"news\": {\n const blocks: Array<Record<string, unknown>> = [];\n\n if (options.title) {\n blocks.push({\n type: \"header\",\n text: { type: \"plain_text\", text: options.title },\n });\n }\n\n for (const item of options.newsItems || []) {\n blocks.push({\n type: \"section\",\n text: {\n type: \"mrkdwn\",\n text: `*<${item.url}|${item.title}>*\\n${item.description || \"\"}`,\n },\n accessory: item.picUrl\n ? {\n type: \"image\",\n image_url: item.picUrl,\n alt_text: item.title,\n }\n : undefined,\n });\n blocks.push({ type: \"divider\" });\n }\n\n return {\n text: options.title || \"News\",\n blocks,\n };\n }\n\n case \"file\":\n // Slack webhooks don't support file upload\n return {\n text: options.content || `[File: ${options.filePath || \"unknown\"}]`,\n };\n\n default:\n return { text: options.content };\n }\n }\n\n async send(options: SendOptions): Promise<SendResult> {\n return this.withTiming(async () => {\n const payload = this.buildPayload(options);\n\n const { status, data } = await this.httpPost(this.cfg.webhook, payload);\n\n // Slack returns 200 with \"ok\" text on success\n if (status === 200) {\n return { success: true, messageId: this.generateMessageId(), raw: data };\n }\n\n return {\n success: false,\n error: `Slack error [${status}]: ${typeof data === \"string\" ? data : JSON.stringify(data)}`,\n raw: data,\n };\n });\n }\n\n async sendFile(filePath: string, _caption?: string): Promise<SendResult> {\n return {\n success: false,\n platform: \"slack\",\n bot: this.botName,\n latencyMs: 0,\n error: \"Slack incoming webhooks do not support file uploads.\",\n };\n }\n}\n","/**\n * Discord webhook adapter\n *\n * Supports: text content, embeds, file attachments (multipart)\n * Security: URL is the credential\n * Rate limit: 5 messages per 2 seconds per webhook\n *\n * Docs: https://discord.com/developers/docs/resources/webhook\n */\n\nimport { readFileSync } from \"node:fs\";\nimport { basename } from \"node:path\";\nimport { PlatformAdapter, type SendOptions, type SendResult } from \"./base.js\";\nimport type { BotConfig } from \"../config/schema.js\";\n\ninterface DiscordConfig extends BotConfig {\n platform: \"discord\";\n webhook: string;\n username?: string;\n avatar_url?: string;\n}\n\nexport class DiscordAdapter extends PlatformAdapter {\n get platformName(): string {\n return \"discord\";\n }\n\n private get cfg(): DiscordConfig {\n return this.config as DiscordConfig;\n }\n\n /**\n * Build common fields for all payloads\n */\n private getBasePayload(): Record<string, unknown> {\n const base: Record<string, unknown> = {};\n if (this.cfg.username) base.username = this.cfg.username;\n if (this.cfg.avatar_url) base.avatar_url = this.cfg.avatar_url;\n return base;\n }\n\n buildPayload(options: SendOptions): Record<string, unknown> {\n const base = this.getBasePayload();\n\n switch (options.type) {\n case \"text\":\n return { ...base, content: options.content };\n\n case \"markdown\":\n case \"link\": {\n const embed: Record<string, unknown> = {\n description: options.content,\n color: 3447003, // Blue\n };\n if (options.title) embed.title = options.title;\n if (options.linkUrl) embed.url = options.linkUrl;\n if (options.picUrl) embed.thumbnail = { url: options.picUrl };\n embed.timestamp = new Date().toISOString();\n\n return { ...base, embeds: [embed] };\n }\n\n case \"image\": {\n const imageUrl = options.imageUrl || options.content;\n return {\n ...base,\n embeds: [\n {\n title: options.title || \"Image\",\n image: { url: imageUrl },\n color: 3447003,\n },\n ],\n };\n }\n\n case \"card\": {\n const embed: Record<string, unknown> = {\n title: options.title || \"Card\",\n description: options.content,\n color: 3447003,\n timestamp: new Date().toISOString(),\n };\n\n if (options.buttons && options.buttons.length > 0) {\n // Discord webhooks only support link buttons (style 5)\n return {\n ...base,\n embeds: [embed],\n components: [\n {\n type: 1,\n components: options.buttons.map((btn) => ({\n type: 2,\n style: 5,\n label: btn.title,\n url: btn.url,\n })),\n },\n ],\n };\n }\n\n return { ...base, embeds: [embed] };\n }\n\n case \"news\": {\n const embeds = (options.newsItems || []).map((item) => ({\n title: item.title,\n description: item.description || \"\",\n url: item.url,\n thumbnail: item.picUrl ? { url: item.picUrl } : undefined,\n color: 3447003,\n }));\n\n // Discord limits 10 embeds per message\n return { ...base, embeds: embeds.slice(0, 10) };\n }\n\n case \"file\":\n return {\n ...base,\n content: options.content || `[File: ${options.filePath || \"unknown\"}]`,\n };\n\n default:\n return { ...base, content: options.content };\n }\n }\n\n async send(options: SendOptions): Promise<SendResult> {\n return this.withTiming(async () => {\n const payload = this.buildPayload(options);\n\n const { status, data } = await this.httpPost(this.cfg.webhook, payload);\n\n // Discord returns 204 No Content on success\n if (status === 204 || status === 200) {\n return { success: true, messageId: this.generateMessageId(), raw: data };\n }\n\n const result = data as Record<string, unknown>;\n return {\n success: false,\n error: `Discord error [${result.code || status}]: ${result.message || JSON.stringify(data)}`,\n raw: result,\n };\n });\n }\n\n async sendFile(filePath: string, caption?: string): Promise<SendResult> {\n return this.withTiming(async () => {\n try {\n const fileBuffer = readFileSync(filePath);\n const fileName = basename(filePath);\n\n const formData = new FormData();\n\n const payloadJson: Record<string, unknown> = {\n ...this.getBasePayload(),\n content: caption || \"\",\n };\n formData.append(\"payload_json\", JSON.stringify(payloadJson));\n formData.append(\"files[0]\", new Blob([fileBuffer]), fileName);\n\n const response = await fetch(this.cfg.webhook, {\n method: \"POST\",\n body: formData,\n });\n\n if (response.status === 204 || response.status === 200) {\n return {\n success: true,\n messageId: this.generateMessageId(),\n raw: await response.text(),\n };\n }\n\n const errorData = await response.json().catch(() => response.statusText);\n return {\n success: false,\n error: `Discord file upload failed [${response.status}]: ${JSON.stringify(errorData)}`,\n };\n } catch (err) {\n return {\n success: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n });\n }\n}\n","/**\n * Telegram Bot API adapter\n *\n * Supports: text (MarkdownV2/HTML), photo, document, inline keyboard\n * Security: bot token from @BotFather\n * Rate limit: 30 messages/second global, 20 messages/minute per group\n *\n * Docs: https://core.telegram.org/bots/api\n */\n\nimport { readFileSync } from \"node:fs\";\nimport { basename } from \"node:path\";\nimport { PlatformAdapter, type SendOptions, type SendResult } from \"./base.js\";\nimport type { BotConfig } from \"../config/schema.js\";\n\ninterface TelegramConfig extends BotConfig {\n platform: \"telegram\";\n token: string;\n chat_id: string;\n parse_mode: \"MarkdownV2\" | \"HTML\" | \"\";\n}\n\nexport class TelegramAdapter extends PlatformAdapter {\n get platformName(): string {\n return \"telegram\";\n }\n\n private get cfg(): TelegramConfig {\n return this.config as TelegramConfig;\n }\n\n private get apiBase(): string {\n return `https://api.telegram.org/bot${this.cfg.token}`;\n }\n\n /**\n * Escape special characters for MarkdownV2\n */\n private escapeMarkdownV2(text: string): string {\n if (this.cfg.parse_mode !== \"MarkdownV2\") return text;\n // Characters that need escaping in MarkdownV2\n return text.replace(/([_*\\[\\]()~`>#+\\-=|{}.!\\\\])/g, \"\\\\$1\");\n }\n\n buildPayload(options: SendOptions): Record<string, unknown> {\n const basePayload: Record<string, unknown> = {\n chat_id: this.cfg.chat_id,\n };\n\n if (this.cfg.parse_mode) {\n basePayload.parse_mode = this.cfg.parse_mode;\n }\n\n switch (options.type) {\n case \"text\":\n return {\n ...basePayload,\n text: options.content,\n };\n\n case \"markdown\":\n return {\n ...basePayload,\n parse_mode: this.cfg.parse_mode || \"MarkdownV2\",\n text: options.content,\n };\n\n case \"link\": {\n const text = options.title\n ? `[${options.title}](${options.linkUrl})\\n${options.content}`\n : `${options.content}\\n${options.linkUrl}`;\n\n return {\n ...basePayload,\n parse_mode: \"MarkdownV2\",\n text: this.escapeMarkdownV2(options.content) +\n (options.linkUrl ? `\\n[Open Link](${options.linkUrl})` : \"\"),\n };\n }\n\n case \"image\":\n // Return payload for sendPhoto\n return {\n chat_id: this.cfg.chat_id,\n photo: options.imageUrl || options.content,\n caption: options.title || \"\",\n ...(this.cfg.parse_mode ? { parse_mode: this.cfg.parse_mode } : {}),\n };\n\n case \"card\": {\n // Use inline keyboard for card buttons\n const inlineKeyboard = (options.buttons || []).map((btn) => [\n { text: btn.title, url: btn.url },\n ]);\n\n const payload: Record<string, unknown> = {\n ...basePayload,\n text: options.title\n ? `*${options.title}*\\n${options.content}`\n : options.content,\n };\n\n if (inlineKeyboard.length > 0) {\n payload.reply_markup = { inline_keyboard: inlineKeyboard };\n }\n\n return payload;\n }\n\n case \"news\": {\n // Telegram doesn't have a native news/feed type\n // Concatenate into a single message\n const lines = (options.newsItems || []).map(\n (item, i) => `${i + 1}. [${item.title}](${item.url})${item.description ? `\\n ${item.description}` : \"\"}`,\n );\n\n return {\n ...basePayload,\n parse_mode: \"MarkdownV2\",\n text: (options.title ? `*${this.escapeMarkdownV2(options.title)}*\\n` : \"\") +\n this.escapeMarkdownV2(lines.join(\"\\n\")),\n };\n }\n\n case \"file\":\n return {\n chat_id: this.cfg.chat_id,\n document: options.content || options.linkUrl || \"\",\n caption: options.title || \"\",\n };\n\n default:\n return { ...basePayload, text: options.content };\n }\n }\n\n /**\n * Determine the correct Telegram API method based on message type\n */\n private getApiMethod(type: string): string {\n switch (type) {\n case \"image\":\n return \"sendPhoto\";\n case \"file\":\n return \"sendDocument\";\n default:\n return \"sendMessage\";\n }\n }\n\n async send(options: SendOptions): Promise<SendResult> {\n return this.withTiming(async () => {\n const method = this.getApiMethod(options.type);\n const url = `${this.apiBase}/${method}`;\n const payload = this.buildPayload(options);\n\n const { status, data } = await this.httpPost(url, payload);\n const result = data as Record<string, unknown>;\n\n if (status === 200 && result.ok === true) {\n const messageData = result.result as Record<string, unknown>;\n return {\n success: true,\n messageId: messageData?.message_id\n ? String(messageData.message_id)\n : this.generateMessageId(),\n raw: result,\n };\n }\n\n return {\n success: false,\n error: `Telegram error [${result.error_code}]: ${result.description}`,\n raw: result,\n };\n });\n }\n\n async sendFile(filePath: string, caption?: string): Promise<SendResult> {\n return this.withTiming(async () => {\n try {\n const url = `${this.apiBase}/sendDocument`;\n const fileBuffer = readFileSync(filePath);\n const fileName = basename(filePath);\n\n const formData = new FormData();\n formData.append(\"chat_id\", this.cfg.chat_id);\n formData.append(\"document\", new Blob([fileBuffer]), fileName);\n if (caption) formData.append(\"caption\", caption);\n if (this.cfg.parse_mode) formData.append(\"parse_mode\", this.cfg.parse_mode);\n\n const response = await fetch(url, {\n method: \"POST\",\n body: formData,\n });\n\n const data = (await response.json()) as Record<string, unknown>;\n\n if (response.status === 200 && data.ok === true) {\n return {\n success: true,\n messageId: String((data.result as Record<string, unknown>)?.message_id || \"\"),\n raw: data,\n };\n }\n\n return {\n success: false,\n error: `Telegram file upload failed [${data.error_code}]: ${data.description}`,\n raw: data,\n };\n } catch (err) {\n return {\n success: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n });\n }\n}\n","/**\n * Platform adapter registry\n * Manages all configured bot instances\n */\n\nimport type { BotConfig, FullConfig } from \"../config/schema.js\";\nimport { PlatformAdapter } from \"./base.js\";\nimport { BotNotFoundError } from \"../errors.js\";\nimport { logger } from \"../logger.js\";\n\n// Import all platform adapters\nimport { DingTalkAdapter } from \"./dingtalk.js\";\nimport { WeComAdapter } from \"./wecom.js\";\nimport { FeishuAdapter } from \"./feishu.js\";\nimport { LarkAdapter } from \"./lark.js\";\nimport { SlackAdapter } from \"./slack.js\";\nimport { DiscordAdapter } from \"./discord.js\";\nimport { TelegramAdapter } from \"./telegram.js\";\n\nexport class PlatformRegistry {\n private bots = new Map<string, PlatformAdapter>();\n\n /**\n * Initialize registry from full config\n */\n loadConfig(config: FullConfig): void {\n for (const [name, botConfig] of Object.entries(config.bots)) {\n this.register(name, botConfig);\n }\n logger.info(`Registry loaded: ${this.bots.size} bot(s) registered`);\n }\n\n /**\n * Register a single bot\n */\n register(name: string, config: BotConfig): void {\n const adapter = this.createAdapter(name, config);\n this.bots.set(name, adapter);\n logger.debug(`Registered bot: ${name} (${config.platform})`);\n }\n\n /**\n * Get a bot adapter by name\n */\n get(name: string): PlatformAdapter {\n const adapter = this.bots.get(name);\n if (!adapter) throw new BotNotFoundError(name);\n return adapter;\n }\n\n /**\n * Check if a bot exists\n */\n has(name: string): boolean {\n return this.bots.has(name);\n }\n\n /**\n * List all registered bots\n */\n list(): Array<{\n name: string;\n platform: string;\n enabled: boolean;\n }> {\n return Array.from(this.bots.entries()).map(([name, adapter]) => ({\n name,\n platform: adapter.platformName,\n enabled: true,\n }));\n }\n\n /**\n * Get all adapter instances\n */\n getAll(): PlatformAdapter[] {\n return Array.from(this.bots.values());\n }\n\n /**\n * Get adapters by bot names\n */\n getMany(names: string[]): PlatformAdapter[] {\n return names.map((name) => this.get(name));\n }\n\n private createAdapter(name: string, config: BotConfig): PlatformAdapter {\n switch (config.platform) {\n case \"dingtalk\":\n return new DingTalkAdapter(name, config);\n case \"wecom\":\n return new WeComAdapter(name, config);\n case \"feishu\":\n return new FeishuAdapter(name, config);\n case \"lark\":\n return new LarkAdapter(name, config);\n case \"slack\":\n return new SlackAdapter(name, config);\n case \"discord\":\n return new DiscordAdapter(name, config);\n case \"telegram\":\n return new TelegramAdapter(name, config);\n default:\n throw new Error(`Unsupported platform: ${(config as BotConfig).platform}`);\n }\n }\n}\n","/**\n * Per-platform rate limiter using Bottleneck\n *\n * Features:\n * - Independent rate limiter per bot instance\n * - Platform-specific default limits\n * - Exponential backoff retry (1s -> 2s -> 4s -> 8s -> 16s, max 5 retries)\n * - High water mark protection to prevent memory overflow\n * - Configurable via settings\n */\n\nimport Bottleneck from \"bottleneck\";\nimport type { Platform } from \"../config/schema.js\";\nimport { logger } from \"../logger.js\";\n\n/**\n * Platform-specific rate limit configurations\n */\nconst PLATFORM_LIMITS: Record<Platform, Bottleneck.ConstructorOptions> = {\n dingtalk: {\n reservoir: 18, // Leave margin below 20/min\n reservoirRefreshAmount: 18,\n reservoirRefreshInterval: 60_000, // per minute\n maxConcurrent: 3,\n minTime: 3_000, // ~20/min spacing\n highWater: 50,\n strategy: Bottleneck.strategy.LEAK,\n },\n wecom: {\n reservoir: 18,\n reservoirRefreshAmount: 18,\n reservoirRefreshInterval: 60_000,\n maxConcurrent: 3,\n minTime: 3_000,\n highWater: 50,\n strategy: Bottleneck.strategy.LEAK,\n },\n feishu: {\n reservoir: 90, // Leave margin below 100/min\n reservoirRefreshAmount: 90,\n reservoirRefreshInterval: 60_000,\n maxConcurrent: 4,\n minTime: 250, // ~5/sec = 200ms spacing + margin\n highWater: 200,\n strategy: Bottleneck.strategy.LEAK,\n },\n lark: {\n reservoir: 90,\n reservoirRefreshAmount: 90,\n reservoirRefreshInterval: 60_000,\n maxConcurrent: 4,\n minTime: 250,\n highWater: 200,\n strategy: Bottleneck.strategy.LEAK,\n },\n slack: {\n reservoir: 55, // ~1/sec with margin\n reservoirRefreshAmount: 55,\n reservoirRefreshInterval: 60_000,\n maxConcurrent: 1,\n minTime: 1_100, // 1.1s between messages\n highWater: 100,\n strategy: Bottleneck.strategy.LEAK,\n },\n discord: {\n reservoir: 4, // Leave margin below 5/2sec\n reservoirRefreshAmount: 4,\n reservoirRefreshInterval: 2_000,\n maxConcurrent: 2,\n minTime: 500,\n highWater: 50,\n strategy: Bottleneck.strategy.LEAK,\n },\n telegram: {\n reservoir: 25, // Leave margin below 30/sec\n reservoirRefreshAmount: 25,\n reservoirRefreshInterval: 1_000,\n maxConcurrent: 5,\n minTime: 40, // ~25/sec\n highWater: 100,\n strategy: Bottleneck.strategy.LEAK,\n },\n};\n\n/**\n * Retryable HTTP status codes and error patterns\n */\nconst RETRYABLE_PATTERNS = [\n \"429\",\n \"500\",\n \"502\",\n \"503\",\n \"504\",\n \"ECONNRESET\",\n \"ETIMEDOUT\",\n \"ENOTFOUND\",\n \"RATE_LIMIT\",\n \"Too Many Requests\",\n];\n\nexport interface RateLimiterOptions {\n maxRetries?: number;\n retryMultiplier?: number;\n maxRetryDelayMs?: number;\n}\n\nexport class RateLimiterManager {\n private limiters = new Map<string, Bottleneck>();\n private maxRetries: number;\n private retryMultiplier: number;\n private maxRetryDelayMs: number;\n\n constructor(options: RateLimiterOptions = {}) {\n this.maxRetries = options.maxRetries ?? 3;\n this.retryMultiplier = options.retryMultiplier ?? 2;\n this.maxRetryDelayMs = options.maxRetryDelayMs ?? 30_000;\n }\n\n /**\n * Get or create a Bottleneck limiter for a specific bot\n */\n getLimiter(botName: string, platform: Platform): Bottleneck {\n if (this.limiters.has(botName)) {\n return this.limiters.get(botName)!;\n }\n\n const platformConfig = PLATFORM_LIMITS[platform] || PLATFORM_LIMITS.telegram;\n const limiter = new Bottleneck({\n ...platformConfig,\n maxExecutionTime: 30_000, // 30s timeout per request\n });\n\n // Configure exponential backoff retry\n limiter.on(\"failed\", async (error, jobInfo) => {\n const errorMessage = error instanceof Error ? error.message : String(error);\n const shouldRetry = RETRYABLE_PATTERNS.some((pattern) =>\n errorMessage.includes(pattern),\n );\n\n if (shouldRetry && jobInfo.retryCount < this.maxRetries) {\n const delay = Math.min(\n Math.pow(this.retryMultiplier, jobInfo.retryCount) * 1000,\n this.maxRetryDelayMs,\n );\n logger.warn(`Retry #${jobInfo.retryCount + 1} for ${botName} after ${delay}ms`, {\n error: errorMessage,\n });\n return delay;\n }\n\n // Stop retrying\n logger.error(`Max retries exceeded for ${botName}`, {\n attempts: jobInfo.retryCount + 1,\n error: errorMessage,\n });\n });\n\n this.limiters.set(botName, limiter);\n logger.debug(`Created rate limiter for bot: ${botName} (${platform})`);\n return limiter;\n }\n\n /**\n * Schedule a task through a bot's rate limiter\n */\n async schedule<T>(\n botName: string,\n platform: Platform,\n fn: () => Promise<T>,\n ): Promise<T> {\n const limiter = this.getLimiter(botName, platform);\n return limiter.schedule(fn);\n }\n\n /**\n * Get queue stats for a specific bot\n */\n getStats(botName: string): Record<string, number> | null {\n const limiter = this.limiters.get(botName);\n if (!limiter) return null;\n\n const counts = limiter.counts();\n return {\n queued: counts.EXECUTING + counts.QUEUED,\n running: counts.RUNNING,\n };\n }\n\n /**\n * Disconnect all limiters (graceful shutdown)\n */\n async disconnect(): Promise<void> {\n const promises = Array.from(this.limiters.values()).map((limiter) =>\n limiter.disconnect(),\n );\n await Promise.all(promises);\n this.limiters.clear();\n logger.info(\"All rate limiters disconnected\");\n }\n}\n","/**\n * Audit logger for message tracking\n *\n * Features:\n * - In-memory ring buffer (default: last 1000 entries)\n * - Optional JSONL file persistence\n * - Queryable by message_id, bot, platform, status, time range\n */\n\nimport { appendFileSync, existsSync, mkdirSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\nimport { logger } from \"../logger.js\";\n\nexport interface AuditEntry {\n id: string;\n messageId?: string;\n bot: string;\n platform: string;\n type: string;\n contentHash: string;\n status: \"success\" | \"failed\" | \"queued\" | \"retrying\";\n timestamp: string;\n latencyMs: number;\n error?: string;\n target?: string;\n}\n\nexport class AuditLogger {\n private entries: AuditEntry[] = [];\n private maxSize: number;\n private filePath?: string;\n\n constructor(options: { maxSize?: number; filePath?: string } = {}) {\n this.maxSize = options.maxSize ?? 1000;\n this.filePath = options.filePath;\n\n // Ensure log directory exists\n if (this.filePath) {\n const dir = dirname(this.filePath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n }\n }\n\n /**\n * Record a message send event\n */\n log(entry: AuditEntry): void {\n // Add to in-memory ring buffer\n this.entries.push(entry);\n if (this.entries.length > this.maxSize) {\n this.entries.shift();\n }\n\n // Persist to file if configured\n if (this.filePath) {\n try {\n appendFileSync(this.filePath, JSON.stringify(entry) + \"\\n\", \"utf-8\");\n } catch (err) {\n logger.warn(\"Failed to write audit log\", {\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }\n\n logger.debug(\"Audit log entry\", {\n id: entry.id,\n bot: entry.bot,\n platform: entry.platform,\n status: entry.status,\n });\n }\n\n /**\n * Query audit entries with filters\n */\n query(filters: {\n messageId?: string;\n bot?: string;\n platform?: string;\n status?: AuditEntry[\"status\"];\n since?: string;\n until?: string;\n limit?: number;\n } = {}): AuditEntry[] {\n let results = [...this.entries];\n\n if (filters.messageId) {\n results = results.filter((e) => e.messageId === filters.messageId);\n }\n if (filters.bot) {\n results = results.filter((e) => e.bot === filters.bot);\n }\n if (filters.platform) {\n results = results.filter((e) => e.platform === filters.platform);\n }\n if (filters.status) {\n results = results.filter((e) => e.status === filters.status);\n }\n if (filters.since) {\n const sinceTime = new Date(filters.since).getTime();\n results = results.filter(\n (e) => new Date(e.timestamp).getTime() >= sinceTime,\n );\n }\n if (filters.until) {\n const untilTime = new Date(filters.until).getTime();\n results = results.filter(\n (e) => new Date(e.timestamp).getTime() <= untilTime,\n );\n }\n\n const limit = filters.limit ?? 50;\n return results.slice(-limit);\n }\n\n /**\n * Get summary statistics\n */\n stats(): {\n total: number;\n success: number;\n failed: number;\n byPlatform: Record<string, number>;\n byBot: Record<string, number>;\n } {\n const byPlatform: Record<string, number> = {};\n const byBot: Record<string, number> = {};\n let success = 0;\n let failed = 0;\n\n for (const entry of this.entries) {\n if (entry.status === \"success\") success++;\n else if (entry.status === \"failed\") failed++;\n byPlatform[entry.platform] = (byPlatform[entry.platform] || 0) + 1;\n byBot[entry.bot] = (byBot[entry.bot] || 0) + 1;\n }\n\n return {\n total: this.entries.length,\n success,\n failed,\n byPlatform,\n byBot,\n };\n }\n\n /**\n * Find entry by audit ID\n */\n findById(id: string): AuditEntry | undefined {\n return this.entries.find((e) => e.id === id);\n }\n\n /**\n * Find entry by message ID\n */\n findByMessageId(messageId: string): AuditEntry | undefined {\n return this.entries.find((e) => e.messageId === messageId);\n }\n\n /**\n * Clear all in-memory entries\n */\n clear(): void {\n this.entries = [];\n }\n}\n\n/**\n * Create a simple hash of content for audit tracking\n */\nexport function hashContent(content: string, maxLen = 32): string {\n if (content.length <= maxLen) return content;\n return content.slice(0, maxLen) + \"...\";\n}\n","/**\n * Handlebars-based message template engine\n *\n * Features:\n * - Custom helpers: date, uppercase, lowercase, truncate, if_eq, json\n * - noEscape mode to prevent HTML entity escaping\n * - Template caching for performance\n * - Partials support for reusable message fragments\n */\n\nimport Handlebars from \"handlebars\";\n\nexport class TemplateEngine {\n private compiled = new Map<string, HandlebarsTemplateDelegate>();\n private hb: typeof Handlebars;\n\n constructor() {\n this.hb = Handlebars.create();\n this.registerHelpers();\n }\n\n private registerHelpers(): void {\n // Format a date string\n this.hb.registerHelper(\"date\", (dateStr: string, format?: string) => {\n const d = new Date(dateStr);\n if (isNaN(d.getTime())) return dateStr;\n if (format === \"iso\") return d.toISOString();\n if (format === \"locale\") return d.toLocaleString(\"zh-CN\");\n // Default: YYYY-MM-DD HH:mm:ss\n const pad = (n: number) => n.toString().padStart(2, \"0\");\n return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;\n });\n\n // String transformations\n this.hb.registerHelper(\"uppercase\", (str: string) =>\n typeof str === \"string\" ? str.toUpperCase() : str,\n );\n this.hb.registerHelper(\"lowercase\", (str: string) =>\n typeof str === \"string\" ? str.toLowerCase() : str,\n );\n this.hb.registerHelper(\"capitalize\", (str: string) =>\n typeof str === \"string\"\n ? str.charAt(0).toUpperCase() + str.slice(1)\n : str,\n );\n\n // Truncate text to a max length\n this.hb.registerHelper(\n \"truncate\",\n (str: string, maxLen: number, suffix?: string) => {\n if (typeof str !== \"string\") return str;\n const limit = typeof maxLen === \"number\" ? maxLen : 100;\n const end = typeof suffix === \"string\" ? suffix : \"...\";\n return str.length > limit ? str.slice(0, limit) + end : str;\n },\n );\n\n // Conditional equality check\n this.hb.registerHelper(\n \"if_eq\",\n function (this: unknown, a: unknown, b: unknown, options: Handlebars.HelperOptions) {\n return a === b ? options.fn(this) : options.inverse(this);\n },\n );\n\n // JSON stringify for debugging\n this.hb.registerHelper(\"json\", (obj: unknown, indent?: number) => {\n const spaces = typeof indent === \"number\" ? indent : 2;\n return JSON.stringify(obj, null, spaces);\n });\n\n // Current timestamp\n this.hb.registerHelper(\"now\", (format?: string) => {\n const now = new Date();\n if (format === \"iso\") return now.toISOString();\n if (format === \"timestamp\") return Math.floor(now.getTime() / 1000).toString();\n const pad = (n: number) => n.toString().padStart(2, \"0\");\n return `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())} ${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}`;\n });\n\n // Conditional: if greater than\n this.hb.registerHelper(\n \"if_gt\",\n function (this: unknown, a: number, b: number, options: Handlebars.HelperOptions) {\n return a > b ? options.fn(this) : options.inverse(this);\n },\n );\n\n // Join array into string\n this.hb.registerHelper(\"join\", (arr: unknown[], separator?: string) => {\n if (!Array.isArray(arr)) return String(arr || \"\");\n const sep = typeof separator === \"string\" ? separator : \", \";\n return arr.join(sep);\n });\n }\n\n /**\n * Register a partial template for reuse\n */\n registerPartial(name: string, template: string): void {\n this.hb.registerPartial(name, template);\n }\n\n /**\n * Compile and cache a template string\n */\n compile(templateStr: string, name?: string): HandlebarsTemplateDelegate {\n if (name && this.compiled.has(name)) {\n return this.compiled.get(name)!;\n }\n const compiled = this.hb.compile(templateStr, { noEscape: true });\n if (name) this.compiled.set(name, compiled);\n return compiled;\n }\n\n /**\n * Render a template string with variables\n */\n render(templateStr: string, variables: Record<string, unknown> = {}): string {\n const template = this.compile(templateStr);\n return template(variables);\n }\n\n /**\n * Check if a string contains template expressions\n */\n hasExpressions(templateStr: string): boolean {\n return /\\{\\{[^}]+\\}\\}/.test(templateStr);\n }\n\n /**\n * Extract variable names from a template string\n */\n extractVariables(templateStr: string): string[] {\n const matches = templateStr.match(/\\{\\{([^}]+)\\}\\}/g);\n if (!matches) return [];\n return [...new Set(matches.map((m) => m.replace(/\\{\\{|\\}\\}/g, \"\").trim()))];\n }\n\n /**\n * Clear the compiled template cache\n */\n clearCache(): void {\n this.compiled.clear();\n }\n}\n\n// Singleton instance\nexport const templateEngine = new TemplateEngine();\n","/**\n * send_message tool - Core message sending\n */\n\nimport type { PlatformAdapter } from \"../platforms/base.js\";\nimport type { PlatformRegistry } from \"../platforms/registry.js\";\nimport type { RateLimiterManager } from \"../queue/rate-limiter.js\";\nimport type { AuditLogger } from \"../audit/logger.js\";\nimport { templateEngine } from \"../templates/engine.js\";\nimport { hashContent } from \"../audit/logger.js\";\nimport { logger } from \"../logger.js\";\nimport type { MessageType, AtConfig } from \"../config/schema.js\";\nimport type { Platform } from \"../config/schema.js\";\n\nexport interface SendMessageArgs {\n bot: string;\n type: MessageType;\n content: string;\n title?: string;\n variables?: Record<string, string>;\n at?: AtConfig;\n link_url?: string;\n pic_url?: string;\n buttons?: Array<{ title: string; url: string }>;\n single_button_text?: string;\n single_button_url?: string;\n news_items?: Array<{\n title: string;\n description?: string;\n url: string;\n pic_url?: string;\n }>;\n image_url?: string;\n image_base64?: string;\n}\n\nexport function createSendMessageHandler(\n registry: PlatformRegistry,\n rateLimiter: RateLimiterManager,\n auditLogger: AuditLogger,\n dryRun: boolean,\n) {\n return async (args: SendMessageArgs) => {\n const adapter = registry.get(args.bot);\n\n // Apply template variables if provided\n let content = args.content;\n if (args.variables && templateEngine.hasExpressions(content)) {\n content = templateEngine.render(content, args.variables);\n }\n\n // Also render title if it contains templates\n let title = args.title;\n if (title && args.variables && templateEngine.hasExpressions(title)) {\n title = templateEngine.render(title, args.variables);\n }\n\n const sendOptions = {\n type: args.type,\n content,\n title,\n at: args.at,\n linkUrl: args.link_url,\n picUrl: args.pic_url,\n buttons: args.buttons,\n singleButtonText: args.single_button_text,\n singleButtonUrl: args.single_button_url,\n newsItems: args.news_items,\n imageUrl: args.image_url,\n imageBase64: args.image_base64,\n };\n\n if (dryRun) {\n const payload = adapter.buildPayload(sendOptions);\n const auditId = `dry_${Date.now().toString(36)}`;\n auditLogger.log({\n id: auditId,\n bot: args.bot,\n platform: adapter.platformName,\n type: args.type,\n contentHash: hashContent(content),\n status: \"success\",\n timestamp: new Date().toISOString(),\n latencyMs: 0,\n });\n\n return {\n dry_run: true,\n bot: args.bot,\n platform: adapter.platformName,\n payload,\n rendered_content: content,\n audit_id: auditId,\n };\n }\n\n // Send through rate limiter\n const platform = adapter.platformName as Platform;\n const result = await rateLimiter.schedule(args.bot, platform, () =>\n adapter.send(sendOptions),\n );\n\n // Audit log\n const auditId = result.messageId || `msg_${Date.now().toString(36)}`;\n auditLogger.log({\n id: auditId,\n messageId: result.messageId,\n bot: args.bot,\n platform: result.platform,\n type: args.type,\n contentHash: hashContent(content),\n status: result.success ? \"success\" : \"failed\",\n timestamp: new Date().toISOString(),\n latencyMs: result.latencyMs,\n error: result.error,\n });\n\n return {\n success: result.success,\n bot: args.bot,\n platform: result.platform,\n message_id: result.messageId,\n latency_ms: result.latencyMs,\n error: result.error,\n audit_id: auditId,\n };\n };\n}\n","/**\n * send_file tool - Send files/images through platform bots\n */\n\nimport type { PlatformRegistry } from \"../platforms/registry.js\";\nimport type { RateLimiterManager } from \"../queue/rate-limiter.js\";\nimport type { AuditLogger } from \"../audit/logger.js\";\nimport { hashContent } from \"../audit/logger.js\";\nimport type { Platform } from \"../config/schema.js\";\n\nexport interface SendFileArgs {\n bot: string;\n file_path: string;\n caption?: string;\n}\n\nexport function createSendFileHandler(\n registry: PlatformRegistry,\n rateLimiter: RateLimiterManager,\n auditLogger: AuditLogger,\n dryRun: boolean,\n) {\n return async (args: SendFileArgs) => {\n const adapter = registry.get(args.bot);\n\n if (dryRun) {\n const auditId = `dry_${Date.now().toString(36)}`;\n auditLogger.log({\n id: auditId,\n bot: args.bot,\n platform: adapter.platformName,\n type: \"file\",\n contentHash: hashContent(args.file_path),\n status: \"success\",\n timestamp: new Date().toISOString(),\n latencyMs: 0,\n });\n return {\n dry_run: true,\n bot: args.bot,\n platform: adapter.platformName,\n file_path: args.file_path,\n audit_id: auditId,\n };\n }\n\n const platform = adapter.platformName as Platform;\n const result = await rateLimiter.schedule(args.bot, platform, () =>\n adapter.sendFile(args.file_path, args.caption),\n );\n\n const auditId = result.messageId || `msg_${Date.now().toString(36)}`;\n auditLogger.log({\n id: auditId,\n messageId: result.messageId,\n bot: args.bot,\n platform: result.platform,\n type: \"file\",\n contentHash: hashContent(args.file_path),\n status: result.success ? \"success\" : \"failed\",\n timestamp: new Date().toISOString(),\n latencyMs: result.latencyMs,\n error: result.error,\n });\n\n return {\n success: result.success,\n bot: args.bot,\n platform: result.platform,\n message_id: result.messageId,\n latency_ms: result.latencyMs,\n error: result.error,\n audit_id: auditId,\n };\n };\n}\n","/**\n * send_broadcast tool - Send to multiple bots simultaneously\n */\n\nimport type { PlatformRegistry } from \"../platforms/registry.js\";\nimport type { RateLimiterManager } from \"../queue/rate-limiter.js\";\nimport type { AuditLogger } from \"../audit/logger.js\";\nimport { templateEngine } from \"../templates/engine.js\";\nimport { hashContent } from \"../audit/logger.js\";\nimport type { MessageType, AtConfig, Platform } from \"../config/schema.js\";\n\nexport interface SendBroadcastArgs {\n bots: string[];\n type: MessageType;\n content: string;\n title?: string;\n variables?: Record<string, string>;\n at?: AtConfig;\n link_url?: string;\n pic_url?: string;\n buttons?: Array<{ title: string; url: string }>;\n news_items?: Array<{\n title: string;\n description?: string;\n url: string;\n pic_url?: string;\n }>;\n image_url?: string;\n}\n\nexport function createSendBroadcastHandler(\n registry: PlatformRegistry,\n rateLimiter: RateLimiterManager,\n auditLogger: AuditLogger,\n dryRun: boolean,\n) {\n return async (args: SendBroadcastArgs) => {\n // Apply template variables\n let content = args.content;\n if (args.variables && templateEngine.hasExpressions(content)) {\n content = templateEngine.render(content, args.variables);\n }\n let title = args.title;\n if (title && args.variables && templateEngine.hasExpressions(title)) {\n title = templateEngine.render(title, args.variables);\n }\n\n const sendOptions = {\n type: args.type,\n content,\n title,\n at: args.at,\n linkUrl: args.link_url,\n picUrl: args.pic_url,\n buttons: args.buttons,\n newsItems: args.news_items,\n imageUrl: args.image_url,\n };\n\n // Send to all bots in parallel\n const results = await Promise.allSettled(\n args.bots.map(async (botName) => {\n const adapter = registry.get(botName);\n const platform = adapter.platformName as Platform;\n\n if (dryRun) {\n return {\n bot: botName,\n platform: adapter.platformName,\n dry_run: true,\n payload: adapter.buildPayload(sendOptions),\n };\n }\n\n const result = await rateLimiter.schedule(botName, platform, () =>\n adapter.send(sendOptions),\n );\n\n const auditId = result.messageId || `msg_${Date.now().toString(36)}`;\n auditLogger.log({\n id: auditId,\n messageId: result.messageId,\n bot: botName,\n platform: result.platform,\n type: args.type,\n contentHash: hashContent(content),\n status: result.success ? \"success\" : \"failed\",\n timestamp: new Date().toISOString(),\n latencyMs: result.latencyMs,\n error: result.error,\n });\n\n return {\n bot: botName,\n success: result.success,\n platform: result.platform,\n message_id: result.messageId,\n latency_ms: result.latencyMs,\n error: result.error,\n audit_id: auditId,\n };\n }),\n );\n\n const outcomes = results.map((r, i) => {\n if (r.status === \"fulfilled\") return r.value;\n return {\n bot: args.bots[i],\n success: false,\n error: r.reason instanceof Error ? r.reason.message : String(r.reason),\n };\n });\n\n const successCount = outcomes.filter((o: any) => o.success || o.dry_run).length;\n const failCount = outcomes.length - successCount;\n\n return {\n total: outcomes.length,\n success: successCount,\n failed: failCount,\n results: outcomes,\n };\n };\n}\n","/**\n * send_batch tool - Send the same message to multiple targets on the same bot\n * Useful for Telegram (multiple chat_ids) or platforms that support target override\n */\n\nimport type { PlatformRegistry } from \"../platforms/registry.js\";\nimport type { RateLimiterManager } from \"../queue/rate-limiter.js\";\nimport type { AuditLogger } from \"../audit/logger.js\";\nimport { templateEngine } from \"../templates/engine.js\";\nimport { hashContent } from \"../audit/logger.js\";\nimport type { MessageType, AtConfig, Platform } from \"../config/schema.js\";\n\nexport interface SendBatchArgs {\n bot: string;\n targets: string[];\n type: MessageType;\n content: string;\n title?: string;\n variables?: Record<string, string>;\n at?: AtConfig;\n link_url?: string;\n pic_url?: string;\n buttons?: Array<{ title: string; url: string }>;\n news_items?: Array<{\n title: string;\n description?: string;\n url: string;\n pic_url?: string;\n }>;\n image_url?: string;\n}\n\nexport function createSendBatchHandler(\n registry: PlatformRegistry,\n rateLimiter: RateLimiterManager,\n auditLogger: AuditLogger,\n dryRun: boolean,\n) {\n return async (args: SendBatchArgs) => {\n const adapter = registry.get(args.bot);\n\n // Apply template variables\n let content = args.content;\n if (args.variables && templateEngine.hasExpressions(content)) {\n content = templateEngine.render(content, args.variables);\n }\n\n const sendOptions = {\n type: args.type,\n content,\n title: args.title,\n at: args.at,\n linkUrl: args.link_url,\n picUrl: args.pic_url,\n buttons: args.buttons,\n newsItems: args.news_items,\n imageUrl: args.image_url,\n };\n\n // Send to all targets sequentially (rate limited)\n const results = await Promise.allSettled(\n args.targets.map(async (target) => {\n if (dryRun) {\n return {\n target,\n dry_run: true,\n platform: adapter.platformName,\n };\n }\n\n const platform = adapter.platformName as Platform;\n const result = await rateLimiter.schedule(args.bot, platform, () =>\n adapter.send(sendOptions),\n );\n\n const auditId = result.messageId || `msg_${Date.now().toString(36)}`;\n auditLogger.log({\n id: auditId,\n messageId: result.messageId,\n bot: args.bot,\n platform: result.platform,\n type: args.type,\n contentHash: hashContent(content),\n status: result.success ? \"success\" : \"failed\",\n timestamp: new Date().toISOString(),\n latencyMs: result.latencyMs,\n target,\n error: result.error,\n });\n\n return {\n target,\n success: result.success,\n message_id: result.messageId,\n latency_ms: result.latencyMs,\n error: result.error,\n audit_id: auditId,\n };\n }),\n );\n\n const outcomes = results.map((r, i) => {\n if (r.status === \"fulfilled\") return r.value;\n return {\n target: args.targets[i],\n success: false,\n error: r.reason instanceof Error ? r.reason.message : String(r.reason),\n };\n });\n\n const successCount = outcomes.filter((o: any) => o.success || o.dry_run).length;\n\n return {\n bot: args.bot,\n total: outcomes.length,\n success: successCount,\n failed: outcomes.length - successCount,\n results: outcomes,\n };\n };\n}\n","/**\n * list_bots tool - List all configured bot instances\n */\n\nimport type { PlatformRegistry } from \"../platforms/registry.js\";\nimport type { RateLimiterManager } from \"../queue/rate-limiter.js\";\n\nexport function createListBotsHandler(\n registry: PlatformRegistry,\n rateLimiter: RateLimiterManager,\n) {\n return async () => {\n const bots = registry.list();\n\n const detailed = bots.map((bot) => {\n const queueStats = rateLimiter.getStats(bot.name);\n return {\n name: bot.name,\n platform: bot.platform,\n enabled: bot.enabled,\n queue: queueStats || { queued: 0, running: 0 },\n };\n });\n\n return {\n total: detailed.length,\n bots: detailed,\n platforms: [...new Set(detailed.map((b) => b.platform))],\n };\n };\n}\n","/**\n * message_status tool - Query audit log for message delivery status\n */\n\nimport type { AuditLogger } from \"../audit/logger.js\";\n\nexport interface MessageStatusArgs {\n message_id?: string;\n audit_id?: string;\n bot?: string;\n platform?: string;\n status?: \"success\" | \"failed\";\n since?: string;\n limit?: number;\n}\n\nexport function createMessageStatusHandler(auditLogger: AuditLogger) {\n return async (args: MessageStatusArgs) => {\n // Single message lookup\n if (args.audit_id) {\n const entry = auditLogger.findById(args.audit_id);\n if (!entry) {\n return { found: false, message: `Audit entry \"${args.audit_id}\" not found` };\n }\n return { found: true, entry };\n }\n\n if (args.message_id) {\n const entry = auditLogger.findByMessageId(args.message_id);\n if (!entry) {\n return { found: false, message: `Message \"${args.message_id}\" not found in audit log` };\n }\n return { found: true, entry };\n }\n\n // Filtered query\n const entries = auditLogger.query({\n bot: args.bot,\n platform: args.platform,\n status: args.status,\n since: args.since,\n limit: args.limit ?? 20,\n });\n\n const stats = auditLogger.stats();\n\n return {\n total_found: entries.length,\n entries,\n stats: {\n total_tracked: stats.total,\n success: stats.success,\n failed: stats.failed,\n by_platform: stats.byPlatform,\n },\n };\n };\n}\n","/**\n * render_template tool - Preview template rendering without sending\n */\n\nimport { templateEngine } from \"../templates/engine.js\";\n\nexport interface RenderTemplateArgs {\n template: string;\n variables?: Record<string, string>;\n}\n\nexport function createRenderTemplateHandler() {\n return async (args: RenderTemplateArgs) => {\n const hasVars = templateEngine.hasExpressions(args.template);\n const variables = templateEngine.extractVariables(args.template);\n\n const rendered = templateEngine.render(args.template, args.variables || {});\n\n return {\n template: args.template,\n variables_detected: variables,\n variables_provided: Object.keys(args.variables || {}),\n rendered: rendered,\n has_expressions: hasVars,\n };\n };\n}\n","/**\n * Tool registry - defines all MCP tools and their schemas\n */\n\nimport type { PlatformRegistry } from \"../platforms/registry.js\";\nimport type { RateLimiterManager } from \"../queue/rate-limiter.js\";\nimport type { AuditLogger } from \"../audit/logger.js\";\n\nimport { createSendMessageHandler } from \"./send-message.js\";\nimport { createSendFileHandler } from \"./send-file.js\";\nimport { createSendBroadcastHandler } from \"./send-broadcast.js\";\nimport { createSendBatchHandler } from \"./send-batch.js\";\nimport { createListBotsHandler } from \"./list-bots.js\";\nimport { createMessageStatusHandler } from \"./message-status.js\";\nimport { createRenderTemplateHandler } from \"./render-template.js\";\n\nexport interface ToolDefinition {\n name: string;\n description: string;\n inputSchema: Record<string, unknown>;\n}\n\nexport const toolDefinitions: ToolDefinition[] = [\n {\n name: \"send_message\",\n description:\n \"Send a message to a configured bot. Supports text, markdown, link, image, card, news, and file types. Content can include Handlebars template variables like {{name}}.\",\n inputSchema: {\n type: \"object\",\n properties: {\n bot: {\n type: \"string\",\n description: \"Bot instance name (as configured, e.g. 'dingtalk-ops', 'telegram-bot')\",\n },\n type: {\n type: \"string\",\n enum: [\"text\", \"markdown\", \"link\", \"image\", \"card\", \"news\", \"file\"],\n description: \"Message type\",\n },\n content: {\n type: \"string\",\n description: \"Message content. Supports Handlebars templates: {{variable_name}}\",\n },\n title: {\n type: \"string\",\n description: \"Message title (for markdown, link, card types)\",\n },\n variables: {\n type: \"object\",\n additionalProperties: { type: \"string\" },\n description: \"Template variables as key-value pairs\",\n },\n at: {\n type: \"object\",\n properties: {\n users: { type: \"array\", items: { type: \"string\" }, description: \"User IDs to mention\" },\n mobiles: { type: \"array\", items: { type: \"string\" }, description: \"Phone numbers to mention\" },\n all: { type: \"boolean\", description: \"Mention everyone\" },\n },\n description: \"@mention configuration\",\n },\n link_url: { type: \"string\", description: \"URL for link type messages\" },\n pic_url: { type: \"string\", description: \"Picture/thumbnail URL\" },\n buttons: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n title: { type: \"string\" },\n url: { type: \"string\" },\n },\n required: [\"title\", \"url\"],\n },\n description: \"Buttons for card type messages\",\n },\n single_button_text: { type: \"string\", description: \"Single button text (for actionCard)\" },\n single_button_url: { type: \"string\", description: \"Single button URL\" },\n news_items: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n title: { type: \"string\" },\n description: { type: \"string\" },\n url: { type: \"string\" },\n pic_url: { type: \"string\" },\n },\n required: [\"title\", \"url\"],\n },\n description: \"News/feed items for news type messages\",\n },\n image_url: { type: \"string\", description: \"Image URL for image type messages\" },\n image_base64: { type: \"string\", description: \"Base64-encoded image data\" },\n },\n required: [\"bot\", \"type\", \"content\"],\n },\n },\n {\n name: \"send_file\",\n description:\n \"Send a file or image through a configured bot. Supported platforms: WeCom (files via media_id), Discord (multipart upload), Telegram (sendDocument).\",\n inputSchema: {\n type: \"object\",\n properties: {\n bot: { type: \"string\", description: \"Bot instance name\" },\n file_path: { type: \"string\", description: \"Absolute path to the file to send\" },\n caption: { type: \"string\", description: \"Optional caption for the file\" },\n },\n required: [\"bot\", \"file_path\"],\n },\n },\n {\n name: \"send_broadcast\",\n description:\n \"Send the same message to multiple bots simultaneously (cross-platform broadcast). Useful for sending alerts to DingTalk + WeCom + Slack at the same time.\",\n inputSchema: {\n type: \"object\",\n properties: {\n bots: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"List of bot instance names to broadcast to\",\n },\n type: {\n type: \"string\",\n enum: [\"text\", \"markdown\", \"link\", \"image\", \"card\", \"news\", \"file\"],\n description: \"Message type\",\n },\n content: { type: \"string\", description: \"Message content (supports Handlebars templates)\" },\n title: { type: \"string\", description: \"Message title\" },\n variables: {\n type: \"object\",\n additionalProperties: { type: \"string\" },\n description: \"Template variables\",\n },\n at: {\n type: \"object\",\n properties: {\n users: { type: \"array\", items: { type: \"string\" } },\n mobiles: { type: \"array\", items: { type: \"string\" } },\n all: { type: \"boolean\" },\n },\n },\n link_url: { type: \"string\" },\n pic_url: { type: \"string\" },\n buttons: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: { title: { type: \"string\" }, url: { type: \"string\" } },\n required: [\"title\", \"url\"],\n },\n },\n news_items: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n title: { type: \"string\" },\n description: { type: \"string\" },\n url: { type: \"string\" },\n pic_url: { type: \"string\" },\n },\n required: [\"title\", \"url\"],\n },\n },\n image_url: { type: \"string\" },\n },\n required: [\"bots\", \"type\", \"content\"],\n },\n },\n {\n name: \"send_batch\",\n description:\n \"Send the same message to multiple targets through the same bot. Useful for Telegram (multiple chat_ids) or broadcasting within one platform.\",\n inputSchema: {\n type: \"object\",\n properties: {\n bot: { type: \"string\", description: \"Bot instance name\" },\n targets: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"List of target IDs (e.g. Telegram chat_ids)\",\n },\n type: {\n type: \"string\",\n enum: [\"text\", \"markdown\", \"link\", \"image\", \"card\", \"news\", \"file\"],\n description: \"Message type\",\n },\n content: { type: \"string\", description: \"Message content\" },\n title: { type: \"string\" },\n variables: {\n type: \"object\",\n additionalProperties: { type: \"string\" },\n },\n at: {\n type: \"object\",\n properties: {\n users: { type: \"array\", items: { type: \"string\" } },\n mobiles: { type: \"array\", items: { type: \"string\" } },\n all: { type: \"boolean\" },\n },\n },\n link_url: { type: \"string\" },\n pic_url: { type: \"string\" },\n buttons: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: { title: { type: \"string\" }, url: { type: \"string\" } },\n required: [\"title\", \"url\"],\n },\n },\n news_items: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n title: { type: \"string\" },\n description: { type: \"string\" },\n url: { type: \"string\" },\n pic_url: { type: \"string\" },\n },\n required: [\"title\", \"url\"],\n },\n },\n image_url: { type: \"string\" },\n },\n required: [\"bot\", \"targets\", \"type\", \"content\"],\n },\n },\n {\n name: \"list_bots\",\n description:\n \"List all configured bot instances with their platform, status, and queue information.\",\n inputSchema: {\n type: \"object\",\n properties: {},\n },\n },\n {\n name: \"message_status\",\n description:\n \"Query the audit log for message delivery status. Look up by message_id, audit_id, or filter by bot/platform/status/time range.\",\n inputSchema: {\n type: \"object\",\n properties: {\n message_id: { type: \"string\", description: \"Message ID to look up\" },\n audit_id: { type: \"string\", description: \"Audit log entry ID\" },\n bot: { type: \"string\", description: \"Filter by bot name\" },\n platform: { type: \"string\", description: \"Filter by platform\" },\n status: { type: \"string\", enum: [\"success\", \"failed\"], description: \"Filter by status\" },\n since: { type: \"string\", description: \"ISO timestamp to filter entries after\" },\n limit: { type: \"number\", description: \"Maximum entries to return (default: 20)\" },\n },\n },\n },\n {\n name: \"render_template\",\n description:\n \"Preview a Handlebars template rendering without sending. Shows detected variables and rendered output.\",\n inputSchema: {\n type: \"object\",\n properties: {\n template: {\n type: \"string\",\n description: \"Handlebars template string (e.g. 'Hello {{name}}, status: {{status}}')\",\n },\n variables: {\n type: \"object\",\n additionalProperties: { type: \"string\" },\n description: \"Variables to substitute\",\n },\n },\n required: [\"template\"],\n },\n },\n];\n\nexport interface ToolHandlers {\n send_message: ReturnType<typeof createSendMessageHandler>;\n send_file: ReturnType<typeof createSendFileHandler>;\n send_broadcast: ReturnType<typeof createSendBroadcastHandler>;\n send_batch: ReturnType<typeof createSendBatchHandler>;\n list_bots: ReturnType<typeof createListBotsHandler>;\n message_status: ReturnType<typeof createMessageStatusHandler>;\n render_template: ReturnType<typeof createRenderTemplateHandler>;\n}\n\nexport function createToolHandlers(\n registry: PlatformRegistry,\n rateLimiter: RateLimiterManager,\n auditLogger: AuditLogger,\n dryRun: boolean,\n): ToolHandlers {\n return {\n send_message: createSendMessageHandler(registry, rateLimiter, auditLogger, dryRun),\n send_file: createSendFileHandler(registry, rateLimiter, auditLogger, dryRun),\n send_broadcast: createSendBroadcastHandler(registry, rateLimiter, auditLogger, dryRun),\n send_batch: createSendBatchHandler(registry, rateLimiter, auditLogger, dryRun),\n list_bots: createListBotsHandler(registry, rateLimiter),\n message_status: createMessageStatusHandler(auditLogger),\n render_template: createRenderTemplateHandler(),\n };\n}\n"],"mappings":"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","names":["readFileSync","readFileSync","createHmac","createHmac","readFileSync","readFileSync","readFileSync","basename","readFileSync","basename","existsSync","existsSync","auditId","auditId"]}
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "botmsg",
3
+ "version": "0.1.0",
4
+ "description": "MCP server for sending messages to multiple bot platforms (DingTalk, WeCom, Feishu, Lark, Slack, Discord, Telegram)",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "botmsg": "dist/index.js"
9
+ },
10
+ "files": [
11
+ "dist"
12
+ ],
13
+ "scripts": {
14
+ "build": "tsup",
15
+ "dev": "tsx src/index.ts",
16
+ "prepublishOnly": "npm run build",
17
+ "test": "vitest run"
18
+ },
19
+ "keywords": [
20
+ "mcp",
21
+ "model-context-protocol",
22
+ "bot",
23
+ "dingtalk",
24
+ "wecom",
25
+ "feishu",
26
+ "lark",
27
+ "slack",
28
+ "discord",
29
+ "telegram",
30
+ "messaging",
31
+ "webhook",
32
+ "ai",
33
+ "claude"
34
+ ],
35
+ "author": "",
36
+ "license": "MIT",
37
+ "repository": {
38
+ "type": "git",
39
+ "url": "https://github.com/user/botmsg"
40
+ },
41
+ "engines": {
42
+ "node": ">=18.0.0"
43
+ },
44
+ "dependencies": {
45
+ "@modelcontextprotocol/sdk": "^1.12.1",
46
+ "bottleneck": "^2.19.5",
47
+ "handlebars": "^4.7.8",
48
+ "yaml": "^2.7.1",
49
+ "zod": "^3.24.4"
50
+ },
51
+ "devDependencies": {
52
+ "@types/node": "^22.15.17",
53
+ "tsup": "^8.4.0",
54
+ "tsx": "^4.19.4",
55
+ "typescript": "^5.8.3",
56
+ "vitest": "^3.1.3"
57
+ }
58
+ }