@chatman-media/channel-telegram 1.8.0 → 1.10.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.
@@ -77,15 +77,19 @@ export declare class TelegramClient {
77
77
  chatId: number | string;
78
78
  photoFileId: string;
79
79
  caption?: string;
80
+ /** Топик форум-группы (operator bot): медиа уходит в конкретный тред. */
81
+ messageThreadId?: number;
80
82
  }): Promise<TgSendMessageResult>;
81
83
  sendVideo(input: {
82
84
  chatId: number | string;
83
85
  videoFileId: string;
84
86
  caption?: string;
87
+ messageThreadId?: number;
85
88
  }): Promise<TgSendMessageResult>;
86
89
  sendVideoNote(input: {
87
90
  chatId: number | string;
88
91
  videoNoteFileId: string;
92
+ messageThreadId?: number;
89
93
  }): Promise<TgSendMessageResult>;
90
94
  sendPhotoUpload(input: {
91
95
  chatId: number | string;
@@ -93,6 +97,7 @@ export declare class TelegramClient {
93
97
  filename: string;
94
98
  contentType?: string;
95
99
  caption?: string;
100
+ messageThreadId?: number;
96
101
  }): Promise<TgSendMessageResult>;
97
102
  sendVideoUpload(input: {
98
103
  chatId: number | string;
@@ -100,12 +105,14 @@ export declare class TelegramClient {
100
105
  filename: string;
101
106
  contentType?: string;
102
107
  caption?: string;
108
+ messageThreadId?: number;
103
109
  }): Promise<TgSendMessageResult>;
104
110
  sendVideoNoteUpload(input: {
105
111
  chatId: number | string;
106
112
  bytes: ArrayBuffer | Uint8Array;
107
113
  filename: string;
108
114
  contentType?: string;
115
+ messageThreadId?: number;
109
116
  }): Promise<TgSendMessageResult>;
110
117
  /**
111
118
  * Send a video from a local file on disk (not a Telegram `file_id`).
@@ -123,6 +130,7 @@ export declare class TelegramClient {
123
130
  chatId: number | string;
124
131
  documentFileId: string;
125
132
  caption?: string;
133
+ messageThreadId?: number;
126
134
  }): Promise<TgSendMessageResult>;
127
135
  sendDocumentUpload(input: {
128
136
  chatId: number | string;
@@ -130,6 +138,7 @@ export declare class TelegramClient {
130
138
  filename: string;
131
139
  contentType?: string;
132
140
  caption?: string;
141
+ messageThreadId?: number;
133
142
  }): Promise<TgSendMessageResult>;
134
143
  /**
135
144
  * Edit a message we previously sent (commonly the lead card after the
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/bot-api/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/bot-api/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAErF,MAAM,MAAM,SAAS,GAAG,OAAO,KAAK,CAAC;AAErC,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB;AAED,qBAAa,gBAAiB,SAAQ,KAAK;IAEhC,MAAM,EAAE,MAAM;IACd,UAAU,EAAE,MAAM;IAClB,SAAS,EAAE,MAAM,GAAG,SAAS;IAC7B,WAAW,EAAE,MAAM;gBAHnB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,WAAW,EAAE,MAAM;CAK7B;AAgBD,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;gBAE1B,IAAI,EAAE,qBAAqB;YAOzB,aAAa;YAuBb,IAAI;YAUJ,aAAa;IA8B3B,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC;IAIxB;;;;;OAKG;IACH,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAIxC;;;;;;;;;;;;;OAaG;IACG,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IASrD,WAAW,CAAC,KAAK,EAAE;QACjB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;QACxB,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,CAAC,EAAE,YAAY,GAAG,MAAM,GAAG,UAAU,CAAC;QAC/C,WAAW,CAAC,EAAE,aAAa,CAAC;QAC5B,qBAAqB,CAAC,EAAE,OAAO,CAAC;QAChC,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,6EAA6E;QAC7E,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAahC;;;;OAIG;IACH,gBAAgB,CAAC,KAAK,EAAE;QACtB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;QACxB,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,GAAG,OAAO,CAAC;QAAE,iBAAiB,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAYxD;;;;;;OAMG;IACH,SAAS,CAAC,KAAK,EAAE;QACf,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;QACxB,WAAW,EAAE,MAAM,CAAC;QACpB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,yEAAyE;QACzE,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAUhC,SAAS,CAAC,KAAK,EAAE;QACf,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;QACxB,WAAW,EAAE,MAAM,CAAC;QACpB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAUhC,aAAa,CAAC,KAAK,EAAE;QACnB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;QACxB,eAAe,EAAE,MAAM,CAAC;QACxB,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAShC,eAAe,CAAC,KAAK,EAAE;QACrB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;QACxB,KAAK,EAAE,WAAW,GAAG,UAAU,CAAC;QAChC,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAiBhC,eAAe,CAAC,KAAK,EAAE;QACrB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;QACxB,KAAK,EAAE,WAAW,GAAG,UAAU,CAAC;QAChC,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAiBhC,mBAAmB,CAAC,KAAK,EAAE;QACzB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;QACxB,KAAK,EAAE,WAAW,GAAG,UAAU,CAAC;QAChC,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAahC;;;;;;OAMG;IACH,cAAc,CAAC,MAAM,EAAE;QACrB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;QACxB,aAAa,EAAE,MAAM,CAAC;QACtB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAIhC,YAAY,CAAC,KAAK,EAAE;QAClB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;QACxB,cAAc,EAAE,MAAM,CAAC;QACvB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAUhC,kBAAkB,CAAC,KAAK,EAAE;QACxB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;QACxB,KAAK,EAAE,WAAW,GAAG,UAAU,CAAC;QAChC,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAiBhC;;;;;;OAMG;IACH,eAAe,CAAC,KAAK,EAAE;QACrB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;QACxB,SAAS,EAAE,MAAM,CAAC;QAClB,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,CAAC,EAAE,YAAY,GAAG,MAAM,GAAG,UAAU,CAAC;QAC/C,WAAW,CAAC,EAAE,aAAa,CAAC;KAC7B,GAAG,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC;IAWvC;;;;OAIG;IACH,aAAa,CAAC,KAAK,EAAE;QAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAOnF;;;;OAIG;IACH,mBAAmB,CAAC,KAAK,EAAE;QACzB,eAAe,EAAE,MAAM,CAAC;QACxB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,GAAG,OAAO,CAAC,IAAI,CAAC;IAUjB,cAAc,CAAC,KAAK,EAAE;QACpB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;QACxB,MAAM,EAAE,QAAQ,GAAG,cAAc,GAAG,cAAc,GAAG,cAAc,GAAG,iBAAiB,CAAC;KACzF,GAAG,OAAO,CAAC,IAAI,CAAC;IAOjB,UAAU,CAAC,KAAK,EAAE;QAChB,GAAG,EAAE,MAAM,CAAC;QACZ,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;QAC1B,kBAAkB,CAAC,EAAE,OAAO,CAAC;KAC9B,GAAG,OAAO,CAAC,IAAI,CAAC;IASjB,aAAa,CAAC,WAAW,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAMjD,cAAc,IAAI,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,oBAAoB,EAAE,MAAM,CAAA;KAAE,CAAC;CAGzE"}
@@ -11,6 +11,10 @@ export interface TgChat {
11
11
  type: "private" | "group" | "supergroup" | "channel";
12
12
  title?: string;
13
13
  username?: string;
14
+ /** true для супергрупп с включёнными топиками (форум). Telegram отдаёт это
15
+ * поле в `message.chat` — используется как opt-in сигнал «оператор-чат —
16
+ * форум» при /setup (#651): 1 топик на диалог. */
17
+ is_forum?: boolean;
14
18
  }
15
19
  /**
16
20
  * One frame of a Telegram photo upload. Telegram delivers an array of
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/bot-api/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/bot-api/types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"update-parser.d.ts","sourceRoot":"","sources":["../../src/bot-api/update-parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAyB,MAAM,6BAA6B,CAAC;AAClF,OAAO,KAAK,EAA0B,QAAQ,EAAE,MAAM,YAAY,CAAC;AAuEnE;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAG,OAAO,GAAG,IAAI,CAwC/E"}
1
+ {"version":3,"file":"update-parser.d.ts","sourceRoot":"","sources":["../../src/bot-api/update-parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAyB,MAAM,6BAA6B,CAAC;AAClF,OAAO,KAAK,EAA0B,QAAQ,EAAE,MAAM,YAAY,CAAC;AAuEnE;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAG,OAAO,GAAG,IAAI,CA0C/E"}
package/dist/index.js CHANGED
@@ -32657,6 +32657,8 @@ class TelegramClient {
32657
32657
  };
32658
32658
  if (input.caption)
32659
32659
  params.caption = input.caption;
32660
+ if (input.messageThreadId !== undefined)
32661
+ params.message_thread_id = input.messageThreadId;
32660
32662
  return this.call("sendPhoto", params);
32661
32663
  }
32662
32664
  sendVideo(input) {
@@ -32666,16 +32668,25 @@ class TelegramClient {
32666
32668
  };
32667
32669
  if (input.caption)
32668
32670
  params.caption = input.caption;
32671
+ if (input.messageThreadId !== undefined)
32672
+ params.message_thread_id = input.messageThreadId;
32669
32673
  return this.call("sendVideo", params);
32670
32674
  }
32671
32675
  sendVideoNote(input) {
32672
- return this.call("sendVideoNote", {
32676
+ const params = {
32673
32677
  chat_id: input.chatId,
32674
32678
  video_note: input.videoNoteFileId
32675
- });
32679
+ };
32680
+ if (input.messageThreadId !== undefined)
32681
+ params.message_thread_id = input.messageThreadId;
32682
+ return this.call("sendVideoNote", params);
32676
32683
  }
32677
32684
  sendPhotoUpload(input) {
32678
- return this.callMultipart("sendPhoto", { chat_id: input.chatId, caption: input.caption }, {
32685
+ return this.callMultipart("sendPhoto", {
32686
+ chat_id: input.chatId,
32687
+ caption: input.caption,
32688
+ message_thread_id: input.messageThreadId
32689
+ }, {
32679
32690
  field: "photo",
32680
32691
  bytes: input.bytes,
32681
32692
  filename: input.filename,
@@ -32683,7 +32694,11 @@ class TelegramClient {
32683
32694
  });
32684
32695
  }
32685
32696
  sendVideoUpload(input) {
32686
- return this.callMultipart("sendVideo", { chat_id: input.chatId, caption: input.caption }, {
32697
+ return this.callMultipart("sendVideo", {
32698
+ chat_id: input.chatId,
32699
+ caption: input.caption,
32700
+ message_thread_id: input.messageThreadId
32701
+ }, {
32687
32702
  field: "video",
32688
32703
  bytes: input.bytes,
32689
32704
  filename: input.filename,
@@ -32691,7 +32706,7 @@ class TelegramClient {
32691
32706
  });
32692
32707
  }
32693
32708
  sendVideoNoteUpload(input) {
32694
- return this.callMultipart("sendVideoNote", { chat_id: input.chatId }, {
32709
+ return this.callMultipart("sendVideoNote", { chat_id: input.chatId, message_thread_id: input.messageThreadId }, {
32695
32710
  field: "video_note",
32696
32711
  bytes: input.bytes,
32697
32712
  filename: input.filename,
@@ -32708,10 +32723,16 @@ class TelegramClient {
32708
32723
  };
32709
32724
  if (input.caption)
32710
32725
  params.caption = input.caption;
32726
+ if (input.messageThreadId !== undefined)
32727
+ params.message_thread_id = input.messageThreadId;
32711
32728
  return this.call("sendDocument", params);
32712
32729
  }
32713
32730
  sendDocumentUpload(input) {
32714
- return this.callMultipart("sendDocument", { chat_id: input.chatId, caption: input.caption }, {
32731
+ return this.callMultipart("sendDocument", {
32732
+ chat_id: input.chatId,
32733
+ caption: input.caption,
32734
+ message_thread_id: input.messageThreadId
32735
+ }, {
32715
32736
  field: "document",
32716
32737
  bytes: input.bytes,
32717
32738
  filename: input.filename,
@@ -32840,10 +32861,9 @@ function parseUpdate(channelId, update) {
32840
32861
  externalMessageId: String(cb.message?.message_id ?? cb.id),
32841
32862
  externalUserId: String(cb.from.id),
32842
32863
  ...cb.from.username ? { externalUsername: cb.from.username } : {},
32843
- parts: [
32844
- { kind: "callback_query", data: cb.data, originalMessageId: String(messageId) }
32845
- ],
32864
+ parts: [{ kind: "callback_query", data: cb.data, originalMessageId: String(messageId) }],
32846
32865
  receivedAt: Math.floor(Date.now() / 1000),
32866
+ ...cb.from.language_code ? { channelLangHint: cb.from.language_code } : {},
32847
32867
  raw: update
32848
32868
  };
32849
32869
  }
@@ -32864,6 +32884,7 @@ function parseUpdate(channelId, update) {
32864
32884
  parts,
32865
32885
  receivedAt: msg.date,
32866
32886
  ...isEdit ? { edited: true } : {},
32887
+ ...msg.from.language_code ? { channelLangHint: msg.from.language_code } : {},
32867
32888
  raw: update
32868
32889
  };
32869
32890
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chatman-media/channel-telegram",
3
- "version": "1.8.0",
3
+ "version": "1.10.0",
4
4
  "description": "Telegram-каналы (BotAPI + MTProto userbot) как реализация ChannelAdapter из @chatman-media/channel-core.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -37,7 +37,7 @@
37
37
  "author": "Alexander Kireev",
38
38
  "license": "MIT",
39
39
  "dependencies": {
40
- "@chatman-media/channel-core": "1.2.0"
40
+ "@chatman-media/channel-core": "1.7.0"
41
41
  },
42
42
  "peerDependencies": {
43
43
  "telegram": ">=2.26.0"
@@ -51,7 +51,7 @@
51
51
  "telegram": "^2.26.22"
52
52
  },
53
53
  "devDependencies": {
54
- "@biomejs/biome": "^2.4.16",
54
+ "@biomejs/biome": "^2.5.0",
55
55
  "@types/bun": "1.3.14",
56
56
  "typescript": "^6.0.3"
57
57
  },
@@ -200,12 +200,15 @@ export class TelegramClient {
200
200
  chatId: number | string;
201
201
  photoFileId: string;
202
202
  caption?: string;
203
+ /** Топик форум-группы (operator bot): медиа уходит в конкретный тред. */
204
+ messageThreadId?: number;
203
205
  }): Promise<TgSendMessageResult> {
204
206
  const params: Record<string, unknown> = {
205
207
  chat_id: input.chatId,
206
208
  photo: input.photoFileId,
207
209
  };
208
210
  if (input.caption) params.caption = input.caption;
211
+ if (input.messageThreadId !== undefined) params.message_thread_id = input.messageThreadId;
209
212
  return this.call<TgSendMessageResult>("sendPhoto", params);
210
213
  }
211
214
 
@@ -213,23 +216,28 @@ export class TelegramClient {
213
216
  chatId: number | string;
214
217
  videoFileId: string;
215
218
  caption?: string;
219
+ messageThreadId?: number;
216
220
  }): Promise<TgSendMessageResult> {
217
221
  const params: Record<string, unknown> = {
218
222
  chat_id: input.chatId,
219
223
  video: input.videoFileId,
220
224
  };
221
225
  if (input.caption) params.caption = input.caption;
226
+ if (input.messageThreadId !== undefined) params.message_thread_id = input.messageThreadId;
222
227
  return this.call<TgSendMessageResult>("sendVideo", params);
223
228
  }
224
229
 
225
230
  sendVideoNote(input: {
226
231
  chatId: number | string;
227
232
  videoNoteFileId: string;
233
+ messageThreadId?: number;
228
234
  }): Promise<TgSendMessageResult> {
229
- return this.call<TgSendMessageResult>("sendVideoNote", {
235
+ const params: Record<string, unknown> = {
230
236
  chat_id: input.chatId,
231
237
  video_note: input.videoNoteFileId,
232
- });
238
+ };
239
+ if (input.messageThreadId !== undefined) params.message_thread_id = input.messageThreadId;
240
+ return this.call<TgSendMessageResult>("sendVideoNote", params);
233
241
  }
234
242
 
235
243
  sendPhotoUpload(input: {
@@ -238,10 +246,15 @@ export class TelegramClient {
238
246
  filename: string;
239
247
  contentType?: string;
240
248
  caption?: string;
249
+ messageThreadId?: number;
241
250
  }): Promise<TgSendMessageResult> {
242
251
  return this.callMultipart<TgSendMessageResult>(
243
252
  "sendPhoto",
244
- { chat_id: input.chatId, caption: input.caption },
253
+ {
254
+ chat_id: input.chatId,
255
+ caption: input.caption,
256
+ message_thread_id: input.messageThreadId,
257
+ },
245
258
  {
246
259
  field: "photo",
247
260
  bytes: input.bytes,
@@ -257,10 +270,15 @@ export class TelegramClient {
257
270
  filename: string;
258
271
  contentType?: string;
259
272
  caption?: string;
273
+ messageThreadId?: number;
260
274
  }): Promise<TgSendMessageResult> {
261
275
  return this.callMultipart<TgSendMessageResult>(
262
276
  "sendVideo",
263
- { chat_id: input.chatId, caption: input.caption },
277
+ {
278
+ chat_id: input.chatId,
279
+ caption: input.caption,
280
+ message_thread_id: input.messageThreadId,
281
+ },
264
282
  {
265
283
  field: "video",
266
284
  bytes: input.bytes,
@@ -275,10 +293,11 @@ export class TelegramClient {
275
293
  bytes: ArrayBuffer | Uint8Array;
276
294
  filename: string;
277
295
  contentType?: string;
296
+ messageThreadId?: number;
278
297
  }): Promise<TgSendMessageResult> {
279
298
  return this.callMultipart<TgSendMessageResult>(
280
299
  "sendVideoNote",
281
- { chat_id: input.chatId },
300
+ { chat_id: input.chatId, message_thread_id: input.messageThreadId },
282
301
  {
283
302
  field: "video_note",
284
303
  bytes: input.bytes,
@@ -307,12 +326,14 @@ export class TelegramClient {
307
326
  chatId: number | string;
308
327
  documentFileId: string;
309
328
  caption?: string;
329
+ messageThreadId?: number;
310
330
  }): Promise<TgSendMessageResult> {
311
331
  const params: Record<string, unknown> = {
312
332
  chat_id: input.chatId,
313
333
  document: input.documentFileId,
314
334
  };
315
335
  if (input.caption) params.caption = input.caption;
336
+ if (input.messageThreadId !== undefined) params.message_thread_id = input.messageThreadId;
316
337
  return this.call<TgSendMessageResult>("sendDocument", params);
317
338
  }
318
339
 
@@ -322,10 +343,15 @@ export class TelegramClient {
322
343
  filename: string;
323
344
  contentType?: string;
324
345
  caption?: string;
346
+ messageThreadId?: number;
325
347
  }): Promise<TgSendMessageResult> {
326
348
  return this.callMultipart<TgSendMessageResult>(
327
349
  "sendDocument",
328
- { chat_id: input.chatId, caption: input.caption },
350
+ {
351
+ chat_id: input.chatId,
352
+ caption: input.caption,
353
+ message_thread_id: input.messageThreadId,
354
+ },
329
355
  {
330
356
  field: "document",
331
357
  bytes: input.bytes,
@@ -14,6 +14,10 @@ export interface TgChat {
14
14
  type: "private" | "group" | "supergroup" | "channel";
15
15
  title?: string;
16
16
  username?: string;
17
+ /** true для супергрупп с включёнными топиками (форум). Telegram отдаёт это
18
+ * поле в `message.chat` — используется как opt-in сигнал «оператор-чат —
19
+ * форум» при /setup (#651): 1 топик на диалог. */
20
+ is_forum?: boolean;
17
21
  }
18
22
 
19
23
  /**
@@ -285,4 +285,52 @@ describe("parseUpdate", () => {
285
285
  };
286
286
  expect(parseUpdate(CH, update)).toBeNull();
287
287
  });
288
+
289
+ // #735 — слабый bootstrap-сигнал языка из Telegram language_code.
290
+ it("пробрасывает from.language_code → Inbound.channelLangHint", () => {
291
+ const update: TgUpdate = {
292
+ update_id: 10,
293
+ message: {
294
+ message_id: 1,
295
+ chat: { id: 1, type: "private" },
296
+ from: { id: 1, language_code: "ko" },
297
+ date: 1700000000,
298
+ text: "안녕",
299
+ },
300
+ };
301
+ expect(parseUpdate(CH, update)?.channelLangHint).toBe("ko");
302
+ });
303
+
304
+ it("без language_code — channelLangHint отсутствует", () => {
305
+ const update: TgUpdate = {
306
+ update_id: 11,
307
+ message: {
308
+ message_id: 2,
309
+ chat: { id: 2, type: "private" },
310
+ from: { id: 2 },
311
+ date: 1700000000,
312
+ text: "hi",
313
+ },
314
+ };
315
+ const inbound = parseUpdate(CH, update);
316
+ expect(inbound).not.toBeNull();
317
+ expect(inbound?.channelLangHint).toBeUndefined();
318
+ });
319
+
320
+ it("пробрасывает language_code из callback_query.from", () => {
321
+ const update: TgUpdate = {
322
+ update_id: 12,
323
+ callback_query: {
324
+ id: "cb1",
325
+ from: { id: 99, language_code: "en-US" },
326
+ data: "ok",
327
+ message: {
328
+ message_id: 50,
329
+ chat: { id: 99, type: "private" },
330
+ date: 1700000000,
331
+ },
332
+ },
333
+ };
334
+ expect(parseUpdate(CH, update)?.channelLangHint).toBe("en-US");
335
+ });
288
336
  });
@@ -85,10 +85,10 @@ export function parseUpdate(channelId: string, update: TgUpdate): Inbound | null
85
85
  externalMessageId: String(cb.message?.message_id ?? cb.id),
86
86
  externalUserId: String(cb.from.id),
87
87
  ...(cb.from.username ? { externalUsername: cb.from.username } : {}),
88
- parts: [
89
- { kind: "callback_query", data: cb.data, originalMessageId: String(messageId) },
90
- ],
88
+ parts: [{ kind: "callback_query", data: cb.data, originalMessageId: String(messageId) }],
91
89
  receivedAt: Math.floor(Date.now() / 1000),
90
+ // #735 — слабый bootstrap-сигнал языка (язык интерфейса клиента, не переписки).
91
+ ...(cb.from.language_code ? { channelLangHint: cb.from.language_code } : {}),
92
92
  raw: update,
93
93
  };
94
94
  }
@@ -113,6 +113,8 @@ export function parseUpdate(channelId: string, update: TgUpdate): Inbound | null
113
113
  parts,
114
114
  receivedAt: msg.date,
115
115
  ...(isEdit ? { edited: true } : {}),
116
+ // #735 — слабый bootstrap-сигнал языка (язык интерфейса клиента, не переписки).
117
+ ...(msg.from.language_code ? { channelLangHint: msg.from.language_code } : {}),
116
118
  raw: update,
117
119
  };
118
120
  }