feat: implement Ancestor quote bot with Docker support
This commit is contained in:
5
.dockerignore
Normal file
5
.dockerignore
Normal file
@@ -0,0 +1,5 @@
|
||||
.git
|
||||
node_modules
|
||||
.env
|
||||
node/
|
||||
.npm
|
||||
5
.env.example
Normal file
5
.env.example
Normal file
@@ -0,0 +1,5 @@
|
||||
# Matrix Ancestor Quote Bot Configuration
|
||||
|
||||
MATRIX_HOME_SERVER=https://your.matrix.server.com:443
|
||||
MATRIX_ACCESS_TOKEN=your_access_token_here
|
||||
BOT_COMMAND=!quote
|
||||
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
node_modules/
|
||||
.env
|
||||
.git
|
||||
*.log
|
||||
@@ -1,6 +1,7 @@
|
||||
FROM node:18-alpine
|
||||
WORKDIR /app
|
||||
COPY package*.json ./
|
||||
RUN npm install --production
|
||||
RUN npm install
|
||||
COPY . .
|
||||
RUN npm prune --production
|
||||
CMD ["node", "index.js"]
|
||||
41
README.md
41
README.md
@@ -1,3 +1,40 @@
|
||||
# matrix-quotes-bot
|
||||
# Ancestor Quote Bot
|
||||
|
||||
AKA ancestor bot. By default it just quotes the Ancestor from Darkest Dungeons. It's like 25 lines of JS and some libraries.
|
||||
A Matrix chatbot that responds to `/quote` commands with random quotes from Darkest Dungeons' Narrator/Ancestor.
|
||||
|
||||
## Setup
|
||||
|
||||
1. Copy `.env.example` to `.env` and fill in your credentials:
|
||||
```bash
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
2. Build the Docker image:
|
||||
```bash
|
||||
docker build -t ancestor-quote-bot .
|
||||
```
|
||||
|
||||
3. Run the bot:
|
||||
```bash
|
||||
docker run --rm \
|
||||
-e MATRIX_HOME_SERVER=https://your.matrix.server.com \
|
||||
-e MATRIX_ACCESS_TOKEN=your_access_token_here \
|
||||
ancestor-quote-bot
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
- `MATRIX_HOME_SERVER`: Your Matrix homeserver URL (e.g., https://matrix.org)
|
||||
- `MATRIX_ACCESS_TOKEN`: Bot access token for authentication
|
||||
- `BOT_COMMAND`: The command trigger (default: `!quote`)
|
||||
|
||||
## Usage
|
||||
|
||||
Type the bot command in any room you've joined, and it will reply with a random Ancestor quote.
|
||||
|
||||
Example:
|
||||
```
|
||||
Room: #general:matrix.org
|
||||
!quote
|
||||
Bot: Dispatch this thug in brutal fashion, that all may hear of your arrival!
|
||||
```
|
||||
|
||||
9
docker-compose.yml
Normal file
9
docker-compose.yml
Normal file
@@ -0,0 +1,9 @@
|
||||
services:
|
||||
ancestor-bot:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
environment:
|
||||
- MATRIX_HOME_SERVER=${MATRIX_HOME_SERVER:-https://matrix.org}
|
||||
- MATRIX_ACCESS_TOKEN=${MATRIX_ACCESS_TOKEN:?required}
|
||||
- BOT_COMMAND=${BOT_COMMAND:-!quote}
|
||||
54
index.js
54
index.js
@@ -4,21 +4,63 @@ const fs = require('fs');
|
||||
|
||||
const client = new Client({
|
||||
accessToken: process.env.MATRIX_ACCESS_TOKEN,
|
||||
ejmtls: process.env.MATRIX_EJMTLS || undefined,
|
||||
matrix_homeserver: {
|
||||
baseUrl: process.env.MATRIX_HOME_SERVER,
|
||||
}
|
||||
});
|
||||
|
||||
const quotes = JSON.parse(fs.readFileSync('./quotes.json', 'utf8'));
|
||||
async function loadQuotes() {
|
||||
const quotesFile = './quotes.json';
|
||||
if (fs.existsSync(quotesFile)) {
|
||||
return JSON.parse(fs.readFileSync(quotesFile, 'utf8'));
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
client.on('sysjmn_message', (event) => {
|
||||
if (event.content && event.content.includes(process.env.BOT_COMMAND)) {
|
||||
const randomQuote = quotes[Math.floor(Math.random() * quotes.length)];
|
||||
client.sendMessage(event.roomId, randomQuote);
|
||||
const quotes = await loadQuotes();
|
||||
|
||||
if (quotes.length === 0) {
|
||||
console.error('No quotes found! Please ensure quotes.json is present.');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
let joinedRooms = new Set();
|
||||
|
||||
client.on('RoomMember#joined', (member) => {
|
||||
const room = member.room;
|
||||
if (!joinedRooms.has(room.roomId)) {
|
||||
joinedRooms.add(room.roomId);
|
||||
console.log(`Joined room: ${room.roomId}`);
|
||||
|
||||
room.on('EventMessage', async (event) => {
|
||||
const messageContent = event.getContent();
|
||||
|
||||
if (!messageContent || !messageContent.body) return;
|
||||
|
||||
const body = messageContent.body.toLowerCase();
|
||||
const botCommand = (process.env.BOT_COMMAND || '!quote').toLowerCase();
|
||||
|
||||
if (body.includes(botCommand)) {
|
||||
const randomQuote = quotes[Math.floor(Math.random() * quotes.length)];
|
||||
try {
|
||||
await room.sendMessage(randomQuote);
|
||||
console.log(`Sent quote to ${room.roomId}`);
|
||||
} catch (err) {
|
||||
console.error('Failed to send message:', err.message);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
room.on('RoomMember#left', () => {
|
||||
joinedRooms.delete(room.roomId);
|
||||
console.log(`Left room: ${room.roomId}`);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
client.init().then(() => {
|
||||
console.log('Bot is online');
|
||||
}).catch(err => {
|
||||
console.error('Failed to initialize client:', err.message);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user