@zhin.js/adapter-telegram 1.1.26 → 1.1.27
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.
- package/CHANGELOG.md +176 -0
- package/LICENSE +21 -0
- package/PERMITS.md +17 -13
- package/README.md +9 -5
- package/adapters/telegram/index.js +3 -0
- package/adapters/telegram/index.ts +3 -0
- package/agents/telegram/conversation.js +35 -0
- package/agents/telegram/conversation.ts +38 -0
- package/agents/telegram/messages.js +8 -0
- package/agents/telegram/messages.ts +8 -0
- package/agents/telegram/skills/telegram-chat-admin/tools/create_invite/index.js +6 -8
- package/agents/telegram/skills/telegram-chat-admin/tools/create_invite/index.ts +7 -9
- package/agents/telegram/skills/telegram-chat-admin/tools/list_admins/index.js +5 -7
- package/agents/telegram/skills/telegram-chat-admin/tools/list_admins/index.ts +6 -8
- package/agents/telegram/skills/telegram-chat-admin/tools/member_count/index.js +5 -7
- package/agents/telegram/skills/telegram-chat-admin/tools/member_count/index.ts +6 -8
- package/agents/telegram/skills/telegram-chat-admin/tools/pin_message/index.js +5 -6
- package/agents/telegram/skills/telegram-chat-admin/tools/pin_message/index.ts +6 -7
- package/agents/telegram/skills/telegram-chat-admin/tools/set_description/index.js +5 -4
- package/agents/telegram/skills/telegram-chat-admin/tools/set_description/index.ts +6 -5
- package/agents/telegram/skills/telegram-chat-admin/tools/unpin_message/index.js +5 -6
- package/agents/telegram/skills/telegram-chat-admin/tools/unpin_message/index.ts +6 -7
- package/agents/telegram/skills/telegram-group-permissions/tools/set_permissions/index.js +5 -6
- package/agents/telegram/skills/telegram-group-permissions/tools/set_permissions/index.ts +6 -7
- package/agents/telegram/skills/telegram-messages/tools/react/index.js +5 -6
- package/agents/telegram/skills/telegram-messages/tools/react/index.ts +6 -7
- package/agents/telegram/skills/telegram-messages/tools/send_poll/index.js +8 -7
- package/agents/telegram/skills/telegram-messages/tools/send_poll/index.ts +9 -8
- package/agents/telegram/skills/telegram-messages/tools/send_sticker/index.js +7 -7
- package/agents/telegram/skills/telegram-messages/tools/send_sticker/index.ts +8 -8
- package/lib/endpoint.d.ts +2 -1
- package/lib/endpoint.js +75 -21
- package/lib/index.d.ts +1 -1
- package/lib/index.js +1 -1
- package/lib/platform-permit.d.ts +16 -16
- package/lib/platform-permit.js +26 -45
- package/lib/protocol.d.ts +25 -4
- package/lib/protocol.js +31 -16
- package/lib/webhook.d.ts +1 -2
- package/lib/webhook.js +9 -20
- package/package.json +23 -27
- package/plugin.js +0 -6
- package/schema.json +0 -56
- package/src/endpoint.ts +73 -25
- package/src/index.ts +1 -3
- package/src/platform-permit.ts +27 -56
- package/src/protocol.ts +52 -20
- package/src/webhook.ts +11 -23
|
@@ -1,21 +1,20 @@
|
|
|
1
1
|
// Generated by build-plugin-runtime-entries.mjs. Do not edit.
|
|
2
2
|
import { messages as t } from "../../../../messages.js";
|
|
3
|
+
import { currentChat } from "../../../../conversation.js";
|
|
3
4
|
import { defineAgentTool } from '@zhin.js/tool';
|
|
4
5
|
import { z } from 'zod';
|
|
5
|
-
import { platformPermission } from '@zhin.js/permission';
|
|
6
6
|
export default defineAgentTool({
|
|
7
|
-
description: '
|
|
7
|
+
description: '置顶当前 Telegram 群组中的消息',
|
|
8
8
|
inputSchema: z.object({
|
|
9
|
-
chat_id: z.string().describe('聊天 ID'),
|
|
10
9
|
message_id: z.string().describe('消息 ID'),
|
|
11
10
|
}),
|
|
12
11
|
adapter: 'telegram',
|
|
13
12
|
scopes: ["group", "channel"],
|
|
14
13
|
tags: ['telegram'],
|
|
15
|
-
permissions: [
|
|
16
|
-
async execute({
|
|
14
|
+
permissions: ['platform-permission:pin_messages', 'bot-permission:pin_messages'],
|
|
15
|
+
async execute({ message_id }, context) {
|
|
17
16
|
const endpoint = context.$client;
|
|
18
|
-
const success = await endpoint.pinMessage(
|
|
17
|
+
const success = await endpoint.pinMessage(currentChat(context), Number(message_id));
|
|
19
18
|
return { success, message: success ? t(context.locale, 'pinDone') : t(context.locale, 'operationFailed') };
|
|
20
19
|
},
|
|
21
20
|
});
|
|
@@ -1,21 +1,20 @@
|
|
|
1
1
|
import { messages as t } from "../../../../messages.js";
|
|
2
|
+
import { currentChat } from "../../../../conversation.js";
|
|
2
3
|
import { defineAgentTool } from '@zhin.js/tool';
|
|
3
4
|
import { z } from 'zod';
|
|
4
|
-
import { platformPermission } from '@zhin.js/permission';
|
|
5
5
|
|
|
6
|
-
export default defineAgentTool<{
|
|
7
|
-
description: '
|
|
6
|
+
export default defineAgentTool<{ message_id: string }>({
|
|
7
|
+
description: '置顶当前 Telegram 群组中的消息',
|
|
8
8
|
inputSchema: z.object({
|
|
9
|
-
chat_id: z.string().describe('聊天 ID'),
|
|
10
9
|
message_id: z.string().describe('消息 ID'),
|
|
11
10
|
}),
|
|
12
11
|
adapter: 'telegram',
|
|
13
12
|
scopes: ["group","channel"],
|
|
14
13
|
tags: ['telegram'],
|
|
15
|
-
permissions: [
|
|
16
|
-
async execute({
|
|
14
|
+
permissions: ['platform-permission:pin_messages', 'bot-permission:pin_messages'],
|
|
15
|
+
async execute({ message_id }, context) {
|
|
17
16
|
const endpoint = context.$client;
|
|
18
|
-
const success = await endpoint.pinMessage(
|
|
17
|
+
const success = await endpoint.pinMessage(currentChat(context), Number(message_id));
|
|
19
18
|
return { success, message: success ? t(context.locale, 'pinDone') : t(context.locale, 'operationFailed') };
|
|
20
19
|
},
|
|
21
20
|
});
|
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
// Generated by build-plugin-runtime-entries.mjs. Do not edit.
|
|
2
2
|
import { messages as t } from "../../../../messages.js";
|
|
3
|
+
import { currentChat } from "../../../../conversation.js";
|
|
3
4
|
import { defineAgentTool } from '@zhin.js/tool';
|
|
4
5
|
import { z } from 'zod';
|
|
5
6
|
export default defineAgentTool({
|
|
6
|
-
description: '
|
|
7
|
+
description: '设置当前 Telegram 群组描述',
|
|
7
8
|
inputSchema: z.object({
|
|
8
|
-
chat_id: z.string().describe('聊天 ID'),
|
|
9
9
|
description: z.string().describe('群描述文字'),
|
|
10
10
|
}),
|
|
11
11
|
adapter: 'telegram',
|
|
12
12
|
scopes: ["group", "channel"],
|
|
13
|
+
permissions: ['platform-permission:change_info', 'bot-permission:change_info'],
|
|
13
14
|
tags: ['telegram'],
|
|
14
|
-
async execute({
|
|
15
|
+
async execute({ description }, context) {
|
|
15
16
|
const endpoint = context.$client;
|
|
16
|
-
const success = await endpoint.setChatDescription(
|
|
17
|
+
const success = await endpoint.setChatDescription(currentChat(context), description);
|
|
17
18
|
return { success, message: success ? t(context.locale, 'descriptionUpdated') : t(context.locale, 'operationFailed') };
|
|
18
19
|
},
|
|
19
20
|
});
|
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
import { messages as t } from "../../../../messages.js";
|
|
2
|
+
import { currentChat } from "../../../../conversation.js";
|
|
2
3
|
import { defineAgentTool } from '@zhin.js/tool';
|
|
3
4
|
import { z } from 'zod';
|
|
4
5
|
|
|
5
|
-
export default defineAgentTool<{
|
|
6
|
-
description: '
|
|
6
|
+
export default defineAgentTool<{ description: string }>({
|
|
7
|
+
description: '设置当前 Telegram 群组描述',
|
|
7
8
|
inputSchema: z.object({
|
|
8
|
-
chat_id: z.string().describe('聊天 ID'),
|
|
9
9
|
description: z.string().describe('群描述文字'),
|
|
10
10
|
}),
|
|
11
11
|
adapter: 'telegram',
|
|
12
12
|
scopes: ["group","channel"],
|
|
13
|
+
permissions: ['platform-permission:change_info', 'bot-permission:change_info'],
|
|
13
14
|
tags: ['telegram'],
|
|
14
|
-
async execute({
|
|
15
|
+
async execute({ description }, context) {
|
|
15
16
|
const endpoint = context.$client;
|
|
16
|
-
const success = await endpoint.setChatDescription(
|
|
17
|
+
const success = await endpoint.setChatDescription(currentChat(context), description);
|
|
17
18
|
return { success, message: success ? t(context.locale, 'descriptionUpdated') : t(context.locale, 'operationFailed') };
|
|
18
19
|
},
|
|
19
20
|
});
|
|
@@ -1,21 +1,20 @@
|
|
|
1
1
|
// Generated by build-plugin-runtime-entries.mjs. Do not edit.
|
|
2
2
|
import { messages as t } from "../../../../messages.js";
|
|
3
|
+
import { currentChat } from "../../../../conversation.js";
|
|
3
4
|
import { defineAgentTool } from '@zhin.js/tool';
|
|
4
5
|
import { z } from 'zod';
|
|
5
|
-
import { platformPermission } from '@zhin.js/permission';
|
|
6
6
|
export default defineAgentTool({
|
|
7
|
-
description: '
|
|
7
|
+
description: '取消置顶当前 Telegram 群组中的消息',
|
|
8
8
|
inputSchema: z.object({
|
|
9
|
-
chat_id: z.string().describe('聊天 ID'),
|
|
10
9
|
message_id: z.string().optional().describe('消息 ID(可选,不提供则取消所有置顶)'),
|
|
11
10
|
}),
|
|
12
11
|
adapter: 'telegram',
|
|
13
12
|
scopes: ["group", "channel"],
|
|
14
13
|
tags: ['telegram'],
|
|
15
|
-
permissions: [
|
|
16
|
-
async execute({
|
|
14
|
+
permissions: ['platform-permission:pin_messages', 'bot-permission:pin_messages'],
|
|
15
|
+
async execute({ message_id }, context) {
|
|
17
16
|
const endpoint = context.$client;
|
|
18
|
-
const success = await endpoint.unpinMessage(
|
|
17
|
+
const success = await endpoint.unpinMessage(currentChat(context), message_id ? Number(message_id) : undefined);
|
|
19
18
|
return { success, message: success ? t(context.locale, 'messageUnpinned') : t(context.locale, 'operationFailed') };
|
|
20
19
|
},
|
|
21
20
|
});
|
|
@@ -1,21 +1,20 @@
|
|
|
1
1
|
import { messages as t } from "../../../../messages.js";
|
|
2
|
+
import { currentChat } from "../../../../conversation.js";
|
|
2
3
|
import { defineAgentTool } from '@zhin.js/tool';
|
|
3
4
|
import { z } from 'zod';
|
|
4
|
-
import { platformPermission } from '@zhin.js/permission';
|
|
5
5
|
|
|
6
|
-
export default defineAgentTool<{
|
|
7
|
-
description: '
|
|
6
|
+
export default defineAgentTool<{ message_id?: string }>({
|
|
7
|
+
description: '取消置顶当前 Telegram 群组中的消息',
|
|
8
8
|
inputSchema: z.object({
|
|
9
|
-
chat_id: z.string().describe('聊天 ID'),
|
|
10
9
|
message_id: z.string().optional().describe('消息 ID(可选,不提供则取消所有置顶)'),
|
|
11
10
|
}),
|
|
12
11
|
adapter: 'telegram',
|
|
13
12
|
scopes: ["group","channel"],
|
|
14
13
|
tags: ['telegram'],
|
|
15
|
-
permissions: [
|
|
16
|
-
async execute({
|
|
14
|
+
permissions: ['platform-permission:pin_messages', 'bot-permission:pin_messages'],
|
|
15
|
+
async execute({ message_id }, context) {
|
|
17
16
|
const endpoint = context.$client;
|
|
18
|
-
const success = await endpoint.unpinMessage(
|
|
17
|
+
const success = await endpoint.unpinMessage(currentChat(context), message_id ? Number(message_id) : undefined);
|
|
19
18
|
return { success, message: success ? t(context.locale, 'messageUnpinned') : t(context.locale, 'operationFailed') };
|
|
20
19
|
},
|
|
21
20
|
});
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
// Generated by build-plugin-runtime-entries.mjs. Do not edit.
|
|
2
2
|
import { messages as t } from "../../../../messages.js";
|
|
3
|
+
import { currentChat } from "../../../../conversation.js";
|
|
3
4
|
import { defineAgentTool } from '@zhin.js/tool';
|
|
4
5
|
import { z } from 'zod';
|
|
5
|
-
import { platformPermission } from '@zhin.js/permission';
|
|
6
6
|
export default defineAgentTool({
|
|
7
|
-
description: '
|
|
7
|
+
description: '设置当前 Telegram 群组的默认成员权限',
|
|
8
8
|
inputSchema: z.object({
|
|
9
|
-
chat_id: z.string().describe('聊天 ID'),
|
|
10
9
|
can_send_messages: z.boolean().optional().describe('是否可以发消息'),
|
|
11
10
|
can_send_photos: z.boolean().optional().describe('是否可以发图片'),
|
|
12
11
|
can_send_videos: z.boolean().optional().describe('是否可以发视频'),
|
|
@@ -20,15 +19,15 @@ export default defineAgentTool({
|
|
|
20
19
|
adapter: 'telegram',
|
|
21
20
|
scopes: ["group"],
|
|
22
21
|
tags: ['telegram'],
|
|
23
|
-
permissions: [
|
|
24
|
-
async execute(
|
|
22
|
+
permissions: ['platform-permission:restrict_members', 'bot-permission:restrict_members'],
|
|
23
|
+
async execute(perms, context) {
|
|
25
24
|
const endpoint = context.$client;
|
|
26
25
|
const permissions = {};
|
|
27
26
|
for (const [k, v] of Object.entries(perms)) {
|
|
28
27
|
if (typeof v === 'boolean')
|
|
29
28
|
permissions[k] = v;
|
|
30
29
|
}
|
|
31
|
-
const success = await endpoint.setChatPermissionsAll(
|
|
30
|
+
const success = await endpoint.setChatPermissionsAll(currentChat(context), permissions);
|
|
32
31
|
return { success, message: success ? t(context.locale, 'permissionsUpdated') : t(context.locale, 'operationFailed') };
|
|
33
32
|
},
|
|
34
33
|
});
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { messages as t } from "../../../../messages.js";
|
|
2
|
+
import { currentChat } from "../../../../conversation.js";
|
|
2
3
|
import { defineAgentTool } from '@zhin.js/tool';
|
|
3
4
|
import { z } from 'zod';
|
|
4
|
-
import { platformPermission } from '@zhin.js/permission';
|
|
5
5
|
|
|
6
|
-
export default defineAgentTool<{
|
|
7
|
-
description: '
|
|
6
|
+
export default defineAgentTool<{ can_send_messages?: boolean; can_send_photos?: boolean; can_send_videos?: boolean; can_send_polls?: boolean; can_send_other_messages?: boolean; can_add_web_page_previews?: boolean; can_change_info?: boolean; can_invite_users?: boolean; can_pin_messages?: boolean }>({
|
|
7
|
+
description: '设置当前 Telegram 群组的默认成员权限',
|
|
8
8
|
inputSchema: z.object({
|
|
9
|
-
chat_id: z.string().describe('聊天 ID'),
|
|
10
9
|
can_send_messages: z.boolean().optional().describe('是否可以发消息'),
|
|
11
10
|
can_send_photos: z.boolean().optional().describe('是否可以发图片'),
|
|
12
11
|
can_send_videos: z.boolean().optional().describe('是否可以发视频'),
|
|
@@ -20,14 +19,14 @@ export default defineAgentTool<{ chat_id: string; can_send_messages?: boolean; c
|
|
|
20
19
|
adapter: 'telegram',
|
|
21
20
|
scopes: ["group"],
|
|
22
21
|
tags: ['telegram'],
|
|
23
|
-
permissions: [
|
|
24
|
-
async execute(
|
|
22
|
+
permissions: ['platform-permission:restrict_members', 'bot-permission:restrict_members'],
|
|
23
|
+
async execute(perms: { can_send_messages?: boolean; can_send_photos?: boolean; can_send_videos?: boolean; can_send_polls?: boolean; can_send_other_messages?: boolean; can_add_web_page_previews?: boolean; can_change_info?: boolean; can_invite_users?: boolean; can_pin_messages?: boolean }, context) {
|
|
25
24
|
const endpoint = context.$client;
|
|
26
25
|
const permissions: Record<string, boolean> = {};
|
|
27
26
|
for (const [k, v] of Object.entries(perms)) {
|
|
28
27
|
if (typeof v === 'boolean') permissions[k] = v;
|
|
29
28
|
}
|
|
30
|
-
const success = await endpoint.setChatPermissionsAll(
|
|
29
|
+
const success = await endpoint.setChatPermissionsAll(currentChat(context), permissions);
|
|
31
30
|
return { success, message: success ? t(context.locale, 'permissionsUpdated') : t(context.locale, 'operationFailed') };
|
|
32
31
|
},
|
|
33
32
|
});
|
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
// Generated by build-plugin-runtime-entries.mjs. Do not edit.
|
|
2
2
|
import { messages as t } from "../../../../messages.js";
|
|
3
|
+
import { currentChat } from "../../../../conversation.js";
|
|
3
4
|
import { defineAgentTool } from '@zhin.js/tool';
|
|
4
5
|
import { z } from 'zod';
|
|
5
6
|
export default defineAgentTool({
|
|
6
|
-
description: '
|
|
7
|
+
description: '对当前 Telegram 会话中的消息添加表情反应',
|
|
7
8
|
inputSchema: z.object({
|
|
8
|
-
|
|
9
|
-
message_id: z.string().describe('消息 ID'),
|
|
9
|
+
message_id: z.string().describe('当前会话中的消息 ID'),
|
|
10
10
|
reaction: z.string().describe('反应表情(如 👍、❤️、🔥)'),
|
|
11
11
|
}),
|
|
12
12
|
adapter: 'telegram',
|
|
13
13
|
tags: ['telegram'],
|
|
14
|
-
async execute({
|
|
15
|
-
const
|
|
16
|
-
const success = await endpoint.setMessageReaction(Number(chat_id), Number(message_id), reaction);
|
|
14
|
+
async execute({ message_id, reaction }, context) {
|
|
15
|
+
const success = await context.$client.setMessageReaction(currentChat(context, { allowPrivate: true }), Number(message_id), reaction);
|
|
17
16
|
return { success, message: success ? t(context.locale, 'reactionAdded', { p0: reaction }) : t(context.locale, 'operationFailed') };
|
|
18
17
|
},
|
|
19
18
|
});
|
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
import { messages as t } from "../../../../messages.js";
|
|
2
|
+
import { currentChat } from "../../../../conversation.js";
|
|
2
3
|
import { defineAgentTool } from '@zhin.js/tool';
|
|
3
4
|
import { z } from 'zod';
|
|
4
5
|
|
|
5
|
-
export default defineAgentTool<{
|
|
6
|
-
description: '
|
|
6
|
+
export default defineAgentTool<{ message_id: string; reaction: string }>({
|
|
7
|
+
description: '对当前 Telegram 会话中的消息添加表情反应',
|
|
7
8
|
inputSchema: z.object({
|
|
8
|
-
|
|
9
|
-
message_id: z.string().describe('消息 ID'),
|
|
9
|
+
message_id: z.string().describe('当前会话中的消息 ID'),
|
|
10
10
|
reaction: z.string().describe('反应表情(如 👍、❤️、🔥)'),
|
|
11
11
|
}),
|
|
12
12
|
adapter: 'telegram',
|
|
13
13
|
tags: ['telegram'],
|
|
14
|
-
async execute({
|
|
15
|
-
const
|
|
16
|
-
const success = await endpoint.setMessageReaction(Number(chat_id), Number(message_id), reaction);
|
|
14
|
+
async execute({ message_id, reaction }, context) {
|
|
15
|
+
const success = await context.$client.setMessageReaction(currentChat(context, { allowPrivate: true }), Number(message_id), reaction);
|
|
17
16
|
return { success, message: success ? t(context.locale, 'reactionAdded', { p0: reaction }) : t(context.locale, 'operationFailed') };
|
|
18
17
|
},
|
|
19
18
|
});
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
// Generated by build-plugin-runtime-entries.mjs. Do not edit.
|
|
2
2
|
import { messages as t } from "../../../../messages.js";
|
|
3
|
+
import { sendToCurrentChat } from "../../../../conversation.js";
|
|
3
4
|
import { defineAgentTool } from '@zhin.js/tool';
|
|
4
5
|
import { z } from 'zod';
|
|
5
6
|
export default defineAgentTool({
|
|
6
|
-
description: '
|
|
7
|
+
description: '在当前 Telegram 会话中发起投票',
|
|
7
8
|
inputSchema: z.object({
|
|
8
|
-
chat_id: z.string().describe('聊天 ID'),
|
|
9
9
|
question: z.string().describe('投票问题'),
|
|
10
10
|
options: z.string().describe('选项 JSON 数组,如 ["A","B","C"]'),
|
|
11
11
|
is_anonymous: z.boolean().optional().describe('是否匿名投票,默认 true'),
|
|
@@ -13,8 +13,7 @@ export default defineAgentTool({
|
|
|
13
13
|
}),
|
|
14
14
|
adapter: 'telegram',
|
|
15
15
|
tags: ['telegram'],
|
|
16
|
-
async execute({
|
|
17
|
-
const endpoint = context.$client;
|
|
16
|
+
async execute({ question, options, is_anonymous, allows_multiple }, context) {
|
|
18
17
|
let optList;
|
|
19
18
|
try {
|
|
20
19
|
optList = JSON.parse(options);
|
|
@@ -25,8 +24,10 @@ export default defineAgentTool({
|
|
|
25
24
|
if (!Array.isArray(optList) || optList.length < 2) {
|
|
26
25
|
return { success: false, message: t(context.locale, 'pollOptionCount') };
|
|
27
26
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
// `telegram:poll` is the Telegram adapter's namespaced outbound segment.
|
|
28
|
+
const result = await sendToCurrentChat(context, { type: 'telegram:poll', data: {
|
|
29
|
+
question, options: optList, is_anonymous: is_anonymous ?? true, allows_multiple_answers: allows_multiple ?? false,
|
|
30
|
+
} });
|
|
31
|
+
return { ...result, message: t(context.locale, result.success ? 'pollSent' : 'operationFailed') };
|
|
31
32
|
},
|
|
32
33
|
});
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { messages as t } from "../../../../messages.js";
|
|
2
|
+
import { sendToCurrentChat } from "../../../../conversation.js";
|
|
2
3
|
import { defineAgentTool } from '@zhin.js/tool';
|
|
3
4
|
import { z } from 'zod';
|
|
4
5
|
|
|
5
|
-
export default defineAgentTool<{
|
|
6
|
-
description: '
|
|
6
|
+
export default defineAgentTool<{ question: string; options: string; is_anonymous?: boolean; allows_multiple?: boolean }>({
|
|
7
|
+
description: '在当前 Telegram 会话中发起投票',
|
|
7
8
|
inputSchema: z.object({
|
|
8
|
-
chat_id: z.string().describe('聊天 ID'),
|
|
9
9
|
question: z.string().describe('投票问题'),
|
|
10
10
|
options: z.string().describe('选项 JSON 数组,如 ["A","B","C"]'),
|
|
11
11
|
is_anonymous: z.boolean().optional().describe('是否匿名投票,默认 true'),
|
|
@@ -13,8 +13,7 @@ export default defineAgentTool<{ chat_id: string; question: string; options: str
|
|
|
13
13
|
}),
|
|
14
14
|
adapter: 'telegram',
|
|
15
15
|
tags: ['telegram'],
|
|
16
|
-
async execute({
|
|
17
|
-
const endpoint = context.$client;
|
|
16
|
+
async execute({ question, options, is_anonymous, allows_multiple }, context) {
|
|
18
17
|
let optList: string[];
|
|
19
18
|
try {
|
|
20
19
|
optList = JSON.parse(options);
|
|
@@ -24,8 +23,10 @@ export default defineAgentTool<{ chat_id: string; question: string; options: str
|
|
|
24
23
|
if (!Array.isArray(optList) || optList.length < 2) {
|
|
25
24
|
return { success: false, message: t(context.locale, 'pollOptionCount') };
|
|
26
25
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
// `telegram:poll` is the Telegram adapter's namespaced outbound segment.
|
|
27
|
+
const result = await sendToCurrentChat(context, { type: 'telegram:poll', data: {
|
|
28
|
+
question, options: optList, is_anonymous: is_anonymous ?? true, allows_multiple_answers: allows_multiple ?? false,
|
|
29
|
+
} });
|
|
30
|
+
return { ...result, message: t(context.locale, result.success ? 'pollSent' : 'operationFailed') };
|
|
30
31
|
},
|
|
31
32
|
});
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
// Generated by build-plugin-runtime-entries.mjs. Do not edit.
|
|
2
2
|
import { messages as t } from "../../../../messages.js";
|
|
3
|
+
import { sendToCurrentChat } from "../../../../conversation.js";
|
|
3
4
|
import { defineAgentTool } from '@zhin.js/tool';
|
|
4
5
|
import { z } from 'zod';
|
|
5
6
|
export default defineAgentTool({
|
|
6
|
-
description: '
|
|
7
|
+
description: '在当前 Telegram 会话发送贴纸',
|
|
7
8
|
inputSchema: z.object({
|
|
8
|
-
|
|
9
|
-
sticker: z.string().describe('贴纸 file_id 或 URL'),
|
|
9
|
+
sticker: z.string().describe('贴纸 file_id 或 http(s) URL'),
|
|
10
10
|
}),
|
|
11
11
|
adapter: 'telegram',
|
|
12
12
|
tags: ['telegram'],
|
|
13
|
-
async execute({
|
|
14
|
-
|
|
15
|
-
const result = await
|
|
16
|
-
return {
|
|
13
|
+
async execute({ sticker }, context) {
|
|
14
|
+
// `telegram:sticker` is the Telegram adapter's namespaced outbound segment.
|
|
15
|
+
const result = await sendToCurrentChat(context, { type: 'telegram:sticker', data: { sticker } });
|
|
16
|
+
return { ...result, message: t(context.locale, result.success ? 'stickerSent' : 'operationFailed') };
|
|
17
17
|
},
|
|
18
18
|
});
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { messages as t } from "../../../../messages.js";
|
|
2
|
+
import { sendToCurrentChat } from "../../../../conversation.js";
|
|
2
3
|
import { defineAgentTool } from '@zhin.js/tool';
|
|
3
4
|
import { z } from 'zod';
|
|
4
5
|
|
|
5
|
-
export default defineAgentTool<{
|
|
6
|
-
description: '
|
|
6
|
+
export default defineAgentTool<{ sticker: string }>({
|
|
7
|
+
description: '在当前 Telegram 会话发送贴纸',
|
|
7
8
|
inputSchema: z.object({
|
|
8
|
-
|
|
9
|
-
sticker: z.string().describe('贴纸 file_id 或 URL'),
|
|
9
|
+
sticker: z.string().describe('贴纸 file_id 或 http(s) URL'),
|
|
10
10
|
}),
|
|
11
11
|
adapter: 'telegram',
|
|
12
12
|
tags: ['telegram'],
|
|
13
|
-
async execute({
|
|
14
|
-
|
|
15
|
-
const result = await
|
|
16
|
-
return {
|
|
13
|
+
async execute({ sticker }, context) {
|
|
14
|
+
// `telegram:sticker` is the Telegram adapter's namespaced outbound segment.
|
|
15
|
+
const result = await sendToCurrentChat(context, { type: 'telegram:sticker', data: { sticker } });
|
|
16
|
+
return { ...result, message: t(context.locale, result.success ? 'stickerSent' : 'operationFailed') };
|
|
17
17
|
},
|
|
18
18
|
});
|
package/lib/endpoint.d.ts
CHANGED
|
@@ -17,7 +17,8 @@ export { TelegramClient, type TelegramClientApi, type TelegramFetch } from './te
|
|
|
17
17
|
/**
|
|
18
18
|
* Telegram Bot API 无列表类接口(无 getMyChats/getChatMembers),
|
|
19
19
|
* 仅 getChat/getChatMember 按已知 id 单查,不构成列表能力;
|
|
20
|
-
* 因此本 endpoint
|
|
20
|
+
* 因此本 endpoint 的 EndpointManagement 只有 `inspectSelfStanding`(ADR 0056 §1:getChatMember bot),
|
|
21
|
+
* Console 社交面 RPC 对该平台保持未接线。
|
|
21
22
|
*/
|
|
22
23
|
export declare class TelegramEndpoint extends TelegramClient implements Endpoint {
|
|
23
24
|
#private;
|
package/lib/endpoint.js
CHANGED
|
@@ -9,19 +9,22 @@ import { EndpointDeliveryError, } from '@zhin.js/im-contract';
|
|
|
9
9
|
import { formatCompact, getAdapterLogger } from '@zhin.js/logger';
|
|
10
10
|
import { runTelegramPollLoop } from './polling.js';
|
|
11
11
|
export { TelegramApiError } from './api-error.js';
|
|
12
|
-
import {
|
|
12
|
+
import { telegramChatMemberStanding } from './platform-permit.js';
|
|
13
13
|
import { buildWebhookUrl, formatCallbackContent, formatCallbackSegments, formatInboundContent, formatInboundSegments, formatOutboundPlan, resolveTelegramChannelType, senderDisplayName, telegramInboundConversation, } from './protocol.js';
|
|
14
14
|
import { registerTelegramWebhookRoutes } from './webhook.js';
|
|
15
15
|
import { createTelegramSelfProfile } from './self-profile.js';
|
|
16
16
|
const CHAT_MEMBER_CACHE_TTL_MS = 60_000;
|
|
17
17
|
const CHAT_MEMBER_CACHE_MAX = 2_000;
|
|
18
|
+
/** A failed `getChatMember` is not retried for every message of a busy chat (unknown standing meanwhile). */
|
|
19
|
+
const CHAT_MEMBER_FAILURE_TTL_MS = 10_000;
|
|
18
20
|
const ADMITTED_UPDATE_LIMIT = 2_048;
|
|
19
21
|
const INFLIGHT_UPDATE_LIMIT = 256;
|
|
20
22
|
export { TelegramClient } from './telegram-client.js';
|
|
21
23
|
/**
|
|
22
24
|
* Telegram Bot API 无列表类接口(无 getMyChats/getChatMembers),
|
|
23
25
|
* 仅 getChat/getChatMember 按已知 id 单查,不构成列表能力;
|
|
24
|
-
* 因此本 endpoint
|
|
26
|
+
* 因此本 endpoint 的 EndpointManagement 只有 `inspectSelfStanding`(ADR 0056 §1:getChatMember bot),
|
|
27
|
+
* Console 社交面 RPC 对该平台保持未接线。
|
|
25
28
|
*/
|
|
26
29
|
export class TelegramEndpoint extends TelegramClient {
|
|
27
30
|
[endpointSpec];
|
|
@@ -44,6 +47,24 @@ export class TelegramEndpoint extends TelegramClient {
|
|
|
44
47
|
ttlMs: CHAT_MEMBER_CACHE_TTL_MS,
|
|
45
48
|
maxEntries: CHAT_MEMBER_CACHE_MAX,
|
|
46
49
|
});
|
|
50
|
+
/** Recently failed lookups (negative cache): the standing stays unknown until it expires. */
|
|
51
|
+
#chatMemberFailures = new TtlLookupCache({
|
|
52
|
+
ttlMs: CHAT_MEMBER_FAILURE_TTL_MS,
|
|
53
|
+
maxEntries: CHAT_MEMBER_CACHE_MAX,
|
|
54
|
+
});
|
|
55
|
+
/** Concurrent messages from one sender share one `getChatMember` call. */
|
|
56
|
+
#chatMemberInflight = new Map();
|
|
57
|
+
#management = Object.freeze({
|
|
58
|
+
// ADR 0056 §1: the Bot's own standing (`bot:*` permits); the framework caches per conversation.
|
|
59
|
+
inspectSelfStanding: async ({ conversation, signal }) => {
|
|
60
|
+
if (conversation.kind === 'private' || !this.#botUserId)
|
|
61
|
+
return undefined;
|
|
62
|
+
const member = await this.callApi('getChatMember', {
|
|
63
|
+
chat_id: Number(conversation.id), user_id: this.#botUserId,
|
|
64
|
+
}, signal);
|
|
65
|
+
return telegramChatMemberStanding(member);
|
|
66
|
+
},
|
|
67
|
+
});
|
|
47
68
|
#control = Object.freeze({
|
|
48
69
|
recall: ({ message, signal }) => this.recallMessage(message, signal),
|
|
49
70
|
});
|
|
@@ -60,7 +81,7 @@ export class TelegramEndpoint extends TelegramClient {
|
|
|
60
81
|
start: signal => this.#startFramework(signal), open: () => this.#openFramework(), close: () => this.#closeFramework(),
|
|
61
82
|
stop: () => this.#stopFramework(), send: request => this.#sendFramework(request),
|
|
62
83
|
get name() { return options.config.id; }, get transportState() { return endpoint.#transportState; },
|
|
63
|
-
control: this.#control, content: this.#content,
|
|
84
|
+
control: this.#control, content: this.#content, management: this.#management,
|
|
64
85
|
streaming: options.config.streaming !== false ? createTelegramStreaming(() => this, options.config.streamingIntervalMs) : undefined,
|
|
65
86
|
profile: createTelegramSelfProfile({ client: this,
|
|
66
87
|
current: () => this.#botName === undefined ? {} : { nickname: this.#botName },
|
|
@@ -340,7 +361,7 @@ export class TelegramEndpoint extends TelegramClient {
|
|
|
340
361
|
sender: {
|
|
341
362
|
id: String(msg.from?.id ?? ''),
|
|
342
363
|
name: senderDisplayName(msg.from) || undefined,
|
|
343
|
-
...(permit
|
|
364
|
+
...(permit ? { platform: permit } : {}),
|
|
344
365
|
},
|
|
345
366
|
endpointId: this.#options.config.id,
|
|
346
367
|
...(mentioned ? { mentioned: true } : {}),
|
|
@@ -350,8 +371,6 @@ export class TelegramEndpoint extends TelegramClient {
|
|
|
350
371
|
chatType: msg.chat.type,
|
|
351
372
|
userId: msg.from?.id,
|
|
352
373
|
date: msg.date,
|
|
353
|
-
...(permit?.role ? { senderRole: permit.role } : {}),
|
|
354
|
-
...(permit?.permissions.length ? { senderPermissions: [...permit.permissions] } : {}),
|
|
355
374
|
}),
|
|
356
375
|
});
|
|
357
376
|
}
|
|
@@ -379,7 +398,10 @@ export class TelegramEndpoint extends TelegramClient {
|
|
|
379
398
|
}
|
|
380
399
|
return false;
|
|
381
400
|
}
|
|
382
|
-
/**
|
|
401
|
+
/**
|
|
402
|
+
* 群消息 sender role 解析:getChatMember + 60s 缓存;并发查询合并为一次调用,失败负缓存 10s,
|
|
403
|
+
* `chat_member` / `my_chat_member` 更新时以新状态覆盖缓存。
|
|
404
|
+
*/
|
|
383
405
|
async #resolveGroupSenderPermit(msg, signal) {
|
|
384
406
|
if (msg.chat.type === 'private' || !msg.from?.id)
|
|
385
407
|
return undefined;
|
|
@@ -389,22 +411,52 @@ export class TelegramEndpoint extends TelegramClient {
|
|
|
389
411
|
const cached = this.#chatMemberCache.get(key);
|
|
390
412
|
if (cached)
|
|
391
413
|
return cached;
|
|
392
|
-
|
|
393
|
-
const member = await this.callApi('getChatMember', {
|
|
394
|
-
chat_id: chatId,
|
|
395
|
-
user_id: userId,
|
|
396
|
-
}, signal);
|
|
397
|
-
if (signal.aborted)
|
|
398
|
-
return undefined;
|
|
399
|
-
const normalized = normalizeTelegramChatMember(member);
|
|
400
|
-
const entry = { ...normalized };
|
|
401
|
-
this.#chatMemberCache.set(key, entry);
|
|
402
|
-
return entry;
|
|
403
|
-
}
|
|
404
|
-
catch {
|
|
405
|
-
// 保守拒绝:无角色快照
|
|
414
|
+
if (this.#chatMemberFailures.get(key))
|
|
406
415
|
return undefined;
|
|
416
|
+
let task = this.#chatMemberInflight.get(key)?.promise;
|
|
417
|
+
if (!task) {
|
|
418
|
+
const lookup = {};
|
|
419
|
+
task = (async () => {
|
|
420
|
+
await undefined; // registered in #chatMemberInflight before the body runs
|
|
421
|
+
try {
|
|
422
|
+
const member = await this.callApi('getChatMember', {
|
|
423
|
+
chat_id: chatId,
|
|
424
|
+
user_id: userId,
|
|
425
|
+
}, signal);
|
|
426
|
+
if (signal.aborted)
|
|
427
|
+
return undefined;
|
|
428
|
+
const entry = telegramChatMemberStanding(member);
|
|
429
|
+
// Invalidated (chat_member update) while in flight: do not store the older answer.
|
|
430
|
+
if (this.#chatMemberInflight.get(key) === lookup)
|
|
431
|
+
this.#chatMemberCache.set(key, entry);
|
|
432
|
+
return entry;
|
|
433
|
+
}
|
|
434
|
+
catch {
|
|
435
|
+
// 保守拒绝:无角色快照;取消不算失败
|
|
436
|
+
if (!signal.aborted && this.#chatMemberInflight.get(key) === lookup)
|
|
437
|
+
this.#chatMemberFailures.set(key, true);
|
|
438
|
+
return undefined;
|
|
439
|
+
}
|
|
440
|
+
finally {
|
|
441
|
+
if (this.#chatMemberInflight.get(key) === lookup)
|
|
442
|
+
this.#chatMemberInflight.delete(key);
|
|
443
|
+
}
|
|
444
|
+
})();
|
|
445
|
+
lookup.promise = task;
|
|
446
|
+
this.#chatMemberInflight.set(key, lookup);
|
|
407
447
|
}
|
|
448
|
+
const entry = await task;
|
|
449
|
+
return signal.aborted ? undefined : entry;
|
|
450
|
+
}
|
|
451
|
+
/** `chat_member` / `my_chat_member`: the update carries the new status, so it replaces the cached one. */
|
|
452
|
+
#applyChatMemberUpdate(update) {
|
|
453
|
+
const userId = update?.new_chat_member?.user?.id;
|
|
454
|
+
if (!update?.chat || userId == null)
|
|
455
|
+
return;
|
|
456
|
+
const key = `${Number(update.chat.id)}:${userId}`;
|
|
457
|
+
this.#chatMemberInflight.delete(key);
|
|
458
|
+
this.#chatMemberFailures.delete(key);
|
|
459
|
+
this.#chatMemberCache.set(key, telegramChatMemberStanding(update.new_chat_member));
|
|
408
460
|
}
|
|
409
461
|
/** Test / internal: admit a callback query when open. */
|
|
410
462
|
admitCallback(query) {
|
|
@@ -482,6 +534,8 @@ export class TelegramEndpoint extends TelegramClient {
|
|
|
482
534
|
await this[endpointSpec].events.platform(eventName, update);
|
|
483
535
|
}
|
|
484
536
|
else {
|
|
537
|
+
this.#applyChatMemberUpdate(update.chat_member);
|
|
538
|
+
this.#applyChatMemberUpdate(update.my_chat_member);
|
|
485
539
|
await this[endpointSpec].events.emitAccepted('platform.receive', Object.freeze({ name: eventName, event: update }));
|
|
486
540
|
return;
|
|
487
541
|
}
|
package/lib/index.d.ts
CHANGED
|
@@ -2,5 +2,5 @@ export { TelegramClient, TelegramEndpoint, type TelegramClientApi, type Telegram
|
|
|
2
2
|
export { botApiUrl, formatCallbackContent, formatInboundContent, formatOutboundActions, formatOutboundPlan, normalizeWebhookPath, resolveTelegramConfig, senderDisplayName, type ResolvedTelegramConfig, type TelegramEndpointConfig, type TelegramCallbackQuery, type TelegramChat, type TelegramChatMember, type TelegramMessage, type TelegramOutboundAction, type TelegramOutboundPlan, type TelegramOutboundUpload, type TelegramUpdate, type TelegramUser, type TelegramWireSegment, } from './protocol.js';
|
|
3
3
|
export { type TelegramClientEventMap } from './client.js';
|
|
4
4
|
export { TelegramAdapter } from './adapter.js';
|
|
5
|
-
export {
|
|
5
|
+
export { telegramChatMemberStanding, platformPermit, } from './platform-permit.js';
|
|
6
6
|
export type { TelegramPollRequest } from './telegram-client.js';
|
package/lib/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { TelegramClient, TelegramEndpoint, } from './endpoint.js';
|
|
2
2
|
export { botApiUrl, formatCallbackContent, formatInboundContent, formatOutboundActions, formatOutboundPlan, normalizeWebhookPath, resolveTelegramConfig, senderDisplayName, } from './protocol.js';
|
|
3
3
|
export { TelegramAdapter } from './adapter.js';
|
|
4
|
-
export {
|
|
4
|
+
export { telegramChatMemberStanding, platformPermit, } from './platform-permit.js';
|