@recoilapp/recoil.js
v1.2.1
Published
The official Node.js API wrapper for the RecoilApp Bot API — build powerful bots with ease.
Downloads
450
Readme
recoil.js
The official Node.js API wrapper for the RecoilApp Bot API — inspired by discord.js.
Build powerful bots for RecoilApp with a clean, fully typed, object-oriented interface.
Features
- ⚡ Full TypeScript — strict typings, enums, interfaces for every entity
- 🏗️ discord.js-style architecture — Client → Managers → Structures
- 📦 Collection caching — in-memory entity caching with a powerful
Collectionclass - 🔒 Permission bitfields — 37 permission flags with preset helper methods
- 🎯 Intent system — 16 intents to control what data the bot receives
- 🔄 Rate limiting — automatic per-route and global rate limit handling
- 📝 JSDoc documented — full documentation on every class, method, and property
- 🛡️ Error hierarchy — typed API errors, permission errors, auth errors, rate limit errors
Installation
npm install recoil.jsRequirements: Node.js ≥ 18.0.0 (uses native fetch)
Quick Start
import { RecoilClient, Intents } from 'recoil.js';
const client = new RecoilClient({
intents: Intents.Flags.Servers | Intents.Flags.ServerMessages | Intents.Flags.MessageContent,
});
client.on('ready', () => {
console.log(`✅ Logged in as ${client.user!.username}`);
console.log(`📡 Serving ${client.servers.size} servers`);
});
client.on('debug', (info) => {
console.log(`[DEBUG] ${info}`);
});
client.login(process.env.BOT_TOKEN!);Usage Examples
Listing Servers
const servers = await client.servers.list();
for (const [id, server] of servers) {
console.log(`${server.name} — ${server.memberCount} members`);
}Fetching & Sending Messages
// Fetch a channel
const channel = await client.servers.cache.first()!.channels.fetch('channel-id');
// Send a message
const message = await channel.send({ content: 'Hello from recoil.js!' });
// Reply to a message
await message.reply({ content: 'This is a threaded reply.' });
// Edit a message
await message.edit('Updated content!');
// Delete a message
await message.delete();Managing Members
const server = await client.servers.fetch('server-id');
const members = await server.members.list({ limit: 50 });
for (const [id, member] of members) {
console.log(`${member.displayTag} — joined ${member.joinedAt}`);
}
// Kick a member
await server.members.kick('user-id', 'Violated rules');
// Ban a member
await server.bans.create('user-id', {
reason: 'Spamming',
delete_message_days: 7,
});Working with Roles
// Create a role
const role = await server.roles.create({
name: 'VIP',
color: '#00BFBF',
is_hoisted: true,
});
// Assign role to member
await server.members.addRole('user-id', role.id);
// Check permissions
if (role.permissions.has('ManageMessages')) {
console.log('This role can manage messages');
}Using Permissions
import { Permissions } from 'recoil.js';
// Create a permission set
const perms = new Permissions(
Permissions.Flags.ViewChannels |
Permissions.Flags.SendMessages |
Permissions.Flags.ManageMessages
);
// Check specific permissions
perms.has('SendMessages'); // true
perms.has('BanMembers'); // false
perms.isAdministrator; // false
// Use presets
const modPerms = new Permissions(Permissions.Presets.Moderator);
modPerms.toArray(); // ['ViewChannels', 'SendMessages', 'BanMembers', ...]Channels, Pins & Threads
// Create a channel
const channel = await server.channels.create({
name: 'bot-commands',
type: 'text',
topic: 'Run bot commands here',
});
// Pin a message
await channel.pins.add('message-id');
// Create a thread
const thread = await channel.threads.create({
name: 'Bug Discussion',
parent_message_id: 'msg-id',
auto_archive_minutes: 1440,
});Reactions
// React to a message
await message.react('👍');
// Remove reaction
await message.unreact('👍');
// List all reactions
const reactions = await message.reactions.list();
for (const reaction of reactions) {
console.log(`${reaction.emoji}: ${reaction.count} reactions`);
}Invites & Bans
// Create an invite
const invite = await server.invites.create({
max_uses: 10,
max_age_seconds: 86400, // 24 hours
});
console.log(`Invite URL: ${invite.url}`);
// List bans
const bans = await server.bans.list();
for (const [id, ban] of bans) {
console.log(`${ban.username} — ${ban.reason ?? 'No reason'}`);
}Custom Emojis & Webhooks
// List emojis
const emojis = await server.emojis.list();
const pepe = emojis.find(e => e.name === 'pepe');
// List webhooks
const webhooks = await server.webhooks.list();
for (const [id, wh] of webhooks) {
console.log(`${wh.name} → #${wh.channelName}`);
}Bulk Operations
// Bulk delete messages (max 100)
const messages = await channel.messages.list({ limit: 50 });
const deleted = await channel.messages.bulkDelete(messages.toKeyArray());
console.log(`Deleted ${deleted} messages`);Gateway & API Info
const gateway = await client.fetchGateway();
console.log(`Gateway URL: ${gateway.url}`);
const info = await client.fetchApiInfo();
console.log(`API Version: ${info.version}`);Architecture
RecoilClient
├── rest: RESTManager ← HTTP client with rate limiting
├── user: ClientUser ← The authenticated bot user
├── servers: ServerManager ← Manage & cache servers
│ └── Server
│ ├── channels: ChannelManager
│ │ └── Channel
│ │ ├── messages: MessageManager
│ │ │ └── Message
│ │ │ └── reactions: ReactionManager
│ │ ├── threads: ThreadManager
│ │ │ └── Thread
│ │ └── pins: PinManager
│ ├── members: MemberManager
│ │ └── Member
│ ├── roles: RoleManager
│ │ └── Role
│ ├── bans: BanManager
│ │ └── Ban
│ ├── invites: InviteManager
│ │ └── Invite
│ ├── emojis: EmojiManager
│ │ └── Emoji
│ └── webhooks: WebhookManager
│ └── Webhook
└── intents: IntentsBitFieldAPI Coverage
| Category | Endpoints | Status |
|----------|-----------|--------|
| Bot User | /@me GET/PATCH | ✅ |
| Servers | List, Fetch, Leave | ✅ |
| Channels | CRUD | ✅ |
| Messages | CRUD + Bulk Delete | ✅ |
| Members | List, Fetch, Edit, Kick | ✅ |
| Roles | CRUD + Assign/Remove | ✅ |
| Reactions | Add, Remove, List | ✅ |
| Pins | List, Pin, Unpin | ✅ |
| Bans | List, Create, Remove | ✅ |
| Invites | List, Create, Delete | ✅ |
| Threads | List, Create | ✅ |
| Custom Emojis | List | ✅ |
| Webhooks | List | ✅ |
| Gateway | Info | ✅ |
| API Info | Version/Limits | ✅ |
Error Handling
import { RecoilAPIError, PermissionError, RateLimitError } from 'recoil.js';
try {
await channel.send({ content: 'Hello!' });
} catch (error) {
if (error instanceof PermissionError) {
console.log(`Missing permissions: ${error.missing.join(', ')}`);
} else if (error instanceof RateLimitError) {
console.log(`Rate limited! Retry after ${error.retryAfter}ms`);
} else if (error instanceof RecoilAPIError) {
console.log(`API Error ${error.status}: ${error.message}`);
}
}Collection
The Collection class extends Map with powerful utility methods:
const servers = await client.servers.list();
servers.first(); // First server
servers.last(); // Last server
servers.random(); // Random server
servers.find(s => s.name === 'My Server');
servers.filter(s => s.memberCount > 100);
servers.map(s => s.name);
servers.sort((a, b) => b.memberCount - a.memberCount);
servers.partition(s => s.isPublic); // [public, private]
servers.toArray(); // Server[]Permissions & Intents
Permission Flags (37 total)
| Flag | Bit | Category | |------|-----|----------| | ViewChannels | 0 | General | | ManageChannels | 1 | General | | ManageServer | 2 | General | | ManageRoles | 3 | General | | ManageEmojis | 4 | General | | ViewAuditLog | 5 | General | | CreateInvites | 6 | General | | ChangeNickname | 7 | General | | ManageNicknames | 8 | General | | KickMembers | 9 | Moderation | | BanMembers | 10 | Moderation | | ModerateMembers | 11 | Moderation | | SendMessages | 12 | Text | | ManageMessages | 17 | Text | | ... | ... | ... | | Administrator | 36 | Advanced |
Intent Flags (16 total)
| Intent | Bit | Privileged? | |--------|-----|------------| | Servers | 0 | No | | ServerMembers | 1 | ⚠️ Yes | | ServerPresences | 8 | ⚠️ Yes | | ServerMessages | 9 | No | | MessageContent | 15 | ⚠️ Yes | | ... | ... | ... |
Configuration
const client = new RecoilClient({
// Required: which events to receive
intents: Intents.Flags.Servers | Intents.Flags.ServerMessages,
// Optional: custom API base URL
apiBaseUrl: 'https://recoilapp.com/api/v1',
// Optional: whether to auto-fetch servers on login
fetchServersOnReady: true,
// Optional: REST client overrides
rest: {
timeout: 15000, // Request timeout (ms)
maxRetries: 3, // Retry attempts on 5xx
retryDelay: 1000, // Base delay for exponential backoff
},
});TypeScript Support
recoil.js is written in TypeScript and ships with full type declarations:
- All classes, methods, and properties have JSDoc documentation
- All API response shapes have typed interfaces
- Enum values for channel types, permissions, intents, etc.
- Generic
Collection<K, V>class
import type {
Snowflake,
APIMessage,
APIServer,
APIChannel,
ClientOptions,
} from 'recoil.js';License
MIT © RecoilApp Team
