The official SDK for building bots on the Sesli platform.
npm install @sesli/botRequires Node.js 18 or later.
Get your bot token from the Developer Portal. Don't hardcode it — use a .env file.
BOT_TOKEN=your_token_here
import { Client } from '@sesli/bot';
const client = new Client({
token: process.env.BOT_TOKEN!,
});
client.on('ready', (data) => {
console.log(`${data.bot.username} is ready on ${data.servers.length} servers`);
});
client.login();client.on('messageCreate', (message) => {
if (message.author.isBot) return;
if (message.content === '!ping') {
client.messages.send(message.channelId, {
content: 'Pong!',
});
}
});Commands need to be registered inside the ready handler — client.commands isn't available before that.
import { Client, SlashCommandBuilder } from '@sesli/bot';
const client = new Client({ token: process.env.BOT_TOKEN! });
client.on('ready', async () => {
const pingCommand = new SlashCommandBuilder()
.setName('ping')
.setDescription('Check the bot latency')
.toJSON();
await client.commands.register(pingCommand);
});
client.on('interactionCreate', async (interaction) => {
if (interaction.commandName === 'ping') {
await interaction.reply({ content: 'Pong!' });
}
});
client.login();const sayCommand = new SlashCommandBuilder()
.setName('say')
.setDescription('Make the bot say something')
.addStringOption((opt) =>
opt
.setName('text')
.setDescription('The text to say')
.setRequired(true)
)
.toJSON();Reading the option inside the interaction handler:
const text = interaction.options.getString('text');client.messages.send(channelId, {
embeds: [
{
title: 'Hello',
description: 'This is an embed',
color: 0x5865f2,
fields: [
{ name: 'Field 1', value: 'Value 1', inline: true },
{ name: 'Field 2', value: 'Value 2', inline: true },
],
},
],
});client.voice lets your bot join voice channels and play any audio you provide as a raw PCM stream.
Step 1 — find out which voice channel the user is in
const voiceState = await client.voice.getUserChannel(interaction.member.userId);
if (!voiceState) {
await interaction.reply({ content: 'You need to be in a voice channel first.', ephemeral: true });
return;
}Step 2 — join and play
await interaction.deferReply();
const connection = await client.voice.join(voiceState.channelId);
// Produce a raw PCM stream — this part is up to you.
// Requirements: signed 16-bit LE, 48 kHz, stereo (2ch).
// Common approach: pipe audio through ffmpeg with -f s16le -ar 48000 -ac 2.
const pcmStream = yourAudioSource();
await connection.play(pcmStream); // resolves when the stream ends
await client.voice.leave(voiceState.channelId);
await interaction.editReply('Done.');Shorthand — join + play in one call
await client.voice.playIn(voiceState.channelId, pcmStream);Stop playback early
const connection = await client.voice.join(channelId);
connection.play(stream); // don't await — let it run in the background
// Stop whenever you need to
connection.stop();| Method | Returns | Description |
|---|---|---|
getUserChannel(userId) |
{ channelId, serverId } | null |
Voice channel the user is currently in |
join(channelId) |
VoiceConnection |
Join a channel (returns existing connection if already in) |
leave(channelId) |
void |
Leave a channel and clean up |
leaveAll() |
void |
Leave all active channels (called automatically on destroy()) |
playIn(channelId, stream) |
void |
Join + play in one call |
| Member | Type | Description |
|---|---|---|
play(pcmStream) |
Promise<void> |
Play a PCM stream; resolves when the stream ends |
stop() |
void |
Abort current playback |
disconnect() |
Promise<void> |
Stop + leave LiveKit room |
isPlaying |
boolean |
Whether audio is currently playing |
channelId |
string |
The channel this connection belongs to |
Your audio source must produce raw audio with these exact parameters:
| Parameter | Value |
|---|---|
| Encoding | Signed 16-bit little-endian (s16le) |
| Sample rate | 48 000 Hz |
| Channels | 2 (stereo) |
Any Readable stream that outputs bytes matching these parameters works. A typical setup pipes audio through ffmpeg -f s16le -ar 48000 -ac 2.
| Event | When it fires |
|---|---|
ready |
Bot connected and ready |
messageCreate |
New message received |
messageUpdate |
Message was edited |
messageDelete |
Message was deleted |
interactionCreate |
Slash command was used |
serverMemberAdd |
Someone joined a server |
serverMemberRemove |
Someone left a server |
disconnect |
Connection dropped |
reconnect |
Reconnected to the gateway |
error |
An error occurred |
If something isn't connecting properly, pass debug: true to log all gateway traffic.
const client = new Client({
token: process.env.BOT_TOKEN!,
debug: true,
});MIT