
Research
Supply Chain Attack on Axios Pulls Malicious Dependency from npm
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.
Superset of discord.js with a built-in command framework.
Prerequisites
You can install Bot-TS with your favorite package manager:
npm install --save bot-tsTo create a bot, you need to create a Client instance.
import { Client } from 'bot-ts'
const client = new Client({
commandPrefix: 'c',
ownerId: '<Your Discord user ID>'
})
client.login('<Secret bot token>').catch(console.error)
The Client requires only two options to be passed in the constructor: the command prefix for your commands, and your Discord user ID.
There are several other options you can pass, but they are completely optional.
To register your commands, you just need to call a single method from the Client.
import * as path from 'path'
client.registerCommandsIn(path.join(__dirname, 'commands')).catch(console.error)
This method will find all commands within a directory and register them.
The directory may contain other files and non-commands. I will ignore those.
Bot-TS includes some base commands that you may find helpful. Register them before you register any custom commands:
client.registerDefaultCommands().registerCommandsIn(path.join(__dirname, 'commands'))
If any of your commands are named the same as a base command (or share an alias), your command will take precedence, overriding the base command.
You can also disable some of the default commands, by passing an object to the registerDefaultCommands method specifying which commands to disable:
client.registerDefaultCommands({
help: false
})
Any default command you set to false will not be registered.
Bot-TS comes with its own command framework, allowing you to create powerful commands very easily.
Let's take a look at the most basic command we can create, a command that simply says "Hello, World!" when it is ran.
To create the command, we first create a commands folder in the root of our project.
Within that folder, create a new file, hello-world.ts (or hello-world.js if you are using JavaScript).
Here is the completed command:
import { Client, Message, Command } from 'bot-ts'
export default class HelloWorldCommand extends Command {
constructor(client) {
super(client, {
name: 'helloworld',
description: 'Greet the world.'
})
}
public async run(msg) {
await msg.reply('Hello, World!')
}
}
All of your commands must be a subclass of the Command class.
They need to be set to export default so the command framework knows to import that class.
Every command will have a minimum of two methods: the constructor and the run method.
run method contains the logic you want to execute when the command is called.In many of your commands, you will want the user to provide values for the command to use. These are called command arguments.
Adding arguments to your commands is very simple.
Let's revise the HelloWorld command from previously to say "Hello, {noun}!" (e.g. "Hello, Planet!", "Hello, Universe!", etc.).
The new command will need a single argument.
An argument requires three properties:
key to label the argument.phrase which is used to prompt the user for a value.type of the argument, which is used to validate what the user types.
'user', 'number', and 'string'[ 'user', 'number' ]).Here is the updated command:
import { Client, Message, Command } from 'bot-ts'
export default class HelloWorldCommand extends Command {
constructor(client) {
super(client, {
name: 'helloworld',
description: 'Greet the world.',
args: [
{
key: 'noun',
phrase: 'What, or who, do you want me to greet?',
type: 'string'
}
]
})
}
public async run(msg, args: { noun: string }) {
await msg.reply(`Hello, ${noun}!`)
}
}
Please note that the object property within the run method must be named exactly the same as the argument key, or it will throw a vague exception when the command is called.
There will be some commands you don't want every user to be able to use (e.g. kick, ban, mute, etc.).
Bot-TS allows you to deny users access to these commands with the hasPermission method where you can require some conditions to be met in order for the user to be able to use the command (e.g. must require a certain permission, a certain role, etc.)
Let's revise the HelloWorld command once again to restrict the command to only be usable by users with the "MANAGE_MESSAGES" permission.
Here's the final command:
import { Client, Message, Command } from 'bot-ts'
export default class HelloWorldCommand extends Command {
constructor(client) {
super(client, {
name: 'helloworld',
description: 'Greet the world.',
args: [
{
key: 'noun',
phrase: 'What, or who, do you want me to greet?',
type: 'string'
}
],
guildOnly: true
})
}
public hasPermission(msg) {
return msg.member.permissions.has('MANAGE_MESSAGES')
}
public async run(msg, args: { noun: string }) {
await msg.reply(`Hello, ${noun}!`)
}
}
FAQs
Superset of discord.js with a built-in command framework.
We found that discord-ts demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.

Research
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.

Security News
TeamPCP is partnering with ransomware group Vect to turn open source supply chain attacks on tools like Trivy and LiteLLM into large-scale ransomware operations.