loopbot-discord-sdk 1.0.0

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.
Files changed (95) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +406 -0
  3. package/dist/Bot.d.ts +323 -0
  4. package/dist/Bot.d.ts.map +1 -0
  5. package/dist/Bot.js +482 -0
  6. package/dist/Bot.js.map +1 -0
  7. package/dist/Client.d.ts +309 -0
  8. package/dist/Client.d.ts.map +1 -0
  9. package/dist/Client.js +533 -0
  10. package/dist/Client.js.map +1 -0
  11. package/dist/builders/ActionRowBuilder.d.ts +11 -0
  12. package/dist/builders/ActionRowBuilder.d.ts.map +1 -0
  13. package/dist/builders/ActionRowBuilder.js +28 -0
  14. package/dist/builders/ActionRowBuilder.js.map +1 -0
  15. package/dist/builders/ButtonBuilder.d.ts +19 -0
  16. package/dist/builders/ButtonBuilder.d.ts.map +1 -0
  17. package/dist/builders/ButtonBuilder.js +46 -0
  18. package/dist/builders/ButtonBuilder.js.map +1 -0
  19. package/dist/builders/CommandBuilder.d.ts +51 -0
  20. package/dist/builders/CommandBuilder.d.ts.map +1 -0
  21. package/dist/builders/CommandBuilder.js +144 -0
  22. package/dist/builders/CommandBuilder.js.map +1 -0
  23. package/dist/builders/ContainerBuilder.d.ts +50 -0
  24. package/dist/builders/ContainerBuilder.d.ts.map +1 -0
  25. package/dist/builders/ContainerBuilder.js +67 -0
  26. package/dist/builders/ContainerBuilder.js.map +1 -0
  27. package/dist/builders/EmbedBuilder.d.ts +21 -0
  28. package/dist/builders/EmbedBuilder.d.ts.map +1 -0
  29. package/dist/builders/EmbedBuilder.js +63 -0
  30. package/dist/builders/EmbedBuilder.js.map +1 -0
  31. package/dist/builders/FileBuilder.d.ts +30 -0
  32. package/dist/builders/FileBuilder.d.ts.map +1 -0
  33. package/dist/builders/FileBuilder.js +42 -0
  34. package/dist/builders/FileBuilder.js.map +1 -0
  35. package/dist/builders/MediaGalleryBuilder.d.ts +33 -0
  36. package/dist/builders/MediaGalleryBuilder.d.ts.map +1 -0
  37. package/dist/builders/MediaGalleryBuilder.js +38 -0
  38. package/dist/builders/MediaGalleryBuilder.js.map +1 -0
  39. package/dist/builders/ModalBuilder.d.ts +21 -0
  40. package/dist/builders/ModalBuilder.d.ts.map +1 -0
  41. package/dist/builders/ModalBuilder.js +46 -0
  42. package/dist/builders/ModalBuilder.js.map +1 -0
  43. package/dist/builders/SectionBuilder.d.ts +43 -0
  44. package/dist/builders/SectionBuilder.d.ts.map +1 -0
  45. package/dist/builders/SectionBuilder.js +55 -0
  46. package/dist/builders/SectionBuilder.js.map +1 -0
  47. package/dist/builders/SelectMenuBuilder.d.ts +16 -0
  48. package/dist/builders/SelectMenuBuilder.d.ts.map +1 -0
  49. package/dist/builders/SelectMenuBuilder.js +50 -0
  50. package/dist/builders/SelectMenuBuilder.js.map +1 -0
  51. package/dist/builders/SeparatorBuilder.d.ts +31 -0
  52. package/dist/builders/SeparatorBuilder.d.ts.map +1 -0
  53. package/dist/builders/SeparatorBuilder.js +34 -0
  54. package/dist/builders/SeparatorBuilder.js.map +1 -0
  55. package/dist/builders/TextDisplayBuilder.d.ts +22 -0
  56. package/dist/builders/TextDisplayBuilder.d.ts.map +1 -0
  57. package/dist/builders/TextDisplayBuilder.js +32 -0
  58. package/dist/builders/TextDisplayBuilder.js.map +1 -0
  59. package/dist/context/BaseContext.d.ts +114 -0
  60. package/dist/context/BaseContext.d.ts.map +1 -0
  61. package/dist/context/BaseContext.js +189 -0
  62. package/dist/context/BaseContext.js.map +1 -0
  63. package/dist/context/ButtonContext.d.ts +30 -0
  64. package/dist/context/ButtonContext.d.ts.map +1 -0
  65. package/dist/context/ButtonContext.js +48 -0
  66. package/dist/context/ButtonContext.js.map +1 -0
  67. package/dist/context/CommandContext.d.ts +55 -0
  68. package/dist/context/CommandContext.d.ts.map +1 -0
  69. package/dist/context/CommandContext.js +98 -0
  70. package/dist/context/CommandContext.js.map +1 -0
  71. package/dist/context/ModalContext.d.ts +24 -0
  72. package/dist/context/ModalContext.d.ts.map +1 -0
  73. package/dist/context/ModalContext.js +54 -0
  74. package/dist/context/ModalContext.js.map +1 -0
  75. package/dist/context/SelectContext.d.ts +38 -0
  76. package/dist/context/SelectContext.d.ts.map +1 -0
  77. package/dist/context/SelectContext.js +60 -0
  78. package/dist/context/SelectContext.js.map +1 -0
  79. package/dist/index.d.ts +22 -0
  80. package/dist/index.d.ts.map +1 -0
  81. package/dist/index.js +63 -0
  82. package/dist/index.js.map +1 -0
  83. package/dist/types/commands.d.ts +42 -0
  84. package/dist/types/commands.d.ts.map +1 -0
  85. package/dist/types/commands.js +25 -0
  86. package/dist/types/commands.js.map +1 -0
  87. package/dist/types/discord.d.ts +76 -0
  88. package/dist/types/discord.d.ts.map +1 -0
  89. package/dist/types/discord.js +4 -0
  90. package/dist/types/discord.js.map +1 -0
  91. package/dist/types/interactions.d.ts +78 -0
  92. package/dist/types/interactions.d.ts.map +1 -0
  93. package/dist/types/interactions.js +22 -0
  94. package/dist/types/interactions.js.map +1 -0
  95. package/package.json +63 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Loop
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,406 @@
1
+ # LoopBot SDK TypeScript
2
+
3
+ The official library for building LoopBot bots using TypeScript/JavaScript.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install loopbot-sdk
9
+ ```
10
+
11
+ ## Initialization
12
+
13
+ ```typescript
14
+ import { Bot } from 'loopbot-sdk';
15
+
16
+ const bot = new Bot({
17
+ token: 'your_token_here'
18
+ });
19
+
20
+ // ... your commands here ...
21
+
22
+ bot.start();
23
+ ```
24
+
25
+ ## Complete Guide
26
+
27
+ ### Working with Embeds
28
+
29
+ Embeds are rich messages that allow you to display information in a structured way.
30
+
31
+ ```typescript
32
+ import { EmbedBuilder } from 'loopbot-sdk';
33
+
34
+ bot.command('embed_demo', 'Embed Demo', (ctx) => {
35
+ // Creating an embed
36
+ const embed = new EmbedBuilder()
37
+ .setTitle('Embed Title')
38
+ .setDescription('Detailed description here...')
39
+ .setColor(0x00FF00) // Hex color (e.g., Green)
40
+ .setURL('https://loopbot.app')
41
+ .setFooter('Footer Text', 'https://example.com/icon.png')
42
+ .setAuthor('Author Name', 'https://profile.com', 'https://avatar.com/img.png')
43
+ .setImage('https://example.com/large_image.png')
44
+ .setThumbnail('https://example.com/thumbnail.png')
45
+ .addField('Field 1', 'Value 1', true) // inline = true
46
+ .addField('Field 2', 'Value 2', true)
47
+ .setTimestamp(); // Uses current time if not specified
48
+
49
+ // Sending the embed
50
+ ctx.reply({ embeds: [embed] });
51
+ });
52
+ ```
53
+
54
+ ### Working with Containers (Components V2)
55
+
56
+ Containers are advanced components that allow you to visually group other components like text, separators, and galleries.
57
+
58
+ > **Note:** To send containers, use the `replyWithComponents` or `updateWithComponents` methods.
59
+
60
+ ```typescript
61
+ import { ContainerBuilder, SeparatorBuilder, MediaGalleryBuilder } from 'loopbot-sdk';
62
+
63
+ bot.command('container_demo', 'Container Demo', (ctx) => {
64
+ // Creating a container
65
+ const container = new ContainerBuilder()
66
+ .setAccentColor(0xFF0000) // Sidebar color
67
+ .setSpoiler(false) // Whether content is a spoiler
68
+ .addText('# Title inside Container')
69
+ .addText('This is normal text inside the container.');
70
+
71
+ // Adding a Separator
72
+ // spacing: 1 (small) or 2 (large)
73
+ container.addSeparator(true, 1);
74
+
75
+ // Adding a Media Gallery
76
+ const gallery = new MediaGalleryBuilder()
77
+ .addItem('https://example.com/img1.png', 'Caption 1')
78
+ .addItem('https://example.com/img2.png', 'Caption 2');
79
+
80
+ container.addComponent(gallery);
81
+
82
+ // Sending the container
83
+ ctx.replyWithComponents({ components: [container] });
84
+ });
85
+ ```
86
+
87
+ ### Separators
88
+
89
+ Separators help visually organize content within containers or as standalone components.
90
+
91
+ ```typescript
92
+ import { SeparatorBuilder } from 'loopbot-sdk';
93
+
94
+ // Separator with visible line and large spacing
95
+ const sep = new SeparatorBuilder()
96
+ .setDivider(true)
97
+ .setSpacing(2);
98
+
99
+ // Can be added to a container
100
+ container.addComponent(sep);
101
+ ```
102
+
103
+ ### Replying to Interactions
104
+
105
+ The context (`ctx`) provides various methods to respond to commands and interactions.
106
+
107
+ #### Reply with Text and Embeds
108
+
109
+ ```typescript
110
+ // Text only
111
+ ctx.reply({ content: 'Hello world!' });
112
+
113
+ // Text and Embed
114
+ ctx.reply({
115
+ content: 'Check this out:',
116
+ embeds: [embed]
117
+ });
118
+
119
+ // Ephemeral response (visible only to the user who ran the command)
120
+ ctx.reply({
121
+ content: 'Secret...',
122
+ ephemeral: true
123
+ });
124
+ ```
125
+
126
+ #### Reply with Components V2 (Containers)
127
+
128
+ To send Containers, Galleries, or Separators as the main response.
129
+
130
+ ```typescript
131
+ ctx.replyWithComponents({ components: [container1, container2] });
132
+ ```
133
+
134
+ #### Updating the Original Message
135
+
136
+ Useful for button or select menu interactions where you want to change the original message instead of sending a new one.
137
+
138
+ ```typescript
139
+ bot.onButton('my_button', (ctx) => {
140
+ // Update text and embeds of the message where the button was
141
+ const embed = new EmbedBuilder().setTitle('Updated!');
142
+
143
+ ctx.update({
144
+ content: 'New message',
145
+ embeds: [embed]
146
+ });
147
+
148
+ // Or to update with Containers
149
+ // ctx.updateWithComponents({ components: [newContainer] });
150
+ });
151
+ ```
152
+
153
+ #### Editing the Response (Follow-up)
154
+
155
+ If you have already replied (e.g., with `defer` or a quick response) and want to edit that response later.
156
+
157
+ ```typescript
158
+ bot.command('process', 'Long processing', async (ctx) => {
159
+ // Acknowledge processing
160
+ ctx.defer();
161
+
162
+ // ... long processing ...
163
+
164
+ // Edit the original response
165
+ await ctx.editReply({
166
+ content: 'Processing complete!',
167
+ embeds: [resultEmbed]
168
+ });
169
+ });
170
+ ```
171
+
172
+ ### Buttons and Action Rows
173
+
174
+ Buttons are interactive components that users can click. They must be placed inside an `ActionRow`.
175
+
176
+ ```typescript
177
+ import { ActionRowBuilder, ButtonBuilder, ButtonStyle } from 'loopbot-sdk';
178
+
179
+ bot.command('buttons', 'Button demo', (ctx) => {
180
+ // Creating buttons
181
+ const btnPrimary = new ButtonBuilder()
182
+ .setLabel('Click here')
183
+ .setCustomId('btn_click')
184
+ .setStyle(ButtonStyle.PRIMARY); // Blue
185
+
186
+ const btnLink = new ButtonBuilder()
187
+ .setLabel('Visit Website')
188
+ .setURL('https://loopbot.app')
189
+ .setStyle(ButtonStyle.LINK); // Gray
190
+
191
+ // Adding to ActionRow
192
+ const row = new ActionRowBuilder()
193
+ .addButton(btnPrimary)
194
+ .addButton(btnLink);
195
+
196
+ ctx.reply({ content: 'Choose an option:', components: [row] });
197
+ });
198
+
199
+ bot.onButton('btn_click', (ctx) => {
200
+ ctx.reply({ content: 'You clicked the button!', ephemeral: true });
201
+ });
202
+ ```
203
+
204
+ ### Select Menus (Dropdowns)
205
+
206
+ Select menus allow users to choose one or more options from a list.
207
+
208
+ ```typescript
209
+ import { SelectMenuBuilder, ActionRowBuilder } from 'loopbot-sdk';
210
+
211
+ bot.command('menu', 'Menu demo', (ctx) => {
212
+ const select = new SelectMenuBuilder()
213
+ .setCustomId('select_menu')
214
+ .setPlaceholder('Choose your class')
215
+ .addOption('Warrior', 'warrior', 'Melee combat class')
216
+ .addOption('Mage', 'mage', 'Magic class', { name: '🔮' })
217
+ .setMinValues(1)
218
+ .setMaxValues(1);
219
+
220
+ const row = new ActionRowBuilder().addSelectMenu(select);
221
+ ctx.reply({ content: 'Select your class:', components: [row] });
222
+ });
223
+
224
+ bot.onSelect('select_menu', (ctx) => {
225
+ const value = ctx.values[0];
226
+ ctx.reply({ content: `You selected: ${value}`, ephemeral: true });
227
+ });
228
+ ```
229
+
230
+ ### Modals (Forms)
231
+
232
+ Modals are pop-up windows with forms for text input.
233
+
234
+ ```typescript
235
+ import { ModalBuilder } from 'loopbot-sdk';
236
+
237
+ bot.command('feedback', 'Send feedback', (ctx) => {
238
+ const modal = new ModalBuilder()
239
+ .setCustomId('feedback_modal')
240
+ .setTitle('Give us your feedback')
241
+ .addTextInput(
242
+ 'input_msg',
243
+ 'Message',
244
+ 'paragraph', // or 'short'
245
+ {
246
+ placeholder: 'Write here...',
247
+ required: true
248
+ }
249
+ );
250
+
251
+ ctx.showModal(modal);
252
+ });
253
+ ```
254
+
255
+ ### Advanced Layout (Sections)
256
+
257
+ Sections allow you to group text with a side "accessory" like a button or image.
258
+
259
+ ```typescript
260
+ import { SectionBuilder, ButtonBuilder, ButtonStyle } from 'loopbot-sdk';
261
+
262
+ bot.command('section', 'Section Demo', (ctx) => {
263
+ const btn = new ButtonBuilder()
264
+ .setLabel('See More')
265
+ .setURL('https://google.com')
266
+ .setStyle(ButtonStyle.LINK);
267
+
268
+ const section = new SectionBuilder()
269
+ .addText('**Section Title**')
270
+ .addText('Detailed description next to the button.')
271
+ .setButtonAccessory(btn);
272
+
273
+ ctx.replyWithComponents({ components: [section] });
274
+ });
275
+ ```
276
+
277
+ ### Files
278
+
279
+ Sending files as attachments or within structures.
280
+
281
+ ```typescript
282
+ import { FileBuilder } from 'loopbot-sdk';
283
+
284
+ const file = new FileBuilder('https://example.com/file.pdf').setSpoiler(false);
285
+ // Add to a container or send as supported by API
286
+ ```
287
+
288
+ ## Quick Reference
289
+
290
+ | Feature | Builder / Method |
291
+ | :--- | :--- |
292
+ | **Embed** | `EmbedBuilder` |
293
+ | **Container** | `ContainerBuilder` |
294
+ | **Separator** | `SeparatorBuilder` |
295
+ | **Gallery** | `MediaGalleryBuilder` |
296
+ | **Button** | `ButtonBuilder` |
297
+ | **Action Row** | `ActionRowBuilder` |
298
+ | **Select Menu** | `SelectMenuBuilder` |
299
+ | **Modal** | `ModalBuilder` |
300
+ | **Section** | `SectionBuilder` |
301
+ | **File** | `FileBuilder` |
302
+ | **Reply** | `ctx.reply(...)` |
303
+ | **Reply (Container)** | `ctx.replyWithComponents(...)` |
304
+ | **Update Msg** | `ctx.update(...)` |
305
+ | **Edit Reply** | `ctx.editReply(...)` |
306
+
307
+ ## Direct Messaging API
308
+
309
+ Send messages outside of interaction context, manage channels, roles, and more.
310
+
311
+ ### Sending Messages
312
+
313
+ ```typescript
314
+ // Send a message to any channel
315
+ await bot.send(channelId, { content: 'Hello!' });
316
+
317
+ // Edit a message
318
+ await bot.editMessage(channelId, messageId, { content: 'Updated!' });
319
+
320
+ // Delete a message
321
+ await bot.deleteMessage(channelId, messageId);
322
+ ```
323
+
324
+ ### Channel Management
325
+
326
+ ```typescript
327
+ // Create a channel
328
+ await bot.createChannel(guildId, { name: 'new-channel', topic: 'Description' });
329
+
330
+ // Modify a channel
331
+ await bot.modifyChannel(channelId, { name: 'renamed-channel' });
332
+
333
+ // Delete a channel
334
+ await bot.deleteChannel(channelId);
335
+ ```
336
+
337
+ ### Forum Channels
338
+
339
+ ```typescript
340
+ // Create a forum post
341
+ await bot.createForumPost(forumChannelId, {
342
+ name: 'My Post Title',
343
+ message: { content: 'Post content here' },
344
+ applied_tags: ['tagId']
345
+ });
346
+
347
+ // Get/modify forum tags
348
+ const tags = await bot.getForumTags(forumChannelId);
349
+ await bot.modifyForumTags(forumChannelId, [{ name: 'New Tag' }]);
350
+
351
+ // Archive/lock threads
352
+ await bot.archiveThread(threadId);
353
+ await bot.lockThread(threadId);
354
+ ```
355
+
356
+ ### Roles
357
+
358
+ ```typescript
359
+ // Get roles
360
+ const roles = await bot.getRoles(guildId);
361
+
362
+ // Create a role
363
+ await bot.createRole(guildId, { name: 'Moderator', color: 0x00FF00 });
364
+
365
+ // Modify a role
366
+ await bot.modifyRole(guildId, roleId, { name: 'Admin', hoist: true });
367
+
368
+ // Delete a role
369
+ await bot.deleteRole(guildId, roleId);
370
+
371
+ // Reorder roles
372
+ await bot.reorderRoles(guildId, [{ id: roleId, position: 2 }]);
373
+ ```
374
+
375
+ ### Webhooks
376
+
377
+ ```typescript
378
+ // Create a webhook
379
+ const webhook = await bot.createWebhook(channelId, { name: 'My Webhook' });
380
+
381
+ // Send message via webhook
382
+ await bot.executeWebhook(webhookId, webhookToken, {
383
+ content: 'Message via webhook!',
384
+ username: 'Custom Name'
385
+ });
386
+
387
+ // Edit/delete webhook message
388
+ await bot.editWebhookMessage(webhookId, webhookToken, messageId, { content: 'Updated' });
389
+ await bot.deleteWebhookMessage(webhookId, webhookToken, messageId);
390
+
391
+ // Delete webhook
392
+ await bot.deleteWebhook(webhookId);
393
+ ```
394
+
395
+ ### Member Management
396
+
397
+ ```typescript
398
+ // Add/remove roles
399
+ await bot.addMemberRole(guildId, userId, roleId);
400
+ await bot.removeMemberRole(guildId, userId, roleId);
401
+
402
+ // Kick/ban members
403
+ await bot.kickMember(guildId, userId);
404
+ await bot.banMember(guildId, userId);
405
+ ```
406
+