api.ts
@file The two Discord calls that need the bot token.
Overview
@file The two Discord calls that need the bot token. Creating a forum post and posting into a thread are the only things this bot does that an interaction token cannot authorise. The token is a Worker secret, is never logged, and is never interpolated into anything that could be echoed back. Channel IDs are checked against a snowflake pattern before they reach a URL. They come from configuration rather than from a user, but a URL built by concatenation is worth validating whatever the source.
depends on env.ts · used by build.ts help-me.ts
API
Fexport function forumChannelFor(env: Env, board: string): string | undefined
The forum channel for a board, or undefined.
FORUM_CHANNELS is BOARD=id,BOARD=id. An unparseable entry is skipped
rather than throwing: a typo in one board's channel must not take
/help-me down for every other board.
onModalSubmitFexport async function createForumThread(env: Env, channelId: string, name: string, content: string, allowedMentions: AllowedMentions, correlationId: string): Promise<string | null>
Create a forum post. Returns the thread ID, or null if it could not.
onModalSubmit · calls callFexport async function postToThread(env: Env, threadId: string, content: string, correlationId: string): Promise<boolean>
Post a follow-on message into a thread. Best effort.
onModalSubmit · calls callFexport async function dispatchFirmwareBuilds(env: Env, ref: string, targets: string, correlationId: string): Promise<
Dispatch firmware-builds.yml with a targets selection.
workflow_dispatch itself returns 204 with no run identifier, so the run
URL is found by asking for the newest workflow_dispatch run afterward. That
is racy against anyone else dispatching the same workflow in the same
second; findLatestRun accepts the gap and the caller degrades to a runs
list link when it cannot find a match.
save_ccache is always false here. Every per-job ccache entry is keyed on
github.run_id, so a normal dispatch always writes a fresh ~300 MB cache
entry — the right default for a maintainer's own run, wrong for a bot
answering a one-off Discord request: ten of those would be 3 GB against the
repository's 10 GB Actions cache LRU budget, pressure that can evict
nrf-workspace or the esp-matter cache, the two entries actually expensive
to rebuild. workflow_dispatch inputs are always strings on the wire, so
this is the literal string "false", not the boolean.
handlerFexport async function findLatestRun(env: Env, since: number, correlationId: string): Promise<string>
Poll briefly for the run a dispatch just created. since is the time just
before the dispatch call, so a run created earlier cannot be mistaken for
this one.
handlerUndocumented (1)
call