diff --git a/plugins/ton-bridge/README.md b/plugins/ton-bridge/README.md index cd67307..dab9a28 100644 --- a/plugins/ton-bridge/README.md +++ b/plugins/ton-bridge/README.md @@ -1,22 +1,23 @@ # TON Bridge -Share the TON Bridge Mini App link with a beautiful inline button in Telegram chats. +Share the TON Bridge Mini App link with an inline button in Telegram chats. +Works in DMs, groups, and channels. TON Bridge works with support from TONBANKCARD. ## Features -- Inline button for TON Bridge Mini App access -- Customizable button text and emoji +- Sends a message with a URL inline button directly to the current chat +- Button text controllable per tool call (the LLM can omit or include emoji) +- Customizable default button text via config - Custom message support -- Easy integration with AI agents ## Tools | Tool | Description | Category | |------|-------------|----------| -| `ton_bridge_open` | Send a message with a TON Bridge Mini App link | action | -| `ton_bridge_about` | Send info about TON Bridge with a link to the Mini App | data-bearing | +| `ton_bridge_open` | Send a message with a TON Bridge Mini App button | action | +| `ton_bridge_about` | Send info about TON Bridge with a Mini App button | data-bearing | | `ton_bridge_custom_message` | Send a custom message alongside a TON Bridge button | action | ## Installation @@ -32,11 +33,12 @@ cp -r plugins/ton-bridge ~/.teleton/plugins/ # ~/.teleton/config.yaml plugins: ton_bridge: - buttonText: "TON Bridge No1" # Button text (default: "TON Bridge No1") - buttonEmoji: "🌉" # Emoji on button (default: "🌉") - startParam: "" # Optional start parameter + buttonText: "TON Bridge No1" # Default button label (default: "TON Bridge No1") + startParam: "" # Optional start parameter appended to the Mini App URL ``` +> **Note:** Emoji on the button is controlled by the agent at call time via the `buttonText` parameter, not by config. This allows the agent to send buttons with or without emoji as requested by the user. + ## Usage Examples ### Open TON Bridge @@ -44,7 +46,14 @@ plugins: Open TON Bridge ``` -Will send a message with a button linking to https://t.me/TONBridge_robot?startapp +Sends a message with a button linking to `https://t.me/TONBridge_robot?startapp`. + +### Open TON Bridge without emoji on button +``` +Open TON Bridge, no emoji on the button +``` + +The agent will call `ton_bridge_open` with `buttonText: "TON Bridge No1"` (no emoji). ### Get Info About TON Bridge ``` @@ -63,16 +72,20 @@ Send "Transfer your assets via TON Bridge" with a TON Bridge button | Param | Type | Required | Default | Description | |-------|------|----------|---------|-------------| | `message` | string | No | — | Optional message text to show with the button | +| `buttonText` | string | No | config default | Button label. Do not include emoji unless user requested it. | ### `ton_bridge_about` -No parameters required. +| Param | Type | Required | Default | Description | +|-------|------|----------|---------|-------------| +| `buttonText` | string | No | config default | Button label. Do not include emoji unless user requested it. | ### `ton_bridge_custom_message` | Param | Type | Required | Default | Description | |-------|------|----------|---------|-------------| | `customMessage` | string | Yes | — | Custom message text to display with the button | +| `buttonText` | string | No | config default | Button label. Do not include emoji unless user requested it. | --- diff --git a/plugins/ton-bridge/index.js b/plugins/ton-bridge/index.js index 8e32906..1d3f672 100644 --- a/plugins/ton-bridge/index.js +++ b/plugins/ton-bridge/index.js @@ -2,7 +2,10 @@ * TON Bridge plugin * * Provides LLM-callable tools to share the TON Bridge Mini App link. - * Pattern B (SDK) — uses sdk.pluginConfig, sdk.log + * Pattern B (SDK) — uses sdk.pluginConfig, sdk.log, sdk.telegram.sendMessage + * + * Actively sends messages with URL inline buttons so the button renders + * correctly in DMs, groups, and channels. */ // ─── Manifest (inline) ──────────────────────────────────────────────────────── @@ -16,7 +19,6 @@ export const manifest = { description: "Share TON Bridge Mini App link with a button. Opens https://t.me/TONBridge_robot?startapp", defaultConfig: { buttonText: "TON Bridge No1", - buttonEmoji: "🌉", startParam: "", }, }; @@ -25,14 +27,10 @@ export const manifest = { const MINI_APP_URL = "https://t.me/TONBridge_robot?startapp"; -function buildReplyMarkup(buttonText, buttonEmoji, startParam) { - const label = buttonEmoji ? `${buttonEmoji} ${buttonText}` : buttonText; - const url = startParam +function buildUrl(startParam) { + return startParam ? `${MINI_APP_URL}=${encodeURIComponent(startParam)}` : MINI_APP_URL; - return { - inline_keyboard: [[{ text: label, url }]], - }; } // ─── Tools ──────────────────────────────────────────────────────────────────── @@ -42,7 +40,7 @@ export const tools = (sdk) => [ { name: "ton_bridge_open", description: - "Send a message with a TON Bridge Mini App link. Use when the user asks to open or access TON Bridge.", + "Send a message with a TON Bridge Mini App button. Use when the user asks to open or access TON Bridge. Sends the message directly to the current chat.", category: "action", parameters: { type: "object", @@ -53,30 +51,45 @@ export const tools = (sdk) => [ minLength: 1, maxLength: 500, }, + buttonText: { + type: "string", + description: "Button label text. Omit to use the configured default. Do NOT include emoji here unless the user explicitly requested one.", + minLength: 1, + maxLength: 64, + }, }, }, execute: async (params, context) => { try { - const buttonText = sdk.pluginConfig?.buttonText ?? "TON Bridge No1"; - const buttonEmoji = sdk.pluginConfig?.buttonEmoji ?? "🌉"; + const buttonText = params.buttonText ?? sdk.pluginConfig?.buttonText ?? "TON Bridge No1"; const startParam = sdk.pluginConfig?.startParam ?? ""; + const url = buildUrl(startParam); - const content = + const text = params.message ?? - "🌉 **TON Bridge** — The #1 Bridge in the TON Catalog\n\nClick the button below to open TON Bridge Mini App."; + "TON Bridge — The #1 Bridge in the TON Catalog\n\nClick the button below to open TON Bridge Mini App."; sdk.log?.info( `ton_bridge_open called by ${context?.senderId ?? "unknown"}` ); + const messageId = await sdk.telegram.sendMessage( + context.chatId, + text, + { + inlineKeyboard: [[{ text: buttonText, url }]], + } + ); + return { success: true, - data: { - content, - reply_markup: buildReplyMarkup(buttonText, buttonEmoji, startParam), - }, + data: { message_id: messageId, chat_id: context.chatId }, }; } catch (err) { + if (err.name === "PluginSDKError") { + sdk.log?.error(`ton_bridge_open failed: ${err.code}: ${err.message}`); + return { success: false, error: `${err.code}: ${String(err.message).slice(0, 500)}` }; + } sdk.log?.error("ton_bridge_open failed:", err.message); return { success: false, error: String(err.message || err).slice(0, 500) }; } @@ -87,31 +100,46 @@ export const tools = (sdk) => [ { name: "ton_bridge_about", description: - "Send an info message about TON Bridge with a link to the Mini App. Use when the user asks about TON Bridge or wants more information.", + "Send an info message about TON Bridge with a Mini App button. Use when the user asks about TON Bridge or wants more information.", category: "data-bearing", parameters: { type: "object", - properties: {}, + properties: { + buttonText: { + type: "string", + description: "Button label text. Omit to use the configured default. Do NOT include emoji here unless the user explicitly requested one.", + minLength: 1, + maxLength: 64, + }, + }, }, execute: async (params, context) => { try { - const buttonText = sdk.pluginConfig?.buttonText ?? "TON Bridge No1"; - const buttonEmoji = sdk.pluginConfig?.buttonEmoji ?? "🌉"; + const buttonText = params.buttonText ?? sdk.pluginConfig?.buttonText ?? "TON Bridge No1"; const startParam = sdk.pluginConfig?.startParam ?? ""; + const url = buildUrl(startParam); sdk.log?.info( `ton_bridge_about called by ${context?.senderId ?? "unknown"}` ); + const messageId = await sdk.telegram.sendMessage( + context.chatId, + "About TON Bridge\n\nTON Bridge is the #1 bridge in the TON Catalog. Transfer assets across chains seamlessly via the official Mini App.", + { + inlineKeyboard: [[{ text: buttonText, url }]], + } + ); + return { success: true, - data: { - content: - "â„šī¸ **About TON Bridge**\n\nTON Bridge is the #1 bridge in the TON Catalog. Transfer assets across chains seamlessly via the official Mini App.", - reply_markup: buildReplyMarkup(buttonText, buttonEmoji, startParam), - }, + data: { message_id: messageId, chat_id: context.chatId }, }; } catch (err) { + if (err.name === "PluginSDKError") { + sdk.log?.error(`ton_bridge_about failed: ${err.code}: ${err.message}`); + return { success: false, error: `${err.code}: ${String(err.message).slice(0, 500)}` }; + } sdk.log?.error("ton_bridge_about failed:", err.message); return { success: false, error: String(err.message || err).slice(0, 500) }; } @@ -133,27 +161,42 @@ export const tools = (sdk) => [ minLength: 1, maxLength: 500, }, + buttonText: { + type: "string", + description: "Button label text. Omit to use the configured default. Do NOT include emoji here unless the user explicitly requested one.", + minLength: 1, + maxLength: 64, + }, }, required: ["customMessage"], }, execute: async (params, context) => { try { - const buttonText = sdk.pluginConfig?.buttonText ?? "TON Bridge No1"; - const buttonEmoji = sdk.pluginConfig?.buttonEmoji ?? "🌉"; + const buttonText = params.buttonText ?? sdk.pluginConfig?.buttonText ?? "TON Bridge No1"; const startParam = sdk.pluginConfig?.startParam ?? ""; + const url = buildUrl(startParam); sdk.log?.info( `ton_bridge_custom_message called by ${context?.senderId ?? "unknown"}` ); + const messageId = await sdk.telegram.sendMessage( + context.chatId, + params.customMessage, + { + inlineKeyboard: [[{ text: buttonText, url }]], + } + ); + return { success: true, - data: { - content: params.customMessage, - reply_markup: buildReplyMarkup(buttonText, buttonEmoji, startParam), - }, + data: { message_id: messageId, chat_id: context.chatId }, }; } catch (err) { + if (err.name === "PluginSDKError") { + sdk.log?.error(`ton_bridge_custom_message failed: ${err.code}: ${err.message}`); + return { success: false, error: `${err.code}: ${String(err.message).slice(0, 500)}` }; + } sdk.log?.error("ton_bridge_custom_message failed:", err.message); return { success: false, error: String(err.message || err).slice(0, 500) }; } diff --git a/plugins/ton-bridge/manifest.json b/plugins/ton-bridge/manifest.json index d402c4d..5631d91 100644 --- a/plugins/ton-bridge/manifest.json +++ b/plugins/ton-bridge/manifest.json @@ -18,7 +18,6 @@ ], "defaultConfig": { "buttonText": "TON Bridge No1", - "buttonEmoji": "🌉", "startParam": "" }, "permissions": [],