@mtcute/core 0.30.2 → 0.31.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 (233) hide show
  1. package/client.cjs +73 -0
  2. package/client.js +73 -0
  3. package/highlevel/client.d.cts +344 -114
  4. package/highlevel/client.d.ts +344 -114
  5. package/highlevel/methods/auth/sign-in-qr.cjs +2 -0
  6. package/highlevel/methods/auth/sign-in-qr.js +2 -0
  7. package/highlevel/methods/auth/sign-in-qr.test.d.cts +1 -0
  8. package/highlevel/methods/auth/sign-in-qr.test.d.ts +1 -0
  9. package/highlevel/methods/chats/join-chat.cjs +1 -1
  10. package/highlevel/methods/chats/join-chat.d.cts +2 -1
  11. package/highlevel/methods/chats/join-chat.d.ts +2 -1
  12. package/highlevel/methods/chats/join-chat.js +1 -1
  13. package/highlevel/methods/chats/transfer-chat-ownership.cjs +6 -17
  14. package/highlevel/methods/chats/transfer-chat-ownership.js +6 -17
  15. package/highlevel/methods/communities/ban-community-participant.cjs +30 -0
  16. package/highlevel/methods/communities/ban-community-participant.d.cts +20 -0
  17. package/highlevel/methods/communities/ban-community-participant.d.ts +20 -0
  18. package/highlevel/methods/communities/ban-community-participant.js +25 -0
  19. package/highlevel/methods/communities/create-community.cjs +29 -0
  20. package/highlevel/methods/communities/create-community.d.cts +22 -0
  21. package/highlevel/methods/communities/create-community.d.ts +22 -0
  22. package/highlevel/methods/communities/create-community.js +24 -0
  23. package/highlevel/methods/communities/get-community-link-requests.cjs +27 -0
  24. package/highlevel/methods/communities/get-community-link-requests.d.cts +17 -0
  25. package/highlevel/methods/communities/get-community-link-requests.d.ts +17 -0
  26. package/highlevel/methods/communities/get-community-link-requests.js +22 -0
  27. package/highlevel/methods/communities/get-community-participant-chats.cjs +24 -0
  28. package/highlevel/methods/communities/get-community-participant-chats.d.cts +17 -0
  29. package/highlevel/methods/communities/get-community-participant-chats.d.ts +17 -0
  30. package/highlevel/methods/communities/get-community-participant-chats.js +19 -0
  31. package/highlevel/methods/communities/get-joined-communities.cjs +21 -0
  32. package/highlevel/methods/communities/get-joined-communities.d.cts +6 -0
  33. package/highlevel/methods/communities/get-joined-communities.d.ts +6 -0
  34. package/highlevel/methods/communities/get-joined-communities.js +16 -0
  35. package/highlevel/methods/communities/hide-community-link-request.cjs +30 -0
  36. package/highlevel/methods/communities/hide-community-link-request.d.cts +22 -0
  37. package/highlevel/methods/communities/hide-community-link-request.d.ts +22 -0
  38. package/highlevel/methods/communities/hide-community-link-request.js +25 -0
  39. package/highlevel/methods/communities/link-community-peer.cjs +32 -0
  40. package/highlevel/methods/communities/link-community-peer.d.cts +22 -0
  41. package/highlevel/methods/communities/link-community-peer.d.ts +22 -0
  42. package/highlevel/methods/communities/link-community-peer.js +27 -0
  43. package/highlevel/methods/communities/toggle-community-collapsed.cjs +18 -0
  44. package/highlevel/methods/communities/toggle-community-collapsed.d.cts +16 -0
  45. package/highlevel/methods/communities/toggle-community-collapsed.d.ts +16 -0
  46. package/highlevel/methods/communities/toggle-community-collapsed.js +13 -0
  47. package/highlevel/methods/ephemeral/delete-ephemeral-message.cjs +20 -0
  48. package/highlevel/methods/ephemeral/delete-ephemeral-message.d.cts +13 -0
  49. package/highlevel/methods/ephemeral/delete-ephemeral-message.d.ts +13 -0
  50. package/highlevel/methods/ephemeral/delete-ephemeral-message.js +15 -0
  51. package/highlevel/methods/ephemeral/edit-ephemeral-message.cjs +33 -0
  52. package/highlevel/methods/ephemeral/edit-ephemeral-message.d.cts +25 -0
  53. package/highlevel/methods/ephemeral/edit-ephemeral-message.d.ts +25 -0
  54. package/highlevel/methods/ephemeral/edit-ephemeral-message.js +28 -0
  55. package/highlevel/methods/ephemeral/find-in-update.cjs +27 -0
  56. package/highlevel/methods/ephemeral/find-in-update.d.cts +8 -0
  57. package/highlevel/methods/ephemeral/find-in-update.d.ts +8 -0
  58. package/highlevel/methods/ephemeral/find-in-update.js +22 -0
  59. package/highlevel/methods/ephemeral/get-ephemeral-callback-answer.cjs +31 -0
  60. package/highlevel/methods/ephemeral/get-ephemeral-callback-answer.d.cts +29 -0
  61. package/highlevel/methods/ephemeral/get-ephemeral-callback-answer.d.ts +29 -0
  62. package/highlevel/methods/ephemeral/get-ephemeral-callback-answer.js +26 -0
  63. package/highlevel/methods/ephemeral/send-ephemeral-message.cjs +38 -0
  64. package/highlevel/methods/ephemeral/send-ephemeral-message.d.cts +29 -0
  65. package/highlevel/methods/ephemeral/send-ephemeral-message.d.ts +29 -0
  66. package/highlevel/methods/ephemeral/send-ephemeral-message.js +33 -0
  67. package/highlevel/methods/files/download-iterable.cjs +4 -2
  68. package/highlevel/methods/files/download-iterable.js +4 -2
  69. package/highlevel/methods/files/download-iterable.test.d.cts +1 -0
  70. package/highlevel/methods/files/download-iterable.test.d.ts +1 -0
  71. package/highlevel/methods/files/download-stream.cjs +5 -6
  72. package/highlevel/methods/files/download-stream.js +5 -6
  73. package/highlevel/methods/forums/create-forum-topic.d.cts +7 -0
  74. package/highlevel/methods/forums/create-forum-topic.d.ts +7 -0
  75. package/highlevel/methods/forums/delete-forum-topic-history.d.cts +1 -1
  76. package/highlevel/methods/forums/delete-forum-topic-history.d.ts +1 -1
  77. package/highlevel/methods/forums/edit-forum-topic.cjs +1 -1
  78. package/highlevel/methods/forums/edit-forum-topic.d.cts +2 -2
  79. package/highlevel/methods/forums/edit-forum-topic.d.ts +2 -2
  80. package/highlevel/methods/forums/edit-forum-topic.js +1 -1
  81. package/highlevel/methods/forums/get-forum-topics-by-id.cjs +5 -1
  82. package/highlevel/methods/forums/get-forum-topics-by-id.d.cts +9 -1
  83. package/highlevel/methods/forums/get-forum-topics-by-id.d.ts +9 -1
  84. package/highlevel/methods/forums/get-forum-topics-by-id.js +5 -1
  85. package/highlevel/methods/forums/get-forum-topics-by-id.test.d.cts +1 -0
  86. package/highlevel/methods/forums/get-forum-topics-by-id.test.d.ts +1 -0
  87. package/highlevel/methods/forums/get-forum-topics.cjs +1 -1
  88. package/highlevel/methods/forums/get-forum-topics.js +1 -1
  89. package/highlevel/methods/forums/toggle-forum-topic-closed.d.cts +1 -1
  90. package/highlevel/methods/forums/toggle-forum-topic-closed.d.ts +1 -1
  91. package/highlevel/methods/forums/toggle-forum-topic-pinned.d.cts +1 -1
  92. package/highlevel/methods/forums/toggle-forum-topic-pinned.d.ts +1 -1
  93. package/highlevel/methods/forums/toggle-general-topic-hidden.cjs +2 -2
  94. package/highlevel/methods/forums/toggle-general-topic-hidden.js +3 -3
  95. package/highlevel/methods/messages/send-common.d.cts +7 -1
  96. package/highlevel/methods/messages/send-common.d.ts +7 -1
  97. package/highlevel/methods/messages/send-text.cjs +70 -4
  98. package/highlevel/methods/messages/send-text.js +70 -4
  99. package/highlevel/methods/users/resolve-peer.cjs +11 -1
  100. package/highlevel/methods/users/resolve-peer.js +11 -1
  101. package/highlevel/methods.d.cts +16 -0
  102. package/highlevel/methods.d.ts +16 -0
  103. package/highlevel/storage/service/peers.cjs +25 -0
  104. package/highlevel/storage/service/peers.js +25 -0
  105. package/highlevel/storage/service/peers.test.d.cts +1 -0
  106. package/highlevel/storage/service/peers.test.d.ts +1 -0
  107. package/highlevel/types/conversation.cjs +8 -0
  108. package/highlevel/types/conversation.d.cts +1 -0
  109. package/highlevel/types/conversation.d.ts +1 -0
  110. package/highlevel/types/conversation.js +10 -2
  111. package/highlevel/types/conversation.test.d.cts +1 -0
  112. package/highlevel/types/conversation.test.d.ts +1 -0
  113. package/highlevel/types/messages/ephemeral-message.cjs +103 -0
  114. package/highlevel/types/messages/ephemeral-message.d.cts +55 -0
  115. package/highlevel/types/messages/ephemeral-message.d.ts +55 -0
  116. package/highlevel/types/messages/ephemeral-message.js +98 -0
  117. package/highlevel/types/messages/index.d.cts +1 -0
  118. package/highlevel/types/messages/index.d.ts +1 -0
  119. package/highlevel/types/messages/message-action.cjs +6 -0
  120. package/highlevel/types/messages/message-action.d.cts +8 -1
  121. package/highlevel/types/messages/message-action.d.ts +8 -1
  122. package/highlevel/types/messages/message-action.js +6 -0
  123. package/highlevel/types/messages/replied-message.cjs +5 -1
  124. package/highlevel/types/messages/replied-message.d.cts +5 -1
  125. package/highlevel/types/messages/replied-message.d.ts +5 -1
  126. package/highlevel/types/messages/replied-message.js +5 -1
  127. package/highlevel/types/peers/chat.cjs +23 -3
  128. package/highlevel/types/peers/chat.d.cts +8 -3
  129. package/highlevel/types/peers/chat.d.ts +8 -3
  130. package/highlevel/types/peers/chat.js +24 -4
  131. package/highlevel/types/peers/community-peer.cjs +60 -0
  132. package/highlevel/types/peers/community-peer.d.cts +37 -0
  133. package/highlevel/types/peers/community-peer.d.ts +37 -0
  134. package/highlevel/types/peers/community-peer.js +55 -0
  135. package/highlevel/types/peers/full-chat.cjs +20 -5
  136. package/highlevel/types/peers/full-chat.d.cts +5 -0
  137. package/highlevel/types/peers/full-chat.d.ts +5 -0
  138. package/highlevel/types/peers/full-chat.js +20 -5
  139. package/highlevel/types/peers/index.d.cts +1 -0
  140. package/highlevel/types/peers/index.d.ts +1 -0
  141. package/highlevel/types/peers/peer.cjs +2 -0
  142. package/highlevel/types/peers/peer.js +2 -0
  143. package/highlevel/types/peers/user.cjs +6 -0
  144. package/highlevel/types/peers/user.d.cts +2 -0
  145. package/highlevel/types/peers/user.d.ts +2 -0
  146. package/highlevel/types/peers/user.js +6 -0
  147. package/highlevel/types/updates/delete-ephemeral-messages-update.cjs +27 -0
  148. package/highlevel/types/updates/delete-ephemeral-messages-update.d.cts +15 -0
  149. package/highlevel/types/updates/delete-ephemeral-messages-update.d.ts +15 -0
  150. package/highlevel/types/updates/delete-ephemeral-messages-update.js +22 -0
  151. package/highlevel/types/updates/ephemeral-callback-query.cjs +61 -0
  152. package/highlevel/types/updates/ephemeral-callback-query.d.cts +38 -0
  153. package/highlevel/types/updates/ephemeral-callback-query.d.ts +38 -0
  154. package/highlevel/types/updates/ephemeral-callback-query.js +56 -0
  155. package/highlevel/types/updates/index.d.cts +16 -2
  156. package/highlevel/types/updates/index.d.ts +16 -2
  157. package/highlevel/types/updates/parse-update.cjs +12 -1
  158. package/highlevel/types/updates/parse-update.js +12 -1
  159. package/highlevel/updates/manager.cjs +31 -13
  160. package/highlevel/updates/manager.d.cts +1 -0
  161. package/highlevel/updates/manager.d.ts +1 -0
  162. package/highlevel/updates/manager.js +31 -13
  163. package/highlevel/updates/manager.test.d.cts +1 -0
  164. package/highlevel/updates/manager.test.d.ts +1 -0
  165. package/highlevel/utils/stream-utils.cjs +8 -4
  166. package/highlevel/utils/stream-utils.js +8 -4
  167. package/highlevel/utils/stream-utils.test.d.cts +1 -0
  168. package/highlevel/utils/stream-utils.test.d.ts +1 -0
  169. package/highlevel/utils/walk-page-blocks.cjs +4 -0
  170. package/highlevel/utils/walk-page-blocks.js +4 -0
  171. package/index.cjs +10 -0
  172. package/index.js +11 -1
  173. package/methods.cjs +27 -0
  174. package/methods.js +27 -0
  175. package/network/client.cjs +4 -3
  176. package/network/client.d.cts +1 -0
  177. package/network/client.d.ts +1 -0
  178. package/network/client.js +4 -3
  179. package/network/middlewares/flood-waiter.cjs +2 -2
  180. package/network/middlewares/flood-waiter.js +2 -2
  181. package/network/middlewares/internal-errors.cjs +1 -1
  182. package/network/middlewares/internal-errors.js +1 -1
  183. package/network/middlewares/media-throttle.cjs +1 -1
  184. package/network/middlewares/media-throttle.js +1 -1
  185. package/network/mtproxy/index.cjs +4 -3
  186. package/network/mtproxy/index.d.cts +2 -2
  187. package/network/mtproxy/index.d.ts +2 -2
  188. package/network/mtproxy/index.js +4 -3
  189. package/network/network-manager.cjs +44 -16
  190. package/network/network-manager.d.cts +10 -3
  191. package/network/network-manager.d.ts +10 -3
  192. package/network/network-manager.js +45 -17
  193. package/network/network-manager.test.d.cts +1 -0
  194. package/network/network-manager.test.d.ts +1 -0
  195. package/network/persistent-connection.cjs +10 -2
  196. package/network/persistent-connection.js +10 -2
  197. package/network/session-connection.cjs +3 -0
  198. package/network/session-connection.js +3 -0
  199. package/network/transports/abstract.cjs +16 -0
  200. package/network/transports/abstract.d.cts +8 -2
  201. package/network/transports/abstract.d.ts +8 -2
  202. package/network/transports/abstract.js +17 -1
  203. package/network/transports/obfuscated.cjs +3 -1
  204. package/network/transports/obfuscated.js +3 -1
  205. package/package.json +6 -6
  206. package/tl/api-schema.json +1 -1
  207. package/tl/binary/reader.cjs +90 -15
  208. package/tl/binary/reader.js +90 -15
  209. package/tl/binary/writer.cjs +385 -80
  210. package/tl/binary/writer.js +385 -80
  211. package/tl/compat/reader.cjs +11 -0
  212. package/tl/compat/reader.js +11 -0
  213. package/tl/index.d.cts +12380 -4272
  214. package/tl/index.d.ts +12380 -4272
  215. package/tl/inner-tl.cjs +70 -20
  216. package/tl/inner-tl.js +70 -20
  217. package/tl/raw-errors.json +1 -1
  218. package/utils/abort-signal.cjs +1 -12
  219. package/utils/abort-signal.js +1 -12
  220. package/utils/abort-signal.test.d.cts +1 -0
  221. package/utils/abort-signal.test.d.ts +1 -0
  222. package/utils/binary/compat.cjs +14 -0
  223. package/utils/binary/compat.js +14 -0
  224. package/utils/early-timer.cjs +3 -11
  225. package/utils/early-timer.js +3 -11
  226. package/utils/early-timer.test.d.cts +1 -0
  227. package/utils/early-timer.test.d.ts +1 -0
  228. package/utils/function-utils.cjs +9 -4
  229. package/utils/function-utils.js +9 -4
  230. package/utils/links/bots.cjs +3 -0
  231. package/utils/links/bots.js +3 -0
  232. package/utils/peer-utils.cjs +8 -0
  233. package/utils/peer-utils.js +8 -0
@@ -0,0 +1,29 @@
1
+ import { tl } from '../../../tl/index.js';
2
+ import { ITelegramClient } from '../../client.types.js';
3
+ import { ReplyMarkup } from '../../types/bots/keyboards/index.js';
4
+ import { EphemeralMessage, InputMediaLike, InputPeerLike, InputText } from '../../types/index.js';
5
+ /**
6
+ * Send an ephemeral message — a message that is only visible
7
+ * to a single user in a chat and is not persisted in the chat history.
8
+ *
9
+ * @param chatId ID of the chat to send the message to
10
+ * @param receiverId ID of the user the message should be visible to
11
+ * @param text Text of the message
12
+ */
13
+ export declare function sendEphemeralMessage(client: ITelegramClient, chatId: InputPeerLike, receiverId: InputPeerLike, text: InputText, params?: {
14
+ /** Media to be attached to the message */
15
+ media?: InputMediaLike;
16
+ /** Message to reply to */
17
+ replyTo?: number;
18
+ /** Ephemeral message to reply to */
19
+ replyToEphemeral?: number;
20
+ /** Reply markup to be attached to the message */
21
+ replyMarkup?: ReplyMarkup;
22
+ /** For guest chat bots, ID of the query that this message is sent in response to */
23
+ queryId?: tl.Long;
24
+ /**
25
+ * Whether to dispatch the returned updates
26
+ * to the client's update handler.
27
+ */
28
+ shouldDispatch?: true;
29
+ }): Promise<EphemeralMessage>;
@@ -0,0 +1,29 @@
1
+ import { tl } from '../../../tl/index.js';
2
+ import { ITelegramClient } from '../../client.types.js';
3
+ import { ReplyMarkup } from '../../types/bots/keyboards/index.js';
4
+ import { EphemeralMessage, InputMediaLike, InputPeerLike, InputText } from '../../types/index.js';
5
+ /**
6
+ * Send an ephemeral message — a message that is only visible
7
+ * to a single user in a chat and is not persisted in the chat history.
8
+ *
9
+ * @param chatId ID of the chat to send the message to
10
+ * @param receiverId ID of the user the message should be visible to
11
+ * @param text Text of the message
12
+ */
13
+ export declare function sendEphemeralMessage(client: ITelegramClient, chatId: InputPeerLike, receiverId: InputPeerLike, text: InputText, params?: {
14
+ /** Media to be attached to the message */
15
+ media?: InputMediaLike;
16
+ /** Message to reply to */
17
+ replyTo?: number;
18
+ /** Ephemeral message to reply to */
19
+ replyToEphemeral?: number;
20
+ /** Reply markup to be attached to the message */
21
+ replyMarkup?: ReplyMarkup;
22
+ /** For guest chat bots, ID of the query that this message is sent in response to */
23
+ queryId?: tl.Long;
24
+ /**
25
+ * Whether to dispatch the returned updates
26
+ * to the client's update handler.
27
+ */
28
+ shouldDispatch?: true;
29
+ }): Promise<EphemeralMessage>;
@@ -0,0 +1,33 @@
1
+ import { randomLong } from "../../../utils/long-utils.js";
2
+ import { _normalizeInputMedia } from "../files/normalize-input-media.js";
3
+ import { _normalizeInputText } from "../misc/normalize-text.js";
4
+ import { resolvePeer, resolveUser } from "../users/resolve-peer.js";
5
+ import { _findEphemeralMessageInUpdate } from "./find-in-update.js";
6
+ import { _convertToTl } from "../../types/bots/keyboards/factories.js";
7
+ async function sendEphemeralMessage(client, chatId, receiverId, text, params) {
8
+ const { media, replyTo, replyToEphemeral, queryId, shouldDispatch } = params ?? {};
9
+ const [message, entities] = await _normalizeInputText(client, text);
10
+ const peer = await resolvePeer(client, chatId);
11
+ let replyToTl;
12
+ if (replyTo !== void 0) {
13
+ replyToTl = { _: "inputReplyToMessage", replyToMsgId: replyTo };
14
+ } else if (replyToEphemeral !== void 0) {
15
+ replyToTl = { _: "inputReplyToEphemeralMessage", id: replyToEphemeral };
16
+ }
17
+ const res = await client.call({
18
+ _: "ephemeral.sendMessage",
19
+ peer,
20
+ receiverId: await resolveUser(client, receiverId),
21
+ queryId,
22
+ message,
23
+ entities,
24
+ media: media ? await _normalizeInputMedia(client, media, { uploadPeer: peer }) : void 0,
25
+ replyMarkup: _convertToTl(params?.replyMarkup),
26
+ randomId: randomLong(),
27
+ replyTo: replyToTl
28
+ });
29
+ return _findEphemeralMessageInUpdate(client, res, false, !shouldDispatch);
30
+ }
31
+ export {
32
+ sendEphemeralMessage
33
+ };
@@ -230,12 +230,13 @@ async function* downloadAsIterable(client, input, params) {
230
230
  }).then(() => {
231
231
  client.log.debug("download workers finished");
232
232
  });
233
- abortSignal$1?.addEventListener("abort", () => {
233
+ const onAbort = () => {
234
234
  client.log.debug("download aborted");
235
235
  error = abortSignal$1.reason;
236
236
  ended = true;
237
237
  nextChunkCv.notify();
238
- });
238
+ };
239
+ abortSignal$1?.addEventListener("abort", onAbort);
239
240
  let position = offset;
240
241
  try {
241
242
  while (position < limitBytes) {
@@ -255,6 +256,7 @@ async function* downloadAsIterable(client, input, params) {
255
256
  }
256
257
  } finally {
257
258
  if (stallTimer) utils.timers.clearTimeout(stallTimer);
259
+ abortSignal$1?.removeEventListener("abort", onAbort);
258
260
  }
259
261
  }
260
262
  exports._normalizeFileDownloadLocation = _normalizeFileDownloadLocation;
@@ -223,12 +223,13 @@ async function* downloadAsIterable(client, input, params) {
223
223
  }).then(() => {
224
224
  client.log.debug("download workers finished");
225
225
  });
226
- abortSignal?.addEventListener("abort", () => {
226
+ const onAbort = () => {
227
227
  client.log.debug("download aborted");
228
228
  error = abortSignal.reason;
229
229
  ended = true;
230
230
  nextChunkCv.notify();
231
- });
231
+ };
232
+ abortSignal?.addEventListener("abort", onAbort);
232
233
  let position = offset;
233
234
  try {
234
235
  while (position < limitBytes) {
@@ -248,6 +249,7 @@ async function* downloadAsIterable(client, input, params) {
248
249
  }
249
250
  } finally {
250
251
  if (stallTimer) timers.clearTimeout(stallTimer);
252
+ abortSignal?.removeEventListener("abort", onAbort);
251
253
  }
252
254
  }
253
255
  export {
@@ -19,11 +19,9 @@ function downloadAsStream(client, location, params) {
19
19
  });
20
20
  }
21
21
  const cancel = new AbortController();
22
- if (params?.abortSignal) {
23
- params?.abortSignal.addEventListener("abort", () => {
24
- cancel.abort();
25
- });
26
- }
22
+ const onAbort = () => cancel.abort();
23
+ params?.abortSignal?.addEventListener("abort", onAbort);
24
+ const removeAbortListener = () => params?.abortSignal?.removeEventListener("abort", onAbort);
27
25
  const backpressureCv = new utils.ConditionVariable();
28
26
  return new ReadableStream({
29
27
  start(controller) {
@@ -38,13 +36,14 @@ function downloadAsStream(client, location, params) {
38
36
  controller.enqueue(chunk);
39
37
  }
40
38
  controller.close();
41
- })().catch((e) => controller.error(e));
39
+ })().catch((e) => controller.error(e)).finally(removeAbortListener);
42
40
  },
43
41
  pull() {
44
42
  backpressureCv.notify();
45
43
  },
46
44
  cancel() {
47
45
  cancel.abort();
46
+ removeAbortListener();
48
47
  }
49
48
  }, {
50
49
  highWaterMark: params?.highWaterMark,
@@ -12,11 +12,9 @@ function downloadAsStream(client, location, params) {
12
12
  });
13
13
  }
14
14
  const cancel = new AbortController();
15
- if (params?.abortSignal) {
16
- params?.abortSignal.addEventListener("abort", () => {
17
- cancel.abort();
18
- });
19
- }
15
+ const onAbort = () => cancel.abort();
16
+ params?.abortSignal?.addEventListener("abort", onAbort);
17
+ const removeAbortListener = () => params?.abortSignal?.removeEventListener("abort", onAbort);
20
18
  const backpressureCv = new ConditionVariable();
21
19
  return new ReadableStream({
22
20
  start(controller) {
@@ -31,13 +29,14 @@ function downloadAsStream(client, location, params) {
31
29
  controller.enqueue(chunk);
32
30
  }
33
31
  controller.close();
34
- })().catch((e) => controller.error(e));
32
+ })().catch((e) => controller.error(e)).finally(removeAbortListener);
35
33
  },
36
34
  pull() {
37
35
  backpressureCv.notify();
38
36
  },
39
37
  cancel() {
40
38
  cancel.abort();
39
+ removeAbortListener();
41
40
  }
42
41
  }, {
43
42
  highWaterMark: params?.highWaterMark,
@@ -6,6 +6,13 @@ import { InputPeerLike, Message } from '../../types/index.js';
6
6
  *
7
7
  * Only admins with `manageTopics` permission can do this.
8
8
  *
9
+ * > **Note**: for bots in private chats with "threaded mode" enabled,
10
+ * > message IDs are separate for each side of the chat, while the
11
+ * > canonical topic ID is always issued in the *user's* ID space.
12
+ * > The `.id` of the returned service message is in the *bot's* ID space,
13
+ * > and is **not** a valid topic ID — use `.replyToMessage.threadId` instead,
14
+ * > which is what all other methods (as well as Bot API's `message_thread_id`) expect.
15
+ *
9
16
  * @returns Service message for the created topic
10
17
  */
11
18
  export declare function createForumTopic(client: ITelegramClient, params: {
@@ -6,6 +6,13 @@ import { InputPeerLike, Message } from '../../types/index.js';
6
6
  *
7
7
  * Only admins with `manageTopics` permission can do this.
8
8
  *
9
+ * > **Note**: for bots in private chats with "threaded mode" enabled,
10
+ * > message IDs are separate for each side of the chat, while the
11
+ * > canonical topic ID is always issued in the *user's* ID space.
12
+ * > The `.id` of the returned service message is in the *bot's* ID space,
13
+ * > and is **not** a valid topic ID — use `.replyToMessage.threadId` instead,
14
+ * > which is what all other methods (as well as Bot API's `message_thread_id`) expect.
15
+ *
9
16
  * @returns Service message for the created topic
10
17
  */
11
18
  export declare function createForumTopic(client: ITelegramClient, params: {
@@ -4,7 +4,7 @@ import { ForumTopic, InputPeerLike } from '../../types/index.js';
4
4
  * Delete a forum topic and all its history
5
5
  *
6
6
  * @param chat Chat or user ID, username, phone number, `"me"` or `"self"`
7
- * @param topicId ID of the topic (i.e. its top message ID)
7
+ * @param topicId ID of the topic (i.e. its top message ID, see note at {@link createForumTopic})
8
8
  */
9
9
  export declare function deleteForumTopicHistory(client: ITelegramClient, chat: InputPeerLike, topicId: number | ForumTopic, params?: {
10
10
  /**
@@ -4,7 +4,7 @@ import { ForumTopic, InputPeerLike } from '../../types/index.js';
4
4
  * Delete a forum topic and all its history
5
5
  *
6
6
  * @param chat Chat or user ID, username, phone number, `"me"` or `"self"`
7
- * @param topicId ID of the topic (i.e. its top message ID)
7
+ * @param topicId ID of the topic (i.e. its top message ID, see note at {@link createForumTopic})
8
8
  */
9
9
  export declare function deleteForumTopicHistory(client: ITelegramClient, chat: InputPeerLike, topicId: number | ForumTopic, params?: {
10
10
  /**
@@ -15,7 +15,7 @@ async function editForumTopic(client, params) {
15
15
  peer: await resolvePeer.resolvePeer(client, chatId),
16
16
  topicId: typeof topicId === "number" ? topicId : topicId.id,
17
17
  title,
18
- iconEmojiId: icon ? icon ?? Long.ZERO : void 0,
18
+ iconEmojiId: icon === null ? Long.ZERO : icon,
19
19
  closed,
20
20
  hidden
21
21
  });
@@ -7,13 +7,13 @@ import { ForumTopic, InputPeerLike, Message } from '../../types/index.js';
7
7
  * Only admins with `manageTopics` permission can do this.
8
8
  *
9
9
  * @param chatId Chat ID or username
10
- * @param topicId ID of the topic (i.e. its top message ID)
10
+ * @param topicId ID of the topic (i.e. its top message ID, see note at {@link createForumTopic})
11
11
  * @returns Service message about the modification
12
12
  */
13
13
  export declare function editForumTopic(client: ITelegramClient, params: {
14
14
  /** Chat ID or username */
15
15
  chatId: InputPeerLike;
16
- /** ID of the topic (i.e. its top message ID) */
16
+ /** ID of the topic (i.e. its top message ID, see note at {@link createForumTopic}) */
17
17
  topicId: number | ForumTopic;
18
18
  /**
19
19
  * New topic title
@@ -7,13 +7,13 @@ import { ForumTopic, InputPeerLike, Message } from '../../types/index.js';
7
7
  * Only admins with `manageTopics` permission can do this.
8
8
  *
9
9
  * @param chatId Chat ID or username
10
- * @param topicId ID of the topic (i.e. its top message ID)
10
+ * @param topicId ID of the topic (i.e. its top message ID, see note at {@link createForumTopic})
11
11
  * @returns Service message about the modification
12
12
  */
13
13
  export declare function editForumTopic(client: ITelegramClient, params: {
14
14
  /** Chat ID or username */
15
15
  chatId: InputPeerLike;
16
- /** ID of the topic (i.e. its top message ID) */
16
+ /** ID of the topic (i.e. its top message ID, see note at {@link createForumTopic}) */
17
17
  topicId: number | ForumTopic;
18
18
  /**
19
19
  * New topic title
@@ -8,7 +8,7 @@ async function editForumTopic(client, params) {
8
8
  peer: await resolvePeer(client, chatId),
9
9
  topicId: typeof topicId === "number" ? topicId : topicId.id,
10
10
  title,
11
- iconEmojiId: icon ? icon ?? Long.ZERO : void 0,
11
+ iconEmojiId: icon === null ? Long.ZERO : icon,
12
12
  closed,
13
13
  hidden
14
14
  });
@@ -14,6 +14,10 @@ async function getForumTopicsById(client, chatId, ids) {
14
14
  peer: await resolvePeer.resolvePeer(client, chatId),
15
15
  topics: ids
16
16
  });
17
- return forumTopic.ForumTopic.parseTlForumTopics(res);
17
+ const index = /* @__PURE__ */ new Map();
18
+ for (const topic of forumTopic.ForumTopic.parseTlForumTopics(res)) {
19
+ index.set(topic.id, topic);
20
+ }
21
+ return ids.map((id) => index.get(id) ?? null);
18
22
  }
19
23
  exports.getForumTopicsById = getForumTopicsById;
@@ -4,6 +4,14 @@ import { InputPeerLike, ForumTopic } from '../../types/index.js';
4
4
  /**
5
5
  * Get forum topics by their IDs
6
6
  *
7
+ * The returned array is aligned with the input IDs.
8
+ * For topics that were deleted (or never existed),
9
+ * `null` will be returned at that position.
10
+ *
11
+ * > **Note**: for bots in private chats with "threaded mode" enabled,
12
+ * > only canonical (user-space) topic IDs are accepted —
13
+ * > see the note at {@link createForumTopic}
14
+ *
7
15
  * @param chatId Chat ID or username
8
16
  */
9
- export declare function getForumTopicsById(client: ITelegramClient, chatId: InputPeerLike, ids: MaybeArray<number>): Promise<ForumTopic[]>;
17
+ export declare function getForumTopicsById(client: ITelegramClient, chatId: InputPeerLike, ids: MaybeArray<number>): Promise<(ForumTopic | null)[]>;
@@ -4,6 +4,14 @@ import { InputPeerLike, ForumTopic } from '../../types/index.js';
4
4
  /**
5
5
  * Get forum topics by their IDs
6
6
  *
7
+ * The returned array is aligned with the input IDs.
8
+ * For topics that were deleted (or never existed),
9
+ * `null` will be returned at that position.
10
+ *
11
+ * > **Note**: for bots in private chats with "threaded mode" enabled,
12
+ * > only canonical (user-space) topic IDs are accepted —
13
+ * > see the note at {@link createForumTopic}
14
+ *
7
15
  * @param chatId Chat ID or username
8
16
  */
9
- export declare function getForumTopicsById(client: ITelegramClient, chatId: InputPeerLike, ids: MaybeArray<number>): Promise<ForumTopic[]>;
17
+ export declare function getForumTopicsById(client: ITelegramClient, chatId: InputPeerLike, ids: MaybeArray<number>): Promise<(ForumTopic | null)[]>;
@@ -7,7 +7,11 @@ async function getForumTopicsById(client, chatId, ids) {
7
7
  peer: await resolvePeer(client, chatId),
8
8
  topics: ids
9
9
  });
10
- return ForumTopic$2.parseTlForumTopics(res);
10
+ const index = /* @__PURE__ */ new Map();
11
+ for (const topic of ForumTopic$2.parseTlForumTopics(res)) {
12
+ index.set(topic.id, topic);
13
+ }
14
+ return ids.map((id) => index.get(id) ?? null);
11
15
  }
12
16
  export {
13
17
  getForumTopicsById
@@ -6,8 +6,8 @@ if (typeof globalThis !== "undefined" && !globalThis._MTCUTE_CJS_DEPRECATION_WAR
6
6
  "use strict";
7
7
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
8
8
  const resolvePeer = require("../users/resolve-peer.cjs");
9
- const miscUtils = require("../../utils/misc-utils.cjs");
10
9
  const forumTopic = require("../../types/peers/forum-topic.cjs");
10
+ const miscUtils = require("../../utils/misc-utils.cjs");
11
11
  const defaultOffset = {
12
12
  date: 0,
13
13
  id: 0,
@@ -1,6 +1,6 @@
1
1
  import { resolvePeer } from "../users/resolve-peer.js";
2
- import { makeArrayPaginated } from "../../utils/misc-utils.js";
3
2
  import { ForumTopic as ForumTopic$2 } from "../../types/peers/forum-topic.js";
3
+ import { makeArrayPaginated } from "../../utils/misc-utils.js";
4
4
  const defaultOffset = {
5
5
  date: 0,
6
6
  id: 0,
@@ -10,7 +10,7 @@ import { ForumTopic, InputPeerLike, Message } from '../../types/index.js';
10
10
  export declare function toggleForumTopicClosed(client: ITelegramClient, parmas: {
11
11
  /** Chat ID or username */
12
12
  chatId: InputPeerLike;
13
- /** ID of the topic (i.e. its top message ID) */
13
+ /** ID of the topic (i.e. its top message ID, see note at {@link createForumTopic}) */
14
14
  topicId: number | ForumTopic;
15
15
  /** Whether the topic should be closed */
16
16
  closed: boolean;
@@ -10,7 +10,7 @@ import { ForumTopic, InputPeerLike, Message } from '../../types/index.js';
10
10
  export declare function toggleForumTopicClosed(client: ITelegramClient, parmas: {
11
11
  /** Chat ID or username */
12
12
  chatId: InputPeerLike;
13
- /** ID of the topic (i.e. its top message ID) */
13
+ /** ID of the topic (i.e. its top message ID, see note at {@link createForumTopic}) */
14
14
  topicId: number | ForumTopic;
15
15
  /** Whether the topic should be closed */
16
16
  closed: boolean;
@@ -8,7 +8,7 @@ import { ForumTopic, InputPeerLike } from '../../types/index.js';
8
8
  export declare function toggleForumTopicPinned(client: ITelegramClient, params: {
9
9
  /** Chat ID or username */
10
10
  chatId: InputPeerLike;
11
- /** ID of the topic (i.e. its top message ID) */
11
+ /** ID of the topic (i.e. its top message ID, see note at {@link createForumTopic}) */
12
12
  topicId: number | ForumTopic;
13
13
  /** Whether the topic should be pinned */
14
14
  pinned: boolean;
@@ -8,7 +8,7 @@ import { ForumTopic, InputPeerLike } from '../../types/index.js';
8
8
  export declare function toggleForumTopicPinned(client: ITelegramClient, params: {
9
9
  /** Chat ID or username */
10
10
  chatId: InputPeerLike;
11
- /** ID of the topic (i.e. its top message ID) */
11
+ /** ID of the topic (i.e. its top message ID, see note at {@link createForumTopic}) */
12
12
  topicId: number | ForumTopic;
13
13
  /** Whether the topic should be pinned */
14
14
  pinned: boolean;
@@ -10,8 +10,8 @@ const resolvePeer = require("../users/resolve-peer.cjs");
10
10
  async function toggleGeneralTopicHidden(client, params) {
11
11
  const { chatId, hidden, shouldDispatch } = params;
12
12
  const res = await client.call({
13
- _: "channels.editForumTopic",
14
- channel: await resolvePeer.resolveChannel(client, chatId),
13
+ _: "messages.editForumTopic",
14
+ peer: await resolvePeer.resolvePeer(client, chatId),
15
15
  topicId: 1,
16
16
  hidden
17
17
  });
@@ -1,10 +1,10 @@
1
1
  import { _findMessageInUpdate } from "../messages/find-in-update.js";
2
- import { resolveChannel } from "../users/resolve-peer.js";
2
+ import { resolvePeer } from "../users/resolve-peer.js";
3
3
  async function toggleGeneralTopicHidden(client, params) {
4
4
  const { chatId, hidden, shouldDispatch } = params;
5
5
  const res = await client.call({
6
- _: "channels.editForumTopic",
7
- channel: await resolveChannel(client, chatId),
6
+ _: "messages.editForumTopic",
7
+ peer: await resolvePeer(client, chatId),
8
8
  topicId: 1,
9
9
  hidden
10
10
  });
@@ -13,7 +13,13 @@ export interface CommonSendParams {
13
13
  * Can also be a message from another chat, in which case a quote will be sent.
14
14
  */
15
15
  replyTo?: number | Message;
16
- /** ID of the thread to reply to */
16
+ /**
17
+ * ID of the thread (topic) to reply to
18
+ *
19
+ * > **Note**: for bots in private chats with "threaded mode" enabled,
20
+ * > this must be the canonical (user-space) topic ID —
21
+ * > see the note at {@link createForumTopic}
22
+ */
17
23
  threadId?: number;
18
24
  /**
19
25
  * If this is a reply to a specific todo item, ID of that item
@@ -13,7 +13,13 @@ export interface CommonSendParams {
13
13
  * Can also be a message from another chat, in which case a quote will be sent.
14
14
  */
15
15
  replyTo?: number | Message;
16
- /** ID of the thread to reply to */
16
+ /**
17
+ * ID of the thread (topic) to reply to
18
+ *
19
+ * > **Note**: for bots in private chats with "threaded mode" enabled,
20
+ * > this must be the canonical (user-space) topic ID —
21
+ * > see the note at {@link createForumTopic}
22
+ */
17
23
  threadId?: number;
18
24
  /**
19
25
  * If this is a reply to a specific todo item, ID of that item
@@ -18,6 +18,49 @@ const findInUpdate = require("./find-in-update.cjs");
18
18
  const sendCommon = require("./send-common.cjs");
19
19
  const factories = require("../../types/bots/keyboards/factories.cjs");
20
20
  const peersIndex = require("../../types/peers/peers-index.cjs");
21
+ function _inputReplyToToHeader(replyTo, peer) {
22
+ if (!replyTo) return [void 0, void 0];
23
+ switch (replyTo._) {
24
+ case "inputReplyToMessage": {
25
+ const replyToPeerId = replyTo.replyToPeerId && peerUtils$1.getMarkedPeerId(replyTo.replyToPeerId) !== peerUtils$1.getMarkedPeerId(peer) ? peerUtils.inputPeerToPeer(replyTo.replyToPeerId) : void 0;
26
+ return [
27
+ {
28
+ _: "messageReplyHeader",
29
+ replyToMsgId: replyTo.replyToMsgId,
30
+ replyToPeerId,
31
+ replyToTopId: replyTo.topMsgId,
32
+ quote: replyTo.quoteText !== void 0 ? true : void 0,
33
+ quoteText: replyTo.quoteText,
34
+ quoteEntities: replyTo.quoteEntities,
35
+ quoteOffset: replyTo.quoteOffset,
36
+ todoItemId: replyTo.todoItemId,
37
+ pollOption: replyTo.pollOption
38
+ },
39
+ replyTo.monoforumPeerId ? peerUtils.inputPeerToPeer(replyTo.monoforumPeerId) : void 0
40
+ ];
41
+ }
42
+ case "inputReplyToStory":
43
+ return [
44
+ {
45
+ _: "messageReplyStoryHeader",
46
+ peer: peerUtils.inputPeerToPeer(replyTo.peer),
47
+ storyId: replyTo.storyId
48
+ },
49
+ void 0
50
+ ];
51
+ case "inputReplyToMonoForum":
52
+ return [void 0, peerUtils.inputPeerToPeer(replyTo.monoforumPeerId)];
53
+ case "inputReplyToEphemeralMessage":
54
+ return [
55
+ {
56
+ _: "messageReplyHeader",
57
+ replyToEphemeral: true,
58
+ replyToMsgId: replyTo.id
59
+ },
60
+ void 0
61
+ ];
62
+ }
63
+ }
21
64
  async function sendText(client, chatId, text, params) {
22
65
  if (!params) params = {};
23
66
  const [message$1, entities] = await normalizeText._normalizeInputText(client, text);
@@ -28,6 +71,7 @@ async function sendText(client, chatId, text, params) {
28
71
  params
29
72
  );
30
73
  const randomId = params.randomId ?? longUtils.randomLong();
74
+ const sendAs = params.sendAs ? await resolvePeer.resolvePeer(client, params.sendAs) : void 0;
31
75
  const res = await client.call(
32
76
  {
33
77
  _: "messages.sendMessage",
@@ -42,7 +86,7 @@ async function sendText(client, chatId, text, params) {
42
86
  entities,
43
87
  clearDraft: params.clearDraft,
44
88
  noforwards: params.forbidForwards,
45
- sendAs: params.sendAs ? await resolvePeer.resolvePeer(client, params.sendAs) : void 0,
89
+ sendAs,
46
90
  invertMedia: params.invertMedia,
47
91
  quickReplyShortcut,
48
92
  effect: params.effect,
@@ -56,16 +100,25 @@ async function sendText(client, chatId, text, params) {
56
100
  }
57
101
  );
58
102
  if (res._ === "updateShortSentMessage") {
103
+ const [replyToHeader, savedPeerId] = _inputReplyToToHeader(replyTo, peer);
59
104
  const msg2 = {
60
105
  _: "message",
61
106
  id: res.id,
62
107
  peerId: peerUtils.inputPeerToPeer(peer),
63
- fromId: { _: "peerUser", userId: client.storage.self.getCached().userId },
108
+ fromId: sendAs ? peerUtils.inputPeerToPeer(sendAs) : { _: "peerUser", userId: client.storage.self.getCached().userId },
109
+ savedPeerId,
110
+ replyTo: replyToHeader,
64
111
  message: message$1,
65
112
  date: res.date,
66
113
  out: res.out,
114
+ silent: params.silent,
115
+ noforwards: params.forbidForwards,
116
+ invertMedia: params.invertMedia,
117
+ effect: params.effect,
67
118
  replyMarkup,
68
- entities: res.entities
119
+ media: res.media,
120
+ entities: res.entities,
121
+ ttlPeriod: res.ttlPeriod
69
122
  };
70
123
  if (!params.shouldDispatch) {
71
124
  client.handleClientUpdate(utils.createDummyUpdate(res.pts, res.ptsCount));
@@ -99,7 +152,20 @@ async function sendText(client, chatId, text, params) {
99
152
  );
100
153
  }
101
154
  };
102
- await Promise.all([fetchPeer(peer), fetchPeer(msg2.fromId)]);
155
+ const peersToFetch = [peer, msg2.fromId];
156
+ if (savedPeerId) peersToFetch.push(savedPeerId);
157
+ if (replyToHeader?._ === "messageReplyHeader" && replyToHeader.replyToPeerId) {
158
+ peersToFetch.push(replyToHeader.replyToPeerId);
159
+ } else if (replyToHeader?._ === "messageReplyStoryHeader") {
160
+ peersToFetch.push(replyToHeader.peer);
161
+ }
162
+ await Promise.all(peersToFetch.map(fetchPeer));
163
+ if (replyToHeader?._ === "messageReplyHeader" && replyToHeader.replyToTopId && replyToHeader.replyToTopId !== 1 && msg2.peerId._ === "peerChannel") {
164
+ const chat = peers.chats.get(msg2.peerId.channelId);
165
+ if (chat?._ === "channel" && chat.forum) {
166
+ replyToHeader.forumTopic = true;
167
+ }
168
+ }
103
169
  const ret = new message.Message(msg2, peers);
104
170
  return ret;
105
171
  }