@openclaw/discord 2026.3.13 → 2026.5.2-beta.1
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.
- package/account-inspect-api.ts +6 -0
- package/action-runtime-api.ts +1 -0
- package/api.ts +132 -0
- package/channel-config-api.ts +1 -0
- package/channel-plugin-api.ts +3 -0
- package/config-api.ts +4 -0
- package/configured-state.ts +6 -0
- package/contract-api.ts +21 -0
- package/directory-contract-api.ts +4 -0
- package/doctor-contract-api.ts +1 -0
- package/index.test.ts +13 -0
- package/index.ts +18 -13
- package/openclaw.plugin.json +3326 -1
- package/package.json +68 -2
- package/runtime-api.actions.ts +15 -0
- package/runtime-api.lookup.ts +22 -0
- package/runtime-api.monitor.ts +50 -0
- package/runtime-api.send.ts +79 -0
- package/runtime-api.threads.ts +30 -0
- package/runtime-api.ts +180 -0
- package/runtime-setter-api.ts +3 -0
- package/secret-contract-api.ts +4 -0
- package/security-audit-contract-api.ts +1 -0
- package/security-contract-api.ts +4 -0
- package/session-key-api.ts +1 -0
- package/setup-entry.ts +9 -0
- package/setup-plugin-api.ts +3 -0
- package/src/account-inspect.test.ts +126 -0
- package/src/account-inspect.ts +132 -0
- package/src/accounts.test.ts +247 -0
- package/src/accounts.ts +196 -0
- package/src/actions/handle-action.guild-admin.ts +411 -0
- package/src/actions/handle-action.test.ts +306 -0
- package/src/actions/handle-action.ts +372 -0
- package/src/actions/runtime.guild.ts +446 -0
- package/src/actions/runtime.messaging.messages.ts +205 -0
- package/src/actions/runtime.messaging.reactions.ts +67 -0
- package/src/actions/runtime.messaging.runtime.ts +69 -0
- package/src/actions/runtime.messaging.send.ts +248 -0
- package/src/actions/runtime.messaging.shared.ts +97 -0
- package/src/actions/runtime.messaging.ts +37 -0
- package/src/actions/runtime.moderation-shared.ts +48 -0
- package/src/actions/runtime.moderation.authz.test.ts +151 -0
- package/src/actions/runtime.moderation.ts +116 -0
- package/src/actions/runtime.presence.test.ts +160 -0
- package/src/actions/runtime.presence.ts +117 -0
- package/src/actions/runtime.shared.ts +83 -0
- package/src/actions/runtime.test.ts +1087 -0
- package/src/actions/runtime.ts +87 -0
- package/src/api-barrel.test.ts +80 -0
- package/src/api.test.ts +130 -0
- package/src/api.ts +169 -0
- package/src/approval-handler.runtime.test.ts +41 -0
- package/src/approval-handler.runtime.ts +632 -0
- package/src/approval-native.test.ts +330 -0
- package/src/approval-native.ts +219 -0
- package/src/approval-runtime.ts +14 -0
- package/src/approval-shared.ts +53 -0
- package/src/audit-core.ts +141 -0
- package/src/audit.test.ts +145 -0
- package/src/audit.ts +32 -0
- package/src/channel-actions.contract.test.ts +45 -0
- package/src/channel-actions.runtime.ts +1 -0
- package/src/channel-actions.test.ts +275 -0
- package/src/channel-actions.ts +203 -0
- package/src/channel-api.ts +29 -0
- package/src/channel.conversation.ts +159 -0
- package/src/channel.loaders.ts +47 -0
- package/src/channel.runtime.ts +1 -0
- package/src/channel.setup.ts +12 -0
- package/src/channel.test.ts +547 -12
- package/src/channel.ts +597 -430
- package/src/chunk.test.ts +157 -0
- package/src/chunk.ts +321 -0
- package/src/client.proxy.test.ts +176 -0
- package/src/client.test.ts +76 -0
- package/src/client.ts +132 -0
- package/src/component-custom-id.ts +72 -0
- package/src/components-registry.ts +356 -0
- package/src/components.builders.ts +409 -0
- package/src/components.modal.ts +124 -0
- package/src/components.parse.ts +407 -0
- package/src/components.test.ts +312 -0
- package/src/components.ts +54 -0
- package/src/components.types.ts +187 -0
- package/src/config-schema.test.ts +325 -0
- package/src/config-schema.ts +6 -0
- package/src/config-ui-hints.ts +249 -0
- package/src/conversation-identity.ts +58 -0
- package/src/delivery-retry.ts +56 -0
- package/src/directory-cache.ts +116 -0
- package/src/directory-config.ts +58 -0
- package/src/directory-contract.test.ts +129 -0
- package/src/directory-live.test.ts +126 -0
- package/src/directory-live.ts +135 -0
- package/src/doctor-contract.ts +477 -0
- package/src/doctor-shared.ts +5 -0
- package/src/doctor.test.ts +405 -0
- package/src/doctor.ts +340 -0
- package/src/draft-chunking.test.ts +64 -0
- package/src/draft-chunking.ts +43 -0
- package/src/draft-stream.test.ts +159 -0
- package/src/draft-stream.ts +154 -0
- package/src/error-body.ts +38 -0
- package/src/exec-approvals.test.ts +88 -0
- package/src/exec-approvals.ts +110 -0
- package/src/gateway-logging.test.ts +98 -0
- package/src/gateway-logging.ts +67 -0
- package/src/group-policy.ts +113 -0
- package/src/guilds.ts +29 -0
- package/src/inbound-context.contract.test.ts +11 -0
- package/src/interactive-dispatch.ts +104 -0
- package/src/internal/api.commands.ts +51 -0
- package/src/internal/api.guild.ts +164 -0
- package/src/internal/api.interactions.ts +53 -0
- package/src/internal/api.messages.ts +113 -0
- package/src/internal/api.reactions.ts +38 -0
- package/src/internal/api.test.ts +262 -0
- package/src/internal/api.ts +61 -0
- package/src/internal/api.users.ts +19 -0
- package/src/internal/api.webhooks.ts +13 -0
- package/src/internal/client.test.ts +408 -0
- package/src/internal/client.ts +308 -0
- package/src/internal/command-deploy.ts +237 -0
- package/src/internal/commands.ts +188 -0
- package/src/internal/components.base.ts +65 -0
- package/src/internal/components.message.ts +279 -0
- package/src/internal/components.modal.ts +95 -0
- package/src/internal/components.ts +31 -0
- package/src/internal/discord.ts +11 -0
- package/src/internal/embeds.ts +35 -0
- package/src/internal/entity-cache.ts +98 -0
- package/src/internal/event-queue.ts +162 -0
- package/src/internal/gateway-close-codes.ts +25 -0
- package/src/internal/gateway-dispatch.ts +96 -0
- package/src/internal/gateway-identify-limiter.ts +26 -0
- package/src/internal/gateway-lifecycle.ts +61 -0
- package/src/internal/gateway-rate-limit.ts +104 -0
- package/src/internal/gateway.test.ts +603 -0
- package/src/internal/gateway.ts +476 -0
- package/src/internal/interaction-dispatch.test.ts +148 -0
- package/src/internal/interaction-dispatch.ts +162 -0
- package/src/internal/interaction-options.ts +98 -0
- package/src/internal/interaction-response.ts +53 -0
- package/src/internal/interactions.test.ts +325 -0
- package/src/internal/interactions.ts +378 -0
- package/src/internal/listeners.ts +85 -0
- package/src/internal/live-smoke.live.test.ts +26 -0
- package/src/internal/modal-fields.ts +95 -0
- package/src/internal/payload.ts +69 -0
- package/src/internal/rest-body.ts +115 -0
- package/src/internal/rest-errors.ts +88 -0
- package/src/internal/rest-routes.ts +50 -0
- package/src/internal/rest-scheduler.ts +557 -0
- package/src/internal/rest.test.ts +673 -0
- package/src/internal/rest.ts +322 -0
- package/src/internal/schemas.ts +36 -0
- package/src/internal/structures.test.ts +43 -0
- package/src/internal/structures.ts +280 -0
- package/src/internal/test-builders.test-support.ts +163 -0
- package/src/internal/voice.ts +49 -0
- package/src/media-detection.ts +28 -0
- package/src/mentions.test.ts +111 -0
- package/src/mentions.ts +147 -0
- package/src/monitor/access-groups.ts +55 -0
- package/src/monitor/ack-reactions.ts +70 -0
- package/src/monitor/acp-bind-here.integration.test.ts +211 -0
- package/src/monitor/agent-components-auth.ts +7 -0
- package/src/monitor/agent-components-context.ts +154 -0
- package/src/monitor/agent-components-data.ts +224 -0
- package/src/monitor/agent-components-dm-auth.ts +221 -0
- package/src/monitor/agent-components-guild-auth.ts +322 -0
- package/src/monitor/agent-components-helpers.runtime.ts +5 -0
- package/src/monitor/agent-components-helpers.ts +34 -0
- package/src/monitor/agent-components-reply.ts +10 -0
- package/src/monitor/agent-components.deps.runtime.ts +2 -0
- package/src/monitor/agent-components.dispatch.ts +366 -0
- package/src/monitor/agent-components.handlers.ts +303 -0
- package/src/monitor/agent-components.modal.ts +160 -0
- package/src/monitor/agent-components.plugin-interactive.ts +187 -0
- package/src/monitor/agent-components.runtime.ts +14 -0
- package/src/monitor/agent-components.system-controls.ts +211 -0
- package/src/monitor/agent-components.ts +70 -0
- package/src/monitor/agent-components.types.ts +58 -0
- package/src/monitor/agent-components.wildcard-controls.ts +168 -0
- package/src/monitor/agent-components.wildcard.test.ts +71 -0
- package/src/monitor/allow-list.test.ts +14 -0
- package/src/monitor/allow-list.ts +633 -0
- package/src/monitor/auto-presence.test.ts +156 -0
- package/src/monitor/auto-presence.ts +356 -0
- package/src/monitor/channel-access.test.ts +99 -0
- package/src/monitor/channel-access.ts +102 -0
- package/src/monitor/commands.test.ts +24 -0
- package/src/monitor/commands.ts +9 -0
- package/src/monitor/dm-command-auth.test.ts +197 -0
- package/src/monitor/dm-command-auth.ts +158 -0
- package/src/monitor/dm-command-decision.test.ts +113 -0
- package/src/monitor/dm-command-decision.ts +49 -0
- package/src/monitor/exec-approvals.test.ts +226 -0
- package/src/monitor/exec-approvals.ts +158 -0
- package/src/monitor/format.ts +45 -0
- package/src/monitor/gateway-handle.ts +34 -0
- package/src/monitor/gateway-metadata.test.ts +29 -0
- package/src/monitor/gateway-metadata.ts +298 -0
- package/src/monitor/gateway-plugin.test.ts +297 -0
- package/src/monitor/gateway-plugin.ts +294 -0
- package/src/monitor/gateway-registry.ts +37 -0
- package/src/monitor/gateway-supervisor.test.ts +150 -0
- package/src/monitor/gateway-supervisor.ts +206 -0
- package/src/monitor/inbound-context.test-helpers.ts +37 -0
- package/src/monitor/inbound-context.test.ts +106 -0
- package/src/monitor/inbound-context.ts +103 -0
- package/src/monitor/inbound-dedupe.ts +79 -0
- package/src/monitor/inbound-job.test.ts +203 -0
- package/src/monitor/inbound-job.ts +118 -0
- package/src/monitor/listeners.queue.ts +91 -0
- package/src/monitor/listeners.reactions.ts +610 -0
- package/src/monitor/listeners.test.ts +200 -0
- package/src/monitor/listeners.ts +150 -0
- package/src/monitor/message-channel-info.ts +96 -0
- package/src/monitor/message-forwarded.ts +107 -0
- package/src/monitor/message-handler.batch-gate.test.ts +22 -0
- package/src/monitor/message-handler.batch-gate.ts +19 -0
- package/src/monitor/message-handler.bot-self-filter.test.ts +68 -0
- package/src/monitor/message-handler.context.ts +406 -0
- package/src/monitor/message-handler.dm-preflight.ts +123 -0
- package/src/monitor/message-handler.draft-preview.ts +246 -0
- package/src/monitor/message-handler.hydration.test.ts +80 -0
- package/src/monitor/message-handler.hydration.ts +198 -0
- package/src/monitor/message-handler.inbound-context.test.ts +59 -0
- package/src/monitor/message-handler.module-test-helpers.ts +31 -0
- package/src/monitor/message-handler.preflight-channel-access.ts +86 -0
- package/src/monitor/message-handler.preflight-channel-context.test.ts +18 -0
- package/src/monitor/message-handler.preflight-channel-context.ts +58 -0
- package/src/monitor/message-handler.preflight-context.ts +54 -0
- package/src/monitor/message-handler.preflight-helpers.ts +164 -0
- package/src/monitor/message-handler.preflight-history.ts +23 -0
- package/src/monitor/message-handler.preflight-logging.ts +36 -0
- package/src/monitor/message-handler.preflight-pluralkit.ts +26 -0
- package/src/monitor/message-handler.preflight-runtime.ts +28 -0
- package/src/monitor/message-handler.preflight-thread.ts +49 -0
- package/src/monitor/message-handler.preflight.acp-bindings.test.ts +369 -0
- package/src/monitor/message-handler.preflight.test-helpers.ts +111 -0
- package/src/monitor/message-handler.preflight.test.ts +1623 -0
- package/src/monitor/message-handler.preflight.ts +679 -0
- package/src/monitor/message-handler.preflight.types.ts +110 -0
- package/src/monitor/message-handler.process.test.ts +1369 -0
- package/src/monitor/message-handler.process.ts +686 -0
- package/src/monitor/message-handler.queue.test.ts +496 -0
- package/src/monitor/message-handler.routing-preflight.ts +112 -0
- package/src/monitor/message-handler.test-harness.ts +99 -0
- package/src/monitor/message-handler.test-helpers.ts +75 -0
- package/src/monitor/message-handler.ts +274 -0
- package/src/monitor/message-media.ts +509 -0
- package/src/monitor/message-run-queue.ts +101 -0
- package/src/monitor/message-text.ts +171 -0
- package/src/monitor/message-utils.test.ts +1157 -0
- package/src/monitor/message-utils.ts +32 -0
- package/src/monitor/model-picker-preferences.test.ts +67 -0
- package/src/monitor/model-picker-preferences.ts +184 -0
- package/src/monitor/model-picker.state.ts +364 -0
- package/src/monitor/model-picker.test-utils.ts +26 -0
- package/src/monitor/model-picker.test.ts +794 -0
- package/src/monitor/model-picker.ts +38 -0
- package/src/monitor/model-picker.view.ts +695 -0
- package/src/monitor/monitor.agent-components.test.ts +375 -0
- package/src/monitor/monitor.test.ts +849 -0
- package/src/monitor/monitor.threading-utils.test.ts +598 -0
- package/src/monitor/native-command-agent-reply.ts +125 -0
- package/src/monitor/native-command-arg-ui.ts +233 -0
- package/src/monitor/native-command-auth.ts +308 -0
- package/src/monitor/native-command-bypass.ts +13 -0
- package/src/monitor/native-command-context.test.ts +98 -0
- package/src/monitor/native-command-context.ts +103 -0
- package/src/monitor/native-command-dispatch.ts +35 -0
- package/src/monitor/native-command-model-picker-apply.ts +177 -0
- package/src/monitor/native-command-model-picker-interaction.ts +461 -0
- package/src/monitor/native-command-model-picker-ui.ts +368 -0
- package/src/monitor/native-command-reply.test.ts +68 -0
- package/src/monitor/native-command-reply.ts +185 -0
- package/src/monitor/native-command-route.ts +91 -0
- package/src/monitor/native-command-status.ts +76 -0
- package/src/monitor/native-command-ui.ts +26 -0
- package/src/monitor/native-command-ui.types.ts +20 -0
- package/src/monitor/native-command.args.ts +45 -0
- package/src/monitor/native-command.command-arg.test.ts +99 -0
- package/src/monitor/native-command.commands-allowfrom.test.ts +490 -0
- package/src/monitor/native-command.model-picker.test.ts +767 -0
- package/src/monitor/native-command.options.test.ts +369 -0
- package/src/monitor/native-command.options.ts +153 -0
- package/src/monitor/native-command.plugin-dispatch.test.ts +961 -0
- package/src/monitor/native-command.runtime.ts +50 -0
- package/src/monitor/native-command.status-direct.test.ts +272 -0
- package/src/monitor/native-command.test-helpers.ts +64 -0
- package/src/monitor/native-command.think-autocomplete.test.ts +416 -0
- package/src/monitor/native-command.ts +700 -0
- package/src/monitor/native-command.types.ts +9 -0
- package/src/monitor/native-interaction-channel-context.ts +50 -0
- package/src/monitor/preflight-audio.runtime.ts +9 -0
- package/src/monitor/preflight-audio.test.ts +157 -0
- package/src/monitor/preflight-audio.ts +130 -0
- package/src/monitor/presence-cache.ts +61 -0
- package/src/monitor/presence.test.ts +44 -0
- package/src/monitor/presence.ts +50 -0
- package/src/monitor/provider-session.runtime.ts +12 -0
- package/src/monitor/provider.acp.ts +89 -0
- package/src/monitor/provider.allowlist.test.ts +149 -0
- package/src/monitor/provider.allowlist.ts +394 -0
- package/src/monitor/provider.cleanup.ts +41 -0
- package/src/monitor/provider.commands.ts +129 -0
- package/src/monitor/provider.config-log.ts +45 -0
- package/src/monitor/provider.deploy-errors.ts +362 -0
- package/src/monitor/provider.deploy.ts +221 -0
- package/src/monitor/provider.interactions.ts +160 -0
- package/src/monitor/provider.lifecycle.test.ts +713 -0
- package/src/monitor/provider.lifecycle.ts +552 -0
- package/src/monitor/provider.proxy.test.ts +745 -0
- package/src/monitor/provider.rest-proxy.test.ts +121 -0
- package/src/monitor/provider.runtime.ts +1 -0
- package/src/monitor/provider.skill-dedupe.test.ts +42 -0
- package/src/monitor/provider.startup-log.ts +32 -0
- package/src/monitor/provider.startup.test.ts +426 -0
- package/src/monitor/provider.startup.ts +323 -0
- package/src/monitor/provider.test.ts +1111 -0
- package/src/monitor/provider.ts +713 -0
- package/src/monitor/reply-context.ts +64 -0
- package/src/monitor/reply-delivery.test.ts +244 -0
- package/src/monitor/reply-delivery.ts +203 -0
- package/src/monitor/rest-fetch.ts +43 -0
- package/src/monitor/route-resolution.test.ts +204 -0
- package/src/monitor/route-resolution.ts +140 -0
- package/src/monitor/sender-identity.ts +81 -0
- package/src/monitor/startup-status.test.ts +30 -0
- package/src/monitor/startup-status.ts +10 -0
- package/src/monitor/status.ts +22 -0
- package/src/monitor/system-events.ts +55 -0
- package/src/monitor/thread-bindings.config.ts +35 -0
- package/src/monitor/thread-bindings.discord-api.test.ts +229 -0
- package/src/monitor/thread-bindings.discord-api.ts +310 -0
- package/src/monitor/thread-bindings.lifecycle.test.ts +1871 -0
- package/src/monitor/thread-bindings.lifecycle.ts +354 -0
- package/src/monitor/thread-bindings.manager.ts +553 -0
- package/src/monitor/thread-bindings.messages.ts +6 -0
- package/src/monitor/thread-bindings.persona.test.ts +34 -0
- package/src/monitor/thread-bindings.persona.ts +25 -0
- package/src/monitor/thread-bindings.session-adapter.ts +229 -0
- package/src/monitor/thread-bindings.session-shared.ts +59 -0
- package/src/monitor/thread-bindings.session-updates.ts +35 -0
- package/src/monitor/thread-bindings.shared-state.test.ts +36 -0
- package/src/monitor/thread-bindings.state.ts +540 -0
- package/src/monitor/thread-bindings.ts +48 -0
- package/src/monitor/thread-bindings.types.ts +83 -0
- package/src/monitor/thread-channel-context.ts +112 -0
- package/src/monitor/thread-session-close.test.ts +180 -0
- package/src/monitor/thread-session-close.ts +63 -0
- package/src/monitor/thread-title.generate.test.ts +197 -0
- package/src/monitor/thread-title.test.ts +31 -0
- package/src/monitor/thread-title.ts +181 -0
- package/src/monitor/threading.auto-thread.test.ts +327 -0
- package/src/monitor/threading.auto-thread.ts +287 -0
- package/src/monitor/threading.cache.ts +45 -0
- package/src/monitor/threading.parent-info.test.ts +156 -0
- package/src/monitor/threading.starter.test.ts +260 -0
- package/src/monitor/threading.starter.ts +287 -0
- package/src/monitor/threading.ts +20 -0
- package/src/monitor/threading.types.ts +102 -0
- package/src/monitor/timeouts.ts +84 -0
- package/src/monitor/typing.test.ts +42 -0
- package/src/monitor/typing.ts +17 -0
- package/src/monitor.gateway.test.ts +187 -0
- package/src/monitor.gateway.ts +75 -0
- package/src/monitor.test.ts +1397 -0
- package/src/monitor.ts +28 -0
- package/src/normalize.test.ts +56 -0
- package/src/normalize.ts +86 -0
- package/src/outbound-adapter.interactive-order.test.ts +64 -0
- package/src/outbound-adapter.test-harness.ts +207 -0
- package/src/outbound-adapter.test.ts +696 -0
- package/src/outbound-adapter.ts +291 -0
- package/src/outbound-approval.ts +29 -0
- package/src/outbound-components.ts +81 -0
- package/src/outbound-payload.contract.test.ts +38 -0
- package/src/outbound-payload.ts +134 -0
- package/src/outbound-send-context.ts +92 -0
- package/src/outbound-session-route.test.ts +34 -0
- package/src/outbound-session-route.ts +72 -0
- package/src/pluralkit.test.ts +67 -0
- package/src/pluralkit.ts +58 -0
- package/src/preview-streaming.ts +32 -0
- package/src/probe.intents.test.ts +94 -0
- package/src/probe.parse-token.test.ts +43 -0
- package/src/probe.runtime.ts +1 -0
- package/src/probe.ts +237 -0
- package/src/proxy-fetch.ts +92 -0
- package/src/proxy-request-client.test.ts +78 -0
- package/src/proxy-request-client.ts +21 -0
- package/src/recipient-resolution.ts +39 -0
- package/src/resolve-allowlist-common.test.ts +36 -0
- package/src/resolve-allowlist-common.ts +39 -0
- package/src/resolve-channels.test.ts +340 -0
- package/src/resolve-channels.ts +369 -0
- package/src/resolve-users.test.ts +222 -0
- package/src/resolve-users.ts +184 -0
- package/src/retry.test.ts +83 -0
- package/src/retry.ts +98 -0
- package/src/runtime-api.ts +64 -0
- package/src/runtime.ts +22 -5
- package/src/secret-config-contract.ts +140 -0
- package/src/security-audit.runtime.ts +1 -0
- package/src/security-audit.test.ts +246 -0
- package/src/security-audit.ts +208 -0
- package/src/security-contract.ts +47 -0
- package/src/security-doctor.test.ts +25 -0
- package/src/security-doctor.ts +20 -0
- package/src/security.ts +60 -0
- package/src/send-target-parsing.ts +14 -0
- package/src/send.channels.ts +139 -0
- package/src/send.components.test.ts +275 -0
- package/src/send.components.ts +381 -0
- package/src/send.creates-thread.test.ts +643 -0
- package/src/send.emojis-stickers.ts +57 -0
- package/src/send.guild.ts +170 -0
- package/src/send.message-request.ts +97 -0
- package/src/send.messages.test.ts +53 -0
- package/src/send.messages.ts +225 -0
- package/src/send.outbound.ts +413 -0
- package/src/send.permissions.authz.test.ts +188 -0
- package/src/send.permissions.ts +283 -0
- package/src/send.reactions.ts +155 -0
- package/src/send.sends-basic-channel-messages.test.ts +941 -0
- package/src/send.shared.ts +447 -0
- package/src/send.test-harness.ts +56 -0
- package/src/send.ts +82 -0
- package/src/send.types.ts +188 -0
- package/src/send.typing.test.ts +41 -0
- package/src/send.typing.ts +9 -0
- package/src/send.voice.ts +134 -0
- package/src/send.webhook-activity.test.ts +105 -0
- package/src/send.webhook.proxy.test.ts +191 -0
- package/src/send.webhook.ts +133 -0
- package/src/session-contract.ts +3 -0
- package/src/session-key-normalization.test.ts +44 -0
- package/src/session-key-normalization.ts +47 -0
- package/src/setup-account-state.test.ts +91 -0
- package/src/setup-account-state.ts +144 -0
- package/src/setup-adapter.ts +12 -0
- package/src/setup-core.ts +212 -0
- package/src/setup-runtime-helpers.ts +10 -0
- package/src/setup-surface.test.ts +137 -0
- package/src/setup-surface.ts +129 -0
- package/src/shared-interactive.test.ts +153 -0
- package/src/shared-interactive.ts +124 -0
- package/src/shared.test.ts +165 -0
- package/src/shared.ts +190 -0
- package/src/status-issues.test.ts +70 -0
- package/src/status-issues.ts +169 -0
- package/src/subagent-hooks.test.ts +130 -81
- package/src/subagent-hooks.ts +184 -122
- package/src/target-parsing.ts +53 -0
- package/src/target-resolver.ts +129 -0
- package/src/targets.test.ts +367 -0
- package/src/targets.ts +12 -0
- package/src/test-http-helpers.ts +10 -0
- package/src/test-support/component-runtime.ts +190 -0
- package/src/test-support/config.ts +7 -0
- package/src/test-support/configured-binding-runtime.ts +29 -0
- package/src/test-support/partial-channel.ts +26 -0
- package/src/test-support/provider.test-support.ts +545 -0
- package/src/token.test.ts +107 -0
- package/src/token.ts +60 -0
- package/src/ui-colors.ts +27 -0
- package/src/ui.ts +20 -0
- package/src/voice/access.test.ts +217 -0
- package/src/voice/access.ts +124 -0
- package/src/voice/audio.ts +173 -0
- package/src/voice/capture-state.test.ts +48 -0
- package/src/voice/capture-state.ts +120 -0
- package/src/voice/command.test.ts +164 -0
- package/src/voice/command.ts +283 -0
- package/src/voice/config.ts +8 -0
- package/src/voice/manager.e2e.test.ts +928 -0
- package/src/voice/manager.ready-listener.test.ts +37 -0
- package/src/voice/manager.runtime.ts +11 -0
- package/src/voice/manager.ts +691 -0
- package/src/voice/prompt.test.ts +16 -0
- package/src/voice/prompt.ts +17 -0
- package/src/voice/receive-recovery.test.ts +79 -0
- package/src/voice/receive-recovery.ts +159 -0
- package/src/voice/sanitize.test.ts +34 -0
- package/src/voice/sanitize.ts +32 -0
- package/src/voice/sdk-runtime.ts +14 -0
- package/src/voice/segment.ts +156 -0
- package/src/voice/session.ts +50 -0
- package/src/voice/speaker-context.ts +127 -0
- package/src/voice/tts.ts +125 -0
- package/src/voice-message.test.ts +234 -0
- package/src/voice-message.ts +444 -0
- package/subagent-hooks-api.ts +27 -0
- package/test-api.ts +4 -0
- package/thread-binding-api.ts +1 -0
- package/timeouts.ts +6 -0
- package/tsconfig.json +16 -0
|
@@ -0,0 +1,446 @@
|
|
|
1
|
+
import type { AgentToolResult } from "@mariozechner/pi-agent-core";
|
|
2
|
+
import { resolveDefaultDiscordAccountId } from "../accounts.js";
|
|
3
|
+
import { getPresence } from "../monitor/presence-cache.js";
|
|
4
|
+
import {
|
|
5
|
+
type ActionGate,
|
|
6
|
+
jsonResult,
|
|
7
|
+
readNumberParam,
|
|
8
|
+
readStringArrayParam,
|
|
9
|
+
readStringParam,
|
|
10
|
+
type DiscordActionConfig,
|
|
11
|
+
type OpenClawConfig,
|
|
12
|
+
} from "../runtime-api.js";
|
|
13
|
+
import {
|
|
14
|
+
addRoleDiscord,
|
|
15
|
+
createChannelDiscord,
|
|
16
|
+
createScheduledEventDiscord,
|
|
17
|
+
deleteChannelDiscord,
|
|
18
|
+
editChannelDiscord,
|
|
19
|
+
fetchChannelInfoDiscord,
|
|
20
|
+
fetchMemberInfoDiscord,
|
|
21
|
+
fetchRoleInfoDiscord,
|
|
22
|
+
fetchVoiceStatusDiscord,
|
|
23
|
+
listGuildChannelsDiscord,
|
|
24
|
+
listGuildEmojisDiscord,
|
|
25
|
+
listScheduledEventsDiscord,
|
|
26
|
+
moveChannelDiscord,
|
|
27
|
+
removeChannelPermissionDiscord,
|
|
28
|
+
removeRoleDiscord,
|
|
29
|
+
setChannelPermissionDiscord,
|
|
30
|
+
uploadEmojiDiscord,
|
|
31
|
+
uploadStickerDiscord,
|
|
32
|
+
resolveEventCoverImage,
|
|
33
|
+
} from "../send.js";
|
|
34
|
+
import {
|
|
35
|
+
createDiscordActionOptions,
|
|
36
|
+
readDiscordChannelCreateParams,
|
|
37
|
+
readDiscordChannelEditParams,
|
|
38
|
+
readDiscordChannelMoveParams,
|
|
39
|
+
} from "./runtime.shared.js";
|
|
40
|
+
|
|
41
|
+
export const discordGuildActionRuntime = {
|
|
42
|
+
addRoleDiscord,
|
|
43
|
+
createChannelDiscord,
|
|
44
|
+
createScheduledEventDiscord,
|
|
45
|
+
resolveEventCoverImage,
|
|
46
|
+
deleteChannelDiscord,
|
|
47
|
+
editChannelDiscord,
|
|
48
|
+
fetchChannelInfoDiscord,
|
|
49
|
+
fetchMemberInfoDiscord,
|
|
50
|
+
fetchRoleInfoDiscord,
|
|
51
|
+
fetchVoiceStatusDiscord,
|
|
52
|
+
listGuildChannelsDiscord,
|
|
53
|
+
listGuildEmojisDiscord,
|
|
54
|
+
listScheduledEventsDiscord,
|
|
55
|
+
moveChannelDiscord,
|
|
56
|
+
removeChannelPermissionDiscord,
|
|
57
|
+
removeRoleDiscord,
|
|
58
|
+
setChannelPermissionDiscord,
|
|
59
|
+
uploadEmojiDiscord,
|
|
60
|
+
uploadStickerDiscord,
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
type DiscordRoleMutationOpts = { cfg: OpenClawConfig; accountId?: string };
|
|
64
|
+
type DiscordRoleMutation = (
|
|
65
|
+
params: {
|
|
66
|
+
guildId: string;
|
|
67
|
+
userId: string;
|
|
68
|
+
roleId: string;
|
|
69
|
+
},
|
|
70
|
+
options: DiscordRoleMutationOpts,
|
|
71
|
+
) => Promise<unknown>;
|
|
72
|
+
|
|
73
|
+
async function runRoleMutation(params: {
|
|
74
|
+
cfg: OpenClawConfig;
|
|
75
|
+
accountId?: string;
|
|
76
|
+
values: Record<string, unknown>;
|
|
77
|
+
mutate: DiscordRoleMutation;
|
|
78
|
+
}) {
|
|
79
|
+
const guildId = readStringParam(params.values, "guildId", { required: true });
|
|
80
|
+
const userId = readStringParam(params.values, "userId", { required: true });
|
|
81
|
+
const roleId = readStringParam(params.values, "roleId", { required: true });
|
|
82
|
+
await params.mutate(
|
|
83
|
+
{ guildId, userId, roleId },
|
|
84
|
+
createDiscordActionOptions({ cfg: params.cfg, accountId: params.accountId }),
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function readChannelPermissionTarget(params: Record<string, unknown>) {
|
|
89
|
+
return {
|
|
90
|
+
channelId: readStringParam(params, "channelId", { required: true }),
|
|
91
|
+
targetId: readStringParam(params, "targetId", { required: true }),
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export async function handleDiscordGuildAction(
|
|
96
|
+
action: string,
|
|
97
|
+
params: Record<string, unknown>,
|
|
98
|
+
isActionEnabled: ActionGate<DiscordActionConfig>,
|
|
99
|
+
cfg: OpenClawConfig,
|
|
100
|
+
options?: { mediaLocalRoots?: readonly string[] },
|
|
101
|
+
): Promise<AgentToolResult<unknown>> {
|
|
102
|
+
const accountId = readStringParam(params, "accountId");
|
|
103
|
+
if (!cfg) {
|
|
104
|
+
throw new Error("Discord guild actions require a resolved runtime config.");
|
|
105
|
+
}
|
|
106
|
+
const withOpts = (extra?: Record<string, unknown>) =>
|
|
107
|
+
createDiscordActionOptions({ cfg, accountId, extra });
|
|
108
|
+
switch (action) {
|
|
109
|
+
case "memberInfo": {
|
|
110
|
+
if (!isActionEnabled("memberInfo")) {
|
|
111
|
+
throw new Error("Discord member info is disabled.");
|
|
112
|
+
}
|
|
113
|
+
const guildId = readStringParam(params, "guildId", {
|
|
114
|
+
required: true,
|
|
115
|
+
});
|
|
116
|
+
const userId = readStringParam(params, "userId", {
|
|
117
|
+
required: true,
|
|
118
|
+
});
|
|
119
|
+
const effectiveAccountId = accountId ?? resolveDefaultDiscordAccountId(cfg);
|
|
120
|
+
const member = await discordGuildActionRuntime.fetchMemberInfoDiscord(
|
|
121
|
+
guildId,
|
|
122
|
+
userId,
|
|
123
|
+
createDiscordActionOptions({ cfg, accountId: effectiveAccountId }),
|
|
124
|
+
);
|
|
125
|
+
const presence = getPresence(effectiveAccountId, userId);
|
|
126
|
+
const activities = presence?.activities ?? undefined;
|
|
127
|
+
const status = presence?.status ?? undefined;
|
|
128
|
+
return jsonResult({ ok: true, member, ...(presence ? { status, activities } : {}) });
|
|
129
|
+
}
|
|
130
|
+
case "roleInfo": {
|
|
131
|
+
if (!isActionEnabled("roleInfo")) {
|
|
132
|
+
throw new Error("Discord role info is disabled.");
|
|
133
|
+
}
|
|
134
|
+
const guildId = readStringParam(params, "guildId", {
|
|
135
|
+
required: true,
|
|
136
|
+
});
|
|
137
|
+
const roles = await discordGuildActionRuntime.fetchRoleInfoDiscord(guildId, withOpts());
|
|
138
|
+
return jsonResult({ ok: true, roles });
|
|
139
|
+
}
|
|
140
|
+
case "emojiList": {
|
|
141
|
+
if (!isActionEnabled("reactions")) {
|
|
142
|
+
throw new Error("Discord reactions are disabled.");
|
|
143
|
+
}
|
|
144
|
+
const guildId = readStringParam(params, "guildId", {
|
|
145
|
+
required: true,
|
|
146
|
+
});
|
|
147
|
+
const emojis = await discordGuildActionRuntime.listGuildEmojisDiscord(guildId, withOpts());
|
|
148
|
+
return jsonResult({ ok: true, emojis });
|
|
149
|
+
}
|
|
150
|
+
case "emojiUpload": {
|
|
151
|
+
if (!isActionEnabled("emojiUploads")) {
|
|
152
|
+
throw new Error("Discord emoji uploads are disabled.");
|
|
153
|
+
}
|
|
154
|
+
const guildId = readStringParam(params, "guildId", {
|
|
155
|
+
required: true,
|
|
156
|
+
});
|
|
157
|
+
const name = readStringParam(params, "name", { required: true });
|
|
158
|
+
const mediaUrl = readStringParam(params, "mediaUrl", {
|
|
159
|
+
required: true,
|
|
160
|
+
});
|
|
161
|
+
const roleIds = readStringArrayParam(params, "roleIds");
|
|
162
|
+
const emoji = await discordGuildActionRuntime.uploadEmojiDiscord(
|
|
163
|
+
{
|
|
164
|
+
guildId,
|
|
165
|
+
name,
|
|
166
|
+
mediaUrl,
|
|
167
|
+
roleIds: roleIds?.length ? roleIds : undefined,
|
|
168
|
+
},
|
|
169
|
+
withOpts(),
|
|
170
|
+
);
|
|
171
|
+
return jsonResult({ ok: true, emoji });
|
|
172
|
+
}
|
|
173
|
+
case "stickerUpload": {
|
|
174
|
+
if (!isActionEnabled("stickerUploads")) {
|
|
175
|
+
throw new Error("Discord sticker uploads are disabled.");
|
|
176
|
+
}
|
|
177
|
+
const guildId = readStringParam(params, "guildId", {
|
|
178
|
+
required: true,
|
|
179
|
+
});
|
|
180
|
+
const name = readStringParam(params, "name", { required: true });
|
|
181
|
+
const description = readStringParam(params, "description", {
|
|
182
|
+
required: true,
|
|
183
|
+
});
|
|
184
|
+
const tags = readStringParam(params, "tags", { required: true });
|
|
185
|
+
const mediaUrl = readStringParam(params, "mediaUrl", {
|
|
186
|
+
required: true,
|
|
187
|
+
});
|
|
188
|
+
const sticker = await discordGuildActionRuntime.uploadStickerDiscord(
|
|
189
|
+
{
|
|
190
|
+
guildId,
|
|
191
|
+
name,
|
|
192
|
+
description,
|
|
193
|
+
tags,
|
|
194
|
+
mediaUrl,
|
|
195
|
+
},
|
|
196
|
+
withOpts(),
|
|
197
|
+
);
|
|
198
|
+
return jsonResult({ ok: true, sticker });
|
|
199
|
+
}
|
|
200
|
+
case "roleAdd": {
|
|
201
|
+
if (!isActionEnabled("roles", false)) {
|
|
202
|
+
throw new Error("Discord role changes are disabled.");
|
|
203
|
+
}
|
|
204
|
+
await runRoleMutation({
|
|
205
|
+
cfg,
|
|
206
|
+
accountId,
|
|
207
|
+
values: params,
|
|
208
|
+
mutate: discordGuildActionRuntime.addRoleDiscord,
|
|
209
|
+
});
|
|
210
|
+
return jsonResult({ ok: true });
|
|
211
|
+
}
|
|
212
|
+
case "roleRemove": {
|
|
213
|
+
if (!isActionEnabled("roles", false)) {
|
|
214
|
+
throw new Error("Discord role changes are disabled.");
|
|
215
|
+
}
|
|
216
|
+
await runRoleMutation({
|
|
217
|
+
cfg,
|
|
218
|
+
accountId,
|
|
219
|
+
values: params,
|
|
220
|
+
mutate: discordGuildActionRuntime.removeRoleDiscord,
|
|
221
|
+
});
|
|
222
|
+
return jsonResult({ ok: true });
|
|
223
|
+
}
|
|
224
|
+
case "channelInfo": {
|
|
225
|
+
if (!isActionEnabled("channelInfo")) {
|
|
226
|
+
throw new Error("Discord channel info is disabled.");
|
|
227
|
+
}
|
|
228
|
+
const channelId = readStringParam(params, "channelId", {
|
|
229
|
+
required: true,
|
|
230
|
+
});
|
|
231
|
+
const channel = await discordGuildActionRuntime.fetchChannelInfoDiscord(
|
|
232
|
+
channelId,
|
|
233
|
+
withOpts(),
|
|
234
|
+
);
|
|
235
|
+
return jsonResult({ ok: true, channel });
|
|
236
|
+
}
|
|
237
|
+
case "channelList": {
|
|
238
|
+
if (!isActionEnabled("channelInfo")) {
|
|
239
|
+
throw new Error("Discord channel info is disabled.");
|
|
240
|
+
}
|
|
241
|
+
const guildId = readStringParam(params, "guildId", {
|
|
242
|
+
required: true,
|
|
243
|
+
});
|
|
244
|
+
const channels = await discordGuildActionRuntime.listGuildChannelsDiscord(
|
|
245
|
+
guildId,
|
|
246
|
+
withOpts(),
|
|
247
|
+
);
|
|
248
|
+
return jsonResult({ ok: true, channels });
|
|
249
|
+
}
|
|
250
|
+
case "voiceStatus": {
|
|
251
|
+
if (!isActionEnabled("voiceStatus")) {
|
|
252
|
+
throw new Error("Discord voice status is disabled.");
|
|
253
|
+
}
|
|
254
|
+
const guildId = readStringParam(params, "guildId", {
|
|
255
|
+
required: true,
|
|
256
|
+
});
|
|
257
|
+
const userId = readStringParam(params, "userId", {
|
|
258
|
+
required: true,
|
|
259
|
+
});
|
|
260
|
+
const voice = await discordGuildActionRuntime.fetchVoiceStatusDiscord(
|
|
261
|
+
guildId,
|
|
262
|
+
userId,
|
|
263
|
+
withOpts(),
|
|
264
|
+
);
|
|
265
|
+
return jsonResult({ ok: true, voice });
|
|
266
|
+
}
|
|
267
|
+
case "eventList": {
|
|
268
|
+
if (!isActionEnabled("events")) {
|
|
269
|
+
throw new Error("Discord events are disabled.");
|
|
270
|
+
}
|
|
271
|
+
const guildId = readStringParam(params, "guildId", {
|
|
272
|
+
required: true,
|
|
273
|
+
});
|
|
274
|
+
const events = await discordGuildActionRuntime.listScheduledEventsDiscord(
|
|
275
|
+
guildId,
|
|
276
|
+
withOpts(),
|
|
277
|
+
);
|
|
278
|
+
return jsonResult({ ok: true, events });
|
|
279
|
+
}
|
|
280
|
+
case "eventCreate": {
|
|
281
|
+
if (!isActionEnabled("events")) {
|
|
282
|
+
throw new Error("Discord events are disabled.");
|
|
283
|
+
}
|
|
284
|
+
const guildId = readStringParam(params, "guildId", {
|
|
285
|
+
required: true,
|
|
286
|
+
});
|
|
287
|
+
const name = readStringParam(params, "name", { required: true });
|
|
288
|
+
const startTime = readStringParam(params, "startTime", {
|
|
289
|
+
required: true,
|
|
290
|
+
});
|
|
291
|
+
const endTime = readStringParam(params, "endTime");
|
|
292
|
+
const description = readStringParam(params, "description");
|
|
293
|
+
const channelId = readStringParam(params, "channelId");
|
|
294
|
+
const location = readStringParam(params, "location");
|
|
295
|
+
const imageUrl = readStringParam(params, "image", { trim: false });
|
|
296
|
+
const entityTypeRaw = readStringParam(params, "entityType");
|
|
297
|
+
const entityType = entityTypeRaw === "stage" ? 1 : entityTypeRaw === "external" ? 3 : 2;
|
|
298
|
+
const image = imageUrl
|
|
299
|
+
? await discordGuildActionRuntime.resolveEventCoverImage(imageUrl, {
|
|
300
|
+
localRoots: options?.mediaLocalRoots,
|
|
301
|
+
})
|
|
302
|
+
: undefined;
|
|
303
|
+
const payload = {
|
|
304
|
+
name,
|
|
305
|
+
description,
|
|
306
|
+
scheduled_start_time: startTime,
|
|
307
|
+
scheduled_end_time: endTime,
|
|
308
|
+
entity_type: entityType,
|
|
309
|
+
channel_id: channelId,
|
|
310
|
+
entity_metadata: entityType === 3 && location ? { location } : undefined,
|
|
311
|
+
image,
|
|
312
|
+
privacy_level: 2,
|
|
313
|
+
};
|
|
314
|
+
const event = await discordGuildActionRuntime.createScheduledEventDiscord(
|
|
315
|
+
guildId,
|
|
316
|
+
payload,
|
|
317
|
+
withOpts(),
|
|
318
|
+
);
|
|
319
|
+
return jsonResult({ ok: true, event });
|
|
320
|
+
}
|
|
321
|
+
case "channelCreate": {
|
|
322
|
+
if (!isActionEnabled("channels")) {
|
|
323
|
+
throw new Error("Discord channel management is disabled.");
|
|
324
|
+
}
|
|
325
|
+
const channel = await discordGuildActionRuntime.createChannelDiscord(
|
|
326
|
+
readDiscordChannelCreateParams(params),
|
|
327
|
+
withOpts(),
|
|
328
|
+
);
|
|
329
|
+
return jsonResult({ ok: true, channel });
|
|
330
|
+
}
|
|
331
|
+
case "channelEdit": {
|
|
332
|
+
if (!isActionEnabled("channels")) {
|
|
333
|
+
throw new Error("Discord channel management is disabled.");
|
|
334
|
+
}
|
|
335
|
+
const channel = await discordGuildActionRuntime.editChannelDiscord(
|
|
336
|
+
readDiscordChannelEditParams(params),
|
|
337
|
+
withOpts(),
|
|
338
|
+
);
|
|
339
|
+
return jsonResult({ ok: true, channel });
|
|
340
|
+
}
|
|
341
|
+
case "channelDelete": {
|
|
342
|
+
if (!isActionEnabled("channels")) {
|
|
343
|
+
throw new Error("Discord channel management is disabled.");
|
|
344
|
+
}
|
|
345
|
+
const channelId = readStringParam(params, "channelId", {
|
|
346
|
+
required: true,
|
|
347
|
+
});
|
|
348
|
+
const result = await discordGuildActionRuntime.deleteChannelDiscord(channelId, withOpts());
|
|
349
|
+
return jsonResult(result);
|
|
350
|
+
}
|
|
351
|
+
case "channelMove": {
|
|
352
|
+
if (!isActionEnabled("channels")) {
|
|
353
|
+
throw new Error("Discord channel management is disabled.");
|
|
354
|
+
}
|
|
355
|
+
await discordGuildActionRuntime.moveChannelDiscord(
|
|
356
|
+
readDiscordChannelMoveParams(params),
|
|
357
|
+
withOpts(),
|
|
358
|
+
);
|
|
359
|
+
return jsonResult({ ok: true });
|
|
360
|
+
}
|
|
361
|
+
case "categoryCreate": {
|
|
362
|
+
if (!isActionEnabled("channels")) {
|
|
363
|
+
throw new Error("Discord channel management is disabled.");
|
|
364
|
+
}
|
|
365
|
+
const guildId = readStringParam(params, "guildId", { required: true });
|
|
366
|
+
const name = readStringParam(params, "name", { required: true });
|
|
367
|
+
const position = readNumberParam(params, "position", { integer: true });
|
|
368
|
+
const channel = await discordGuildActionRuntime.createChannelDiscord(
|
|
369
|
+
{
|
|
370
|
+
guildId,
|
|
371
|
+
name,
|
|
372
|
+
type: 4,
|
|
373
|
+
position: position ?? undefined,
|
|
374
|
+
},
|
|
375
|
+
withOpts(),
|
|
376
|
+
);
|
|
377
|
+
return jsonResult({ ok: true, category: channel });
|
|
378
|
+
}
|
|
379
|
+
case "categoryEdit": {
|
|
380
|
+
if (!isActionEnabled("channels")) {
|
|
381
|
+
throw new Error("Discord channel management is disabled.");
|
|
382
|
+
}
|
|
383
|
+
const categoryId = readStringParam(params, "categoryId", {
|
|
384
|
+
required: true,
|
|
385
|
+
});
|
|
386
|
+
const name = readStringParam(params, "name");
|
|
387
|
+
const position = readNumberParam(params, "position", { integer: true });
|
|
388
|
+
const channel = await discordGuildActionRuntime.editChannelDiscord(
|
|
389
|
+
{
|
|
390
|
+
channelId: categoryId,
|
|
391
|
+
name: name ?? undefined,
|
|
392
|
+
position: position ?? undefined,
|
|
393
|
+
},
|
|
394
|
+
withOpts(),
|
|
395
|
+
);
|
|
396
|
+
return jsonResult({ ok: true, category: channel });
|
|
397
|
+
}
|
|
398
|
+
case "categoryDelete": {
|
|
399
|
+
if (!isActionEnabled("channels")) {
|
|
400
|
+
throw new Error("Discord channel management is disabled.");
|
|
401
|
+
}
|
|
402
|
+
const categoryId = readStringParam(params, "categoryId", {
|
|
403
|
+
required: true,
|
|
404
|
+
});
|
|
405
|
+
const result = await discordGuildActionRuntime.deleteChannelDiscord(categoryId, withOpts());
|
|
406
|
+
return jsonResult(result);
|
|
407
|
+
}
|
|
408
|
+
case "channelPermissionSet": {
|
|
409
|
+
if (!isActionEnabled("channels")) {
|
|
410
|
+
throw new Error("Discord channel management is disabled.");
|
|
411
|
+
}
|
|
412
|
+
const { channelId, targetId } = readChannelPermissionTarget(params);
|
|
413
|
+
const targetTypeRaw = readStringParam(params, "targetType", {
|
|
414
|
+
required: true,
|
|
415
|
+
});
|
|
416
|
+
const targetType = targetTypeRaw === "member" ? 1 : 0;
|
|
417
|
+
const allow = readStringParam(params, "allow");
|
|
418
|
+
const deny = readStringParam(params, "deny");
|
|
419
|
+
await discordGuildActionRuntime.setChannelPermissionDiscord(
|
|
420
|
+
{
|
|
421
|
+
channelId,
|
|
422
|
+
targetId,
|
|
423
|
+
targetType,
|
|
424
|
+
allow: allow ?? undefined,
|
|
425
|
+
deny: deny ?? undefined,
|
|
426
|
+
},
|
|
427
|
+
withOpts(),
|
|
428
|
+
);
|
|
429
|
+
return jsonResult({ ok: true });
|
|
430
|
+
}
|
|
431
|
+
case "channelPermissionRemove": {
|
|
432
|
+
if (!isActionEnabled("channels")) {
|
|
433
|
+
throw new Error("Discord channel management is disabled.");
|
|
434
|
+
}
|
|
435
|
+
const { channelId, targetId } = readChannelPermissionTarget(params);
|
|
436
|
+
await discordGuildActionRuntime.removeChannelPermissionDiscord(
|
|
437
|
+
channelId,
|
|
438
|
+
targetId,
|
|
439
|
+
withOpts(),
|
|
440
|
+
);
|
|
441
|
+
return jsonResult({ ok: true });
|
|
442
|
+
}
|
|
443
|
+
default:
|
|
444
|
+
throw new Error(`Unknown action: ${action}`);
|
|
445
|
+
}
|
|
446
|
+
}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import {
|
|
2
|
+
jsonResult,
|
|
3
|
+
readNumberParam,
|
|
4
|
+
readStringArrayParam,
|
|
5
|
+
readStringParam,
|
|
6
|
+
} from "../runtime-api.js";
|
|
7
|
+
import { discordMessagingActionRuntime } from "./runtime.messaging.runtime.js";
|
|
8
|
+
import type { DiscordMessagingActionContext } from "./runtime.messaging.shared.js";
|
|
9
|
+
|
|
10
|
+
function parseDiscordMessageLink(link: string) {
|
|
11
|
+
const normalized = link.trim();
|
|
12
|
+
const match = normalized.match(
|
|
13
|
+
/^(?:https?:\/\/)?(?:ptb\.|canary\.)?discord(?:app)?\.com\/channels\/(\d+)\/(\d+)\/(\d+)(?:\/?|\?.*)$/i,
|
|
14
|
+
);
|
|
15
|
+
if (!match) {
|
|
16
|
+
throw new Error(
|
|
17
|
+
"Invalid Discord message link. Expected https://discord.com/channels/<guildId>/<channelId>/<messageId>.",
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
return {
|
|
21
|
+
guildId: match[1],
|
|
22
|
+
channelId: match[2],
|
|
23
|
+
messageId: match[3],
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export async function handleDiscordMessageManagementAction(ctx: DiscordMessagingActionContext) {
|
|
28
|
+
switch (ctx.action) {
|
|
29
|
+
case "permissions": {
|
|
30
|
+
if (!ctx.isActionEnabled("permissions")) {
|
|
31
|
+
throw new Error("Discord permissions are disabled.");
|
|
32
|
+
}
|
|
33
|
+
const channelId = ctx.resolveChannelId();
|
|
34
|
+
const permissions = await discordMessagingActionRuntime.fetchChannelPermissionsDiscord(
|
|
35
|
+
channelId,
|
|
36
|
+
ctx.withOpts(),
|
|
37
|
+
);
|
|
38
|
+
return jsonResult({ ok: true, permissions });
|
|
39
|
+
}
|
|
40
|
+
case "fetchMessage": {
|
|
41
|
+
if (!ctx.isActionEnabled("messages")) {
|
|
42
|
+
throw new Error("Discord message reads are disabled.");
|
|
43
|
+
}
|
|
44
|
+
const messageLink = readStringParam(ctx.params, "messageLink");
|
|
45
|
+
let guildId = readStringParam(ctx.params, "guildId");
|
|
46
|
+
let channelId = readStringParam(ctx.params, "channelId");
|
|
47
|
+
let messageId = readStringParam(ctx.params, "messageId");
|
|
48
|
+
if (messageLink) {
|
|
49
|
+
const parsed = parseDiscordMessageLink(messageLink);
|
|
50
|
+
guildId = parsed.guildId;
|
|
51
|
+
channelId = parsed.channelId;
|
|
52
|
+
messageId = parsed.messageId;
|
|
53
|
+
}
|
|
54
|
+
if (!guildId || !channelId || !messageId) {
|
|
55
|
+
throw new Error(
|
|
56
|
+
"Discord message fetch requires guildId, channelId, and messageId (or a valid messageLink).",
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
const message = await discordMessagingActionRuntime.fetchMessageDiscord(
|
|
60
|
+
channelId,
|
|
61
|
+
messageId,
|
|
62
|
+
ctx.withOpts(),
|
|
63
|
+
);
|
|
64
|
+
return jsonResult({
|
|
65
|
+
ok: true,
|
|
66
|
+
message: ctx.normalizeMessage(message),
|
|
67
|
+
guildId,
|
|
68
|
+
channelId,
|
|
69
|
+
messageId,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
case "readMessages": {
|
|
73
|
+
if (!ctx.isActionEnabled("messages")) {
|
|
74
|
+
throw new Error("Discord message reads are disabled.");
|
|
75
|
+
}
|
|
76
|
+
const channelId = ctx.resolveChannelId();
|
|
77
|
+
const query = {
|
|
78
|
+
limit: readNumberParam(ctx.params, "limit"),
|
|
79
|
+
before: readStringParam(ctx.params, "before"),
|
|
80
|
+
after: readStringParam(ctx.params, "after"),
|
|
81
|
+
around: readStringParam(ctx.params, "around"),
|
|
82
|
+
};
|
|
83
|
+
const messages = await discordMessagingActionRuntime.readMessagesDiscord(
|
|
84
|
+
channelId,
|
|
85
|
+
query,
|
|
86
|
+
ctx.withOpts(),
|
|
87
|
+
);
|
|
88
|
+
return jsonResult({
|
|
89
|
+
ok: true,
|
|
90
|
+
messages: messages.map((message) => ctx.normalizeMessage(message)),
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
case "editMessage": {
|
|
94
|
+
if (!ctx.isActionEnabled("messages")) {
|
|
95
|
+
throw new Error("Discord message edits are disabled.");
|
|
96
|
+
}
|
|
97
|
+
const channelId = ctx.resolveChannelId();
|
|
98
|
+
const messageId = readStringParam(ctx.params, "messageId", {
|
|
99
|
+
required: true,
|
|
100
|
+
});
|
|
101
|
+
const content = readStringParam(ctx.params, "content", {
|
|
102
|
+
required: true,
|
|
103
|
+
});
|
|
104
|
+
const message = await discordMessagingActionRuntime.editMessageDiscord(
|
|
105
|
+
channelId,
|
|
106
|
+
messageId,
|
|
107
|
+
{ content },
|
|
108
|
+
ctx.withOpts(),
|
|
109
|
+
);
|
|
110
|
+
return jsonResult({ ok: true, message });
|
|
111
|
+
}
|
|
112
|
+
case "deleteMessage": {
|
|
113
|
+
if (!ctx.isActionEnabled("messages")) {
|
|
114
|
+
throw new Error("Discord message deletes are disabled.");
|
|
115
|
+
}
|
|
116
|
+
const channelId = ctx.resolveChannelId();
|
|
117
|
+
const messageId = readStringParam(ctx.params, "messageId", {
|
|
118
|
+
required: true,
|
|
119
|
+
});
|
|
120
|
+
await discordMessagingActionRuntime.deleteMessageDiscord(
|
|
121
|
+
channelId,
|
|
122
|
+
messageId,
|
|
123
|
+
ctx.withOpts(),
|
|
124
|
+
);
|
|
125
|
+
return jsonResult({ ok: true });
|
|
126
|
+
}
|
|
127
|
+
case "pinMessage": {
|
|
128
|
+
if (!ctx.isActionEnabled("pins")) {
|
|
129
|
+
throw new Error("Discord pins are disabled.");
|
|
130
|
+
}
|
|
131
|
+
const channelId = ctx.resolveChannelId();
|
|
132
|
+
const messageId = readStringParam(ctx.params, "messageId", {
|
|
133
|
+
required: true,
|
|
134
|
+
});
|
|
135
|
+
await discordMessagingActionRuntime.pinMessageDiscord(channelId, messageId, ctx.withOpts());
|
|
136
|
+
return jsonResult({ ok: true });
|
|
137
|
+
}
|
|
138
|
+
case "unpinMessage": {
|
|
139
|
+
if (!ctx.isActionEnabled("pins")) {
|
|
140
|
+
throw new Error("Discord pins are disabled.");
|
|
141
|
+
}
|
|
142
|
+
const channelId = ctx.resolveChannelId();
|
|
143
|
+
const messageId = readStringParam(ctx.params, "messageId", {
|
|
144
|
+
required: true,
|
|
145
|
+
});
|
|
146
|
+
await discordMessagingActionRuntime.unpinMessageDiscord(channelId, messageId, ctx.withOpts());
|
|
147
|
+
return jsonResult({ ok: true });
|
|
148
|
+
}
|
|
149
|
+
case "listPins": {
|
|
150
|
+
if (!ctx.isActionEnabled("pins")) {
|
|
151
|
+
throw new Error("Discord pins are disabled.");
|
|
152
|
+
}
|
|
153
|
+
const channelId = ctx.resolveChannelId();
|
|
154
|
+
const pins = await discordMessagingActionRuntime.listPinsDiscord(channelId, ctx.withOpts());
|
|
155
|
+
return jsonResult({ ok: true, pins: pins.map((pin) => ctx.normalizeMessage(pin)) });
|
|
156
|
+
}
|
|
157
|
+
case "searchMessages": {
|
|
158
|
+
if (!ctx.isActionEnabled("search")) {
|
|
159
|
+
throw new Error("Discord search is disabled.");
|
|
160
|
+
}
|
|
161
|
+
const guildId = readStringParam(ctx.params, "guildId", {
|
|
162
|
+
required: true,
|
|
163
|
+
});
|
|
164
|
+
const content = readStringParam(ctx.params, "content", {
|
|
165
|
+
required: true,
|
|
166
|
+
});
|
|
167
|
+
const channelId = readStringParam(ctx.params, "channelId");
|
|
168
|
+
const channelIds = readStringArrayParam(ctx.params, "channelIds");
|
|
169
|
+
const authorId = readStringParam(ctx.params, "authorId");
|
|
170
|
+
const authorIds = readStringArrayParam(ctx.params, "authorIds");
|
|
171
|
+
const limit = readNumberParam(ctx.params, "limit");
|
|
172
|
+
const channelIdList = [...(channelIds ?? []), ...(channelId ? [channelId] : [])];
|
|
173
|
+
const authorIdList = [...(authorIds ?? []), ...(authorId ? [authorId] : [])];
|
|
174
|
+
const results = await discordMessagingActionRuntime.searchMessagesDiscord(
|
|
175
|
+
{
|
|
176
|
+
guildId,
|
|
177
|
+
content,
|
|
178
|
+
channelIds: channelIdList.length ? channelIdList : undefined,
|
|
179
|
+
authorIds: authorIdList.length ? authorIdList : undefined,
|
|
180
|
+
limit,
|
|
181
|
+
},
|
|
182
|
+
ctx.withOpts(),
|
|
183
|
+
);
|
|
184
|
+
if (!results || typeof results !== "object") {
|
|
185
|
+
return jsonResult({ ok: true, results });
|
|
186
|
+
}
|
|
187
|
+
const resultsRecord = results as Record<string, unknown>;
|
|
188
|
+
const messages = resultsRecord.messages;
|
|
189
|
+
const normalizedMessages = Array.isArray(messages)
|
|
190
|
+
? messages.map((group) =>
|
|
191
|
+
Array.isArray(group) ? group.map((msg) => ctx.normalizeMessage(msg)) : group,
|
|
192
|
+
)
|
|
193
|
+
: messages;
|
|
194
|
+
return jsonResult({
|
|
195
|
+
ok: true,
|
|
196
|
+
results: {
|
|
197
|
+
...resultsRecord,
|
|
198
|
+
messages: normalizedMessages,
|
|
199
|
+
},
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
default:
|
|
203
|
+
return undefined;
|
|
204
|
+
}
|
|
205
|
+
}
|