A simple Discord bot that logs all messages to the console and can respond to specific trigger words.
- Logs all messages from Discord servers to the console
- Logs attachments with their URLs
- Responds to configured trigger words with custom responses
- Supports different word matching modes (whole word, starts with, ends with)
- Containerized with Docker for easy deployment
- GitHub Actions workflow for automatic container publishing
- Node.js 22.0.0 or higher
- Discord.js v14
- A Discord bot token
- Clone this repository
- Install dependencies:
npm install - Create a
.envfile with your Discord bot token:DISCORD_TOKEN=your_token_here - Start the bot:
npm start
# Pull the latest image
docker pull ghcr.io/Flyy-y/bot_kette:latest
# Run with your Discord token
docker run -d --name bot_kette -e DISCORD_TOKEN=your_token_here ghcr.io/Flyy-y/bot_kette:latest- Clone this repository
- Update the Discord token in
compose.yml - Run with Docker Compose:
docker compose up -d
Example compose.yml:
services:
bot:
image: ghcr.io/Flyy-y/bot_kette:latest
# Alternatively, build locally:
# build: .
container_name: bot_kette
restart: unless-stopped
environment:
- DISCORD_TOKEN=your_token_here
volumes:
# Mount custom answerMap.json (optional)
- ./answerMap.json:/app/answerMap.json:ro- Clone this repository
- Build the Docker image:
docker build -t bot_kette . - Run the container:
docker run -d --name bot_kette -e DISCORD_TOKEN=your_token_here bot_kette
The bot uses an answerMap.json file to configure trigger words and responses. The format is:
{
"trigger1": {"answer": "response1", "on": "endsWith"},
"trigger2": {"answer": "response2", "on": "startsWith"},
"trigger3": {"answer": "response3", "on": "always"},
"trigger4": {"answer": ["response4a", "response4b"], "on": "always", "secondaryMatches": ["alt1", "alt2"]}
}The bot supports both single responses and arrays of possible responses:
-
Single Response: Provide a string as the
answervalue- Example:
"trigger": {"answer": "response", "on": "always"}
- Example:
-
Multiple Responses: Provide an array of strings as the
answervalue- Example:
"trigger": {"answer": ["response1", "response2", "response3"], "on": "always"} - When triggered, the bot will randomly select one of the responses
- Example:
You can define alternative words that will also trigger the same response:
- Use the
secondaryMatcheskey with an array of alternative trigger words - Example:
"ca": {"answer": "lope", "on": "always", "secondaryMatches": ["sa", "ça"]} - This will trigger the same response for "ca", "sa", or "ça"
When a message contains multiple trigger words:
- The bot will collect all matching responses
- Responses are kept in the same order as they appear in the original message
- Responses are joined with " + "
- If there are 3 or more matches, "+ ratio" is added at the end
- Example: For a message containing "oui c'est quoi ça", the response would be "stiti + feur + lope + ratio"
The bot supports three different matching modes:
-
endsWith: Triggers when the message ends with the specified word
- Example: With
"oui": {"answer": "stiti", "on": "endsWith"}, the message "ça va oui" will trigger the response
- Example: With
-
startsWith: Triggers when the message starts with the specified word
- Example: With
"hello": {"answer": "world", "on": "startsWith"}, the message "hello everyone" will trigger the response
- Example: With
-
always: Triggers when the word appears anywhere in the message as a whole word (not as part of another word)
- Example: With
"thanks": {"answer": "you're welcome", "on": "always"}, the message "thanks for your help" will trigger the response, but "thanksgiving" will not
- Example: With
The bot only checks for whole words, so partial matches like "jouir" will not trigger the "oui" response.
The bot automatically removes accents from words before matching:
- Accented characters are normalized to their non-accented equivalents
- For example, "ça" will match "ca" and vice versa
- This works for all matching modes (always, startsWith, endsWith)
- Example: With
"ca": {"answer": "lope", "on": "always"}, the message "ça va bien" will trigger the response
This project includes a comprehensive test suite using Jest. The tests cover:
- Utility functions for string matching (containsWholeWord, startsWithWord, endsWithWord)
- answerMap loading functionality
- Message handling and response logic
# Install dependencies including dev dependencies
npm install
# Run tests
npm test
# Run tests with coverage report
npm run test:coverage# Build and run tests using Docker
docker build -t bot_kette_test -f Dockerfile.test .
docker run bot_kette_testThe current test coverage is:
| File | % Statements | % Branches | % Functions | % Lines |
|---|---|---|---|---|
| All files | 85.18 | 87.5 | 50 | 84.9 |
| index.js | 82.97 | 83.33 | 20 | 82.6 |
| utils.js | 100 | 100 | 100 | 100 |
This repository includes GitHub Actions workflows that automatically:
- Builds a Docker test image
- Runs all tests inside the Docker container
- Generates and uploads test coverage reports
- Automatically comments on PRs with test results if tests fail
- Prevents Docker image building if tests fail
- Runs on every push to main and add-unit-tests branches, pull requests to main, and manual triggering
- Builds the Docker image
- Tags it with the version from package.json
- Publishes it to GitHub Container Registry (ghcr.io)
- Runs on every push, version tags (v*..), pull requests to main, and manual triggering
The image will be available at ghcr.io/Flyy-y/bot_kette:latest and ghcr.io/Flyy-y/bot_kette:1.0.0 (or whatever version is in package.json).
This project is licensed under the MIT License - see the LICENSE file for details.