@alemonjs/telegram 0.2.3 → 2.1.0-alpha.1

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/README.md CHANGED
@@ -1,6 +1,20 @@
1
1
  # [https://alemonjs.com/](https://alemonjs.com/)
2
2
 
3
- 跨平台开发的事件驱动机器人
3
+ [文档 https://core.telegram.org/bots ](https://core.telegram.org/bots)
4
+
5
+ ## 创建机器人
6
+
7
+ [访问 https://core.telegram.org/bots/tutorial#obtain-your-bot-token](https://core.telegram.org/bots/tutorial#obtain-your-bot-token)
8
+
9
+ 点击添加`@BotFather`并发送`/newbot`,并继续发送 `NameXBot` 得以生产 `token`
10
+
11
+ ```yaml
12
+ 79179797979:AAAAAAAAAAAAAABBBBBBCCCCCCCCCC
13
+ ```
14
+
15
+ - NameXdBot 即自定义的 bot 名
16
+
17
+ [访问 https://web.telegram.org/k/#@NameXdBot 以添加](https://web.telegram.org/k/#@NameXdBot)
4
18
 
5
19
  ## USE
6
20
 
@@ -22,9 +36,12 @@ telegram:
22
36
  master_key: null
23
37
  # other
24
38
  base_api_url: null
39
+ #
25
40
  request_url: null
41
+ # 使用 user_key
42
+ master_key:
43
+ - 'xxx'
44
+ # 使用 user_id
45
+ master_id:
46
+ - 'yyy'
26
47
  ```
27
-
28
- ## Community
29
-
30
- QQ Group 806943302
@@ -0,0 +1,11 @@
1
+ export declare const platform = "telegram";
2
+ export type Options = {
3
+ token: string;
4
+ base_api_url?: string;
5
+ request_url?: string;
6
+ proxy?: string;
7
+ master_key?: string[];
8
+ master_id?: string[];
9
+ };
10
+ export declare const getTGConfig: () => Options;
11
+ export declare const getMaster: (UserId: string) => readonly [boolean, string];
package/lib/config.js ADDED
@@ -0,0 +1,20 @@
1
+ import { getConfigValue, useUserHashKey } from 'alemonjs';
2
+
3
+ const platform = 'telegram';
4
+ const getTGConfig = () => {
5
+ const value = getConfigValue() || {};
6
+ return value[platform] || {};
7
+ };
8
+ const getMaster = (UserId) => {
9
+ const config = getTGConfig();
10
+ const master_key = config.master_key || [];
11
+ const master_id = config.master_id || [];
12
+ const UserKey = useUserHashKey({
13
+ Platform: platform,
14
+ UserId: UserId
15
+ });
16
+ const is = master_key.includes(UserKey) || master_id.includes(UserId);
17
+ return [is, UserKey];
18
+ };
19
+
20
+ export { getMaster, getTGConfig, platform };
package/lib/hook.d.ts ADDED
@@ -0,0 +1,26 @@
1
+ import { EventKeys, Events } from 'alemonjs';
2
+ import API from 'node-telegram-bot-api';
3
+ import TelegramClient from 'node-telegram-bot-api';
4
+ type MAP = {
5
+ 'message.create': TelegramClient.Message;
6
+ 'private.message.create': undefined;
7
+ 'interaction.create': undefined;
8
+ 'private.interaction.create': undefined;
9
+ 'message.update': undefined;
10
+ 'message.delete': undefined;
11
+ 'message.reaction.add': undefined;
12
+ 'message.reaction.remove': undefined;
13
+ 'channel.create': undefined;
14
+ 'channel.delete': undefined;
15
+ 'guild.join': undefined;
16
+ 'guild.exit': undefined;
17
+ 'member.add': undefined;
18
+ 'member.remove': undefined;
19
+ 'private.message.update': undefined;
20
+ 'private.message.delete': undefined;
21
+ 'private.friend.add': undefined;
22
+ 'private.guild.add': undefined;
23
+ };
24
+ export declare const useValue: <T extends EventKeys>(event: Events[T]) => readonly [MAP[T]];
25
+ export declare const useClient: <T extends EventKeys>(event: Events[T]) => readonly [API, MAP[T]];
26
+ export {};
package/lib/hook.js ADDED
@@ -0,0 +1,14 @@
1
+ import { createEventValue, useClient as useClient$1 } from 'alemonjs';
2
+ import TelegramClient from 'node-telegram-bot-api';
3
+
4
+ const useValue = (event) => {
5
+ const value = createEventValue(event);
6
+ return [value];
7
+ };
8
+ const useClient = (event) => {
9
+ const [client] = useClient$1(event, TelegramClient);
10
+ const value = createEventValue(event);
11
+ return [client, value];
12
+ };
13
+
14
+ export { useClient, useValue };
package/lib/index.d.ts CHANGED
@@ -1,9 +1,7 @@
1
- import * as alemonjs from 'alemonjs';
2
1
  import TelegramClient from 'node-telegram-bot-api';
3
-
4
- type Client = typeof TelegramClient.prototype;
5
- declare const client: Client;
6
- declare const platform = "telegram";
7
- declare const _default: () => alemonjs.ClientAPI;
8
-
9
- export { type Client, client, _default as default, platform };
2
+ export { platform } from './config';
3
+ export { type Options } from './config';
4
+ export declare const API: typeof TelegramClient;
5
+ export * from './hook';
6
+ declare const _default: () => any;
7
+ export default _default;
package/lib/index.js CHANGED
@@ -1,22 +1,13 @@
1
- import { defineBot, getConfigValue, useUserHashKey, OnProcessor } from 'alemonjs';
1
+ import { definePlatform, cbpPlatform, createResult, ResultCode } from 'alemonjs';
2
+ import { getBufferByURL } from 'alemonjs/utils';
2
3
  import TelegramClient from 'node-telegram-bot-api';
4
+ import { getTGConfig, getMaster, platform } from './config.js';
5
+ import { readFileSync } from 'fs';
6
+ export { useClient, useValue } from './hook.js';
3
7
 
4
- const client = new Proxy({}, {
5
- get: (_, prop) => {
6
- if (prop in global.client) {
7
- const original = global.client[prop];
8
- // 防止函数内this丢失
9
- return typeof original === 'function' ? original.bind(global.client) : original;
10
- }
11
- return undefined;
12
- }
13
- });
14
- const platform = 'telegram';
15
- var index = defineBot(() => {
16
- let value = getConfigValue();
17
- if (!value)
18
- value = {};
19
- const config = value[platform];
8
+ const API = TelegramClient;
9
+ const main = () => {
10
+ const config = getTGConfig();
20
11
  const client = new TelegramClient(config.token, {
21
12
  polling: true,
22
13
  baseApiUrl: config?.base_api_url ?? '',
@@ -25,240 +16,211 @@ var index = defineBot(() => {
25
16
  proxy: config?.proxy ?? ''
26
17
  }
27
18
  });
28
- /**
29
- *
30
- * @param UserId
31
- * @returns
32
- */
33
- const getUserProfilePhotosUrl = (UserId) => {
34
- return new Promise((resolve, reject) => {
35
- if (!UserId) {
36
- reject(new Error('UserId 不能为空'));
37
- return;
19
+ const url = `ws://127.0.0.1:${process.env?.port || 17117}`;
20
+ const cbp = cbpPlatform(url);
21
+ const getUserProfilePhotosUrl = async (UserId) => {
22
+ if (!UserId) {
23
+ return '';
24
+ }
25
+ try {
26
+ const profilePhotos = await client.getUserProfilePhotos(UserId);
27
+ if (profilePhotos.total_count > 0) {
28
+ const fileId = profilePhotos.photos[0][0].file_id;
29
+ const file = await client.getFile(fileId);
30
+ return `https://api.telegram.org/file/bot${config.token}/${file.file_path}`;
38
31
  }
39
- client
40
- .getUserProfilePhotos(UserId)
41
- .then(profilePhotos => {
42
- if (profilePhotos.total_count > 0) {
43
- // 获取第一张头像的文件 Id
44
- const fileId = profilePhotos.photos[0][0].file_id;
45
- // 获取文件信息以获取下载链接
46
- client
47
- .getFile(fileId)
48
- .then(file => {
49
- const filePath = file.file_path;
50
- resolve(`https://api.telegram.org/file/bot${config.token}/${filePath}`);
51
- })
52
- .catch(reject);
53
- }
54
- else {
55
- reject(new Error('用户没有头像'));
56
- }
57
- })
58
- .catch(reject);
59
- });
32
+ }
33
+ catch {
34
+ }
35
+ return '';
60
36
  };
61
37
  client.on('text', async (event) => {
62
38
  const UserId = String(event?.from?.id);
63
- const UserKey = useUserHashKey({
64
- Platform: platform,
65
- UserId: UserId
66
- });
67
- const UserAvatar = {
68
- toBuffer: async () => {
69
- if (event?.chat.type == 'supergroup' || event?.chat.type == 'private') {
70
- const photo = await getUserProfilePhotosUrl(event?.from?.id).catch(console.error);
71
- if (typeof photo == 'string') {
72
- const arrayBuffer = await fetch(photo).then(res => res.arrayBuffer());
73
- return Buffer.from(arrayBuffer);
74
- }
75
- }
76
- return;
77
- },
78
- toURL: async () => {
79
- if (event?.chat.type == 'supergroup' || event?.chat.type == 'private') {
80
- const photo = await getUserProfilePhotosUrl(event?.from?.id).catch(console.error);
81
- if (typeof photo == 'string') {
82
- return photo;
83
- }
84
- }
85
- return;
86
- },
87
- toBase64: async () => {
88
- if (event?.chat.type == 'supergroup' || event?.chat.type == 'private') {
89
- const photo = await getUserProfilePhotosUrl(event?.from?.id).catch(console.error);
90
- if (typeof photo == 'string') {
91
- const arrayBuffer = await fetch(photo).then(res => res.arrayBuffer());
92
- return Buffer.from(arrayBuffer).toString('base64');
93
- }
94
- }
39
+ const [isMaster, UserKey] = getMaster(UserId);
40
+ const UserAvatar = await getUserProfilePhotosUrl(event?.from?.id);
41
+ if (event?.chat.type === 'channel' || event?.chat.type === 'supergroup') {
42
+ if (event?.from?.is_bot) {
95
43
  return;
96
44
  }
97
- };
98
- if (event?.chat.type == 'channel' || event?.chat.type == 'supergroup') {
99
- // 机器人消息不处理
100
- if (event?.from?.is_bot)
101
- return;
102
- // 定义消
103
45
  const e = {
104
- // 事件类型
105
46
  Platform: platform,
106
- // 频道
47
+ name: 'message.create',
107
48
  GuildId: String(event?.chat.id),
108
49
  ChannelId: String(event?.chat.id),
109
- // user
50
+ SpaceId: String(event?.chat.id),
110
51
  UserId: UserId,
111
52
  UserKey: UserKey,
112
53
  UserName: event?.chat.username,
113
54
  UserAvatar: UserAvatar,
114
- IsMaster: false,
55
+ IsMaster: isMaster,
115
56
  IsBot: false,
116
- // message
117
57
  MessageId: String(event?.message_id),
58
+ MessageText: event?.text,
118
59
  OpenId: String(event?.chat?.id),
119
60
  CreateAt: Date.now(),
120
- // other
121
61
  tag: 'txt',
122
- value: null
62
+ value: event
123
63
  };
124
- // 当访问的时候获取
125
- Object.defineProperty(e, 'value', {
126
- get() {
127
- return event;
128
- }
129
- });
130
- //
131
- OnProcessor(e, 'message.create');
132
- //
64
+ cbp.send(e);
133
65
  }
134
- else if (event?.chat.type == 'private') {
135
- // 定义消
66
+ else if (event?.chat.type === 'private') {
136
67
  const e = {
137
68
  name: 'private.message.create',
138
- // 事件类型
139
69
  Platform: platform,
140
- // 用户Id
141
70
  UserId: String(event?.from.id),
142
71
  UserKey: UserKey,
143
72
  UserName: event?.from?.username,
144
73
  UserAvatar: UserAvatar,
145
- IsMaster: false,
74
+ IsMaster: isMaster,
146
75
  IsBot: false,
147
- // message
148
76
  MessageId: String(event?.message_id),
149
77
  MessageText: event?.text,
150
78
  OpenId: String(event?.chat?.id),
151
79
  CreateAt: Date.now(),
152
- // other
153
80
  tag: 'txt',
154
- value: null
81
+ value: event
155
82
  };
156
- // 当访问的时候获取
157
- Object.defineProperty(e, 'value', {
158
- get() {
159
- return event;
160
- }
161
- });
162
- // 处理消息
163
- OnProcessor(e, 'private.message.create');
83
+ cbp.send(e);
164
84
  }
165
85
  });
166
86
  client.on('new_chat_members', async (event) => {
167
- // 机器人消息不处理
168
- if (event?.from.is_bot)
87
+ if (event?.from.is_bot) {
169
88
  return;
89
+ }
170
90
  const UserId = String(event?.from?.id);
171
- const UserKey = useUserHashKey({
172
- Platform: platform,
173
- UserId: UserId
174
- });
175
- const UserAvatar = {
176
- toBuffer: async () => {
177
- const photo = await getUserProfilePhotosUrl(event?.from?.id).catch(console.error);
178
- if (typeof photo == 'string') {
179
- const arrayBuffer = await fetch(photo).then(res => res.arrayBuffer());
180
- return Buffer.from(arrayBuffer);
181
- }
182
- return;
183
- },
184
- toURL: async () => {
185
- const photo = await getUserProfilePhotosUrl(event?.from?.id).catch(console.error);
186
- if (typeof photo == 'string') {
187
- return photo;
188
- }
189
- return;
190
- },
191
- toBase64: async () => {
192
- const photo = await getUserProfilePhotosUrl(event?.from?.id).catch(console.error);
193
- if (typeof photo == 'string') {
194
- const arrayBuffer = await fetch(photo).then(res => res.arrayBuffer());
195
- return Buffer.from(arrayBuffer).toString('base64');
196
- }
197
- return;
198
- }
199
- };
200
- // 定义消
91
+ const [isMaster, UserKey] = getMaster(UserId);
92
+ const UserAvatar = await getUserProfilePhotosUrl(event?.from?.id);
201
93
  const e = {
202
- naem: 'member.add',
203
- // 事件类型
94
+ name: 'member.add',
204
95
  Platform: platform,
205
- // guild
206
96
  GuildId: String(event?.chat.id),
207
97
  ChannelId: String(event?.chat.id),
208
- // GuildName: event?.chat.title,
209
- // user
98
+ SpaceId: String(event?.chat.id),
210
99
  UserId: UserId,
211
100
  UserKey: UserKey,
212
101
  UserName: event?.chat.username,
213
102
  UserAvatar: UserAvatar,
214
- IsMaster: false,
103
+ IsMaster: isMaster,
215
104
  IsBot: false,
216
- // message
217
105
  MessageId: String(event?.message_id),
218
- // MessageText: event?.text,
219
- // OpenId: String(event?.chat?.id),
220
106
  CreateAt: Date.now(),
221
- // othder
222
107
  tag: 'txt',
223
- value: null
108
+ value: event
224
109
  };
225
- // 当访问的时候获取
226
- Object.defineProperty(e, 'value', {
227
- get() {
228
- return event;
229
- }
230
- });
231
- //
232
- OnProcessor(e, 'member.add');
110
+ cbp.send(e);
233
111
  });
234
- global.client = client;
235
- return {
236
- api: {
237
- use: {
238
- send: (event, val) => {
239
- if (val.length < 0)
240
- return Promise.all([]);
241
- const content = val
242
- .filter(item => item.type == 'Link' || item.type == 'Mention' || item.type == 'Text')
243
- .map(item => item.value)
244
- .join('');
245
- const e = event?.value;
112
+ const api = {
113
+ use: {
114
+ send: async (event, val) => {
115
+ if (!val || val.length <= 0) {
116
+ return [];
117
+ }
118
+ const content = val
119
+ .filter(item => item.type === 'Link' || item.type === 'Mention' || item.type === 'Text')
120
+ .map(item => item.value)
121
+ .join('');
122
+ const e = event?.value;
123
+ try {
246
124
  if (content) {
247
- return Promise.all([content].map(item => client.sendMessage(e.chat.id, item)));
125
+ const res = await client.sendMessage(e.chat.id, content);
126
+ return [createResult(ResultCode.Ok, 'message.send', res)];
248
127
  }
249
- const images = val.filter(item => item.type == 'Image').map(item => item.value);
250
- if (images) {
251
- return Promise.all(images.map(item => client.sendPhoto(e.chat.id, item)));
128
+ const images = val.filter(item => item.type === 'Image' || item.type === 'ImageFile' || item.type === 'ImageURL');
129
+ if (images.length > 0) {
130
+ let data = null;
131
+ for (let i = 0; i < images.length; i++) {
132
+ if (data) {
133
+ break;
134
+ }
135
+ const item = images[i];
136
+ if (item.type === 'Image') {
137
+ if (Buffer.isBuffer(item.value)) {
138
+ data = item.value;
139
+ }
140
+ else if (typeof item.value === 'string') {
141
+ if (item.value.startsWith('http://') || item.value.startsWith('https://')) {
142
+ data = await getBufferByURL(item.value);
143
+ }
144
+ else if (item.value.startsWith('base64://')) {
145
+ data = Buffer.from(item.value.slice(9), 'base64');
146
+ }
147
+ else if (item.value.startsWith('file://')) {
148
+ data = readFileSync(item.value.slice(7));
149
+ }
150
+ else {
151
+ data = Buffer.from(item.value, 'base64');
152
+ }
153
+ }
154
+ }
155
+ else if (item.type === 'ImageFile') {
156
+ data = readFileSync(item.value);
157
+ }
158
+ else if (item.type === 'ImageURL') {
159
+ data = await getBufferByURL(item.value);
160
+ }
161
+ }
162
+ if (data) {
163
+ const res = await client.sendPhoto(e.chat.id, data);
164
+ return [createResult(ResultCode.Ok, 'message.send', res)];
165
+ }
252
166
  }
253
- return Promise.all([]);
254
- },
255
- mention: async () => {
256
- // const event: TelegramClient.Message = e.value
257
- return [];
258
167
  }
168
+ catch (err) {
169
+ return [createResult(ResultCode.Fail, err?.response?.data ?? err?.message ?? err, null)];
170
+ }
171
+ return [];
172
+ },
173
+ mention: () => {
174
+ return new Promise(resolve => {
175
+ resolve([]);
176
+ });
259
177
  }
260
178
  }
261
179
  };
262
- });
180
+ const onactions = async (data, consume) => {
181
+ try {
182
+ if (data.action === 'message.send') {
183
+ const event = data.payload.event;
184
+ const paramFormat = data.payload.params.format;
185
+ const res = await api.use.send(event, paramFormat);
186
+ consume(res);
187
+ }
188
+ else if (data.action === 'message.send.channel') {
189
+ consume([createResult(ResultCode.Fail, '暂未支持,请尝试升级版本', null)]);
190
+ }
191
+ else if (data.action === 'message.send.user') {
192
+ consume([createResult(ResultCode.Fail, '暂未支持,请尝试升级版本', null)]);
193
+ }
194
+ else if (data.action === 'mention.get') {
195
+ consume([createResult(ResultCode.Fail, '暂未支持,请尝试升级版本', null)]);
196
+ }
197
+ else {
198
+ consume([createResult(ResultCode.Fail, '未知请求,请尝试升级版本', null)]);
199
+ }
200
+ }
201
+ catch (error) {
202
+ consume([createResult(ResultCode.Fail, '请求失败', error)]);
203
+ }
204
+ };
205
+ cbp.onactions((data, consume) => void onactions(data, consume));
206
+ const onapis = async (data, consume) => {
207
+ const key = data.payload?.key;
208
+ if (client[key]) {
209
+ const params = data.payload.params;
210
+ try {
211
+ const res = await client[key](...params);
212
+ consume([createResult(ResultCode.Ok, '请求完成', res)]);
213
+ }
214
+ catch (error) {
215
+ consume([createResult(ResultCode.Fail, '请求失败', error)]);
216
+ }
217
+ }
218
+ else {
219
+ consume([createResult(ResultCode.Fail, '未知请求,请尝试升级版本', null)]);
220
+ }
221
+ };
222
+ cbp.onapis((data, consume) => void onapis(data, consume));
223
+ };
224
+ var index = definePlatform({ main });
263
225
 
264
- export { client, index as default, platform };
226
+ export { API, index as default, platform };
package/package.json CHANGED
@@ -1,19 +1,23 @@
1
1
  {
2
2
  "name": "@alemonjs/telegram",
3
- "version": "0.2.3",
4
- "description": "telegram-bot",
3
+ "version": "2.1.0-alpha.1",
4
+ "description": "telegram platform connection",
5
5
  "author": "lemonade",
6
6
  "license": "MIT",
7
7
  "type": "module",
8
8
  "main": "lib/index.js",
9
9
  "types": "lib",
10
10
  "scripts": {
11
- "build": "node bundle.js"
11
+ "build": "lvy build"
12
12
  },
13
13
  "dependencies": {
14
+ "@types/node-telegram-bot-api": "^0.64.9",
14
15
  "grammy": "^1.30.0",
15
16
  "node-telegram-bot-api": "^0.66.0"
16
17
  },
18
+ "peerDependencies": {
19
+ "alemonjs": "^2.1.0-alpha.15"
20
+ },
17
21
  "exports": {
18
22
  ".": {
19
23
  "import": "./lib/index.js",
@@ -42,4 +46,4 @@
42
46
  "type": "git",
43
47
  "url": "https://github.com/lemonade-lab/alemonjs.git"
44
48
  }
45
- }
49
+ }