1 | |
2 |
|
3 | |
4 | * Send Message via Webhook |
5 | * Post a message to a Chat space through its incoming webhook, as the webhook (no OAuth connection or Chat app needed). Send `text` (Chat markup: `*bold*`, `_italic_`, `<users/123>` mentions), `cards_v2` (a list of `{ cardId, card }` objects), or both. Set `thread_key` to group messages into a thread; `message_reply_option` picks whether a missing thread is created (REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD, the default when a key is set) or the message fails (REPLY_MESSAGE_OR_FAIL). Google allows 1 request per second per space, shared by all its webhooks. |
6 | */ |
7 | export async function main( |
8 | auth: RT.GchatWebhook, |
9 | text: string | undefined, |
10 | cards_v2: { [key: string]: any }[] | undefined, |
11 | thread_key: string | undefined, |
12 | message_reply_option: |
13 | | "REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD" |
14 | | "REPLY_MESSAGE_OR_FAIL" |
15 | | undefined |
16 | ) { |
17 | if (!text && !cards_v2?.length) { |
18 | throw new Error("Set text, cards_v2 or both") |
19 | } |
20 | if (message_reply_option && !thread_key) { |
21 | throw new Error("message_reply_option needs a thread_key") |
22 | } |
23 | const url = new URL(auth.url) |
24 | const body: { [key: string]: any } = { |
25 | text: text || undefined, |
26 | cardsV2: cards_v2?.length ? cards_v2 : undefined, |
27 | } |
28 | if (thread_key) { |
29 | body.thread = { threadKey: thread_key } |
30 | url.searchParams.set( |
31 | "messageReplyOption", |
32 | message_reply_option || "REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD" |
33 | ) |
34 | } |
35 |
|
36 | const response = await fetch(url, { |
37 | method: "POST", |
38 | headers: { |
39 | "Content-Type": "application/json; charset=UTF-8", |
40 | Accept: "application/json", |
41 | }, |
42 | body: JSON.stringify(body), |
43 | }) |
44 | if (response.status === 429) { |
45 | const retry = response.headers.get("Retry-After") |
46 | throw new Error( |
47 | `429 rate limited: Google Chat allows 1 request per second per space, shared by all its webhooks${ |
48 | retry ? `; retry after ${retry}s` : "" |
49 | }. ${await response.text()}` |
50 | ) |
51 | } |
52 | if (!response.ok) { |
53 | throw new Error(`${response.status} ${await response.text()}`) |
54 | } |
55 |
|
56 | return await response.json() |
57 | } |
58 |
|