### Install taverns.js SDK Source: https://github.com/tav-gg/taverns.js/blob/main/README.md Install the taverns.js SDK using npm. ```bash npm install taverns.js ``` -------------------------------- ### Quick Start: Initialize and Run a Tavern Bot Source: https://github.com/tav-gg/taverns.js/blob/main/README.md Initialize the client with your bot token, log in, and set up event listeners for ready, message creation, member join, and errors. ```typescript import { Client } from 'taverns.js'; const client = new Client({ token: 'tavbot_your_token_here' }); client.on('ready', () => { console.log(`Logged in as ${client.user.displayName}`); console.log(`Connected to ${client.taverns.size} tavern(s)`); }); client.on('messageCreate', async (message) => { // Ignore messages from bots (including self) if (message.sender.id === client.user.id) return; if (message.content === '!ping') { await message.reply('Pong!'); } if (message.content === '!info') { const tavern = client.taverns.get(message.tavernId); await message.reply(`This tavern is "${tavern?.name}" with ${tavern?.memberCount} members.`); } }); client.on('memberJoin', (event) => { console.log(`${event.displayName} joined tavern ${event.tavernId}`); }); client.on('error', (error) => { console.error('Client error:', error); }); client.login(); ``` -------------------------------- ### REST Client Direct Access Example Source: https://context7.com/tav-gg/taverns.js/llms.txt Demonstrates how to use the RESTClient for direct API calls, including fetching bot info, tavern details, searching messages, and retrieving pinned messages. ```APIDOC ## REST Client Direct Access The RESTClient class provides direct access to all API endpoints for advanced use cases. It handles authentication, rate limiting with automatic retries, and provides typed responses. You can access it via client.rest or instantiate it separately. ### GET /users/@me #### Description Fetches information about the authenticated bot user. ### Method GET ### Endpoint `/users/@me` ### Response #### Success Response (200) - **id** (string) - The unique identifier of the bot user. - **name** (string) - The display name of the bot. - **user** (object) - User details. - **displayName** (string) - The display name of the user. ### GET /taverns/{tavernId} #### Description Fetches details for a specific tavern. ### Method GET ### Endpoint `/taverns/{tavernId}` ### Parameters #### Path Parameters - **tavernId** (string) - Required - The ID of the tavern to fetch. ### Response #### Success Response (200) - **name** (string) - The name of the tavern. - **memberCount** (integer) - The number of members in the tavern. ### POST /taverns/{tavernId}/messages/search #### Description Searches for messages within a specific tavern. ### Method POST ### Endpoint `/taverns/{tavernId}/messages/search` ### Parameters #### Path Parameters - **tavernId** (string) - Required - The ID of the tavern to search within. #### Request Body - **query** (string) - Required - The search query string. - **limit** (integer) - Optional - The maximum number of results to return. - **offset** (integer) - Optional - The number of results to skip. ### Response #### Success Response (200) - **total** (integer) - The total number of messages found. - **messages** (array) - An array of message objects. ### GET /taverns/{tavernId}/channels/{channelId}/pins #### Description Retrieves all pinned messages in a specific channel within a tavern. ### Method GET ### Endpoint `/taverns/{tavernId}/channels/{channelId}/pins` ### Parameters #### Path Parameters - **tavernId** (string) - Required - The ID of the tavern. - **channelId** (string) - Required - The ID of the channel. ### Response #### Success Response (200) - **messages** (array) - An array of pinned message objects. ### GET /taverns #### Description Fetches a list of taverns the authenticated bot is a member of. ### Method GET ### Endpoint `/taverns` ### Response #### Success Response (200) - **taverns** (array) - An array of tavern objects. - **name** (string) - The name of the tavern. ``` -------------------------------- ### Initialize Client with Options Source: https://github.com/tav-gg/taverns.js/blob/main/README.md Configure the client with various options such as token, API URLs, and reconnection settings. ```typescript const client = new Client({ token: 'tavbot_...', // Required (or pass to login()) apiUrl: '...', // Override REST API URL wsUrl: '...', // Override WebSocket URL autoReconnect: true, // Auto-reconnect on disconnect maxReconnectAttempts: 10, // Give up after N attempts heartbeatInterval: 30000, // Heartbeat interval (ms) }); await client.login(); ``` -------------------------------- ### Handle Bot Token using Environment Variables Source: https://github.com/tav-gg/taverns.js/blob/main/README.md Securely manage your bot token by using environment variables. ```typescript const client = new Client({ token: process.env.TAVERN_BOT_TOKEN }); ``` -------------------------------- ### Initialize and Connect Taverns.js Client Source: https://context7.com/tav-gg/taverns.js/llms.txt Initializes the Taverns.js Client with authentication token and connection options. Handles 'ready', 'error', 'disconnected', and 'reconnecting' events. Automatically manages reconnections and heartbeats. ```typescript import { Client } from 'taverns.js'; const client = new Client({ token: process.env.TAVERN_BOT_TOKEN, // Must start with 'tavbot_' autoReconnect: true, // Auto-reconnect on disconnect (default: true) maxReconnectAttempts: 10, // Max reconnect attempts before giving up heartbeatInterval: 30000, // Heartbeat interval in ms (default: 30000) }); client.on('ready', () => { console.log(`Logged in as ${client.user.displayName}`); console.log(`Connected to ${client.taverns.size} tavern(s)`); // Access cached data const firstTavern = client.taverns.first(); console.log(`First tavern: ${firstTavern?.name}`); }); client.on('error', (error) => { console.error('Client error:', error.message); }); client.on('disconnected', (code, reason) => { console.log(`Disconnected: ${code} - ${reason}`); }); client.on('reconnecting', (attempt) => { console.log(`Reconnecting... attempt ${attempt}`); }); // Connect to the gateway await client.login(); // Gracefully disconnect when done // client.destroy(); ``` -------------------------------- ### Accessing REST API endpoints Source: https://context7.com/tav-gg/taverns.js/llms.txt Demonstrates using the REST client via the main bot client and as a standalone instance for direct API operations. ```typescript import { Client, RESTClient } from 'taverns.js'; const client = new Client({ token: process.env.TAVERN_BOT_TOKEN }); client.on('ready', async () => { const tavernId = client.taverns.first()?.id; if (!tavernId) return; // Access via client.rest const botInfo = await client.rest.getSelf(); console.log(`Bot: ${botInfo.name}`); console.log(`User: ${botInfo.user.displayName}`); console.log(`Installed in ${botInfo.taverns.length} taverns`); // Get tavern details const tavern = await client.rest.getTavern(tavernId); console.log(`Tavern: ${tavern.name}, Members: ${tavern.memberCount}`); // Search messages const searchResults = await client.rest.searchMessages(tavernId, { query: 'hello', limit: 10, offset: 0, }); console.log(`Found ${searchResults.total} messages matching "hello"`); // Get pinned messages const channelId = client.channels.first()?.id; if (channelId) { const pinned = await client.rest.getPinnedMessages(tavernId, channelId); console.log(`${pinned.length} pinned messages`); } // Bulk delete messages (requires MANAGE_MESSAGES permission) // await client.rest.bulkDeleteMessages(tavernId, channelId, ['msg1', 'msg2', 'msg3']); // Add/remove reactions // await client.rest.addReaction(tavernId, 'message-id', '👍'); // await client.rest.removeReaction(tavernId, 'message-id', '👍'); }); // Standalone REST client usage const rest = new RESTClient(process.env.TAVERN_BOT_TOKEN!, 'https://api.tav.gg/api/v1'); const myTaverns = await rest.getMyTaverns(); console.log('My taverns:', myTaverns.map(t => t.name)); await client.login(); ``` -------------------------------- ### Handle Message Creation and Interactions Source: https://context7.com/tav-gg/taverns.js/llms.txt Listens for new messages, ignoring bot messages. Demonstrates replying, accessing tavern information, reacting to messages, and echoing content with message editing. ```typescript import { Client } from 'taverns.js'; const client = new Client({ token: process.env.TAVERN_BOT_TOKEN }); client.on('messageCreate', async (message) => { // Ignore messages from bots (including self) if (message.sender.isBot) return; if (message.sender.id === client.user.id) return; // Simple command handling if (message.content === '!ping') { await message.reply('Pong!'); return; } if (message.content === '!info') { const tavern = client.taverns.get(message.tavernId); await message.reply(`This tavern is "${tavern?.name}" with ${tavern?.memberCount} members.`); return; } if (message.content === '!react') { await message.react('👍'); return; } // Echo command with edit demonstration if (message.content.startsWith('!echo ')) { const content = message.content.slice(6); const sent = await message.reply(`You said: ${content}`); // Edit the message after 2 seconds setTimeout(async () => { await client.editMessage(message.tavernId, sent.id, `Edited: ${content}`); }, 2000); } }); client.on('messageUpdate', (event) => { console.log(`Message ${event.id} was edited at ${event.editedAt}`); }); client.on('messageDelete', (event) => { console.log(`Message ${event.id} was deleted in channel ${event.channelId}`); }); await client.login(); ``` -------------------------------- ### Configure Gateway Intents for Taverns.js Client Source: https://context7.com/tav-gg/taverns.js/llms.txt Specify which events your bot should receive by configuring GatewayIntents. Privileged intents like MESSAGE_CONTENT and TAVERN_MEMBERS require explicit enablement. Use preset combinations or individual intents. ```typescript import { Client, GatewayIntents } from 'taverns.js'; // Use specific intents for focused functionality const client = new Client({ token: process.env.TAVERN_BOT_TOKEN, intents: GatewayIntents.TAVERN_MESSAGES | // Receive message events GatewayIntents.MESSAGE_CONTENT | // Privileged: access message content GatewayIntents.TAVERN_MEMBERS | // Privileged: member join/leave events GatewayIntents.INTERACTIONS, // Slash command interactions }); // Or use preset combinations const defaultClient = new Client({ token: process.env.TAVERN_BOT_TOKEN, intents: GatewayIntents.DEFAULT, // All non-privileged intents }); const fullClient = new Client({ token: process.env.TAVERN_BOT_TOKEN, intents: GatewayIntents.ALL, // All intents including privileged }); // Available intents: // GatewayIntents.TAVERN_MESSAGES - Message create/edit/delete events // GatewayIntents.MESSAGE_CONTENT - Access to message content (privileged) // GatewayIntents.TAVERN_MEMBERS - Member join/leave events (privileged) // GatewayIntents.TAVERN_MODERATION - Moderation events // GatewayIntents.TAVERN_CHANNELS - Channel create/update/delete // GatewayIntents.TAVERN_THREADS - Thread events // GatewayIntents.TAVERN_FORUMS - Forum events // GatewayIntents.TAVERN_ROLES - Role events // GatewayIntents.TAVERN_SETTINGS - Tavern settings changes // GatewayIntents.TAVERN_EVENTS - Calendar event events // GatewayIntents.TAVERN_VOICE - Voice state updates // GatewayIntents.TAVERN_BROADCASTS - Broadcast messages // GatewayIntents.TAVERN_TYPING - Typing indicators // GatewayIntents.TAVERN_REACTIONS - Reaction events // GatewayIntents.TAVERN_PINS - Pin/unpin events // GatewayIntents.INTERACTIONS - Slash command interactions await client.login(); ``` -------------------------------- ### Registering and Handling Slash Commands Source: https://context7.com/tav-gg/taverns.js/llms.txt Register commands via the REST API and handle incoming interactions using the interactionCreate event. Use deferReply for long-running operations before sending a follow-up response. ```typescript import { Client, CommandOptionType } from 'taverns.js'; const client = new Client({ token: process.env.TAVERN_BOT_TOKEN }); client.on('ready', async () => { // Register slash commands await client.rest.registerCommands([ { name: 'ping', description: 'Check if the bot is responsive', }, { name: 'greet', description: 'Greet a user', options: [ { name: 'user', description: 'The user to greet', type: CommandOptionType.USER, required: true, }, { name: 'message', description: 'Custom greeting message', type: CommandOptionType.STRING, required: false, }, ], }, { name: 'roll', description: 'Roll a dice', options: [ { name: 'sides', description: 'Number of sides on the dice', type: CommandOptionType.INTEGER, required: false, choices: [ { name: '6-sided', value: 6 }, { name: '20-sided', value: 20 }, { name: '100-sided', value: 100 }, ], }, ], }, ]); console.log('Commands registered!'); }); client.on('interactionCreate', async (interaction) => { if (interaction.commandName === 'ping') { await interaction.reply('Pong! Bot is online.'); return; } if (interaction.commandName === 'greet') { const userId = interaction.options.user; const customMessage = interaction.options.message || 'Hello'; await interaction.reply(`${customMessage}, <@${userId}>!`); return; } if (interaction.commandName === 'roll') { // Defer for longer operations await interaction.deferReply(); const sides = interaction.options.sides || 6; const result = Math.floor(Math.random() * sides) + 1; // Follow up after deferring await interaction.followUp(`You rolled a **${result}** on a d${sides}!`); } }); await client.login(); ``` -------------------------------- ### Manage Channels with Taverns.js SDK Source: https://context7.com/tav-gg/taverns.js/llms.txt Use this snippet to create, update, list, and delete channels. It requires the client to be logged in and listens for channel-related events. ```typescript import { Client, ChannelType } from 'taverns.js'; const client = new Client({ token: process.env.TAVERN_BOT_TOKEN }); client.on('ready', async () => { const tavernId = client.taverns.first()?.id; if (!tavernId) return; // Create a new text channel const newChannel = await client.createChannel(tavernId, { name: 'bot-announcements', type: ChannelType.TEXT, topic: 'Automated announcements from the bot', slowModeSeconds: 30, isPrivate: false, }); console.log(`Created channel: ${newChannel.name} (${newChannel.id})`); // Update channel settings const updated = await client.updateChannel(tavernId, newChannel.id, { name: 'announcements', topic: 'Updated topic for announcements', slowModeSeconds: 60, }); console.log(`Updated channel: ${updated.name}`); // List all channels via REST const channels = await client.rest.getChannels(tavernId); for (const channel of channels) { console.log(`- ${channel.name} (${channel.type})`); } // Delete a channel // await client.deleteChannel(tavernId, newChannel.id); }); // Listen for channel events client.on('channelCreate', (channel) => { console.log(`Channel created: ${channel.name}`); }); client.on('channelUpdate', (event) => { console.log(`Channel ${event.id} updated`); }); client.on('channelDelete', (event) => { console.log(`Channel ${event.id} deleted`); }); await client.login(); ``` -------------------------------- ### Interact with Collections (Taverns, Channels) Source: https://github.com/tav-gg/taverns.js/blob/main/README.md Utilize collection methods like find, filter, first, and map for data retrieval and manipulation. ```typescript // Taverns collection (extends Map) const tavern = client.taverns.find(t => t.name === 'My Tavern'); const textChannels = client.channels.filter(c => c.type === 'TEXT'); const firstTavern = client.taverns.first(); const names = client.taverns.map(t => t.name); ``` -------------------------------- ### ActionableMessage Methods Source: https://github.com/tav-gg/taverns.js/blob/main/README.md Helper methods available on messages received via the messageCreate event. ```APIDOC ## ActionableMessage Methods ### Description Helper methods attached to message objects for quick interaction. ### Methods - **message.reply(content)**: Reply to the message. - **message.edit(content)**: Edit the message. - **message.delete()**: Delete the message. - **message.pin()**: Pin the message. - **message.unpin()**: Unpin the message. - **message.react(emoji)**: Add a reaction. ``` -------------------------------- ### Manage Threads with Taverns.js Client Source: https://context7.com/tav-gg/taverns.js/llms.txt This snippet demonstrates creating and managing threads within channels, including setting archive durations and privacy. Ensure the client is logged in and has valid tavern and channel IDs. ```typescript import { Client } from 'taverns.js'; const client = new Client({ token: process.env.TAVERN_BOT_TOKEN }); client.on('ready', async () => { const tavernId = client.taverns.first()?.id; const channel = client.channels.find(c => c.type === 'TEXT'); if (!tavernId || !channel) return; // Create a thread from a message const thread = await client.rest.createThread(tavernId, channel.id, { name: 'Discussion Thread', rootMessageId: 'message-id-to-thread-from', // Optional starterMessage: 'Welcome to this discussion!', autoArchiveDuration: 1440, // Archive after 24 hours of inactivity isPrivate: false, }); console.log(`Created thread: ${thread.name} (${thread.id})`); // List threads in a channel const threads = await client.rest.getThreads(tavernId, channel.id); for (const t of threads) { console.log(`- ${t.name} (archived: ${t.isArchived})`); } // Get all active threads in the tavern const activeThreads = await client.rest.getActiveThreads(tavernId); console.log(`${activeThreads.length} active threads`); // Send a message to a thread (threads are channels) await client.sendMessage(tavernId, thread.id, 'Hello from the thread!'); }); client.on('threadCreate', (channel) => { console.log(`Thread created: ${channel.name}`); }); client.on('threadArchived', (event) => { console.log('Thread was archived:', event); }); await client.login(); ``` -------------------------------- ### Client Methods Source: https://github.com/tav-gg/taverns.js/blob/main/README.md Core methods for the taverns.js client to manage authentication, messages, channels, and members. ```APIDOC ## Client Methods ### Description Methods available on the main client instance for interacting with the taverns API. ### Methods - **login(token?)**: Connect and authenticate. - **destroy()**: Disconnect and clean up. - **sendMessage(tavernId, channelId, options)**: Send a message. - **editMessage(tavernId, messageId, options)**: Edit a message. - **deleteMessage(tavernId, messageId)**: Delete a message. - **getMessages(tavernId, channelId, options?)**: Fetch messages. - **createChannel(tavernId, options)**: Create a channel. - **updateChannel(tavernId, channelId, options)**: Update a channel. - **deleteChannel(tavernId, channelId)**: Delete a channel. - **getMembers(tavernId, options?)**: List tavern members. - **getMember(tavernId, userId)**: Get a specific member. ``` -------------------------------- ### Make Direct REST API Calls Source: https://github.com/tav-gg/taverns.js/blob/main/README.md Access the REST client directly for advanced use cases like fetching channels, members, or sending messages. ```typescript // Direct REST calls const channels = await client.rest.getChannels(tavernId); const members = await client.rest.getMembers(tavernId); const message = await client.rest.sendMessage(tavernId, channelId, { content: 'Hello!', }); ``` -------------------------------- ### Verify Webhook Signature with Express Source: https://context7.com/tav-gg/taverns.js/llms.txt Implement webhook signature verification for incoming requests. Ensure the 'x-tavern-signature' and 'x-tavern-timestamp' headers are present and valid. The raw request body is required for verification. ```typescript import express from 'express'; import { verifyWebhookSignature } from 'taverns.js'; const app = express(); // Use raw body parser for webhook endpoint app.use('/webhook', express.raw({ type: 'application/json' })); app.post('/webhook', (req, res) => { const signature = req.headers['x-tavern-signature'] as string; const timestamp = req.headers['x-tavern-timestamp'] as string; const secret = process.env.WEBHOOK_SECRET!; const isValid = verifyWebhookSignature( req.body, // Raw body as Buffer signature, // Format: "sha256=" secret, // Your webhook signing secret timestamp, // Unix timestamp in milliseconds 300, // Max age in seconds (default: 5 minutes) ); if (!isValid) { console.error('Invalid webhook signature'); return res.status(401).send('Invalid signature'); } // Parse and handle the event const event = JSON.parse(req.body.toString()); console.log(`Received webhook event: ${event.event}`); console.log('Event data:', event.data); switch (event.event) { case 'tavern_message': console.log(`New message: ${event.data.content}`); break; case 'member_joined': console.log(`New member: ${event.data.displayName}`); break; default: console.log('Unknown event type'); } res.status(200).send('OK'); }); app.listen(3000, () => { console.log('Webhook server listening on port 3000'); }); ``` -------------------------------- ### Role Management API Source: https://context7.com/tav-gg/taverns.js/llms.txt Endpoints for managing roles within a tavern, including creation, updates, deletion, and member role assignment. ```APIDOC ## GET /taverns/{tavernId}/roles ### Description Retrieves a list of all roles within a specific tavern. ### Method GET ### Endpoint /taverns/{tavernId}/roles ### Parameters #### Path Parameters - **tavernId** (string) - Required - The ID of the tavern. ## POST /taverns/{tavernId}/roles ### Description Creates a new role in the specified tavern. ### Method POST ### Endpoint /taverns/{tavernId}/roles ### Parameters #### Path Parameters - **tavernId** (string) - Required - The ID of the tavern. #### Request Body - **name** (string) - Required - Name of the role. - **color** (string) - Optional - Hex color code. - **permissions** (string) - Optional - Permission bitfield string. - **isMentionable** (boolean) - Optional - Whether the role is mentionable. ## PATCH /taverns/{tavernId}/roles/{roleId} ### Description Updates an existing role's properties. ### Method PATCH ### Endpoint /taverns/{tavernId}/roles/{roleId} ### Parameters #### Path Parameters - **tavernId** (string) - Required - The ID of the tavern. - **roleId** (string) - Required - The ID of the role. #### Request Body - **name** (string) - Optional - New name for the role. - **color** (string) - Optional - New hex color code. ``` -------------------------------- ### Thread Management API Source: https://context7.com/tav-gg/taverns.js/llms.txt Endpoints for creating and managing threads within channels, including listing active threads. ```APIDOC ## POST /taverns/{tavernId}/channels/{channelId}/threads ### Description Creates a new thread within a channel. ### Method POST ### Endpoint /taverns/{tavernId}/channels/{channelId}/threads ### Parameters #### Path Parameters - **tavernId** (string) - Required - The ID of the tavern. - **channelId** (string) - Required - The ID of the channel. #### Request Body - **name** (string) - Required - Name of the thread. - **rootMessageId** (string) - Optional - ID of the message to thread from. - **starterMessage** (string) - Optional - Initial message content. - **autoArchiveDuration** (number) - Optional - Minutes until inactivity archive. - **isPrivate** (boolean) - Optional - Whether the thread is private. ## GET /taverns/{tavernId}/channels/{channelId}/threads ### Description Lists all threads in a specific channel. ### Method GET ### Endpoint /taverns/{tavernId}/channels/{channelId}/threads ### Parameters #### Path Parameters - **tavernId** (string) - Required - The ID of the tavern. - **channelId** (string) - Required - The ID of the channel. ## GET /taverns/{tavernId}/threads/active ### Description Retrieves all active threads within a tavern. ### Method GET ### Endpoint /taverns/{tavernId}/threads/active ### Parameters #### Path Parameters - **tavernId** (string) - Required - The ID of the tavern. ``` -------------------------------- ### Manage Members with Taverns.js SDK Source: https://context7.com/tav-gg/taverns.js/llms.txt Use this snippet to fetch, cache, and manage tavern members, including performing moderation actions. It requires the client to be logged in and listens for member join/leave events. ```typescript import { Client } from 'taverns.js'; const client = new Client({ token: process.env.TAVERN_BOT_TOKEN }); client.on('ready', async () => { const tavernId = client.taverns.first()?.id; if (!tavernId) return; // Fetch members (results are cached) const members = await client.getMembers(tavernId, { limit: 100 }); console.log(`Fetched ${members.size} members`); // Iterate over members for (const [userId, member] of members) { console.log(`- ${member.user.displayName} (${member.status})`); if (member.roles) { console.log(` Roles: ${member.roles.map(r => r.name).join(', ')}`); } } // Get a specific member const specificMember = await client.getMember(tavernId, 'user-id-here'); console.log(`Found: ${specificMember.user.displayName}`); // Moderation actions (requires appropriate permissions) // await client.rest.kickMember(tavernId, 'user-id', 'Reason for kick'); // await client.rest.banMember(tavernId, 'user-id', 'Reason for ban'); // await client.rest.unbanMember(tavernId, 'user-id'); }); // Listen for member events client.on('memberJoin', (event) => { console.log(`${event.displayName} joined tavern ${event.tavernId}`); }); client.on('memberLeave', (event) => { console.log(`User ${event.userId} left tavern ${event.tavernId}`); }); await client.login(); ``` -------------------------------- ### Check Permissions using PermissionsBitField Source: https://github.com/tav-gg/taverns.js/blob/main/README.md Instantiate PermissionsBitField with granted permissions and check for specific permissions like SEND_MESSAGES or ADMINISTRATOR. ```typescript import { PermissionsBitField } from 'taverns.js'; const perms = new PermissionsBitField(tavern.grantedPermissions); if (perms.has('SEND_MESSAGES')) { // Bot can send messages } if (perms.has('ADMINISTRATOR')) { // Bot has full admin access } console.log(perms.toArray()); // ['VIEW_CHANNELS', 'SEND_MESSAGES', 'READ_MESSAGE_HISTORY', ...] ``` -------------------------------- ### Manage Permissions with PermissionsBitField Source: https://context7.com/tav-gg/taverns.js/llms.txt Use PermissionsBitField to check, add, or remove permissions using BigInt bitfields. The ADMINISTRATOR flag automatically grants all other permissions. ```typescript import { Client, PermissionsBitField, PermissionFlags } from 'taverns.js'; const client = new Client({ token: process.env.TAVERN_BOT_TOKEN }); client.on('ready', () => { for (const [tavernId, tavern] of client.taverns) { const perms = new PermissionsBitField(tavern.grantedPermissions); console.log(`\nTavern: ${tavern.name}`); console.log(`Permissions: ${perms.toArray().join(', ')}`); // Check individual permissions if (perms.has('ADMINISTRATOR')) { console.log('Bot has full admin access'); } if (perms.has('SEND_MESSAGES')) { console.log('Bot can send messages'); } // Check multiple permissions if (perms.hasAll('SEND_MESSAGES', 'EMBED_LINKS', 'ATTACH_FILES')) { console.log('Bot can send rich content'); } if (perms.hasAny('KICK_MEMBERS', 'BAN_MEMBERS')) { console.log('Bot has moderation powers'); } } }); // Working with permission bitfields const customPerms = new PermissionsBitField(0n) .add('VIEW_CHANNELS') .add('SEND_MESSAGES') .add('READ_MESSAGE_HISTORY'); console.log('Custom permissions:', customPerms.toArray()); console.log('Bitfield value:', customPerms.toString()); // Remove a permission const reduced = customPerms.remove('SEND_MESSAGES'); console.log('After removal:', reduced.toArray()); // Access static flags console.log('Send messages bit:', PermissionsBitField.FLAGS.SEND_MESSAGES); await client.login(); ``` -------------------------------- ### Manage Roles with Taverns.js Client Source: https://context7.com/tav-gg/taverns.js/llms.txt Use this snippet to perform CRUD operations on roles and manage member role assignments. Ensure the client is logged in and has access to the tavern. ```typescript import { Client, PermissionsBitField } from 'taverns.js'; const client = new Client({ token: process.env.TAVERN_BOT_TOKEN }); client.on('ready', async () => { const tavernId = client.taverns.first()?.id; if (!tavernId) return; // List all roles const roles = await client.rest.getRoles(tavernId); for (const role of roles) { const perms = new PermissionsBitField(role.permissions); console.log(`Role: ${role.name}, Color: ${role.color}, Perms: ${perms.toArray().length}`); } // Create a new role const moderatorPerms = new PermissionsBitField(0n) .add('KICK_MEMBERS') .add('MUTE_MEMBERS') .add('MANAGE_MESSAGES'); const newRole = await client.rest.createRole(tavernId, { name: 'Moderator', color: '#E74C3C', permissions: moderatorPerms.toString(), isMentionable: true, }); console.log(`Created role: ${newRole.name}`); // Update a role const updatedRole = await client.rest.updateRole(tavernId, newRole.id, { name: 'Senior Moderator', color: '#9B59B6', }); // Assign role to a member // await client.rest.addMemberRole(tavernId, 'user-id', newRole.id); // Remove role from a member // await client.rest.removeMemberRole(tavernId, 'user-id', newRole.id); // Delete a role // await client.rest.deleteRole(tavernId, newRole.id); }); client.on('roleUpdate', (role) => { console.log(`Role updated: ${role.name}`); }); client.on('roleDelete', (event) => { console.log(`Role ${event.id} deleted from tavern ${event.tavernId}`); }); await client.login(); ``` -------------------------------- ### Sending Messages and Embeds with Taverns.js Source: https://context7.com/tav-gg/taverns.js/llms.txt Use the Client class to send text messages and rich embeds. The EmbedBuilder provides a fluent interface for constructing complex message content. ```typescript import { Client, EmbedBuilder } from 'taverns.js'; const client = new Client({ token: process.env.TAVERN_BOT_TOKEN }); client.on('ready', async () => { const tavernId = client.taverns.first()?.id; const channel = client.channels.find(c => c.name === 'general'); if (!tavernId || !channel) return; // Simple text message await client.sendMessage(tavernId, channel.id, 'Hello, tavern!'); // Message with options await client.sendMessage(tavernId, channel.id, { content: 'Check out this info!', metadata: { source: 'bot-announcement' }, }); // Message with rich embed const embed = new EmbedBuilder() .setTitle('Server Stats') .setDescription('Current server statistics') .setColor('#5865F2') .addField('Members', '150', true) .addField('Channels', '12', true) .addField('Roles', '8', true) .setFooter('Updated just now') .setThumbnail('https://example.com/icon.png') .setImage('https://example.com/banner.png'); await client.sendMessage(tavernId, channel.id, { content: 'Here are the latest stats:', embeds: [embed.toJSON()], }); }); await client.login(); ``` -------------------------------- ### Manipulate Data with Collection Source: https://context7.com/tav-gg/taverns.js/llms.txt The Collection class extends Map with array-like utility methods for filtering, mapping, and sorting cached data. It supports initialization from arrays using a key selector. ```typescript import { Client, Collection } from 'taverns.js'; const client = new Client({ token: process.env.TAVERN_BOT_TOKEN }); client.on('ready', () => { // Find a specific tavern const myTavern = client.taverns.find(t => t.name === 'My Community'); console.log('Found tavern:', myTavern?.name); // Filter channels by type const textChannels = client.channels.filter(c => c.type === 'TEXT'); console.log(`Found ${textChannels.size} text channels`); // Map tavern names const tavernNames = client.taverns.map(t => t.name); console.log('All taverns:', tavernNames.join(', ')); // Check conditions const hasLargeTavern = client.taverns.some(t => t.memberCount > 1000); console.log('Has large tavern:', hasLargeTavern); const allPublic = client.taverns.every(t => t.isPublic === true); console.log('All taverns public:', allPublic); // Get first/last/random const firstChannel = client.channels.first(); const lastChannel = client.channels.last(); const randomChannel = client.channels.random(); // Get multiple const firstThree = client.channels.first(3); const lastTwo = client.channels.last(2); // Reduce to calculate total members const totalMembers = client.taverns.reduce((sum, t) => sum + t.memberCount, 0); console.log('Total members across all taverns:', totalMembers); // Sort channels by position const sorted = client.channels.sort((a, b) => a.position - b.position); // Convert to arrays const channelArray = client.channels.toArray(); const channelIds = client.channels.keyArray(); }); // Create collection from array const items = [ { id: '1', name: 'Alpha' }, { id: '2', name: 'Beta' }, ]; const collection = Collection.from(items, item => item.id); console.log(collection.get('1')); // { id: '1', name: 'Alpha' } await client.login(); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.