@classytic/social 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.
Files changed (121) hide show
  1. package/CHANGELOG.md +65 -0
  2. package/LICENSE +21 -0
  3. package/README.md +368 -0
  4. package/dist/base-Bw7e52V8.mjs +246 -0
  5. package/dist/base-Bw7e52V8.mjs.map +1 -0
  6. package/dist/base-DBtKFiSX.d.mts +226 -0
  7. package/dist/base-DBtKFiSX.d.mts.map +1 -0
  8. package/dist/chunk-DQk6qfdC.mjs +18 -0
  9. package/dist/client/index.d.mts +44 -0
  10. package/dist/client/index.d.mts.map +1 -0
  11. package/dist/client/index.mjs +154 -0
  12. package/dist/client/index.mjs.map +1 -0
  13. package/dist/common/index.d.mts +3 -0
  14. package/dist/common/index.mjs +7 -0
  15. package/dist/contracts-Cdwa4zlg.d.mts +121 -0
  16. package/dist/contracts-Cdwa4zlg.d.mts.map +1 -0
  17. package/dist/contracts-lCa069IK.mjs +221 -0
  18. package/dist/contracts-lCa069IK.mjs.map +1 -0
  19. package/dist/env-Bl0cwwjC.mjs +955 -0
  20. package/dist/env-Bl0cwwjC.mjs.map +1 -0
  21. package/dist/env-DxOZHf0p.d.mts +394 -0
  22. package/dist/env-DxOZHf0p.d.mts.map +1 -0
  23. package/dist/errors-Cm6LeKf7.mjs +32 -0
  24. package/dist/errors-Cm6LeKf7.mjs.map +1 -0
  25. package/dist/facebook-l_4CghaA.mjs +95 -0
  26. package/dist/facebook-l_4CghaA.mjs.map +1 -0
  27. package/dist/http-DpcLSR1M.mjs +197 -0
  28. package/dist/http-DpcLSR1M.mjs.map +1 -0
  29. package/dist/index.d.mts +42 -0
  30. package/dist/index.d.mts.map +1 -0
  31. package/dist/index.mjs +71 -0
  32. package/dist/index.mjs.map +1 -0
  33. package/dist/instagram-BGaeUFU2.mjs +90 -0
  34. package/dist/instagram-BGaeUFU2.mjs.map +1 -0
  35. package/dist/linkedin-70whtVKa.mjs +101 -0
  36. package/dist/linkedin-70whtVKa.mjs.map +1 -0
  37. package/dist/meta-D3vcJU1c.mjs +126 -0
  38. package/dist/meta-D3vcJU1c.mjs.map +1 -0
  39. package/dist/pkce-jq5II68b.mjs +72 -0
  40. package/dist/pkce-jq5II68b.mjs.map +1 -0
  41. package/dist/polling-DZ1apXtA.mjs +25 -0
  42. package/dist/polling-DZ1apXtA.mjs.map +1 -0
  43. package/dist/providers/facebook.d.mts +135 -0
  44. package/dist/providers/facebook.d.mts.map +1 -0
  45. package/dist/providers/facebook.mjs +450 -0
  46. package/dist/providers/facebook.mjs.map +1 -0
  47. package/dist/providers/instagram.d.mts +122 -0
  48. package/dist/providers/instagram.d.mts.map +1 -0
  49. package/dist/providers/instagram.mjs +496 -0
  50. package/dist/providers/instagram.mjs.map +1 -0
  51. package/dist/providers/linkedin.d.mts +145 -0
  52. package/dist/providers/linkedin.d.mts.map +1 -0
  53. package/dist/providers/linkedin.mjs +574 -0
  54. package/dist/providers/linkedin.mjs.map +1 -0
  55. package/dist/providers/reddit.d.mts +102 -0
  56. package/dist/providers/reddit.d.mts.map +1 -0
  57. package/dist/providers/reddit.mjs +657 -0
  58. package/dist/providers/reddit.mjs.map +1 -0
  59. package/dist/providers/telegram.d.mts +139 -0
  60. package/dist/providers/telegram.d.mts.map +1 -0
  61. package/dist/providers/telegram.mjs +517 -0
  62. package/dist/providers/telegram.mjs.map +1 -0
  63. package/dist/providers/tiktok.d.mts +116 -0
  64. package/dist/providers/tiktok.d.mts.map +1 -0
  65. package/dist/providers/tiktok.mjs +676 -0
  66. package/dist/providers/tiktok.mjs.map +1 -0
  67. package/dist/providers/twitter.d.mts +150 -0
  68. package/dist/providers/twitter.d.mts.map +1 -0
  69. package/dist/providers/twitter.mjs +628 -0
  70. package/dist/providers/twitter.mjs.map +1 -0
  71. package/dist/providers/whatsapp.d.mts +79 -0
  72. package/dist/providers/whatsapp.d.mts.map +1 -0
  73. package/dist/providers/whatsapp.mjs +376 -0
  74. package/dist/providers/whatsapp.mjs.map +1 -0
  75. package/dist/providers/youtube.d.mts +153 -0
  76. package/dist/providers/youtube.d.mts.map +1 -0
  77. package/dist/providers/youtube.mjs +902 -0
  78. package/dist/providers/youtube.mjs.map +1 -0
  79. package/dist/reddit-B10kS4Se.mjs +126 -0
  80. package/dist/reddit-B10kS4Se.mjs.map +1 -0
  81. package/dist/schemas/index.d.mts +819 -0
  82. package/dist/schemas/index.d.mts.map +1 -0
  83. package/dist/schemas/index.mjs +31 -0
  84. package/dist/schemas/index.mjs.map +1 -0
  85. package/dist/security-BXhfebWm.d.mts +338 -0
  86. package/dist/security-BXhfebWm.d.mts.map +1 -0
  87. package/dist/shared-Fvc6xQku.mjs +100 -0
  88. package/dist/shared-Fvc6xQku.mjs.map +1 -0
  89. package/dist/telegram-FaUHpZgB.mjs +107 -0
  90. package/dist/telegram-FaUHpZgB.mjs.map +1 -0
  91. package/dist/tiktok-B_bMk4G-.mjs +94 -0
  92. package/dist/tiktok-B_bMk4G-.mjs.map +1 -0
  93. package/dist/twitter-BC22zfuc.mjs +98 -0
  94. package/dist/twitter-BC22zfuc.mjs.map +1 -0
  95. package/dist/types-BFE4psYI.d.mts +102 -0
  96. package/dist/types-BFE4psYI.d.mts.map +1 -0
  97. package/dist/types-Bv27tcT0.d.mts +230 -0
  98. package/dist/types-Bv27tcT0.d.mts.map +1 -0
  99. package/dist/types-BwkKyqpi.d.mts +253 -0
  100. package/dist/types-BwkKyqpi.d.mts.map +1 -0
  101. package/dist/types-CJrHMDV9.mjs +27 -0
  102. package/dist/types-CJrHMDV9.mjs.map +1 -0
  103. package/dist/types-ClbVc2rc.d.mts +117 -0
  104. package/dist/types-ClbVc2rc.d.mts.map +1 -0
  105. package/dist/types-D91N16Ym.d.mts +242 -0
  106. package/dist/types-D91N16Ym.d.mts.map +1 -0
  107. package/dist/types-DfLp_ibQ.d.mts +178 -0
  108. package/dist/types-DfLp_ibQ.d.mts.map +1 -0
  109. package/dist/types-DfjDgEoJ.d.mts +88 -0
  110. package/dist/types-DfjDgEoJ.d.mts.map +1 -0
  111. package/dist/types-Dp5Z9VBr.mjs +23 -0
  112. package/dist/types-Dp5Z9VBr.mjs.map +1 -0
  113. package/dist/types-hriBJTsU.d.mts +129 -0
  114. package/dist/types-hriBJTsU.d.mts.map +1 -0
  115. package/dist/types-rn6UuLL8.d.mts +184 -0
  116. package/dist/types-rn6UuLL8.d.mts.map +1 -0
  117. package/dist/whatsapp-CFp7ryR4.mjs +101 -0
  118. package/dist/whatsapp-CFp7ryR4.mjs.map +1 -0
  119. package/dist/youtube-Bs0fdY7H.mjs +98 -0
  120. package/dist/youtube-Bs0fdY7H.mjs.map +1 -0
  121. package/package.json +148 -0
@@ -0,0 +1,517 @@
1
+ import { t as PlatformProvider } from "../base-Bw7e52V8.mjs";
2
+ import { t as SocialError } from "../errors-Cm6LeKf7.mjs";
3
+ import { t as httpRequest } from "../http-DpcLSR1M.mjs";
4
+ import { t as TelegramCredentialsSchema } from "../telegram-FaUHpZgB.mjs";
5
+
6
+ //#region src/providers/telegram/index.ts
7
+ /**
8
+ * Telegram Platform Provider
9
+ * ==========================
10
+ * Telegram Bot API integration for channels, groups, and direct messages.
11
+ *
12
+ * Uses token-based auth (Bot Token from @BotFather) — NOT OAuth.
13
+ * The bot must be added as admin to the target channel/group.
14
+ *
15
+ * Key endpoints (Telegram Bot API):
16
+ * - GET /getMe — verify bot identity
17
+ * - POST /sendMessage — send text message
18
+ * - POST /sendPhoto — send photo with caption
19
+ * - POST /sendVideo — send video with caption
20
+ * - POST /sendDocument — send file attachment
21
+ * - POST /sendMediaGroup — send album (2-10 photos/videos)
22
+ * - POST /getChat — get chat/channel info
23
+ * - POST /getChatMemberCount — get subscriber count
24
+ * - POST /pinChatMessage — pin a message
25
+ * - POST /deleteMessage — delete a message
26
+ *
27
+ * @see https://core.telegram.org/bots/api
28
+ */
29
+ const BOT_API_BASE = "https://api.telegram.org/bot";
30
+ /**
31
+ * Human-friendly explanations for common Telegram Bot API error descriptions.
32
+ * @see https://core.telegram.org/api/errors
33
+ */
34
+ const ERROR_HINTS = {
35
+ "Unauthorized": "Bot token is invalid or has been revoked. Generate a new token from @BotFather.",
36
+ "chat not found": "The chat/channel ID is wrong or the bot has not been added to it. Add the bot as admin first.",
37
+ "bot is not a member": "The bot is not a member of this chat/channel. Add it as an admin with \"Post Messages\" permission.",
38
+ "not enough rights": "The bot lacks admin permissions. Promote it to admin with the required permissions (Post Messages, Edit Messages, etc.).",
39
+ "CHAT_WRITE_FORBIDDEN": "The bot cannot write to this chat. Check that posting is allowed and the bot has \"Post Messages\" permission.",
40
+ "message to delete not found": "The message has already been deleted or the ID is incorrect.",
41
+ "message is not modified": "The new message content is identical to the current one.",
42
+ "too many requests": "Rate limit hit. Telegram allows ~30 messages/second to different chats, 1 msg/second to same chat. Wait and retry.",
43
+ "Bad Request: wrong file_id": "The file_id is invalid or expired. Re-upload the file.",
44
+ "group chat was upgraded to a supergroup": "The group was converted to a supergroup. Use the new chat ID (starts with -100).",
45
+ "FLOOD_WAIT": "Rate limit — wait the indicated number of seconds before retrying."
46
+ };
47
+ var TelegramProvider = class extends PlatformProvider {
48
+ constructor(config = {}) {
49
+ super(config);
50
+ this.name = "telegram";
51
+ this.displayName = "Telegram";
52
+ this.authType = "token";
53
+ }
54
+ /**
55
+ * Make a request to the Telegram Bot API
56
+ * @private
57
+ * @param method - Bot API method name (e.g. 'sendMessage')
58
+ * @param botToken - Bot token from @BotFather
59
+ * @param body - Request body (JSON or FormData for file uploads)
60
+ * @returns API response result
61
+ */
62
+ async _api(method, botToken, body = null) {
63
+ const url = `${BOT_API_BASE}${botToken}/${method}`;
64
+ const isForm = body instanceof FormData;
65
+ const data = (await httpRequest("telegram", {
66
+ method: body ? "POST" : "GET",
67
+ url,
68
+ json: !isForm && body ? body : void 0,
69
+ form: isForm ? body : void 0,
70
+ timeout: 6e4,
71
+ retry: { attempts: 2 },
72
+ parseError: (raw, status) => {
73
+ if (raw && typeof raw === "object") {
74
+ const r = raw;
75
+ const description = r.description || `Telegram API error (${status})`;
76
+ const params = r.parameters;
77
+ const hint = Object.entries(ERROR_HINTS).find(([key]) => description.toLowerCase().includes(key.toLowerCase()));
78
+ return {
79
+ message: description,
80
+ errorCode: r.error_code,
81
+ hint: hint ? hint[1] : null,
82
+ retryAfter: params?.retry_after ?? null
83
+ };
84
+ }
85
+ return null;
86
+ }
87
+ })).data;
88
+ if (!data.ok) {
89
+ const description = data.description || `Telegram API error (${data.error_code})`;
90
+ const hint = Object.entries(ERROR_HINTS).find(([key]) => description.toLowerCase().includes(key.toLowerCase()));
91
+ throw new SocialError("telegram", description, {
92
+ statusCode: data.error_code >= 400 && data.error_code < 500 ? data.error_code : 502,
93
+ errorCode: data.error_code,
94
+ hint: hint ? hint[1] : null,
95
+ retryAfter: data.parameters?.retry_after || null
96
+ });
97
+ }
98
+ return data.result;
99
+ }
100
+ /**
101
+ * Get bot identity and verify token validity
102
+ */
103
+ async getAccountInfo(accessToken) {
104
+ const bot = await this._api("getMe", accessToken);
105
+ return {
106
+ id: String(bot.id),
107
+ name: bot.first_name + (bot.last_name ? ` ${bot.last_name}` : ""),
108
+ username: bot.username,
109
+ profileImage: null
110
+ };
111
+ }
112
+ /**
113
+ * Test credential validity
114
+ */
115
+ async testCredential(credentialData) {
116
+ try {
117
+ const { botToken, chatId } = credentialData;
118
+ if (!botToken) return {
119
+ status: "Error",
120
+ message: "Bot Token is required. Get one from @BotFather on Telegram."
121
+ };
122
+ const botInfo = await this.getAccountInfo(botToken);
123
+ const result = {
124
+ status: "OK",
125
+ message: `Connected as @${botInfo.username}`,
126
+ data: {
127
+ channelId: botInfo.id,
128
+ channelTitle: botInfo.name,
129
+ username: botInfo.username
130
+ }
131
+ };
132
+ if (chatId) try {
133
+ const chat = await this.getChat(botToken, chatId);
134
+ result.data.chatTitle = chat.title || chat.username || chatId;
135
+ result.data.chatType = chat.type;
136
+ result.message += ` — channel "${chat.title || chatId}" accessible`;
137
+ } catch (chatError) {
138
+ result.status = "Warning";
139
+ const hint = chatError.hint || chatError.message || "unknown error";
140
+ result.message += ` — cannot access chat "${chatId}": ${hint}`;
141
+ const discovered = await this.discoverChats(botToken);
142
+ if (discovered.length > 0) result.data.availableChats = discovered;
143
+ }
144
+ return result;
145
+ } catch (error) {
146
+ return {
147
+ status: "Error",
148
+ message: error.hint || error.message || "Failed to validate Telegram credential"
149
+ };
150
+ }
151
+ }
152
+ /**
153
+ * Get chat/channel information
154
+ * @param botToken
155
+ * @param chatId - Channel username (@channel) or numeric ID
156
+ */
157
+ async getChat(botToken, chatId) {
158
+ return this._api("getChat", botToken, { chat_id: chatId });
159
+ }
160
+ /**
161
+ * Get subscriber/member count for a chat
162
+ * @param botToken
163
+ * @param chatId
164
+ * @returns Member count
165
+ */
166
+ async getChatMemberCount(botToken, chatId) {
167
+ return this._api("getChatMemberCount", botToken, { chat_id: chatId });
168
+ }
169
+ /**
170
+ * Discover chats the bot has interacted with recently.
171
+ * Uses getUpdates (only works when no webhook is active, falls back gracefully).
172
+ */
173
+ async discoverChats(botToken) {
174
+ try {
175
+ if ((await this._api("getWebhookInfo", botToken))?.url) return [];
176
+ const updates = await this._api("getUpdates", botToken, { limit: 50 });
177
+ const chats = /* @__PURE__ */ new Map();
178
+ for (const update of updates || []) {
179
+ const sources = [
180
+ update.message?.chat,
181
+ update.channel_post?.chat,
182
+ update.my_chat_member?.chat,
183
+ update.edited_message?.chat
184
+ ];
185
+ for (const chat of sources) if (chat?.id) chats.set(chat.id, {
186
+ id: chat.id,
187
+ title: chat.title || chat.username || chat.first_name || String(chat.id),
188
+ type: chat.type
189
+ });
190
+ }
191
+ return Array.from(chats.values());
192
+ } catch {
193
+ return [];
194
+ }
195
+ }
196
+ /**
197
+ * Send a text message
198
+ * @param botToken
199
+ * @param chatId
200
+ * @param text - Message text (1-4096 characters)
201
+ * @param options
202
+ */
203
+ async sendMessage(botToken, chatId, text, options = {}) {
204
+ return this._api("sendMessage", botToken, {
205
+ chat_id: chatId,
206
+ message_thread_id: options.messageThreadId,
207
+ text,
208
+ parse_mode: options.parseMode,
209
+ disable_notification: options.disableNotification,
210
+ reply_parameters: options.replyToMessageId !== void 0 ? { message_id: options.replyToMessageId } : void 0,
211
+ link_preview_options: options.disableWebPagePreview ? { is_disabled: true } : void 0
212
+ });
213
+ }
214
+ /**
215
+ * Send a photo with optional caption
216
+ * @param botToken
217
+ * @param chatId
218
+ * @param photo - Photo URL or file_id
219
+ * @param options
220
+ */
221
+ async sendPhoto(botToken, chatId, photo, options = {}) {
222
+ return this._api("sendPhoto", botToken, {
223
+ chat_id: chatId,
224
+ photo,
225
+ caption: options.caption,
226
+ parse_mode: options.parseMode,
227
+ disable_notification: options.disableNotification
228
+ });
229
+ }
230
+ /**
231
+ * Send a video with optional caption
232
+ * @param botToken
233
+ * @param chatId
234
+ * @param video - Video URL or file_id
235
+ * @param options
236
+ */
237
+ async sendVideo(botToken, chatId, video, options = {}) {
238
+ return this._api("sendVideo", botToken, {
239
+ chat_id: chatId,
240
+ video,
241
+ caption: options.caption,
242
+ parse_mode: options.parseMode,
243
+ duration: options.duration,
244
+ width: options.width,
245
+ height: options.height,
246
+ supports_streaming: options.supportsStreaming,
247
+ disable_notification: options.disableNotification
248
+ });
249
+ }
250
+ /**
251
+ * Send a document/file
252
+ * @param botToken
253
+ * @param chatId
254
+ * @param document - Document URL or file_id
255
+ * @param options
256
+ */
257
+ async sendDocument(botToken, chatId, document, options = {}) {
258
+ return this._api("sendDocument", botToken, {
259
+ chat_id: chatId,
260
+ document,
261
+ caption: options.caption,
262
+ parse_mode: options.parseMode,
263
+ disable_notification: options.disableNotification
264
+ });
265
+ }
266
+ /**
267
+ * Send a media group (album) of 2-10 photos/videos
268
+ * @param botToken
269
+ * @param chatId
270
+ * @param media
271
+ * @param options
272
+ */
273
+ async sendMediaGroup(botToken, chatId, media, options = {}) {
274
+ if (!media || media.length < 2 || media.length > 10) throw new SocialError("telegram", "Media group requires 2-10 items");
275
+ return this._api("sendMediaGroup", botToken, {
276
+ chat_id: chatId,
277
+ media,
278
+ disable_notification: options.disableNotification
279
+ });
280
+ }
281
+ /**
282
+ * Pin a message in a chat
283
+ * @param botToken
284
+ * @param chatId
285
+ * @param messageId
286
+ * @param options
287
+ */
288
+ async pinMessage(botToken, chatId, messageId, options = {}) {
289
+ return this._api("pinChatMessage", botToken, {
290
+ chat_id: chatId,
291
+ message_id: messageId,
292
+ disable_notification: options.disableNotification
293
+ });
294
+ }
295
+ /**
296
+ * Delete a message
297
+ * @param botToken
298
+ * @param chatId
299
+ * @param messageId
300
+ */
301
+ async deleteMessage(botToken, chatId, messageId) {
302
+ return this._api("deleteMessage", botToken, {
303
+ chat_id: chatId,
304
+ message_id: messageId
305
+ });
306
+ }
307
+ /**
308
+ * Edit a text message
309
+ * @param botToken
310
+ * @param chatId
311
+ * @param messageId
312
+ * @param text - New message text
313
+ * @param options
314
+ */
315
+ async editMessage(botToken, chatId, messageId, text, options = {}) {
316
+ return this._api("editMessageText", botToken, {
317
+ chat_id: chatId,
318
+ message_id: messageId,
319
+ text,
320
+ parse_mode: options.parseMode,
321
+ link_preview_options: options.disableWebPagePreview ? { is_disabled: true } : void 0
322
+ });
323
+ }
324
+ async getChatAdministrators(botToken, chatId) {
325
+ return this._api("getChatAdministrators", botToken, { chat_id: chatId });
326
+ }
327
+ async getChatMember(botToken, chatId, userId) {
328
+ return this._api("getChatMember", botToken, {
329
+ chat_id: chatId,
330
+ user_id: userId
331
+ });
332
+ }
333
+ async leaveChat(botToken, chatId) {
334
+ return this._api("leaveChat", botToken, { chat_id: chatId });
335
+ }
336
+ async setChatTitle(botToken, chatId, title) {
337
+ return this._api("setChatTitle", botToken, {
338
+ chat_id: chatId,
339
+ title
340
+ });
341
+ }
342
+ async setChatDescription(botToken, chatId, description) {
343
+ return this._api("setChatDescription", botToken, {
344
+ chat_id: chatId,
345
+ description
346
+ });
347
+ }
348
+ async sendLocation(botToken, chatId, latitude, longitude, options = {}) {
349
+ return this._api("sendLocation", botToken, {
350
+ chat_id: chatId,
351
+ latitude,
352
+ longitude,
353
+ horizontal_accuracy: options.horizontalAccuracy,
354
+ live_period: options.livePeriod,
355
+ heading: options.heading,
356
+ proximity_alert_radius: options.proximityAlertRadius,
357
+ disable_notification: options.disableNotification,
358
+ protect_content: options.protectContent,
359
+ reply_parameters: options.replyToMessageId !== void 0 ? { message_id: options.replyToMessageId } : void 0
360
+ });
361
+ }
362
+ async sendAudio(botToken, chatId, audio, options = {}) {
363
+ return this._api("sendAudio", botToken, {
364
+ chat_id: chatId,
365
+ audio,
366
+ caption: options.caption,
367
+ parse_mode: options.parseMode,
368
+ duration: options.duration,
369
+ performer: options.performer,
370
+ title: options.title,
371
+ thumbnail: options.thumbnail,
372
+ disable_notification: options.disableNotification,
373
+ protect_content: options.protectContent
374
+ });
375
+ }
376
+ async sendSticker(botToken, chatId, sticker, options = {}) {
377
+ return this._api("sendSticker", botToken, {
378
+ chat_id: chatId,
379
+ sticker,
380
+ emoji: options.emoji,
381
+ disable_notification: options.disableNotification,
382
+ protect_content: options.protectContent,
383
+ reply_parameters: options.replyToMessageId !== void 0 ? { message_id: options.replyToMessageId } : void 0
384
+ });
385
+ }
386
+ async sendChatAction(botToken, chatId, action) {
387
+ return this._api("sendChatAction", botToken, {
388
+ chat_id: chatId,
389
+ action
390
+ });
391
+ }
392
+ async forwardMessage(botToken, chatId, fromChatId, messageId, options = {}) {
393
+ return this._api("forwardMessage", botToken, {
394
+ chat_id: chatId,
395
+ from_chat_id: fromChatId,
396
+ message_id: messageId,
397
+ disable_notification: options.disableNotification,
398
+ protect_content: options.protectContent
399
+ });
400
+ }
401
+ async copyMessage(botToken, chatId, fromChatId, messageId, options = {}) {
402
+ return this._api("copyMessage", botToken, {
403
+ chat_id: chatId,
404
+ from_chat_id: fromChatId,
405
+ message_id: messageId,
406
+ caption: options.caption,
407
+ parse_mode: options.parseMode,
408
+ disable_notification: options.disableNotification,
409
+ protect_content: options.protectContent
410
+ });
411
+ }
412
+ async answerCallbackQuery(botToken, callbackQueryId, options = {}) {
413
+ return this._api("answerCallbackQuery", botToken, {
414
+ callback_query_id: callbackQueryId,
415
+ text: options.text,
416
+ show_alert: options.showAlert,
417
+ url: options.url,
418
+ cache_time: options.cacheTime
419
+ });
420
+ }
421
+ /**
422
+ * Upload a video to a Telegram channel/chat
423
+ * Telegram supports video by URL (up to 50MB for URL, 2GB for binary upload via multipart).
424
+ *
425
+ * @param params - Upload parameters
426
+ */
427
+ async uploadVideo(params) {
428
+ const { videoUrl, title = "", description = "", tokens, onProgress } = params;
429
+ const { botToken, chatId } = tokens;
430
+ if (!chatId) throw new SocialError("telegram", "Chat ID is required to post. Set it in credential config.");
431
+ if (!videoUrl) throw new SocialError("telegram", "Video URL is required. Telegram accepts public URLs up to 50MB.");
432
+ const caption = [title, description].filter(Boolean).join("\n\n").substring(0, 1024);
433
+ if (onProgress) onProgress(10);
434
+ const message = await this.sendVideo(botToken, chatId, videoUrl, {
435
+ caption,
436
+ parseMode: "HTML",
437
+ supportsStreaming: true
438
+ });
439
+ if (onProgress) onProgress(100);
440
+ return {
441
+ platformVideoId: String(message.message_id),
442
+ platformUrl: chatId.toString().startsWith("@") ? `https://t.me/${chatId.replace("@", "")}/${message.message_id}` : null,
443
+ status: "published",
444
+ uploadedAt: /* @__PURE__ */ new Date(),
445
+ metadata: {
446
+ chatId,
447
+ messageId: message.message_id,
448
+ caption
449
+ }
450
+ };
451
+ }
452
+ getCredentialZodSchema() {
453
+ return TelegramCredentialsSchema;
454
+ }
455
+ getCredentialSchema() {
456
+ return [{
457
+ name: "botToken",
458
+ displayName: "Bot Token",
459
+ type: "password",
460
+ required: true,
461
+ description: "Bot token from @BotFather (format: 123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11)"
462
+ }, {
463
+ name: "chatId",
464
+ displayName: "Default Chat/Channel ID",
465
+ type: "text",
466
+ required: false,
467
+ description: "Channel username (@channel) or numeric ID (-100xxx). The bot must be admin of this channel."
468
+ }];
469
+ }
470
+ getMetadata() {
471
+ return {
472
+ name: this.name,
473
+ displayName: this.displayName,
474
+ authType: this.authType,
475
+ icon: "telegram",
476
+ brandColor: "#26A5E4",
477
+ description: "Post to Telegram channels, groups, and chats via Bot API",
478
+ scopes: [],
479
+ scopeDescriptions: {},
480
+ supportsScheduling: false,
481
+ supportsEnvironment: false,
482
+ setupGuide: [
483
+ {
484
+ step: 1,
485
+ title: "Open @BotFather",
486
+ description: "On Telegram, search for @BotFather and start a chat"
487
+ },
488
+ {
489
+ step: 2,
490
+ title: "Create a Bot",
491
+ description: "Send /newbot, choose a display name and username (must end in \"bot\")"
492
+ },
493
+ {
494
+ step: 3,
495
+ title: "Copy Bot Token",
496
+ description: "BotFather will give you a token like 123456:ABC-DEF... — paste it above"
497
+ },
498
+ {
499
+ step: 4,
500
+ title: "Add Bot to Channel",
501
+ description: "Open your channel/group → Settings → Admins → Add the bot as admin with \"Post Messages\" permission"
502
+ },
503
+ {
504
+ step: 5,
505
+ title: "Get Channel ID",
506
+ description: "For public channels: use @channelname. For private: forward a channel message to @userinfobot to get the numeric ID (starts with -100)"
507
+ }
508
+ ],
509
+ redirectUriPattern: null,
510
+ credentialSchema: this.getCredentialSchema()
511
+ };
512
+ }
513
+ };
514
+
515
+ //#endregion
516
+ export { TelegramProvider };
517
+ //# sourceMappingURL=telegram.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telegram.mjs","names":[],"sources":["../../src/providers/telegram/index.ts"],"sourcesContent":["/**\n * Telegram Platform Provider\n * ==========================\n * Telegram Bot API integration for channels, groups, and direct messages.\n *\n * Uses token-based auth (Bot Token from @BotFather) — NOT OAuth.\n * The bot must be added as admin to the target channel/group.\n *\n * Key endpoints (Telegram Bot API):\n * - GET /getMe — verify bot identity\n * - POST /sendMessage — send text message\n * - POST /sendPhoto — send photo with caption\n * - POST /sendVideo — send video with caption\n * - POST /sendDocument — send file attachment\n * - POST /sendMediaGroup — send album (2-10 photos/videos)\n * - POST /getChat — get chat/channel info\n * - POST /getChatMemberCount — get subscriber count\n * - POST /pinChatMessage — pin a message\n * - POST /deleteMessage — delete a message\n *\n * @see https://core.telegram.org/bots/api\n */\n\nimport { PlatformProvider } from '../../base.js';\nimport type { CredentialField, ProviderMetadata, ProviderConfig } from '../../base.js';\nimport { SocialError } from '../../errors.js';\nimport { TelegramCredentialsSchema } from '../../schemas/telegram.js';\nimport { httpRequest } from '../../common/http.js';\nimport type { z } from 'zod';\nimport type {\n TelegramApiResponse,\n TelegramBotInfo,\n TelegramChat,\n TelegramMessage,\n TelegramCredentialData,\n SendMessageOptions,\n SendPhotoOptions,\n SendVideoOptions,\n SendDocumentOptions,\n MediaGroupItem,\n SendMediaGroupOptions,\n PinMessageOptions,\n EditMessageOptions,\n TelegramUploadVideoParams,\n TelegramUploadVideoResult,\n TelegramTestResult,\n DiscoveredChat,\n TelegramUser,\n ChatAdministrator,\n ChatMember,\n SendLocationOptions,\n SendAudioOptions,\n SendStickerOptions,\n ChatAction,\n ForwardMessageOptions,\n CopyMessageOptions,\n AnswerCallbackQueryOptions,\n} from './types.js';\n\nexport type {\n TelegramApiResponse,\n TelegramBotInfo,\n TelegramChat,\n TelegramMessage,\n TelegramCredentialData,\n TelegramParseMode,\n SendMessageOptions,\n SendPhotoOptions,\n SendVideoOptions,\n SendDocumentOptions,\n MediaGroupItem,\n SendMediaGroupOptions,\n PinMessageOptions,\n EditMessageOptions,\n TelegramUploadVideoParams,\n TelegramUploadVideoResult,\n TelegramTestResult,\n DiscoveredChat,\n TelegramUser,\n ChatAdministrator,\n ChatMember,\n SendLocationOptions,\n SendAudioOptions,\n SendStickerOptions,\n ChatAction,\n ForwardMessageOptions,\n CopyMessageOptions,\n AnswerCallbackQueryOptions,\n} from './types.js';\n\nconst BOT_API_BASE = 'https://api.telegram.org/bot';\n\n/**\n * Human-friendly explanations for common Telegram Bot API error descriptions.\n * @see https://core.telegram.org/api/errors\n */\nconst ERROR_HINTS: Record<string, string> = {\n 'Unauthorized': 'Bot token is invalid or has been revoked. Generate a new token from @BotFather.',\n 'chat not found': 'The chat/channel ID is wrong or the bot has not been added to it. Add the bot as admin first.',\n 'bot is not a member': 'The bot is not a member of this chat/channel. Add it as an admin with \"Post Messages\" permission.',\n 'not enough rights': 'The bot lacks admin permissions. Promote it to admin with the required permissions (Post Messages, Edit Messages, etc.).',\n 'CHAT_WRITE_FORBIDDEN': 'The bot cannot write to this chat. Check that posting is allowed and the bot has \"Post Messages\" permission.',\n 'message to delete not found': 'The message has already been deleted or the ID is incorrect.',\n 'message is not modified': 'The new message content is identical to the current one.',\n 'too many requests': 'Rate limit hit. Telegram allows ~30 messages/second to different chats, 1 msg/second to same chat. Wait and retry.',\n 'Bad Request: wrong file_id': 'The file_id is invalid or expired. Re-upload the file.',\n 'group chat was upgraded to a supergroup': 'The group was converted to a supergroup. Use the new chat ID (starts with -100).',\n 'FLOOD_WAIT': 'Rate limit — wait the indicated number of seconds before retrying.',\n};\n\nexport class TelegramProvider extends PlatformProvider {\n constructor(config: ProviderConfig = {}) {\n super(config);\n this.name = 'telegram';\n this.displayName = 'Telegram';\n this.authType = 'token'; // No OAuth — user pastes Bot Token\n }\n\n // ─── API Helper ──────────────────────────────────────────────────────\n\n /**\n * Make a request to the Telegram Bot API\n * @private\n * @param method - Bot API method name (e.g. 'sendMessage')\n * @param botToken - Bot token from @BotFather\n * @param body - Request body (JSON or FormData for file uploads)\n * @returns API response result\n */\n async _api(method: string, botToken: string, body: Record<string, any> | FormData | null = null): Promise<any> {\n const url = `${BOT_API_BASE}${botToken}/${method}`;\n\n const isForm = body instanceof FormData;\n const result = await httpRequest<TelegramApiResponse>('telegram', {\n method: body ? 'POST' : 'GET',\n url,\n json: !isForm && body ? body : undefined,\n form: isForm ? body : undefined,\n timeout: 60_000,\n retry: { attempts: 2 },\n // Telegram returns 200 OK for failures with `ok: false` — the parser\n // below handles non-OK HTTP statuses; the post-processing below handles\n // application-level errors.\n parseError: (raw, status) => {\n if (raw && typeof raw === 'object') {\n const r = raw as Record<string, unknown>;\n const description = (r.description as string) || `Telegram API error (${status})`;\n const params = r.parameters as { retry_after?: number } | undefined;\n const hint = Object.entries(ERROR_HINTS).find(([key]) =>\n description.toLowerCase().includes(key.toLowerCase()),\n );\n return {\n message: description,\n errorCode: r.error_code as number | undefined,\n hint: hint ? hint[1] : null,\n retryAfter: params?.retry_after ?? null,\n };\n }\n return null;\n },\n });\n\n const data = result.data;\n if (!data.ok) {\n const description = data.description || `Telegram API error (${data.error_code})`;\n const hint = Object.entries(ERROR_HINTS).find(([key]) =>\n description.toLowerCase().includes(key.toLowerCase()),\n );\n throw new SocialError('telegram', description, {\n statusCode: data.error_code! >= 400 && data.error_code! < 500 ? data.error_code : 502,\n errorCode: data.error_code,\n hint: hint ? hint[1] : null,\n retryAfter: data.parameters?.retry_after || null,\n });\n }\n\n return data.result;\n }\n\n // ─── Account Info ────────────────────────────────────────────────────\n\n /**\n * Get bot identity and verify token validity\n */\n async getAccountInfo(accessToken: string): Promise<{ id: string; name: string; username: string; profileImage: null }> {\n const bot: TelegramBotInfo = await this._api('getMe', accessToken);\n return {\n id: String(bot.id),\n name: bot.first_name + (bot.last_name ? ` ${bot.last_name}` : ''),\n username: bot.username,\n profileImage: null, // Bot API doesn't return profile photo in getMe\n };\n }\n\n /**\n * Test credential validity\n */\n async testCredential(credentialData: TelegramCredentialData): Promise<TelegramTestResult> {\n try {\n const { botToken, chatId } = credentialData;\n\n if (!botToken) {\n return {\n status: 'Error',\n message: 'Bot Token is required. Get one from @BotFather on Telegram.',\n };\n }\n\n // Verify bot token\n const botInfo = await this.getAccountInfo(botToken);\n const result: TelegramTestResult = {\n status: 'OK',\n message: `Connected as @${botInfo.username}`,\n data: {\n channelId: botInfo.id,\n channelTitle: botInfo.name,\n username: botInfo.username,\n },\n };\n\n // Optionally verify chat access\n if (chatId) {\n try {\n const chat: TelegramChat = await this.getChat(botToken, chatId);\n result.data!.chatTitle = chat.title || chat.username || chatId;\n result.data!.chatType = chat.type;\n result.message += ` — channel \"${chat.title || chatId}\" accessible`;\n } catch (chatError: any) {\n result.status = 'Warning';\n const hint = chatError.hint || chatError.message || 'unknown error';\n result.message += ` — cannot access chat \"${chatId}\": ${hint}`;\n\n // Discover available chats from recent bot activity\n const discovered = await this.discoverChats(botToken);\n if (discovered.length > 0) {\n result.data!.availableChats = discovered;\n }\n }\n }\n\n return result;\n } catch (error: any) {\n return {\n status: 'Error',\n message: error.hint || error.message || 'Failed to validate Telegram credential',\n };\n }\n }\n\n // ─── Chat Operations ─────────────────────────────────────────────────\n\n /**\n * Get chat/channel information\n * @param botToken\n * @param chatId - Channel username (@channel) or numeric ID\n */\n async getChat(botToken: string, chatId: string | number): Promise<TelegramChat> {\n return this._api('getChat', botToken, { chat_id: chatId });\n }\n\n /**\n * Get subscriber/member count for a chat\n * @param botToken\n * @param chatId\n * @returns Member count\n */\n async getChatMemberCount(botToken: string, chatId: string | number): Promise<number> {\n return this._api('getChatMemberCount', botToken, { chat_id: chatId });\n }\n\n /**\n * Discover chats the bot has interacted with recently.\n * Uses getUpdates (only works when no webhook is active, falls back gracefully).\n */\n async discoverChats(botToken: string): Promise<DiscoveredChat[]> {\n try {\n // Check if a webhook is active — if so, getUpdates won't work\n const webhookInfo = await this._api('getWebhookInfo', botToken);\n if (webhookInfo?.url) return []; // webhook active, can't use getUpdates\n\n const updates = await this._api('getUpdates', botToken, { limit: 50 });\n const chats = new Map<number, { id: number; title: string; type: string }>();\n\n for (const update of updates || []) {\n const sources = [\n update.message?.chat,\n update.channel_post?.chat,\n update.my_chat_member?.chat,\n update.edited_message?.chat,\n ];\n for (const chat of sources) {\n if (chat?.id) {\n chats.set(chat.id, {\n id: chat.id,\n title: chat.title || chat.username || chat.first_name || String(chat.id),\n type: chat.type,\n });\n }\n }\n }\n\n return Array.from(chats.values());\n } catch {\n return [];\n }\n }\n\n // ─── Messaging ────────────────────────────────────────────────────────\n\n /**\n * Send a text message\n * @param botToken\n * @param chatId\n * @param text - Message text (1-4096 characters)\n * @param options\n */\n async sendMessage(botToken: string, chatId: string | number, text: string, options: SendMessageOptions = {}): Promise<TelegramMessage> {\n return this._api('sendMessage', botToken, {\n chat_id: chatId,\n message_thread_id: options.messageThreadId,\n text,\n parse_mode: options.parseMode,\n disable_notification: options.disableNotification,\n reply_parameters: options.replyToMessageId !== undefined ? { message_id: options.replyToMessageId } : undefined,\n link_preview_options: options.disableWebPagePreview ? { is_disabled: true } : undefined,\n });\n }\n\n /**\n * Send a photo with optional caption\n * @param botToken\n * @param chatId\n * @param photo - Photo URL or file_id\n * @param options\n */\n async sendPhoto(botToken: string, chatId: string | number, photo: string, options: SendPhotoOptions = {}): Promise<TelegramMessage> {\n return this._api('sendPhoto', botToken, {\n chat_id: chatId,\n photo,\n caption: options.caption,\n parse_mode: options.parseMode,\n disable_notification: options.disableNotification,\n });\n }\n\n /**\n * Send a video with optional caption\n * @param botToken\n * @param chatId\n * @param video - Video URL or file_id\n * @param options\n */\n async sendVideo(botToken: string, chatId: string | number, video: string, options: SendVideoOptions = {}): Promise<TelegramMessage> {\n return this._api('sendVideo', botToken, {\n chat_id: chatId,\n video,\n caption: options.caption,\n parse_mode: options.parseMode,\n duration: options.duration,\n width: options.width,\n height: options.height,\n supports_streaming: options.supportsStreaming,\n disable_notification: options.disableNotification,\n });\n }\n\n /**\n * Send a document/file\n * @param botToken\n * @param chatId\n * @param document - Document URL or file_id\n * @param options\n */\n async sendDocument(botToken: string, chatId: string | number, document: string, options: SendDocumentOptions = {}): Promise<TelegramMessage> {\n return this._api('sendDocument', botToken, {\n chat_id: chatId,\n document,\n caption: options.caption,\n parse_mode: options.parseMode,\n disable_notification: options.disableNotification,\n });\n }\n\n /**\n * Send a media group (album) of 2-10 photos/videos\n * @param botToken\n * @param chatId\n * @param media\n * @param options\n */\n async sendMediaGroup(botToken: string, chatId: string | number, media: MediaGroupItem[], options: SendMediaGroupOptions = {}): Promise<TelegramMessage[]> {\n if (!media || media.length < 2 || media.length > 10) {\n throw new SocialError('telegram', 'Media group requires 2-10 items');\n }\n\n return this._api('sendMediaGroup', botToken, {\n chat_id: chatId,\n media,\n disable_notification: options.disableNotification,\n });\n }\n\n // ─── Message Management ───────────────────────────────────────────────\n\n /**\n * Pin a message in a chat\n * @param botToken\n * @param chatId\n * @param messageId\n * @param options\n */\n async pinMessage(botToken: string, chatId: string | number, messageId: number, options: PinMessageOptions = {}): Promise<true> {\n return this._api('pinChatMessage', botToken, {\n chat_id: chatId,\n message_id: messageId,\n disable_notification: options.disableNotification,\n });\n }\n\n /**\n * Delete a message\n * @param botToken\n * @param chatId\n * @param messageId\n */\n async deleteMessage(botToken: string, chatId: string | number, messageId: number): Promise<true> {\n return this._api('deleteMessage', botToken, {\n chat_id: chatId,\n message_id: messageId,\n });\n }\n\n /**\n * Edit a text message\n * @param botToken\n * @param chatId\n * @param messageId\n * @param text - New message text\n * @param options\n */\n async editMessage(botToken: string, chatId: string | number, messageId: number, text: string, options: EditMessageOptions = {}): Promise<TelegramMessage> {\n return this._api('editMessageText', botToken, {\n chat_id: chatId,\n message_id: messageId,\n text,\n parse_mode: options.parseMode,\n link_preview_options: options.disableWebPagePreview ? { is_disabled: true } : undefined,\n });\n }\n\n // ─── Chat Management ────────────────────────────────────────────────\n\n async getChatAdministrators(botToken: string, chatId: string | number): Promise<ChatAdministrator[]> {\n return this._api('getChatAdministrators', botToken, { chat_id: chatId });\n }\n\n async getChatMember(botToken: string, chatId: string | number, userId: number): Promise<ChatMember> {\n return this._api('getChatMember', botToken, { chat_id: chatId, user_id: userId });\n }\n\n async leaveChat(botToken: string, chatId: string | number): Promise<true> {\n return this._api('leaveChat', botToken, { chat_id: chatId });\n }\n\n async setChatTitle(botToken: string, chatId: string | number, title: string): Promise<true> {\n return this._api('setChatTitle', botToken, { chat_id: chatId, title });\n }\n\n async setChatDescription(botToken: string, chatId: string | number, description: string): Promise<true> {\n return this._api('setChatDescription', botToken, { chat_id: chatId, description });\n }\n\n // ─── Additional Message Types ──────────────────────────────────────\n\n async sendLocation(botToken: string, chatId: string | number, latitude: number, longitude: number, options: SendLocationOptions = {}): Promise<TelegramMessage> {\n return this._api('sendLocation', botToken, {\n chat_id: chatId,\n latitude,\n longitude,\n horizontal_accuracy: options.horizontalAccuracy,\n live_period: options.livePeriod,\n heading: options.heading,\n proximity_alert_radius: options.proximityAlertRadius,\n disable_notification: options.disableNotification,\n protect_content: options.protectContent,\n reply_parameters: options.replyToMessageId !== undefined ? { message_id: options.replyToMessageId } : undefined,\n });\n }\n\n async sendAudio(botToken: string, chatId: string | number, audio: string, options: SendAudioOptions = {}): Promise<TelegramMessage> {\n return this._api('sendAudio', botToken, {\n chat_id: chatId,\n audio,\n caption: options.caption,\n parse_mode: options.parseMode,\n duration: options.duration,\n performer: options.performer,\n title: options.title,\n thumbnail: options.thumbnail,\n disable_notification: options.disableNotification,\n protect_content: options.protectContent,\n });\n }\n\n async sendSticker(botToken: string, chatId: string | number, sticker: string, options: SendStickerOptions = {}): Promise<TelegramMessage> {\n return this._api('sendSticker', botToken, {\n chat_id: chatId,\n sticker,\n emoji: options.emoji,\n disable_notification: options.disableNotification,\n protect_content: options.protectContent,\n reply_parameters: options.replyToMessageId !== undefined ? { message_id: options.replyToMessageId } : undefined,\n });\n }\n\n async sendChatAction(botToken: string, chatId: string | number, action: ChatAction): Promise<true> {\n return this._api('sendChatAction', botToken, { chat_id: chatId, action });\n }\n\n // ─── Message Forwarding & Copying ──────────────────────────────────\n\n async forwardMessage(botToken: string, chatId: string | number, fromChatId: string | number, messageId: number, options: ForwardMessageOptions = {}): Promise<TelegramMessage> {\n return this._api('forwardMessage', botToken, {\n chat_id: chatId,\n from_chat_id: fromChatId,\n message_id: messageId,\n disable_notification: options.disableNotification,\n protect_content: options.protectContent,\n });\n }\n\n async copyMessage(botToken: string, chatId: string | number, fromChatId: string | number, messageId: number, options: CopyMessageOptions = {}): Promise<{ message_id: number }> {\n return this._api('copyMessage', botToken, {\n chat_id: chatId,\n from_chat_id: fromChatId,\n message_id: messageId,\n caption: options.caption,\n parse_mode: options.parseMode,\n disable_notification: options.disableNotification,\n protect_content: options.protectContent,\n });\n }\n\n // ─── Callback Queries ──────────────────────────────────────────────\n\n async answerCallbackQuery(botToken: string, callbackQueryId: string, options: AnswerCallbackQueryOptions = {}): Promise<true> {\n return this._api('answerCallbackQuery', botToken, {\n callback_query_id: callbackQueryId,\n text: options.text,\n show_alert: options.showAlert,\n url: options.url,\n cache_time: options.cacheTime,\n });\n }\n\n // ─── Upload (Video to Channel) ────────────────────────────────────────\n\n /**\n * Upload a video to a Telegram channel/chat\n * Telegram supports video by URL (up to 50MB for URL, 2GB for binary upload via multipart).\n *\n * @param params - Upload parameters\n */\n async uploadVideo(params: TelegramUploadVideoParams): Promise<TelegramUploadVideoResult> {\n const {\n videoUrl,\n title = '',\n description = '',\n tokens,\n onProgress,\n } = params;\n\n const { botToken, chatId } = tokens;\n\n if (!chatId) {\n throw new SocialError('telegram', 'Chat ID is required to post. Set it in credential config.');\n }\n\n if (!videoUrl) {\n throw new SocialError('telegram', 'Video URL is required. Telegram accepts public URLs up to 50MB.');\n }\n\n const caption = [title, description].filter(Boolean).join('\\n\\n').substring(0, 1024);\n\n if (onProgress) onProgress(10);\n\n const message: TelegramMessage = await this.sendVideo(botToken, chatId, videoUrl, {\n caption,\n parseMode: 'HTML',\n supportsStreaming: true,\n });\n\n if (onProgress) onProgress(100);\n\n return {\n platformVideoId: String(message.message_id),\n platformUrl: chatId.toString().startsWith('@')\n ? `https://t.me/${chatId.replace('@', '')}/${message.message_id}`\n : null,\n status: 'published',\n uploadedAt: new Date(),\n metadata: {\n chatId,\n messageId: message.message_id,\n caption,\n },\n };\n }\n\n // ─── Schema & Metadata ────────────────────────────────────────────────\n\n getCredentialZodSchema(): z.ZodType {\n return TelegramCredentialsSchema;\n }\n\n getCredentialSchema(): CredentialField[] {\n return [\n {\n name: 'botToken',\n displayName: 'Bot Token',\n type: 'password',\n required: true,\n description: 'Bot token from @BotFather (format: 123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11)',\n },\n {\n name: 'chatId',\n displayName: 'Default Chat/Channel ID',\n type: 'text',\n required: false,\n description: 'Channel username (@channel) or numeric ID (-100xxx). The bot must be admin of this channel.',\n },\n ];\n }\n\n getMetadata(): ProviderMetadata {\n return {\n name: this.name,\n displayName: this.displayName,\n authType: this.authType,\n icon: 'telegram',\n brandColor: '#26A5E4',\n description: 'Post to Telegram channels, groups, and chats via Bot API',\n scopes: [],\n scopeDescriptions: {},\n supportsScheduling: false,\n supportsEnvironment: false,\n setupGuide: [\n { step: 1, title: 'Open @BotFather', description: 'On Telegram, search for @BotFather and start a chat' },\n { step: 2, title: 'Create a Bot', description: 'Send /newbot, choose a display name and username (must end in \"bot\")' },\n { step: 3, title: 'Copy Bot Token', description: 'BotFather will give you a token like 123456:ABC-DEF... — paste it above' },\n { step: 4, title: 'Add Bot to Channel', description: 'Open your channel/group → Settings → Admins → Add the bot as admin with \"Post Messages\" permission' },\n { step: 5, title: 'Get Channel ID', description: 'For public channels: use @channelname. For private: forward a channel message to @userinfobot to get the numeric ID (starts with -100)' },\n ],\n redirectUriPattern: null, // No OAuth redirect needed\n credentialSchema: this.getCredentialSchema(),\n };\n }\n}\n"],"mappings":"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"}