oneki framework for discord.js


Keywords
oneki, djs, discord.js, discordjs, discord-bot, bot, discord-api, discord, framework, node, nodejs, node.js
License
MIT
Install
npm install offdjs@1.1.1

Documentation


OFFDJS


Discord server npm version npm downloads

About

offdjs is a small framework that uses discord.js created to solve the needs and simplify the development of the Oneki bot made public so that anyone can create their own bot in a few lines of code

  • little
  • fast
  • easy to use

Installation

Node.js 16.9.0 or newer is required.

npm install off

Example usage

Install discord.js:

npm i offdjs

create a script in your package.json that runs offdjs:

{
    "scripts": {
        "start": "offdjs"
    }
}

Set your token in an .env file at the root of the project (according to discord.js specs)

DISCORD_TOKEN=your_discord_token

At this point you can run your script and the bot will turn on without requiring any configuration

npm start

Events

To load events you just need to create a folder in the root called events and offdjs will read all the files whose name has the following structure:

eventName.event.js

offdjs can read subfolders within the events folder for easy event management

example:

.
├── events
│   ├── ready.event.js
│   └── guild
│       ├── guildMemberAdd.event.js
│       └── guildMemberRemove.event.js
├── node_modules
│   └── ...
├── .env
└── package.json

The script should export by default a function which will be executed with the parameters of said event

export default function ready(client) {
    console.log('ready')
}

Commands

To load commands you just need to create a folder in the root called commands and offdjs will read all the files whose name has the following structure:

commandName.command.js

offdjs can read subfolders within the commands folder to make managing commands easier

example:

.
├── commands
│   ├── ping.command.js
│   └── actions
│       ├── punch.command.js
│       └── kiss.command.js
├── node_modules
│   └── ...
├── .env
└── package.json

The script must export a default class that extends from the Command class provided by offdjs which is initialized in the super with at least the name that must match the name put in the file and a description, both properties are objects with properties named as local Discord API, en-US at least (this will change in the future)

The Comand class has an ChatInputCommandInteraction method with a parameter of type ChatInputCommandInteraction<'cached'> which is executed every time it receives a command interaction with the same name set which you can override to execute and respond to said interaction

example:

import { Command } from 'offdjs'

export default class Ping extends Command {
    constructor() {
        super({
            name: {
                'en-US': 'ping'
            },
            description: {
                'en-US': 'Ping the bot'
            },
            global: false
        })
    }

    async ChatInputCommandInteraction(interaction) {
        interaction.reply('Pong!')
    }
}

If you want to abstract the functionality of the command you can create a folder called interactions and export a function chatInputCommandInteraction in a file with the name of the command, it will receive the interaction as a parameter of type ChatInputCommandInteraction<'cached'>

example:

.
├── interactions
│   └── ping.js
├── node_modules
│   └── ...
├── .env
└── package.json
//ping.js

export function chatInputCommandInteraction(interaction) {
    interaction.reply('Pong!')
}

If you use subcommands you can create folders to use them as if the command name were a path; /test ping => interactions/test/ping.js

example:

.
├── interactions
│   └── test
│       └── ping.js
├── node_modules
│   └── ...
├── .env
└── package.json
//ping.js

export function chatInputCommandInteraction(interaction) {
    interaction.reply('Pong!')
}

Buttons

To receive button interactions you can create a folder called interactions and export a function buttonInteraction in a file with the name of the button id, it will receive the interaction as a parameter of type ButtonInteraction<'cached'>

example:

.
├── interactions
│   └── custom_id.js
├── node_modules
│   └── ...
├── .env
└── package.json
//ping.js

export function buttonInteraction(interaction) {
    interaction.reply('you clicked the button')
}

if you need to use arguments in the button, you can pass them by the customId as a string separating them with : (you can custom interactionSplit). This also allows you to create subinteractions with the commands that like the chatInputCommandInteraction will split the logic into different files for example interaction.customId = 'test:yes' => interactions/test/yes.js. The arguments passed by id will be received along with the interaction

example:

.
├── interactions
│   ├── test.js
│   └── test
│       └── yes.js
├── node_modules
│   └── ...
├── .env
└── package.json
//test.js

export function buttonInteraction(interaction, _, choice) {
    // this is executed in case the interaction.customId
    // is 'test:yes' or 'test:no'
    interaction.reply('you selected ' + choice)
    // choice contains a 'yes' or 'no'
}
//test/yes.js

export function buttonInteraction(interaction) {
    // this is executed only in case
    // the interaction.customId is 'test:yes'
    interaction.reply('you selected yes')
}

Client

To obtain the client, offdjs exports the client already initialized as default so if it requires. this is initialized by running offdjs

example:

import client, { Command } from 'offdjs'

client.on('ready', () => console.log('ready'))

executing index file

As you may have noticed, there is no index file to run, however, if required, you can easily create an index file to run extra processes like connecting to a database

You only have to import the client and use the login method in said file and you can change your script in the package.json or execute said file

example:

//index.js

// import the client
import client from 'offdjs'

// others imports
import mongoose from 'mongoose'

// login the client (important)
client.login()

// connect to de db or others process
await mongoose.connect('mongodb://localhost/my_database')

If you run index.js it works without problems

node index.js

Config

So far no configuration has been required, however, if you need to touch client configurations you can generate a offdjs.config.js file in the root where you export by default an object with properties to pass to the client, this step is optional

example:

.
├── offdjs.config.js
├── node_modules
│   └── ...
├── .env
└── package.json
// offdjs.config.js
export default {
    intents: [
        IntentsBitField.Flags.Guilds,
        IntentsBitField.Flags.GuildMembers,
        IntentsBitField.Flags.MessageContent,
        IntentsBitField.Flags.DirectMessages
    ]
}

Root Directory

If you are working with typescript it is common to have a build folder

.
├── build
│   └── events
│       └── ...
├── node_modules
│   └── ...
├── .env
├── offdjs.config.js
└── package.json
└── tsc.json

By default offdjs reads the commands and events folders in root, to change root to the build folder you will need to export a root property in the config with the new route

example:

// offdjs.config.js
export default {
    intents: [IntentsBitField.Flags.Guilds],
    root: 'build'
}

i18n

offdjs has i18n integration, you can enable the defaults in offdjs.config.js by setting the i18n property to true or by setting your own config

example:

// offdjs.config.js
export default {
    i18n: true
}

or

// offdjs.config.js
export default {
    i18n: {
        locales: ['en', es],
        directory: join(cwd, 'lang'),
        defaultLocale: 'en',
        retryInDefaultLocale: true
        // more config
    }
}

it also provides a function to create a translator which receives an interaction or message object and returns a function which you can use as a translator. The first parameter of the returned function will be a string with the phrase to translate and the second will be an object with the keywords to replace (optional) as if it were i18n.__n()

example:

// x.command.js
import client, { Command, Translator } from 'offdjs'

export default class Ping extends Command {
    constructor() { super({ ... }) }

    async interaction(interaction) {
        const translate = Translator(interaction)
        await interaction.reply(translate('ping.response'))
        interaction.editReply(translate('ping.other', {
            name: client.user.username
        }))
    }
}

interactions

...coming soon