@codebam/cf-workers-telegram-bot 12.2.0 → 12.4.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.
@@ -20,6 +20,10 @@ export default class TelegramBot {
20
20
  defaultCommand: string;
21
21
  /** Optional secret token for webhook verification */
22
22
  secretToken?: string;
23
+ /** The bot's own user ID */
24
+ botId: number;
25
+ /** TTL for self-responses */
26
+ ttl: number;
23
27
  /**
24
28
  * Create a bot
25
29
  * @param token - the telegram secret token
@@ -19,6 +19,10 @@ export default class TelegramBot {
19
19
  defaultCommand = ':message';
20
20
  /** Optional secret token for webhook verification */
21
21
  secretToken;
22
+ /** The bot's own user ID */
23
+ botId;
24
+ /** TTL for self-responses */
25
+ ttl = 2;
22
26
  /**
23
27
  * Create a bot
24
28
  * @param token - the telegram secret token
@@ -27,6 +31,7 @@ export default class TelegramBot {
27
31
  constructor(token, options) {
28
32
  this.token = token.trim();
29
33
  this.api = new URL('https://api.telegram.org/bot' + this.token);
34
+ this.botId = parseInt(this.token.split(':')[0]);
30
35
  if (options?.defaultCommand) {
31
36
  this.defaultCommand = options.defaultCommand;
32
37
  }
@@ -7,6 +7,8 @@ export default class TelegramExecutionContext {
7
7
  private static businessOwners;
8
8
  /** Cache for dead business connections */
9
9
  private static poisonedConnections;
10
+ /** Cache for self-response counts to prevent infinite loops */
11
+ private static selfResponseCount;
10
12
  /** an instance of the telegram bot */
11
13
  bot: TelegramBot;
12
14
  /** an instance of the telegram update */
@@ -38,6 +40,11 @@ export default class TelegramExecutionContext {
38
40
  * @returns The user ID or undefined if not available
39
41
  */
40
42
  get userId(): number | undefined;
43
+ /**
44
+ * Check if the message sender is a bot
45
+ * @returns True if the sender is a bot
46
+ */
47
+ get isBot(): boolean;
41
48
  /**
42
49
  * Parse arguments from the update
43
50
  * @returns array of argument strings
@@ -5,6 +5,8 @@ export default class TelegramExecutionContext {
5
5
  static businessOwners = new Map();
6
6
  /** Cache for dead business connections */
7
7
  static poisonedConnections = new Set();
8
+ /** Cache for self-response counts to prevent infinite loops */
9
+ static selfResponseCount = new Map();
8
10
  /** an instance of the telegram bot */
9
11
  bot;
10
12
  /** an instance of the telegram update */
@@ -47,6 +49,16 @@ export default class TelegramExecutionContext {
47
49
  get userId() {
48
50
  return this.update.message?.from?.id ?? this.update.business_message?.from?.id ?? this.update.guest_message?.from?.id;
49
51
  }
52
+ /**
53
+ * Check if the message sender is a bot
54
+ * @returns True if the sender is a bot
55
+ */
56
+ get isBot() {
57
+ return (this.update.message?.from?.is_bot ??
58
+ this.update.business_message?.from?.is_bot ??
59
+ this.update.guest_message?.from?.is_bot ??
60
+ false);
61
+ }
50
62
  /**
51
63
  * Parse arguments from the update
52
64
  * @returns array of argument strings
@@ -73,6 +85,16 @@ export default class TelegramExecutionContext {
73
85
  */
74
86
  async shouldProcess() {
75
87
  if (this.update_type !== 'business_message') {
88
+ if (this.userId === this.bot.botId) {
89
+ const chatId = this.getChatId();
90
+ const count = TelegramExecutionContext.selfResponseCount.get(chatId) || 0;
91
+ if (count < this.bot.ttl) {
92
+ TelegramExecutionContext.selfResponseCount.set(chatId, count + 1);
93
+ return true;
94
+ }
95
+ return false;
96
+ }
97
+ TelegramExecutionContext.selfResponseCount.delete(this.getChatId());
76
98
  return true;
77
99
  }
78
100
  const connectionId = this.update.business_message?.business_connection_id?.toString();
@@ -111,8 +133,15 @@ export default class TelegramExecutionContext {
111
133
  }
112
134
  }
113
135
  if (ownerId !== undefined && (this.getChatId() === ownerId.toString() || this.userId === ownerId)) {
136
+ const chatId = this.getChatId();
137
+ const count = TelegramExecutionContext.selfResponseCount.get(chatId) || 0;
138
+ if (count < this.bot.ttl) {
139
+ TelegramExecutionContext.selfResponseCount.set(chatId, count + 1);
140
+ return true;
141
+ }
114
142
  return false;
115
143
  }
144
+ TelegramExecutionContext.selfResponseCount.delete(this.getChatId());
116
145
  return true;
117
146
  }
118
147
  determineUpdateType() {
@@ -156,13 +185,13 @@ export default class TelegramExecutionContext {
156
185
  * @returns The chat ID as a string or empty string if not available
157
186
  */
158
187
  getChatId() {
159
- if (this.update.message?.chat.id) {
188
+ if (this.update.message?.chat?.id) {
160
189
  return this.update.message.chat.id.toString();
161
190
  }
162
- else if (this.update.business_message?.chat.id) {
191
+ else if (this.update.business_message?.chat?.id) {
163
192
  return this.update.business_message.chat.id.toString();
164
193
  }
165
- else if (this.update.guest_message?.chat.id) {
194
+ else if (this.update.guest_message?.chat?.id) {
166
195
  return this.update.guest_message.chat.id.toString();
167
196
  }
168
197
  return '';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codebam/cf-workers-telegram-bot",
3
- "version": "12.2.0",
3
+ "version": "12.4.0",
4
4
  "description": "serverless telegram bot on cf workers",
5
5
  "main": "./dist/main.js",
6
6
  "module": "./dist/main.js",