@gakr-gakr/discord 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 (353) hide show
  1. package/account-inspect-api.ts +6 -0
  2. package/action-runtime-api.ts +1 -0
  3. package/api.ts +130 -0
  4. package/autobot.plugin.json +15 -0
  5. package/channel-config-api.ts +1 -0
  6. package/channel-plugin-api.ts +3 -0
  7. package/config-api.ts +4 -0
  8. package/configured-state.ts +6 -0
  9. package/contract-api.ts +21 -0
  10. package/directory-contract-api.ts +4 -0
  11. package/doctor-contract-api.ts +1 -0
  12. package/index.ts +24 -0
  13. package/package.json +79 -0
  14. package/runtime-api.actions.ts +15 -0
  15. package/runtime-api.lookup.ts +22 -0
  16. package/runtime-api.monitor.ts +50 -0
  17. package/runtime-api.send.ts +79 -0
  18. package/runtime-api.threads.ts +31 -0
  19. package/runtime-api.ts +181 -0
  20. package/runtime-setter-api.ts +3 -0
  21. package/secret-contract-api.ts +4 -0
  22. package/security-audit-contract-api.ts +1 -0
  23. package/security-contract-api.ts +4 -0
  24. package/session-key-api.ts +1 -0
  25. package/setup-entry.ts +9 -0
  26. package/setup-plugin-api.ts +3 -0
  27. package/src/account-inspect.ts +131 -0
  28. package/src/accounts.ts +205 -0
  29. package/src/actions/handle-action.guild-admin.ts +421 -0
  30. package/src/actions/handle-action.ts +402 -0
  31. package/src/actions/runtime.guild.ts +446 -0
  32. package/src/actions/runtime.messaging.messages.ts +226 -0
  33. package/src/actions/runtime.messaging.reactions.ts +67 -0
  34. package/src/actions/runtime.messaging.runtime.ts +73 -0
  35. package/src/actions/runtime.messaging.send.ts +336 -0
  36. package/src/actions/runtime.messaging.shared.ts +97 -0
  37. package/src/actions/runtime.messaging.ts +37 -0
  38. package/src/actions/runtime.moderation-shared.ts +48 -0
  39. package/src/actions/runtime.moderation.ts +116 -0
  40. package/src/actions/runtime.presence.ts +117 -0
  41. package/src/actions/runtime.shared.ts +86 -0
  42. package/src/actions/runtime.ts +87 -0
  43. package/src/api.ts +219 -0
  44. package/src/approval-handler.runtime.ts +636 -0
  45. package/src/approval-native.ts +219 -0
  46. package/src/approval-runtime.ts +14 -0
  47. package/src/approval-shared.ts +56 -0
  48. package/src/audit-core.ts +178 -0
  49. package/src/audit.ts +32 -0
  50. package/src/channel-actions.runtime.ts +1 -0
  51. package/src/channel-actions.ts +254 -0
  52. package/src/channel-api.ts +29 -0
  53. package/src/channel.conversation.ts +159 -0
  54. package/src/channel.loaders.ts +50 -0
  55. package/src/channel.runtime.ts +1 -0
  56. package/src/channel.setup.ts +12 -0
  57. package/src/channel.ts +728 -0
  58. package/src/chunk.ts +321 -0
  59. package/src/client.ts +143 -0
  60. package/src/component-custom-id.ts +72 -0
  61. package/src/components-registry.ts +356 -0
  62. package/src/components.builders.ts +410 -0
  63. package/src/components.modal.ts +124 -0
  64. package/src/components.parse.ts +407 -0
  65. package/src/components.ts +54 -0
  66. package/src/components.types.ts +187 -0
  67. package/src/config-schema.ts +6 -0
  68. package/src/config-ui-hints.ts +354 -0
  69. package/src/conversation-identity.ts +58 -0
  70. package/src/delivery-retry.ts +56 -0
  71. package/src/directory-cache.ts +116 -0
  72. package/src/directory-config.ts +58 -0
  73. package/src/directory-live.ts +135 -0
  74. package/src/doctor-contract.ts +477 -0
  75. package/src/doctor-shared.ts +5 -0
  76. package/src/doctor.ts +340 -0
  77. package/src/draft-chunking.ts +43 -0
  78. package/src/draft-stream.ts +162 -0
  79. package/src/error-body.ts +38 -0
  80. package/src/exec-approvals.ts +110 -0
  81. package/src/gateway-logging.ts +67 -0
  82. package/src/group-policy.ts +113 -0
  83. package/src/guilds.ts +29 -0
  84. package/src/inbound-event-delivery.ts +135 -0
  85. package/src/interactive-dispatch.ts +104 -0
  86. package/src/internal/api.commands.ts +51 -0
  87. package/src/internal/api.guild.ts +164 -0
  88. package/src/internal/api.interactions.ts +53 -0
  89. package/src/internal/api.messages.ts +113 -0
  90. package/src/internal/api.reactions.ts +38 -0
  91. package/src/internal/api.ts +61 -0
  92. package/src/internal/api.users.ts +19 -0
  93. package/src/internal/api.webhooks.ts +13 -0
  94. package/src/internal/client.ts +310 -0
  95. package/src/internal/command-deploy.ts +352 -0
  96. package/src/internal/commands.ts +188 -0
  97. package/src/internal/components.base.ts +65 -0
  98. package/src/internal/components.message.ts +279 -0
  99. package/src/internal/components.modal.ts +95 -0
  100. package/src/internal/components.ts +31 -0
  101. package/src/internal/discord.ts +11 -0
  102. package/src/internal/embeds.ts +35 -0
  103. package/src/internal/entity-cache.ts +98 -0
  104. package/src/internal/event-queue.ts +185 -0
  105. package/src/internal/gateway-close-codes.ts +25 -0
  106. package/src/internal/gateway-dispatch.ts +96 -0
  107. package/src/internal/gateway-identify-limiter.ts +26 -0
  108. package/src/internal/gateway-lifecycle.ts +75 -0
  109. package/src/internal/gateway-rate-limit.ts +104 -0
  110. package/src/internal/gateway.ts +479 -0
  111. package/src/internal/interaction-dispatch.ts +162 -0
  112. package/src/internal/interaction-options.ts +98 -0
  113. package/src/internal/interaction-response.ts +53 -0
  114. package/src/internal/interactions.ts +378 -0
  115. package/src/internal/listeners.ts +91 -0
  116. package/src/internal/modal-fields.ts +95 -0
  117. package/src/internal/payload.ts +69 -0
  118. package/src/internal/rest-body.ts +115 -0
  119. package/src/internal/rest-errors.ts +88 -0
  120. package/src/internal/rest-routes.ts +50 -0
  121. package/src/internal/rest-scheduler.ts +557 -0
  122. package/src/internal/rest.ts +322 -0
  123. package/src/internal/schemas.ts +36 -0
  124. package/src/internal/structures.ts +280 -0
  125. package/src/internal/test-builders.test-support.ts +167 -0
  126. package/src/internal/voice.ts +49 -0
  127. package/src/media-detection.ts +28 -0
  128. package/src/mentions.ts +147 -0
  129. package/src/monitor/ack-reactions.ts +70 -0
  130. package/src/monitor/agent-components-auth.ts +7 -0
  131. package/src/monitor/agent-components-context.ts +154 -0
  132. package/src/monitor/agent-components-data.ts +224 -0
  133. package/src/monitor/agent-components-dm-auth.ts +177 -0
  134. package/src/monitor/agent-components-guild-auth.ts +322 -0
  135. package/src/monitor/agent-components-helpers.runtime.ts +3 -0
  136. package/src/monitor/agent-components-helpers.ts +34 -0
  137. package/src/monitor/agent-components-reply.ts +10 -0
  138. package/src/monitor/agent-components.deps.runtime.ts +2 -0
  139. package/src/monitor/agent-components.dispatch.ts +359 -0
  140. package/src/monitor/agent-components.handlers.ts +303 -0
  141. package/src/monitor/agent-components.modal.ts +160 -0
  142. package/src/monitor/agent-components.plugin-interactive.ts +187 -0
  143. package/src/monitor/agent-components.runtime.ts +14 -0
  144. package/src/monitor/agent-components.system-controls.ts +215 -0
  145. package/src/monitor/agent-components.ts +70 -0
  146. package/src/monitor/agent-components.types.ts +58 -0
  147. package/src/monitor/agent-components.wildcard-controls.ts +171 -0
  148. package/src/monitor/allow-list.ts +631 -0
  149. package/src/monitor/auto-presence.ts +356 -0
  150. package/src/monitor/channel-access.ts +102 -0
  151. package/src/monitor/commands.ts +9 -0
  152. package/src/monitor/dm-command-auth.ts +259 -0
  153. package/src/monitor/dm-command-decision.ts +49 -0
  154. package/src/monitor/exec-approvals.ts +161 -0
  155. package/src/monitor/format.ts +45 -0
  156. package/src/monitor/gateway-handle.ts +34 -0
  157. package/src/monitor/gateway-metadata.ts +298 -0
  158. package/src/monitor/gateway-plugin.ts +302 -0
  159. package/src/monitor/gateway-registry.ts +37 -0
  160. package/src/monitor/gateway-supervisor.ts +206 -0
  161. package/src/monitor/inbound-context.ts +95 -0
  162. package/src/monitor/inbound-dedupe.ts +79 -0
  163. package/src/monitor/inbound-job.ts +118 -0
  164. package/src/monitor/listeners.queue.ts +91 -0
  165. package/src/monitor/listeners.reactions.ts +594 -0
  166. package/src/monitor/listeners.ts +150 -0
  167. package/src/monitor/message-channel-info.ts +96 -0
  168. package/src/monitor/message-forwarded.ts +114 -0
  169. package/src/monitor/message-handler.batch-gate.ts +19 -0
  170. package/src/monitor/message-handler.context.ts +492 -0
  171. package/src/monitor/message-handler.dm-preflight.ts +119 -0
  172. package/src/monitor/message-handler.draft-preview.ts +436 -0
  173. package/src/monitor/message-handler.hydration.ts +198 -0
  174. package/src/monitor/message-handler.module-test-helpers.ts +31 -0
  175. package/src/monitor/message-handler.preflight-channel-access.ts +86 -0
  176. package/src/monitor/message-handler.preflight-channel-context.ts +58 -0
  177. package/src/monitor/message-handler.preflight-context.ts +54 -0
  178. package/src/monitor/message-handler.preflight-helpers.ts +164 -0
  179. package/src/monitor/message-handler.preflight-history.ts +23 -0
  180. package/src/monitor/message-handler.preflight-logging.ts +36 -0
  181. package/src/monitor/message-handler.preflight-pluralkit.ts +28 -0
  182. package/src/monitor/message-handler.preflight-runtime.ts +28 -0
  183. package/src/monitor/message-handler.preflight-thread.ts +49 -0
  184. package/src/monitor/message-handler.preflight.ts +822 -0
  185. package/src/monitor/message-handler.preflight.types.ts +115 -0
  186. package/src/monitor/message-handler.process.ts +1033 -0
  187. package/src/monitor/message-handler.routing-preflight.ts +112 -0
  188. package/src/monitor/message-handler.ts +309 -0
  189. package/src/monitor/message-media.ts +536 -0
  190. package/src/monitor/message-run-queue.ts +101 -0
  191. package/src/monitor/message-text.ts +171 -0
  192. package/src/monitor/message-utils.ts +34 -0
  193. package/src/monitor/model-picker-preferences.ts +184 -0
  194. package/src/monitor/model-picker.state.ts +364 -0
  195. package/src/monitor/model-picker.test-utils.ts +26 -0
  196. package/src/monitor/model-picker.ts +38 -0
  197. package/src/monitor/model-picker.view.ts +722 -0
  198. package/src/monitor/native-command-agent-reply.ts +125 -0
  199. package/src/monitor/native-command-arg-ui.ts +233 -0
  200. package/src/monitor/native-command-auth.ts +309 -0
  201. package/src/monitor/native-command-bypass.ts +13 -0
  202. package/src/monitor/native-command-context.ts +109 -0
  203. package/src/monitor/native-command-dispatch.ts +35 -0
  204. package/src/monitor/native-command-model-picker-apply.ts +209 -0
  205. package/src/monitor/native-command-model-picker-interaction.ts +516 -0
  206. package/src/monitor/native-command-model-picker-ui.ts +357 -0
  207. package/src/monitor/native-command-reply.ts +185 -0
  208. package/src/monitor/native-command-route.ts +91 -0
  209. package/src/monitor/native-command-status.ts +76 -0
  210. package/src/monitor/native-command-ui.ts +26 -0
  211. package/src/monitor/native-command-ui.types.ts +20 -0
  212. package/src/monitor/native-command.args.ts +45 -0
  213. package/src/monitor/native-command.options.ts +153 -0
  214. package/src/monitor/native-command.runtime.ts +51 -0
  215. package/src/monitor/native-command.ts +747 -0
  216. package/src/monitor/native-command.types.ts +9 -0
  217. package/src/monitor/native-interaction-channel-context.ts +50 -0
  218. package/src/monitor/preflight-audio.runtime.ts +9 -0
  219. package/src/monitor/preflight-audio.ts +130 -0
  220. package/src/monitor/presence-cache.ts +61 -0
  221. package/src/monitor/presence.ts +50 -0
  222. package/src/monitor/provider-session.runtime.ts +12 -0
  223. package/src/monitor/provider.acp.ts +89 -0
  224. package/src/monitor/provider.allowlist.ts +398 -0
  225. package/src/monitor/provider.cleanup.ts +41 -0
  226. package/src/monitor/provider.commands.ts +129 -0
  227. package/src/monitor/provider.config-log.ts +45 -0
  228. package/src/monitor/provider.deploy-errors.ts +362 -0
  229. package/src/monitor/provider.deploy.ts +221 -0
  230. package/src/monitor/provider.interactions.ts +160 -0
  231. package/src/monitor/provider.lifecycle.ts +562 -0
  232. package/src/monitor/provider.runtime.ts +1 -0
  233. package/src/monitor/provider.startup-log.ts +32 -0
  234. package/src/monitor/provider.startup.ts +323 -0
  235. package/src/monitor/provider.ts +688 -0
  236. package/src/monitor/reply-context.ts +64 -0
  237. package/src/monitor/reply-delivery.ts +216 -0
  238. package/src/monitor/reply-safety.ts +96 -0
  239. package/src/monitor/rest-fetch.ts +97 -0
  240. package/src/monitor/route-resolution.ts +140 -0
  241. package/src/monitor/sender-identity.ts +81 -0
  242. package/src/monitor/startup-status.ts +10 -0
  243. package/src/monitor/status.ts +22 -0
  244. package/src/monitor/system-events.ts +55 -0
  245. package/src/monitor/thread-bindings.config.ts +35 -0
  246. package/src/monitor/thread-bindings.discord-api.ts +310 -0
  247. package/src/monitor/thread-bindings.lifecycle.ts +354 -0
  248. package/src/monitor/thread-bindings.manager.ts +554 -0
  249. package/src/monitor/thread-bindings.messages.ts +6 -0
  250. package/src/monitor/thread-bindings.persona.ts +25 -0
  251. package/src/monitor/thread-bindings.session-adapter.ts +229 -0
  252. package/src/monitor/thread-bindings.session-shared.ts +59 -0
  253. package/src/monitor/thread-bindings.session-updates.ts +35 -0
  254. package/src/monitor/thread-bindings.state.ts +540 -0
  255. package/src/monitor/thread-bindings.ts +48 -0
  256. package/src/monitor/thread-bindings.types.ts +83 -0
  257. package/src/monitor/thread-channel-context.ts +112 -0
  258. package/src/monitor/thread-session-close.ts +63 -0
  259. package/src/monitor/thread-title.ts +181 -0
  260. package/src/monitor/threading.auto-thread.ts +287 -0
  261. package/src/monitor/threading.cache.ts +45 -0
  262. package/src/monitor/threading.starter.ts +288 -0
  263. package/src/monitor/threading.ts +20 -0
  264. package/src/monitor/threading.types.ts +102 -0
  265. package/src/monitor/timeouts.ts +84 -0
  266. package/src/monitor/typing.ts +17 -0
  267. package/src/monitor.gateway.ts +75 -0
  268. package/src/monitor.ts +28 -0
  269. package/src/network-config.ts +79 -0
  270. package/src/normalize.ts +86 -0
  271. package/src/outbound-adapter.ts +327 -0
  272. package/src/outbound-approval.ts +29 -0
  273. package/src/outbound-components.ts +86 -0
  274. package/src/outbound-payload.ts +208 -0
  275. package/src/outbound-send-context.ts +92 -0
  276. package/src/outbound-session-route.ts +72 -0
  277. package/src/pluralkit.ts +58 -0
  278. package/src/preview-streaming.ts +18 -0
  279. package/src/probe.runtime.ts +1 -0
  280. package/src/probe.ts +237 -0
  281. package/src/proxy-fetch.ts +92 -0
  282. package/src/proxy-request-client.ts +21 -0
  283. package/src/recipient-resolution.ts +39 -0
  284. package/src/resolve-allowlist-common.ts +39 -0
  285. package/src/resolve-channels.ts +369 -0
  286. package/src/resolve-users.ts +184 -0
  287. package/src/retry.ts +98 -0
  288. package/src/runtime-api.ts +64 -0
  289. package/src/runtime-config.ts +16 -0
  290. package/src/runtime.ts +23 -0
  291. package/src/secret-config-contract.ts +140 -0
  292. package/src/security-audit.runtime.ts +1 -0
  293. package/src/security-audit.ts +208 -0
  294. package/src/security-contract.ts +47 -0
  295. package/src/security-doctor.ts +20 -0
  296. package/src/security.ts +60 -0
  297. package/src/send-target-parsing.ts +14 -0
  298. package/src/send.channels.ts +139 -0
  299. package/src/send.components.ts +391 -0
  300. package/src/send.emojis-stickers.ts +57 -0
  301. package/src/send.guild.ts +170 -0
  302. package/src/send.message-request.ts +112 -0
  303. package/src/send.messages.ts +229 -0
  304. package/src/send.outbound.ts +459 -0
  305. package/src/send.permissions.ts +283 -0
  306. package/src/send.reactions.ts +155 -0
  307. package/src/send.receipt.ts +69 -0
  308. package/src/send.shared.ts +469 -0
  309. package/src/send.ts +82 -0
  310. package/src/send.types.ts +191 -0
  311. package/src/send.typing.ts +9 -0
  312. package/src/send.voice.ts +140 -0
  313. package/src/send.webhook.ts +137 -0
  314. package/src/session-contract.ts +3 -0
  315. package/src/session-key-normalization.ts +47 -0
  316. package/src/setup-account-state.ts +144 -0
  317. package/src/setup-adapter.ts +14 -0
  318. package/src/setup-core.ts +215 -0
  319. package/src/setup-runtime-helpers.ts +10 -0
  320. package/src/setup-surface.ts +132 -0
  321. package/src/shared-interactive.ts +167 -0
  322. package/src/shared.ts +197 -0
  323. package/src/status-issues.ts +201 -0
  324. package/src/subagent-hooks.ts +232 -0
  325. package/src/target-parsing.ts +70 -0
  326. package/src/target-resolver.ts +129 -0
  327. package/src/targets.ts +12 -0
  328. package/src/token.ts +107 -0
  329. package/src/ui-colors.ts +27 -0
  330. package/src/ui.ts +20 -0
  331. package/src/voice/access.ts +126 -0
  332. package/src/voice/audio.ts +249 -0
  333. package/src/voice/capture-state.ts +120 -0
  334. package/src/voice/command.ts +284 -0
  335. package/src/voice/config.ts +8 -0
  336. package/src/voice/ingress.ts +164 -0
  337. package/src/voice/manager.runtime.ts +14 -0
  338. package/src/voice/manager.ts +1155 -0
  339. package/src/voice/prompt.ts +22 -0
  340. package/src/voice/realtime.ts +1370 -0
  341. package/src/voice/receive-recovery.ts +159 -0
  342. package/src/voice/sanitize.ts +29 -0
  343. package/src/voice/sdk-runtime.ts +14 -0
  344. package/src/voice/segment.ts +160 -0
  345. package/src/voice/session.ts +81 -0
  346. package/src/voice/speaker-context.ts +127 -0
  347. package/src/voice/tts.ts +151 -0
  348. package/src/voice-message.ts +474 -0
  349. package/subagent-hooks-api.ts +27 -0
  350. package/test-api.ts +4 -0
  351. package/thread-binding-api.ts +1 -0
  352. package/timeouts.ts +6 -0
  353. package/tsconfig.json +16 -0
@@ -0,0 +1,112 @@
1
+ import { MessageFlags, type APIEmbed } from "discord-api-types/v10";
2
+ import {
3
+ Embed,
4
+ serializePayload,
5
+ type MessagePayloadFile,
6
+ type MessagePayloadObject,
7
+ type TopLevelComponents,
8
+ } from "./internal/discord.js";
9
+
10
+ export const SUPPRESS_EMBEDS_FLAG = MessageFlags.SuppressEmbeds;
11
+ export const SUPPRESS_NOTIFICATIONS_FLAG = MessageFlags.SuppressNotifications;
12
+
13
+ export type DiscordSendComponentFactory = (text: string) => TopLevelComponents[];
14
+ export type DiscordSendComponents = TopLevelComponents[] | DiscordSendComponentFactory;
15
+ export type DiscordSendEmbeds = Array<APIEmbed | Embed>;
16
+
17
+ export function resolveDiscordSendComponents(params: {
18
+ components?: DiscordSendComponents;
19
+ text: string;
20
+ isFirst: boolean;
21
+ }): TopLevelComponents[] | undefined {
22
+ if (!params.components || !params.isFirst) {
23
+ return undefined;
24
+ }
25
+ return typeof params.components === "function"
26
+ ? params.components(params.text)
27
+ : params.components;
28
+ }
29
+
30
+ function normalizeDiscordEmbeds(embeds?: DiscordSendEmbeds): Embed[] | undefined {
31
+ if (!embeds?.length) {
32
+ return undefined;
33
+ }
34
+ return embeds.map((embed) => (embed instanceof Embed ? embed : new Embed(embed)));
35
+ }
36
+
37
+ export function resolveDiscordSendEmbeds(params: {
38
+ embeds?: DiscordSendEmbeds;
39
+ isFirst: boolean;
40
+ }): Embed[] | undefined {
41
+ if (!params.embeds || !params.isFirst) {
42
+ return undefined;
43
+ }
44
+ return normalizeDiscordEmbeds(params.embeds);
45
+ }
46
+
47
+ export function buildDiscordMessagePayload(params: {
48
+ text: string;
49
+ components?: TopLevelComponents[];
50
+ embeds?: Embed[];
51
+ flags?: number;
52
+ files?: MessagePayloadFile[];
53
+ }): MessagePayloadObject {
54
+ const payload: MessagePayloadObject = {};
55
+ const hasV2 = hasV2Components(params.components);
56
+ const trimmed = params.text.trim();
57
+ if (!hasV2 && trimmed) {
58
+ payload.content = params.text;
59
+ }
60
+ if (params.components?.length) {
61
+ payload.components = params.components;
62
+ }
63
+ if (!hasV2 && params.embeds?.length) {
64
+ payload.embeds = params.embeds;
65
+ }
66
+ if (params.flags !== undefined) {
67
+ payload.flags = params.flags;
68
+ }
69
+ if (params.files?.length) {
70
+ payload.files = params.files;
71
+ }
72
+ return payload;
73
+ }
74
+
75
+ export function resolveDiscordMessageFlags(params: {
76
+ silent?: boolean;
77
+ suppressEmbeds?: boolean;
78
+ }): number | undefined {
79
+ let flags = 0;
80
+ if (params.suppressEmbeds) {
81
+ flags |= SUPPRESS_EMBEDS_FLAG;
82
+ }
83
+ if (params.silent) {
84
+ flags |= SUPPRESS_NOTIFICATIONS_FLAG;
85
+ }
86
+ return flags || undefined;
87
+ }
88
+
89
+ export function buildDiscordMessageRequest(params: {
90
+ text: string;
91
+ components?: TopLevelComponents[];
92
+ embeds?: Embed[];
93
+ files?: MessagePayloadFile[];
94
+ flags?: number;
95
+ replyTo?: string;
96
+ }) {
97
+ const payload = buildDiscordMessagePayload(params);
98
+ return stripUndefinedFields({
99
+ ...serializePayload(payload),
100
+ ...(params.replyTo
101
+ ? { message_reference: { message_id: params.replyTo, fail_if_not_exists: false } }
102
+ : {}),
103
+ });
104
+ }
105
+
106
+ export function stripUndefinedFields<T extends object>(value: T): T {
107
+ return Object.fromEntries(Object.entries(value).filter(([, entry]) => entry !== undefined)) as T;
108
+ }
109
+
110
+ function hasV2Components(components?: TopLevelComponents[]): boolean {
111
+ return Boolean(components?.some((component) => "isV2" in component && component.isV2));
112
+ }
@@ -0,0 +1,229 @@
1
+ import type { APIChannel, APIMessage } from "discord-api-types/v10";
2
+ import { ChannelType } from "discord-api-types/v10";
3
+ import {
4
+ createChannelMessage,
5
+ createThread,
6
+ deleteChannelMessage,
7
+ editChannelMessage,
8
+ getChannel,
9
+ getChannelMessage,
10
+ listChannelArchivedThreads,
11
+ listGuildActiveThreads,
12
+ listChannelMessages,
13
+ listChannelPins,
14
+ pinChannelMessage,
15
+ searchGuildMessages,
16
+ unpinChannelMessage,
17
+ } from "./internal/discord.js";
18
+ import { resolveDiscordRest } from "./send.shared.js";
19
+ import type {
20
+ DiscordMessageEdit,
21
+ DiscordMessageQuery,
22
+ DiscordReactOpts,
23
+ DiscordSearchQuery,
24
+ DiscordThreadCreate,
25
+ DiscordThreadList,
26
+ } from "./send.types.js";
27
+
28
+ function formatDiscordThreadInitialMessageError(error: unknown): string {
29
+ return error instanceof Error ? error.message : String(error);
30
+ }
31
+
32
+ export class DiscordThreadInitialMessageError extends Error {
33
+ readonly initialMessageError: string;
34
+ readonly thread: APIChannel;
35
+
36
+ constructor(thread: APIChannel, error: unknown) {
37
+ const initialMessageError = formatDiscordThreadInitialMessageError(error);
38
+ super(
39
+ `Discord thread was created, but sending the initial message failed: ${initialMessageError}`,
40
+ );
41
+ this.name = "DiscordThreadInitialMessageError";
42
+ this.initialMessageError = initialMessageError;
43
+ this.thread = thread;
44
+ }
45
+ }
46
+
47
+ export async function readMessagesDiscord(
48
+ channelId: string,
49
+ query: DiscordMessageQuery | undefined,
50
+ opts: DiscordReactOpts,
51
+ ): Promise<APIMessage[]> {
52
+ const messageQuery = query ?? {};
53
+ const rest = resolveDiscordRest(opts);
54
+ const limit =
55
+ typeof messageQuery.limit === "number" && Number.isFinite(messageQuery.limit)
56
+ ? Math.min(Math.max(Math.floor(messageQuery.limit), 1), 100)
57
+ : undefined;
58
+ const params: Record<string, string | number> = {};
59
+ if (limit) {
60
+ params.limit = limit;
61
+ }
62
+ if (messageQuery.before) {
63
+ params.before = messageQuery.before;
64
+ }
65
+ if (messageQuery.after) {
66
+ params.after = messageQuery.after;
67
+ }
68
+ if (messageQuery.around) {
69
+ params.around = messageQuery.around;
70
+ }
71
+ return await listChannelMessages(rest, channelId, params);
72
+ }
73
+
74
+ export async function fetchMessageDiscord(
75
+ channelId: string,
76
+ messageId: string,
77
+ opts: DiscordReactOpts,
78
+ ): Promise<APIMessage> {
79
+ const rest = resolveDiscordRest(opts);
80
+ return await getChannelMessage(rest, channelId, messageId);
81
+ }
82
+
83
+ export async function editMessageDiscord(
84
+ channelId: string,
85
+ messageId: string,
86
+ payload: DiscordMessageEdit,
87
+ opts: DiscordReactOpts,
88
+ ): Promise<APIMessage> {
89
+ const rest = resolveDiscordRest(opts);
90
+ return await editChannelMessage(rest, channelId, messageId, {
91
+ body: {
92
+ content: payload.content,
93
+ ...(payload.flags !== undefined ? { flags: payload.flags } : {}),
94
+ },
95
+ });
96
+ }
97
+
98
+ export async function deleteMessageDiscord(
99
+ channelId: string,
100
+ messageId: string,
101
+ opts: DiscordReactOpts,
102
+ ) {
103
+ const rest = resolveDiscordRest(opts);
104
+ await deleteChannelMessage(rest, channelId, messageId);
105
+ return { ok: true };
106
+ }
107
+
108
+ export async function pinMessageDiscord(
109
+ channelId: string,
110
+ messageId: string,
111
+ opts: DiscordReactOpts,
112
+ ) {
113
+ const rest = resolveDiscordRest(opts);
114
+ await pinChannelMessage(rest, channelId, messageId);
115
+ return { ok: true };
116
+ }
117
+
118
+ export async function unpinMessageDiscord(
119
+ channelId: string,
120
+ messageId: string,
121
+ opts: DiscordReactOpts,
122
+ ) {
123
+ const rest = resolveDiscordRest(opts);
124
+ await unpinChannelMessage(rest, channelId, messageId);
125
+ return { ok: true };
126
+ }
127
+
128
+ export async function listPinsDiscord(
129
+ channelId: string,
130
+ opts: DiscordReactOpts,
131
+ ): Promise<APIMessage[]> {
132
+ const rest = resolveDiscordRest(opts);
133
+ return await listChannelPins(rest, channelId);
134
+ }
135
+
136
+ export async function createThreadDiscord(
137
+ channelId: string,
138
+ payload: DiscordThreadCreate,
139
+ opts: DiscordReactOpts,
140
+ ) {
141
+ const rest = resolveDiscordRest(opts);
142
+ const body: Record<string, unknown> = { name: payload.name };
143
+ if (payload.autoArchiveMinutes) {
144
+ body.auto_archive_duration = payload.autoArchiveMinutes;
145
+ }
146
+ if (!payload.messageId && payload.type !== undefined) {
147
+ body.type = payload.type;
148
+ }
149
+ let channelType: ChannelType | undefined;
150
+ if (!payload.messageId) {
151
+ // Only detect channel kind for route-less thread creation.
152
+ // If this lookup fails, keep prior behavior and let Discord validate.
153
+ try {
154
+ const channel = await getChannel(rest, channelId);
155
+ channelType = channel?.type;
156
+ } catch {
157
+ channelType = undefined;
158
+ }
159
+ }
160
+ const isForumLike =
161
+ channelType === ChannelType.GuildForum || channelType === ChannelType.GuildMedia;
162
+ if (isForumLike) {
163
+ const starterContent = payload.content?.trim() ? payload.content : payload.name;
164
+ body.message = { content: starterContent };
165
+ if (payload.appliedTags?.length) {
166
+ body.applied_tags = payload.appliedTags;
167
+ }
168
+ }
169
+ // When creating a standalone thread (no messageId) in a non-forum channel,
170
+ // default to public thread (type 11). Discord defaults to private (type 12)
171
+ // which is unexpected for most users. (#14147)
172
+ if (!payload.messageId && !isForumLike && body.type === undefined) {
173
+ body.type = ChannelType.PublicThread;
174
+ }
175
+ const thread = await createThread(rest, channelId, { body }, payload.messageId);
176
+
177
+ // For non-forum channels, send the initial message separately after thread creation.
178
+ // Forum channels handle this via the `message` field in the request body.
179
+ if (!isForumLike && payload.content?.trim() && "id" in thread) {
180
+ try {
181
+ await createChannelMessage(rest, thread.id, {
182
+ body: { content: payload.content },
183
+ });
184
+ } catch (error) {
185
+ throw new DiscordThreadInitialMessageError(thread, error);
186
+ }
187
+ }
188
+
189
+ return thread;
190
+ }
191
+
192
+ export async function listThreadsDiscord(payload: DiscordThreadList, opts: DiscordReactOpts) {
193
+ const rest = resolveDiscordRest(opts);
194
+ if (payload.includeArchived) {
195
+ if (!payload.channelId) {
196
+ throw new Error("channelId required to list archived threads");
197
+ }
198
+ const params: Record<string, string | number> = {};
199
+ if (payload.before) {
200
+ params.before = payload.before;
201
+ }
202
+ if (payload.limit) {
203
+ params.limit = payload.limit;
204
+ }
205
+ return await listChannelArchivedThreads(rest, payload.channelId, params);
206
+ }
207
+ return await listGuildActiveThreads(rest, payload.guildId);
208
+ }
209
+
210
+ export async function searchMessagesDiscord(query: DiscordSearchQuery, opts: DiscordReactOpts) {
211
+ const rest = resolveDiscordRest(opts);
212
+ const params = new URLSearchParams();
213
+ params.set("content", query.content);
214
+ if (query.channelIds?.length) {
215
+ for (const channelId of query.channelIds) {
216
+ params.append("channel_id", channelId);
217
+ }
218
+ }
219
+ if (query.authorIds?.length) {
220
+ for (const authorId of query.authorIds) {
221
+ params.append("author_id", authorId);
222
+ }
223
+ }
224
+ if (query.limit) {
225
+ const limit = Math.min(Math.max(Math.floor(query.limit), 1), 25);
226
+ params.set("limit", String(limit));
227
+ }
228
+ return await searchGuildMessages(rest, query.guildId, params);
229
+ }