1 | type DiscordBotConfiguration = { |
2 | |
3 | bot_token?: string, |
4 | |
5 | |
6 | public_key?: string, |
7 | application_id: string |
8 | }; |
9 |
|
10 | |
11 | * Creates a thread in Discord and sends a series of messages to it using the Discord bot configuration. |
12 | * The series starts with a firstMessage, followed by the messages array, and ends with a lastMessage. |
13 | * Before attempting to create the thread, it validates that all messages (including first and last) are within the character limit. |
14 | * If any message exceeds the limit, it throws an error without creating the thread. |
15 | * @param discordBotConfigResource Contains the Discord bot configuration necessary for API requests. |
16 | * @param channelId The ID of the Discord channel where the thread will be created. |
17 | * @param threadName The name of the thread to be created. Must be 100 characters or less. |
18 | * @param firstMessage The first message to be sent to the thread. Must be 2000 characters or less. |
19 | * @param messages An array of messages to be sent to the thread after the firstMessage and before the lastMessage. Each message must be 2000 characters or less. |
20 | * @param lastMessage The last message to be sent to the thread. Must be 2000 characters or less. |
21 | * @returns An object indicating the success status of thread creation and each message sent. |
22 | * @throws Error if the thread creation or any message sending fails, or if input validations fail. |
23 | */ |
24 | export async function main( |
25 | discordBotConfigResource: DiscordBotConfiguration, |
26 | channelId: string, |
27 | threadName: string, |
28 | firstMessage: string, |
29 | messages: string[], |
30 | lastMessage: string |
31 | ): Promise<{ thread: boolean; messages: boolean[] }> { |
32 | |
33 | if (threadName.length > 100) { |
34 | throw new Error("Thread name must be 100 characters or less."); |
35 | } |
36 |
|
37 | |
38 | if (firstMessage.length > 2000) { |
39 | throw new Error("First message must be 2000 characters or less."); |
40 | } |
41 | if (lastMessage.length > 2000) { |
42 | throw new Error("Last message must be 2000 characters or less."); |
43 | } |
44 |
|
45 | |
46 | for (const message of messages) { |
47 | if (message.length > 2000) { |
48 | throw new Error("Each message must be 2000 characters or less."); |
49 | } |
50 | } |
51 |
|
52 | |
53 | const result = { |
54 | thread: false, |
55 | messages: [] |
56 | }; |
57 |
|
58 | |
59 | const createThreadUrl = `https://discord.com/api/v9/channels/${channelId}/threads`; |
60 |
|
61 | |
62 | const createThreadBody = JSON.stringify({ |
63 | name: threadName, |
64 | auto_archive_duration: 60, |
65 | type: 11 |
66 | }); |
67 |
|
68 | |
69 | const headers = { |
70 | 'Content-Type': 'application/json', |
71 | 'Authorization': `Bot ${discordBotConfigResource.bot_token ?? discordBotConfigResource.public_key}` |
72 | }; |
73 |
|
74 | |
75 | const createThreadResponse = await fetch(createThreadUrl, { |
76 | method: 'POST', |
77 | headers: headers, |
78 | body: createThreadBody |
79 | }); |
80 |
|
81 | if (!createThreadResponse.ok) { |
82 | throw new Error("Failed to create thread"); |
83 | } |
84 |
|
85 | |
86 | const threadInfo = await createThreadResponse.json(); |
87 | const threadId = threadInfo.id; |
88 | result.thread = true; |
89 |
|
90 | |
91 | const sendMessage = async (message: string) => { |
92 | |
93 | const sendMessageUrl = `https://discord.com/api/v9/channels/${threadId}/messages`; |
94 |
|
95 | |
96 | const messageBody = JSON.stringify({ |
97 | content: message |
98 | }); |
99 |
|
100 | |
101 | const sendMessageResponse = await fetch(sendMessageUrl, { |
102 | method: 'POST', |
103 | headers: headers, |
104 | body: messageBody |
105 | }); |
106 |
|
107 | |
108 | if (sendMessageResponse.status === 429) { |
109 | const retryAfter = parseInt(sendMessageResponse.headers.get('Retry-After'), 10); |
110 | console.log(`Rate limit hit, retrying after ${retryAfter} seconds.`); |
111 | await new Promise(resolve => setTimeout(resolve, retryAfter * 1000)); |
112 | return sendMessage(message); |
113 | } |
114 |
|
115 | if (!sendMessageResponse.ok) { |
116 | throw new Error(`Failed to send message: ${message}`); |
117 | } |
118 |
|
119 | |
120 | result.messages.push(true); |
121 | }; |
122 |
|
123 | |
124 | await sendMessage(firstMessage); |
125 |
|
126 | |
127 | for (const message of messages) { |
128 | await sendMessage(message); |
129 | } |
130 |
|
131 | |
132 | await sendMessage(lastMessage); |
133 |
|
134 | return result; |
135 | } |