@poolzin/pool-bot 2026.2.21 → 2026.2.22
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/CHANGELOG.md +17 -0
- package/dist/agents/api-key-rotation.js +47 -0
- package/dist/agents/apply-patch-update.js +19 -9
- package/dist/agents/apply-patch.js +72 -47
- package/dist/agents/bash-tools.exec.js +141 -559
- package/dist/agents/cli-backends.js +49 -6
- package/dist/agents/cli-runner/helpers.js +69 -152
- package/dist/agents/cli-runner.js +70 -19
- package/dist/agents/identity.js +20 -1
- package/dist/agents/image-sanitization.js +9 -0
- package/dist/agents/live-auth-keys.js +123 -26
- package/dist/agents/live-model-filter.js +13 -4
- package/dist/agents/model-catalog.js +40 -9
- package/dist/agents/model-forward-compat.js +60 -23
- package/dist/agents/model-selection.js +134 -41
- package/dist/agents/pi-auth-json.js +2 -2
- package/dist/agents/pi-embedded-helpers/bootstrap.js +65 -15
- package/dist/agents/pi-embedded-helpers/errors.js +140 -15
- package/dist/agents/pi-embedded-helpers/images.js +22 -12
- package/dist/agents/pi-embedded-helpers.js +2 -2
- package/dist/agents/pi-embedded-runner/abort.js +10 -3
- package/dist/agents/pi-embedded-runner/compact.js +230 -32
- package/dist/agents/pi-embedded-runner/extra-params.js +203 -12
- package/dist/agents/pi-embedded-runner/google.js +109 -19
- package/dist/agents/pi-embedded-runner/history.js +35 -17
- package/dist/agents/pi-embedded-runner/run/attempt.js +386 -95
- package/dist/agents/pi-embedded-runner/run/images.js +81 -55
- package/dist/agents/pi-embedded-runner/run/payloads.js +89 -39
- package/dist/agents/pi-embedded-runner/run.js +193 -25
- package/dist/agents/pi-embedded-runner/run.overflow-compaction.mocks.shared.js +2 -2
- package/dist/agents/pi-embedded-runner/runs.js +17 -8
- package/dist/agents/pi-embedded-runner/tool-result-context-guard.js +262 -0
- package/dist/agents/pi-embedded-runner.js +1 -1
- package/dist/agents/pi-embedded-subscribe.handlers.tools.js +180 -10
- package/dist/agents/pi-embedded-subscribe.js +37 -0
- package/dist/agents/pi-embedded-subscribe.tools.js +127 -30
- package/dist/agents/pi-model-discovery.js +9 -2
- package/dist/agents/pi-tool-definition-adapter.js +60 -8
- package/dist/agents/pi-tools.before-tool-call.js +1 -1
- package/dist/agents/pi-tools.js +113 -94
- package/dist/agents/pi-tools.read.js +337 -38
- package/dist/agents/poolbot-tools.js +14 -5
- package/dist/agents/sandbox/docker.js +10 -5
- package/dist/agents/sandbox/registry.js +96 -46
- package/dist/agents/sandbox/sanitize-env-vars.js +82 -0
- package/dist/agents/sandbox-paths.js +43 -10
- package/dist/agents/session-tool-result-guard-wrapper.js +23 -11
- package/dist/agents/session-tool-result-guard.js +39 -39
- package/dist/agents/session-transcript-repair.js +36 -33
- package/dist/agents/session-write-lock.js +62 -44
- package/dist/agents/skills/frontmatter.js +49 -88
- package/dist/agents/skills/workspace.js +335 -28
- package/dist/agents/subagent-announce.js +508 -174
- package/dist/agents/subagent-registry.js +45 -4
- package/dist/agents/subagent-spawn.js +16 -33
- package/dist/agents/system-prompt-report.js +27 -10
- package/dist/agents/system-prompt.js +26 -32
- package/dist/agents/tool-call-id.js +69 -17
- package/dist/agents/tool-display-common.js +1 -1
- package/dist/agents/tool-images.js +64 -31
- package/dist/agents/tools/canvas-tool.js +17 -11
- package/dist/agents/tools/common.js +37 -19
- package/dist/agents/tools/cron-tool.js +40 -38
- package/dist/agents/tools/gateway.js +70 -2
- package/dist/agents/tools/message-tool.js +181 -40
- package/dist/agents/tools/nodes-tool.js +128 -36
- package/dist/agents/tools/nodes-utils.js +12 -38
- package/dist/agents/tools/session-status-tool.js +24 -71
- package/dist/agents/tools/sessions-helpers.js +38 -210
- package/dist/agents/tools/sessions-spawn-tool.js +28 -198
- package/dist/agents/tools/telegram-actions.js +58 -7
- package/dist/agents/tools/web-fetch-utils.js +112 -7
- package/dist/agents/tools/web-fetch.js +279 -175
- package/dist/agents/tools/web-shared.js +71 -8
- package/dist/agents/usage.js +25 -16
- package/dist/auto-reply/commands-registry.data.js +85 -11
- package/dist/auto-reply/dispatch.js +40 -21
- package/dist/auto-reply/reply/abort.js +102 -33
- package/dist/auto-reply/reply/commands-core.js +82 -33
- package/dist/auto-reply/reply/commands-export-session.js +1 -1
- package/dist/auto-reply/reply/commands-info.js +41 -12
- package/dist/auto-reply/reply/commands-subagents.js +352 -100
- package/dist/auto-reply/reply/commands-system-prompt.js +2 -2
- package/dist/auto-reply/reply/dispatch-from-config.js +100 -29
- package/dist/auto-reply/reply/elevated-unavailable.js +1 -1
- package/dist/auto-reply/reply/inbound-meta.js +12 -1
- package/dist/auto-reply/reply/mentions.js +18 -11
- package/dist/auto-reply/reply/normalize-reply.js +17 -8
- package/dist/auto-reply/reply/reply-dispatcher.js +62 -10
- package/dist/auto-reply/reply/session.js +102 -21
- package/dist/auto-reply/reply/streaming-directives.js +16 -5
- package/dist/auto-reply/status.js +73 -50
- package/dist/browser/extension-relay.js +3 -3
- package/dist/browser/http-auth.js +1 -1
- package/dist/browser/paths.js +2 -2
- package/dist/build-info.json +3 -3
- package/dist/channels/allowlist-match.js +20 -0
- package/dist/channels/allowlists/resolve-utils.js +65 -2
- package/dist/channels/chat-type.js +8 -4
- package/dist/channels/dock.js +127 -35
- package/dist/channels/draft-stream-loop.js +6 -2
- package/dist/channels/plugins/actions/telegram.js +42 -18
- package/dist/channels/plugins/allowlist-match.js +1 -1
- package/dist/channels/plugins/group-mentions.js +51 -41
- package/dist/channels/plugins/message-action-names.js +2 -0
- package/dist/channels/plugins/message-actions.js +24 -5
- package/dist/channels/plugins/normalize/discord.js +26 -4
- package/dist/channels/plugins/normalize/signal.js +35 -22
- package/dist/channels/plugins/onboarding/helpers.js +8 -26
- package/dist/channels/plugins/outbound/imessage.js +15 -14
- package/dist/channels/registry.js +20 -7
- package/dist/cli/acp-cli.js +7 -5
- package/dist/cli/browser-cli-extension.js +25 -12
- package/dist/cli/browser-cli-state.cookies-storage.js +25 -6
- package/dist/cli/browser-cli-state.js +101 -145
- package/dist/cli/command-options.js +28 -0
- package/dist/cli/completion-cli.js +6 -6
- package/dist/cli/cron-cli/register.cron-add.js +25 -1
- package/dist/cli/cron-cli/register.cron-edit.js +44 -0
- package/dist/cli/cron-cli/shared.js +7 -1
- package/dist/cli/daemon-cli/lifecycle-core.js +23 -21
- package/dist/cli/daemon-cli/lifecycle.js +23 -247
- package/dist/cli/daemon-cli/register-service-commands.js +25 -4
- package/dist/cli/daemon-cli.js +1 -0
- package/dist/cli/devices-cli.js +33 -20
- package/dist/cli/gateway-cli/register.js +37 -105
- package/dist/cli/gateway-cli/run.js +49 -11
- package/dist/cli/nodes-camera.js +59 -4
- package/dist/cli/nodes-cli/register.camera.js +27 -24
- package/dist/cli/nodes-cli/rpc.js +21 -38
- package/dist/cli/qr-cli.js +2 -2
- package/dist/cli/skills-cli.format.js +2 -2
- package/dist/cli/update-cli/progress.js +2 -2
- package/dist/cli/update-cli/restart-helper.js +28 -7
- package/dist/cli/update-cli/shared.js +7 -7
- package/dist/cli/update-cli/status.js +1 -1
- package/dist/cli/update-cli/update-command.js +14 -8
- package/dist/cli/update-cli/wizard.js +2 -2
- package/dist/cli/update-cli.js +21 -1027
- package/dist/commands/auth-choice.apply.anthropic.js +10 -2
- package/dist/commands/channels/add-mutators.js +3 -35
- package/dist/commands/channels/add.js +39 -51
- package/dist/commands/config-validation.js +1 -1
- package/dist/commands/configure.gateway-auth.js +52 -15
- package/dist/commands/configure.gateway.js +84 -40
- package/dist/commands/doctor-completion.js +3 -3
- package/dist/commands/doctor-config-flow.js +536 -16
- package/dist/commands/doctor-gateway-services.js +103 -79
- package/dist/commands/doctor-memory-search.js +9 -9
- package/dist/commands/doctor-platform-notes.js +57 -30
- package/dist/commands/doctor-prompter.js +26 -15
- package/dist/commands/doctor-session-locks.js +1 -1
- package/dist/commands/doctor.js +21 -9
- package/dist/commands/model-picker.js +120 -95
- package/dist/commands/models/set.js +2 -21
- package/dist/commands/models/shared.js +65 -37
- package/dist/commands/onboard-helpers.js +81 -39
- package/dist/commands/openai-codex-oauth.js +1 -1
- package/dist/commands/sessions.js +52 -53
- package/dist/commands/status.summary.js +52 -34
- package/dist/commands/test-wizard-helpers.js +2 -2
- package/dist/config/defaults.js +79 -42
- package/dist/config/group-policy.js +50 -18
- package/dist/config/includes.js +37 -10
- package/dist/config/schema.help.js +5 -4
- package/dist/config/schema.hints.js +2 -2
- package/dist/config/schema.labels.js +1 -0
- package/dist/config/sessions/group.js +12 -11
- package/dist/config/sessions/paths.js +137 -11
- package/dist/config/sessions/store.js +185 -65
- package/dist/config/sessions/types.js +15 -1
- package/dist/config/sessions.js +1 -0
- package/dist/config/telegram-custom-commands.js +3 -2
- package/dist/config/types.js +2 -0
- package/dist/config/zod-schema.agent-defaults.js +6 -27
- package/dist/config/zod-schema.agent-runtime.js +171 -79
- package/dist/config/zod-schema.providers-core.js +138 -65
- package/dist/config/zod-schema.session.js +49 -22
- package/dist/control-ui/assets/index-HRr1grwl.js.map +1 -1
- package/dist/cron/isolated-agent/run.js +224 -57
- package/dist/cron/normalize.js +48 -45
- package/dist/cron/run-log.js +14 -0
- package/dist/cron/service/jobs.js +190 -28
- package/dist/cron/service/normalize.js +29 -11
- package/dist/cron/service/store.js +30 -44
- package/dist/cron/service/timer.js +182 -96
- package/dist/cron/service.js +3 -0
- package/dist/cron/stagger.js +37 -0
- package/dist/daemon/inspect.js +132 -92
- package/dist/daemon/runtime-paths.js +25 -4
- package/dist/daemon/service-audit.js +47 -16
- package/dist/discord/accounts.js +23 -20
- package/dist/discord/monitor/agent-components.js +1115 -219
- package/dist/discord/monitor/allow-list.js +114 -34
- package/dist/discord/monitor/listeners.js +204 -97
- package/dist/discord/monitor/message-handler.js +21 -10
- package/dist/discord/monitor/message-handler.preflight.js +195 -101
- package/dist/discord/monitor/message-handler.process.js +384 -123
- package/dist/discord/monitor/message-utils.js +86 -23
- package/dist/discord/monitor/native-command.js +77 -57
- package/dist/discord/monitor/provider.js +122 -117
- package/dist/discord/monitor/reply-context.js +20 -16
- package/dist/discord/monitor/reply-delivery.js +40 -8
- package/dist/discord/monitor/rest-fetch.js +22 -0
- package/dist/discord/monitor/threading.js +117 -24
- package/dist/discord/send.js +2 -1
- package/dist/discord/send.outbound.js +124 -11
- package/dist/discord/send.shared.js +112 -72
- package/dist/discord/voice-message.js +3 -3
- package/dist/gateway/auth.js +119 -44
- package/dist/gateway/call.js +76 -34
- package/dist/gateway/channel-health-monitor.js +57 -50
- package/dist/gateway/client.js +63 -29
- package/dist/gateway/control-ui-contract.js +1 -1
- package/dist/gateway/gateway-config-prompts.shared.js +2 -2
- package/dist/gateway/net.js +109 -1
- package/dist/gateway/protocol/index.js +5 -8
- package/dist/gateway/protocol/schema/agent.js +19 -1
- package/dist/gateway/protocol/schema/channels.js +21 -0
- package/dist/gateway/protocol/schema/cron.js +43 -30
- package/dist/gateway/protocol/schema/protocol-schemas.js +6 -11
- package/dist/gateway/protocol/schema/sessions.js +5 -1
- package/dist/gateway/protocol/schema.js +0 -1
- package/dist/gateway/server/presence-events.js +12 -0
- package/dist/gateway/server/ws-connection/message-handler.js +203 -212
- package/dist/gateway/server/ws-connection.js +58 -21
- package/dist/gateway/server-broadcast.js +18 -13
- package/dist/gateway/server-cron.js +177 -10
- package/dist/gateway/server-methods/agent-job.js +131 -38
- package/dist/gateway/server-methods/send.js +60 -14
- package/dist/gateway/server-methods/sessions.js +160 -96
- package/dist/gateway/server-methods/system.js +5 -7
- package/dist/gateway/server-methods-list.js +8 -0
- package/dist/gateway/server-methods.js +24 -8
- package/dist/gateway/server-node-events.js +278 -68
- package/dist/gateway/session-utils.fs.js +316 -75
- package/dist/gateway/session-utils.js +224 -70
- package/dist/gateway/sessions-patch.js +63 -20
- package/dist/gateway/test-temp-config.js +1 -1
- package/dist/gateway/tools-invoke-http.js +118 -70
- package/dist/gateway/ws-log.js +135 -107
- package/dist/hooks/frontmatter.js +36 -82
- package/dist/hooks/install.js +149 -139
- package/dist/hooks/internal-hooks.js +29 -4
- package/dist/hooks/plugin-hooks.js +2 -1
- package/dist/imessage/monitor/deliver.js +10 -4
- package/dist/imessage/monitor/monitor-provider.js +138 -375
- package/dist/imessage/monitor/runtime.js +4 -8
- package/dist/imessage/send.js +65 -19
- package/dist/infra/exec-approvals-allowlist.js +7 -0
- package/dist/infra/exec-approvals.js +35 -920
- package/dist/infra/exec-safe-bin-trust.js +64 -0
- package/dist/infra/heartbeat-runner.js +207 -134
- package/dist/infra/heartbeat-wake.js +183 -22
- package/dist/infra/install-source-utils.js +47 -0
- package/dist/infra/net/ssrf.js +170 -36
- package/dist/infra/outbound/deliver.js +224 -58
- package/dist/infra/outbound/message-action-spec.js +12 -5
- package/dist/infra/outbound/outbound-session.js +27 -25
- package/dist/infra/poolbot-root.js +32 -22
- package/dist/infra/ports.js +14 -11
- package/dist/infra/skills-remote.js +48 -37
- package/dist/infra/system-events.js +25 -11
- package/dist/infra/system-presence.js +26 -33
- package/dist/infra/tmp-poolbot-dir.js +81 -2
- package/dist/infra/wsl.js +37 -1
- package/dist/line/bot-message-context.js +163 -191
- package/dist/logging/subsystem.js +59 -22
- package/dist/markdown/ir.js +124 -50
- package/dist/media/store.js +1 -1
- package/dist/media-understanding/runner.entries.js +42 -25
- package/dist/media-understanding/runner.js +53 -488
- package/dist/memory/embeddings-gemini.js +53 -38
- package/dist/memory/manager-embedding-ops.js +48 -69
- package/dist/pairing/pairing-store.js +178 -119
- package/dist/plugin-sdk/index.js +34 -6
- package/dist/plugins/hooks.js +135 -14
- package/dist/plugins/install.js +190 -152
- package/dist/polls.js +11 -0
- package/dist/routing/resolve-route.js +190 -56
- package/dist/routing/session-key.js +38 -22
- package/dist/runtime.js +35 -9
- package/dist/security/audit-channel.js +1 -1
- package/dist/sessions/session-key-utils.js +29 -11
- package/dist/shared/frontmatter.js +5 -5
- package/dist/shared/node-list-types.js +1 -0
- package/dist/shared/string-normalization.js +15 -0
- package/dist/signal/monitor/event-handler.js +68 -36
- package/dist/signal/send.js +29 -37
- package/dist/slack/monitor/allow-list.js +10 -11
- package/dist/slack/monitor/commands.js +14 -3
- package/dist/slack/monitor/events/interactions.js +4 -4
- package/dist/slack/monitor/media.js +224 -16
- package/dist/slack/monitor/message-handler/dispatch.js +247 -13
- package/dist/slack/monitor/message-handler/prepare.js +128 -45
- package/dist/slack/monitor/slash.js +357 -144
- package/dist/slack/streaming.js +77 -0
- package/dist/telegram/accounts.js +40 -13
- package/dist/telegram/allowed-updates.js +3 -0
- package/dist/telegram/bot/delivery.js +129 -66
- package/dist/telegram/bot/helpers.js +136 -122
- package/dist/telegram/bot-handlers.js +600 -339
- package/dist/telegram/bot-message-context.js +115 -73
- package/dist/telegram/bot-message-dispatch.js +235 -104
- package/dist/telegram/bot-native-command-menu.js +3 -1
- package/dist/telegram/bot-native-commands.js +213 -193
- package/dist/telegram/bot.js +24 -132
- package/dist/telegram/draft-stream.js +84 -75
- package/dist/telegram/format.js +150 -6
- package/dist/telegram/send.js +415 -255
- package/dist/telegram/targets.js +21 -2
- package/dist/telegram/update-offset-store.js +19 -3
- package/dist/terminal/restore.js +5 -2
- package/dist/test-utils/fetch-mock.js +5 -0
- package/dist/version.js +18 -5
- package/dist/web/auto-reply/monitor/broadcast.js +7 -3
- package/dist/web/auto-reply/monitor/on-message.js +6 -3
- package/dist/web/inbound/media.js +34 -8
- package/dist/web/inbound/monitor.js +34 -17
- package/dist/web/inbound/send-api.js +18 -17
- package/dist/web/outbound.js +12 -5
- package/dist/wizard/clack-prompter.js +40 -7
- package/extensions/bluebubbles/package.json +1 -1
- package/extensions/copilot-proxy/package.json +1 -1
- package/extensions/diagnostics-otel/package.json +1 -1
- package/extensions/discord/package.json +1 -1
- package/extensions/feishu/package.json +1 -1
- package/extensions/google-antigravity-auth/package.json +1 -1
- package/extensions/google-gemini-cli-auth/package.json +1 -1
- package/extensions/googlechat/package.json +1 -1
- package/extensions/imessage/package.json +1 -1
- package/extensions/irc/package.json +1 -1
- package/extensions/line/package.json +1 -1
- package/extensions/llm-task/package.json +1 -1
- package/extensions/lobster/package.json +1 -1
- package/extensions/matrix/CHANGELOG.md +5 -0
- package/extensions/matrix/package.json +1 -1
- package/extensions/mattermost/package.json +1 -1
- package/extensions/memory-core/package.json +1 -1
- package/extensions/memory-lancedb/package.json +1 -1
- package/extensions/minimax-portal-auth/package.json +1 -1
- package/extensions/msteams/CHANGELOG.md +5 -0
- package/extensions/msteams/package.json +1 -1
- package/extensions/nextcloud-talk/package.json +1 -1
- package/extensions/nostr/CHANGELOG.md +5 -0
- package/extensions/nostr/package.json +1 -1
- package/extensions/open-prose/package.json +1 -1
- package/extensions/openai-codex-auth/package.json +1 -1
- package/extensions/signal/package.json +1 -1
- package/extensions/slack/package.json +1 -1
- package/extensions/telegram/package.json +1 -1
- package/extensions/tlon/package.json +1 -1
- package/extensions/twitch/CHANGELOG.md +5 -0
- package/extensions/twitch/package.json +1 -1
- package/extensions/voice-call/CHANGELOG.md +5 -0
- package/extensions/voice-call/package.json +1 -1
- package/extensions/whatsapp/package.json +1 -1
- package/extensions/zalo/CHANGELOG.md +5 -0
- package/extensions/zalo/package.json +1 -1
- package/extensions/zalouser/CHANGELOG.md +5 -0
- package/extensions/zalouser/package.json +1 -1
- package/package.json +1 -1
- package/skills/apple-reminders/SKILL.md +100 -49
- package/skills/coding-agent/SKILL.md +34 -28
- package/skills/github/SKILL.md +131 -16
- package/skills/imsg/SKILL.md +112 -15
- package/skills/openhue/SKILL.md +101 -19
- package/skills/tmux/SKILL.md +111 -79
- package/skills/weather/SKILL.md +88 -25
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
import { formatLocationText } from "../../channels/location.js";
|
|
2
|
+
import { readChannelAllowFromStore } from "../../pairing/pairing-store.js";
|
|
3
|
+
import { firstDefined, normalizeAllowFromWithStore, } from "../bot-access.js";
|
|
2
4
|
const TELEGRAM_GENERAL_TOPIC_ID = 1;
|
|
5
|
+
export async function resolveTelegramGroupAllowFromContext(params) {
|
|
6
|
+
const resolvedThreadId = resolveTelegramForumThreadId({
|
|
7
|
+
isForum: params.isForum,
|
|
8
|
+
messageThreadId: params.messageThreadId,
|
|
9
|
+
});
|
|
10
|
+
const storeAllowFrom = await readChannelAllowFromStore("telegram", process.env, params.accountId).catch(() => []);
|
|
11
|
+
const { groupConfig, topicConfig } = params.resolveTelegramGroupConfig(params.chatId, resolvedThreadId);
|
|
12
|
+
const groupAllowOverride = firstDefined(topicConfig?.allowFrom, groupConfig?.allowFrom);
|
|
13
|
+
const effectiveGroupAllow = normalizeAllowFromWithStore({
|
|
14
|
+
allowFrom: groupAllowOverride ?? params.groupAllowFrom,
|
|
15
|
+
storeAllowFrom,
|
|
16
|
+
});
|
|
17
|
+
const hasGroupAllowOverride = typeof groupAllowOverride !== "undefined";
|
|
18
|
+
return {
|
|
19
|
+
resolvedThreadId,
|
|
20
|
+
storeAllowFrom,
|
|
21
|
+
groupConfig,
|
|
22
|
+
topicConfig,
|
|
23
|
+
groupAllowOverride,
|
|
24
|
+
effectiveGroupAllow,
|
|
25
|
+
hasGroupAllowOverride,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
3
28
|
/**
|
|
4
29
|
* Resolve the thread ID for Telegram forum topics.
|
|
5
30
|
* For non-forum groups, returns undefined even if messageThreadId is present
|
|
@@ -38,30 +63,28 @@ export function resolveTelegramThreadSpec(params) {
|
|
|
38
63
|
}
|
|
39
64
|
/**
|
|
40
65
|
* Build thread params for Telegram API calls (messages, media).
|
|
66
|
+
*
|
|
67
|
+
* IMPORTANT: Thread IDs behave differently based on chat type:
|
|
68
|
+
* - DMs (private chats): Include message_thread_id when present (DM topics)
|
|
69
|
+
* - Forum topics: Skip thread_id=1 (General topic), include others
|
|
70
|
+
* - Regular groups: Thread IDs are ignored by Telegram
|
|
71
|
+
*
|
|
41
72
|
* General forum topic (id=1) must be treated like a regular supergroup send:
|
|
42
73
|
* Telegram rejects sendMessage/sendMedia with message_thread_id=1 ("thread not found").
|
|
43
74
|
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
75
|
+
* @param thread - Thread specification with ID and scope
|
|
76
|
+
* @returns API params object or undefined if thread_id should be omitted
|
|
46
77
|
*/
|
|
47
|
-
export function buildTelegramThreadParams(
|
|
48
|
-
if (
|
|
78
|
+
export function buildTelegramThreadParams(thread) {
|
|
79
|
+
if (thread?.id == null) {
|
|
49
80
|
return undefined;
|
|
50
81
|
}
|
|
51
|
-
|
|
52
|
-
if (
|
|
53
|
-
|
|
54
|
-
if (normalized === TELEGRAM_GENERAL_TOPIC_ID) {
|
|
55
|
-
return undefined;
|
|
56
|
-
}
|
|
57
|
-
return { message_thread_id: normalized };
|
|
58
|
-
}
|
|
59
|
-
// New call: TelegramThreadSpec
|
|
60
|
-
if (!threadOrId.id) {
|
|
61
|
-
return undefined;
|
|
82
|
+
const normalized = Math.trunc(thread.id);
|
|
83
|
+
if (thread.scope === "dm") {
|
|
84
|
+
return normalized > 0 ? { message_thread_id: normalized } : undefined;
|
|
62
85
|
}
|
|
63
|
-
|
|
64
|
-
if (normalized === TELEGRAM_GENERAL_TOPIC_ID
|
|
86
|
+
// Telegram rejects message_thread_id=1 for General forum topic
|
|
87
|
+
if (normalized === TELEGRAM_GENERAL_TOPIC_ID) {
|
|
65
88
|
return undefined;
|
|
66
89
|
}
|
|
67
90
|
return { message_thread_id: normalized };
|
|
@@ -78,8 +101,9 @@ export function buildTypingThreadParams(messageThreadId) {
|
|
|
78
101
|
}
|
|
79
102
|
export function resolveTelegramStreamMode(telegramCfg) {
|
|
80
103
|
const raw = telegramCfg?.streamMode?.trim().toLowerCase();
|
|
81
|
-
if (raw === "off" || raw === "partial" || raw === "block")
|
|
104
|
+
if (raw === "off" || raw === "partial" || raw === "block") {
|
|
82
105
|
return raw;
|
|
106
|
+
}
|
|
83
107
|
return "partial";
|
|
84
108
|
}
|
|
85
109
|
export function buildTelegramGroupPeerId(chatId, messageThreadId) {
|
|
@@ -106,6 +130,27 @@ export function buildSenderName(msg) {
|
|
|
106
130
|
msg.from?.username;
|
|
107
131
|
return name || undefined;
|
|
108
132
|
}
|
|
133
|
+
export function resolveTelegramMediaPlaceholder(msg) {
|
|
134
|
+
if (!msg) {
|
|
135
|
+
return undefined;
|
|
136
|
+
}
|
|
137
|
+
if (msg.photo) {
|
|
138
|
+
return "<media:image>";
|
|
139
|
+
}
|
|
140
|
+
if (msg.video || msg.video_note) {
|
|
141
|
+
return "<media:video>";
|
|
142
|
+
}
|
|
143
|
+
if (msg.audio || msg.voice) {
|
|
144
|
+
return "<media:audio>";
|
|
145
|
+
}
|
|
146
|
+
if (msg.document) {
|
|
147
|
+
return "<media:document>";
|
|
148
|
+
}
|
|
149
|
+
if (msg.sticker) {
|
|
150
|
+
return "<media:sticker>";
|
|
151
|
+
}
|
|
152
|
+
return undefined;
|
|
153
|
+
}
|
|
109
154
|
export function buildSenderLabel(msg, senderId) {
|
|
110
155
|
const name = buildSenderName(msg);
|
|
111
156
|
const username = msg.from?.username ? `@${msg.from.username}` : undefined;
|
|
@@ -119,41 +164,49 @@ export function buildSenderLabel(msg, senderId) {
|
|
|
119
164
|
const normalizedSenderId = senderId != null && `${senderId}`.trim() ? `${senderId}`.trim() : undefined;
|
|
120
165
|
const fallbackId = normalizedSenderId ?? (msg.from?.id != null ? String(msg.from.id) : undefined);
|
|
121
166
|
const idPart = fallbackId ? `id:${fallbackId}` : undefined;
|
|
122
|
-
if (label && idPart)
|
|
167
|
+
if (label && idPart) {
|
|
123
168
|
return `${label} ${idPart}`;
|
|
124
|
-
|
|
169
|
+
}
|
|
170
|
+
if (label) {
|
|
125
171
|
return label;
|
|
172
|
+
}
|
|
126
173
|
return idPart ?? "id:unknown";
|
|
127
174
|
}
|
|
128
175
|
export function buildGroupLabel(msg, chatId, messageThreadId) {
|
|
129
176
|
const title = msg.chat?.title;
|
|
130
177
|
const topicSuffix = messageThreadId != null ? ` topic:${messageThreadId}` : "";
|
|
131
|
-
if (title)
|
|
178
|
+
if (title) {
|
|
132
179
|
return `${title} id:${chatId}${topicSuffix}`;
|
|
180
|
+
}
|
|
133
181
|
return `group:${chatId}${topicSuffix}`;
|
|
134
182
|
}
|
|
135
183
|
export function hasBotMention(msg, botUsername) {
|
|
136
184
|
const text = (msg.text ?? msg.caption ?? "").toLowerCase();
|
|
137
|
-
if (text.includes(`@${botUsername}`))
|
|
185
|
+
if (text.includes(`@${botUsername}`)) {
|
|
138
186
|
return true;
|
|
187
|
+
}
|
|
139
188
|
const entities = msg.entities ?? msg.caption_entities ?? [];
|
|
140
189
|
for (const ent of entities) {
|
|
141
|
-
if (ent.type !== "mention")
|
|
190
|
+
if (ent.type !== "mention") {
|
|
142
191
|
continue;
|
|
192
|
+
}
|
|
143
193
|
const slice = (msg.text ?? msg.caption ?? "").slice(ent.offset, ent.offset + ent.length);
|
|
144
|
-
if (slice.toLowerCase() === `@${botUsername}`)
|
|
194
|
+
if (slice.toLowerCase() === `@${botUsername}`) {
|
|
145
195
|
return true;
|
|
196
|
+
}
|
|
146
197
|
}
|
|
147
198
|
return false;
|
|
148
199
|
}
|
|
149
200
|
export function expandTextLinks(text, entities) {
|
|
150
|
-
if (!text || !entities?.length)
|
|
201
|
+
if (!text || !entities?.length) {
|
|
151
202
|
return text;
|
|
203
|
+
}
|
|
152
204
|
const textLinks = entities
|
|
153
205
|
.filter((entity) => entity.type === "text_link" && Boolean(entity.url))
|
|
154
206
|
.toSorted((a, b) => b.offset - a.offset);
|
|
155
|
-
if (textLinks.length === 0)
|
|
207
|
+
if (textLinks.length === 0) {
|
|
156
208
|
return text;
|
|
209
|
+
}
|
|
157
210
|
let result = text;
|
|
158
211
|
for (const entity of textLinks) {
|
|
159
212
|
const linkText = text.slice(entity.offset, entity.offset + entity.length);
|
|
@@ -164,17 +217,18 @@ export function expandTextLinks(text, entities) {
|
|
|
164
217
|
return result;
|
|
165
218
|
}
|
|
166
219
|
export function resolveTelegramReplyId(raw) {
|
|
167
|
-
if (!raw)
|
|
220
|
+
if (!raw) {
|
|
168
221
|
return undefined;
|
|
222
|
+
}
|
|
169
223
|
const parsed = Number(raw);
|
|
170
|
-
if (!Number.isFinite(parsed))
|
|
224
|
+
if (!Number.isFinite(parsed)) {
|
|
171
225
|
return undefined;
|
|
226
|
+
}
|
|
172
227
|
return parsed;
|
|
173
228
|
}
|
|
174
229
|
export function describeReplyTarget(msg) {
|
|
175
230
|
const reply = msg.reply_to_message;
|
|
176
|
-
const externalReply = msg
|
|
177
|
-
.external_reply;
|
|
231
|
+
const externalReply = msg.external_reply;
|
|
178
232
|
const quoteText = msg.quote?.text ??
|
|
179
233
|
externalReply?.quote?.text;
|
|
180
234
|
let body = "";
|
|
@@ -190,19 +244,8 @@ export function describeReplyTarget(msg) {
|
|
|
190
244
|
const replyBody = (replyLike.text ?? replyLike.caption ?? "").trim();
|
|
191
245
|
body = replyBody;
|
|
192
246
|
if (!body) {
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
}
|
|
196
|
-
else if (replyLike.video) {
|
|
197
|
-
body = "<media:video>";
|
|
198
|
-
}
|
|
199
|
-
else if (replyLike.audio || replyLike.voice) {
|
|
200
|
-
body = "<media:audio>";
|
|
201
|
-
}
|
|
202
|
-
else if (replyLike.document) {
|
|
203
|
-
body = "<media:document>";
|
|
204
|
-
}
|
|
205
|
-
else {
|
|
247
|
+
body = resolveTelegramMediaPlaceholder(replyLike) ?? "";
|
|
248
|
+
if (!body) {
|
|
206
249
|
const locationData = extractTelegramLocation(replyLike);
|
|
207
250
|
if (locationData) {
|
|
208
251
|
body = formatLocationText(locationData);
|
|
@@ -225,23 +268,24 @@ export function describeReplyTarget(msg) {
|
|
|
225
268
|
function normalizeForwardedUserLabel(user) {
|
|
226
269
|
const name = [user.first_name, user.last_name].filter(Boolean).join(" ").trim();
|
|
227
270
|
const username = user.username?.trim() || undefined;
|
|
228
|
-
const id =
|
|
271
|
+
const id = String(user.id);
|
|
229
272
|
const display = (name && username
|
|
230
273
|
? `${name} (@${username})`
|
|
231
|
-
: name || (username ? `@${username}` : undefined)) ||
|
|
274
|
+
: name || (username ? `@${username}` : undefined)) || `user:${id}`;
|
|
232
275
|
return { display, name: name || undefined, username, id };
|
|
233
276
|
}
|
|
234
277
|
function normalizeForwardedChatLabel(chat, fallbackKind) {
|
|
235
278
|
const title = chat.title?.trim() || undefined;
|
|
236
279
|
const username = chat.username?.trim() || undefined;
|
|
237
|
-
const id =
|
|
238
|
-
const display = title || (username ? `@${username}` : undefined) ||
|
|
280
|
+
const id = String(chat.id);
|
|
281
|
+
const display = title || (username ? `@${username}` : undefined) || `${fallbackKind}:${id}`;
|
|
239
282
|
return { display, title, username, id };
|
|
240
283
|
}
|
|
241
284
|
function buildForwardedContextFromUser(params) {
|
|
242
285
|
const { display, name, username, id } = normalizeForwardedUserLabel(params.user);
|
|
243
|
-
if (!display)
|
|
286
|
+
if (!display) {
|
|
244
287
|
return null;
|
|
288
|
+
}
|
|
245
289
|
return {
|
|
246
290
|
from: display,
|
|
247
291
|
date: params.date,
|
|
@@ -253,8 +297,9 @@ function buildForwardedContextFromUser(params) {
|
|
|
253
297
|
}
|
|
254
298
|
function buildForwardedContextFromHiddenName(params) {
|
|
255
299
|
const trimmed = params.name?.trim();
|
|
256
|
-
if (!trimmed)
|
|
300
|
+
if (!trimmed) {
|
|
257
301
|
return null;
|
|
302
|
+
}
|
|
258
303
|
return {
|
|
259
304
|
from: trimmed,
|
|
260
305
|
date: params.date,
|
|
@@ -263,10 +308,11 @@ function buildForwardedContextFromHiddenName(params) {
|
|
|
263
308
|
};
|
|
264
309
|
}
|
|
265
310
|
function buildForwardedContextFromChat(params) {
|
|
266
|
-
const fallbackKind = params.type === "channel"
|
|
311
|
+
const fallbackKind = params.type === "channel" ? "channel" : "chat";
|
|
267
312
|
const { display, title, username, id } = normalizeForwardedChatLabel(params.chat, fallbackKind);
|
|
268
|
-
if (!display)
|
|
313
|
+
if (!display) {
|
|
269
314
|
return null;
|
|
315
|
+
}
|
|
270
316
|
const signature = params.signature?.trim() || undefined;
|
|
271
317
|
const from = signature ? `${display} (${signature})` : display;
|
|
272
318
|
const chatType = (params.chat.type?.trim() || undefined);
|
|
@@ -282,83 +328,51 @@ function buildForwardedContextFromChat(params) {
|
|
|
282
328
|
fromMessageId: params.messageId,
|
|
283
329
|
};
|
|
284
330
|
}
|
|
285
|
-
function resolveForwardOrigin(origin
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
331
|
+
function resolveForwardOrigin(origin) {
|
|
332
|
+
switch (origin.type) {
|
|
333
|
+
case "user":
|
|
334
|
+
return buildForwardedContextFromUser({
|
|
335
|
+
user: origin.sender_user,
|
|
336
|
+
date: origin.date,
|
|
337
|
+
type: "user",
|
|
338
|
+
});
|
|
339
|
+
case "hidden_user":
|
|
340
|
+
return buildForwardedContextFromHiddenName({
|
|
341
|
+
name: origin.sender_user_name,
|
|
342
|
+
date: origin.date,
|
|
343
|
+
type: "hidden_user",
|
|
344
|
+
});
|
|
345
|
+
case "chat":
|
|
346
|
+
return buildForwardedContextFromChat({
|
|
347
|
+
chat: origin.sender_chat,
|
|
348
|
+
date: origin.date,
|
|
349
|
+
type: "chat",
|
|
350
|
+
signature: origin.author_signature,
|
|
351
|
+
});
|
|
352
|
+
case "channel":
|
|
353
|
+
return buildForwardedContextFromChat({
|
|
354
|
+
chat: origin.chat,
|
|
355
|
+
date: origin.date,
|
|
356
|
+
type: "channel",
|
|
357
|
+
signature: origin.author_signature,
|
|
358
|
+
messageId: origin.message_id,
|
|
359
|
+
});
|
|
360
|
+
default:
|
|
361
|
+
// Exhaustiveness guard: if Grammy adds a new MessageOrigin variant,
|
|
362
|
+
// TypeScript will flag this assignment as an error.
|
|
363
|
+
origin;
|
|
364
|
+
return null;
|
|
299
365
|
}
|
|
300
|
-
if (origin.type === "chat" && origin.sender_chat) {
|
|
301
|
-
return buildForwardedContextFromChat({
|
|
302
|
-
chat: origin.sender_chat,
|
|
303
|
-
date: origin.date,
|
|
304
|
-
type: "chat",
|
|
305
|
-
signature,
|
|
306
|
-
});
|
|
307
|
-
}
|
|
308
|
-
if (origin.type === "channel" && origin.chat) {
|
|
309
|
-
return buildForwardedContextFromChat({
|
|
310
|
-
chat: origin.chat,
|
|
311
|
-
date: origin.date,
|
|
312
|
-
type: "channel",
|
|
313
|
-
signature,
|
|
314
|
-
});
|
|
315
|
-
}
|
|
316
|
-
return null;
|
|
317
366
|
}
|
|
318
|
-
/**
|
|
319
|
-
* Extract forwarded message origin info from Telegram message.
|
|
320
|
-
* Supports both new forward_origin API and legacy forward_from/forward_from_chat fields.
|
|
321
|
-
*/
|
|
367
|
+
/** Extract forwarded message origin info from Telegram message. */
|
|
322
368
|
export function normalizeForwardedContext(msg) {
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
if (forwardMsg.forward_origin) {
|
|
326
|
-
const originContext = resolveForwardOrigin(forwardMsg.forward_origin, signature);
|
|
327
|
-
if (originContext)
|
|
328
|
-
return originContext;
|
|
329
|
-
}
|
|
330
|
-
if (forwardMsg.forward_from_chat) {
|
|
331
|
-
const legacyType = forwardMsg.forward_from_chat.type === "channel" ? "legacy_channel" : "legacy_chat";
|
|
332
|
-
const legacyContext = buildForwardedContextFromChat({
|
|
333
|
-
chat: forwardMsg.forward_from_chat,
|
|
334
|
-
date: forwardMsg.forward_date,
|
|
335
|
-
type: legacyType,
|
|
336
|
-
signature,
|
|
337
|
-
});
|
|
338
|
-
if (legacyContext)
|
|
339
|
-
return legacyContext;
|
|
340
|
-
}
|
|
341
|
-
if (forwardMsg.forward_from) {
|
|
342
|
-
const legacyContext = buildForwardedContextFromUser({
|
|
343
|
-
user: forwardMsg.forward_from,
|
|
344
|
-
date: forwardMsg.forward_date,
|
|
345
|
-
type: "legacy_user",
|
|
346
|
-
});
|
|
347
|
-
if (legacyContext)
|
|
348
|
-
return legacyContext;
|
|
369
|
+
if (!msg.forward_origin) {
|
|
370
|
+
return null;
|
|
349
371
|
}
|
|
350
|
-
|
|
351
|
-
name: forwardMsg.forward_sender_name,
|
|
352
|
-
date: forwardMsg.forward_date,
|
|
353
|
-
type: "legacy_hidden_user",
|
|
354
|
-
});
|
|
355
|
-
if (hiddenContext)
|
|
356
|
-
return hiddenContext;
|
|
357
|
-
return null;
|
|
372
|
+
return resolveForwardOrigin(msg.forward_origin);
|
|
358
373
|
}
|
|
359
374
|
export function extractTelegramLocation(msg) {
|
|
360
|
-
const
|
|
361
|
-
const { venue, location } = msgWithLocation;
|
|
375
|
+
const { venue, location } = msg;
|
|
362
376
|
if (venue) {
|
|
363
377
|
return {
|
|
364
378
|
latitude: venue.location.latitude,
|