mirror of
https://github.com/pacnpal/markov-discord.git
synced 2025-12-20 11:01:04 -05:00
Update 0.7.1: Various config fixes, response quality fixes.
This commit is contained in:
20
.vscode/launch.json
vendored
Normal file
20
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
// Use IntelliSense to learn about possible attributes.
|
||||||
|
// Hover to view descriptions of existing attributes.
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"type": "node",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "Launch Program",
|
||||||
|
"runtimeArgs": [
|
||||||
|
"-r",
|
||||||
|
"ts-node/register"
|
||||||
|
],
|
||||||
|
"args": [
|
||||||
|
"${workspaceFolder}/index.ts"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
110
README.md
110
README.md
@@ -1,27 +1,48 @@
|
|||||||
# MarkBot for Discord
|
# MarkBot for Discord
|
||||||
|
|
||||||
A Markov chain bot using markov-strings.
|
A Markov chain bot using markov-strings.
|
||||||
|
|
||||||
# Setup
|
## Usage
|
||||||
First, create a [Discord bot application](https://discordapp.com/developers/applications/).
|
|
||||||
## Windows
|
|
||||||
### Requirements
|
|
||||||
* [Node.js 8.0+ (Current)](https://nodejs.org/en/download/current/)
|
|
||||||
|
|
||||||
### Setup
|
1. Train the bot in a lengthy text channel:
|
||||||
1. Install Node.js 8.0 or newer.
|
* User: `!mark train`
|
||||||
|
* Markbot: `@User, Finished training from past 76394 messages.`
|
||||||
|
1. Ask the bot to say something:
|
||||||
|
* User: `!mark`
|
||||||
|
* Markbot: `This Shopko has a Linux release`
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
First, create a [Discord bot application](https://discordapp.com/developers/applications/).
|
||||||
|
|
||||||
|
### Windows
|
||||||
|
|
||||||
|
#### Requirements
|
||||||
|
|
||||||
|
* [Node.js 12.0+ (Current)](https://nodejs.org/en/download/)
|
||||||
|
* Installing with build tools is recommended
|
||||||
|
|
||||||
|
#### Setup
|
||||||
|
|
||||||
|
1. Install Node.js 12.0 or newer.
|
||||||
1. Download this repository using git in a command prompt
|
1. Download this repository using git in a command prompt
|
||||||
|
|
||||||
```cmd
|
```cmd
|
||||||
git clone https://github.com/charlocharlie/markov-discord.git
|
git clone https://github.com/charlocharlie/markov-discord.git
|
||||||
```
|
```
|
||||||
|
|
||||||
or by just downloading and extracting the [project zip](https://github.com/charlocharlie/markov-discord/archive/master.zip) from GitHub.
|
or by just downloading and extracting the [project zip](https://github.com/charlocharlie/markov-discord/archive/master.zip) from GitHub.
|
||||||
1. Open a command prompt in the `markov-discord` folder.
|
1. Open a command prompt in the `markov-discord` folder.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
# Install Windows build tools
|
# Install Windows build tools (if you didn't install build tools with Node)
|
||||||
npm install --global --production windows-build-tools
|
npm install --global --production windows-build-tools
|
||||||
# NPM install non-development packages
|
# NPM install non-development packages
|
||||||
npm install --production
|
npm install --production
|
||||||
```
|
```
|
||||||
|
|
||||||
1. Create a file called `config.json` in the project directory with the contents:
|
1. Create a file called `config.json` in the project directory with the contents:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"prefix":"!mark",
|
"prefix":"!mark",
|
||||||
@@ -29,28 +50,34 @@ First, create a [Discord bot application](https://discordapp.com/developers/appl
|
|||||||
"token":"k5NzE2NDg1MTIwMjc0ODQ0Nj.DSnXwg.ttNotARealToken5p3WfDoUxhiH"
|
"token":"k5NzE2NDg1MTIwMjc0ODQ0Nj.DSnXwg.ttNotARealToken5p3WfDoUxhiH"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Feel free to change the command prefix, game display. Add your bot token.
|
Feel free to change the command prefix, game display. Add your bot token.
|
||||||
1. Run the bot:
|
1. Run the bot:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
npm start
|
npm start
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Debian Linux
|
||||||
|
|
||||||
## Debian Linux
|
#### Requirements
|
||||||
### Requirements
|
|
||||||
* Node.js 8.0+
|
* Node.js 12.0+
|
||||||
* Python 2.7 (for erlpack)
|
* Python 2.7 (for erlpack)
|
||||||
* C++ build tools (for erlpack)
|
* C++ build tools (for erlpack)
|
||||||
|
|
||||||
### Download
|
#### Download
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
# Clone this repository
|
# Clone this repository
|
||||||
git clone https://github.com/charlocharlie/markov-discord.git
|
git clone https://github.com/charlocharlie/markov-discord.git
|
||||||
cd markov-discord
|
cd markov-discord
|
||||||
```
|
```
|
||||||
|
|
||||||
### Configure
|
#### Configure
|
||||||
|
|
||||||
Create a file called `config.json` in the project directory with the contents:
|
Create a file called `config.json` in the project directory with the contents:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"prefix":"!mark",
|
"prefix":"!mark",
|
||||||
@@ -58,9 +85,11 @@ Create a file called `config.json` in the project directory with the contents:
|
|||||||
"token":"k5NzE2NDg1MTIwMjc0ODQ0Nj.DSnXwg.ttNotARealToken5p3WfDoUxhiH"
|
"token":"k5NzE2NDg1MTIwMjc0ODQ0Nj.DSnXwg.ttNotARealToken5p3WfDoUxhiH"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Feel free to change the command prefix, game display. Add your bot token.
|
Feel free to change the command prefix, game display. Add your bot token.
|
||||||
|
|
||||||
### Install and Run
|
#### Install and Run
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
# Install Node.js if you haven't already
|
# Install Node.js if you haven't already
|
||||||
wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash
|
wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash
|
||||||
@@ -77,43 +106,61 @@ sudo apt-get install build-essential -y
|
|||||||
npm start
|
npm start
|
||||||
```
|
```
|
||||||
|
|
||||||
## Docker
|
### Docker
|
||||||
### Setup with source
|
|
||||||
1. Install Docker for your OS.
|
#### Setup with Docker Hub image
|
||||||
1. Download this repository using git in a command prompt
|
|
||||||
```sh
|
|
||||||
git clone https://github.com/charlocharlie/markov-discord.git
|
|
||||||
```
|
|
||||||
or by just downloading and extracting the [project zip](https://github.com/charlocharlie/markov-discord/archive/master.zip) from GitHub.
|
|
||||||
1. Open a command prompt in the markov-discord folder and run this one-liner:
|
|
||||||
```sh
|
|
||||||
docker run --rm -e TOKEN=YOUR.BOT.TOKEN -v config:/usr/src/markbot/config -it $(docker build -q .)
|
|
||||||
# Be patient as the build output is suppressed
|
|
||||||
```
|
|
||||||
|
|
||||||
### Setup with Docker Hub image
|
|
||||||
1. Install Docker for your OS.
|
1. Install Docker for your OS.
|
||||||
1. Open a command prompts and run:
|
1. Open a command prompts and run:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
docker pull charlocharlie/markov-discord
|
docker pull charlocharlie/markov-discord
|
||||||
docker run --rm -d charlocharlie/markov-discord:latest
|
docker run --rm -d charlocharlie/markov-discord:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Setup with source
|
||||||
|
|
||||||
|
1. Install Docker for your OS.
|
||||||
|
1. Download this repository using git in a command prompt
|
||||||
|
|
||||||
|
```sh
|
||||||
|
git clone https://github.com/charlocharlie/markov-discord.git
|
||||||
|
```
|
||||||
|
|
||||||
|
or by just downloading and extracting the [project zip](https://github.com/charlocharlie/markov-discord/archive/master.zip) from GitHub.
|
||||||
|
1. Open a command prompt in the markov-discord folder and run this one-liner:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker run --rm -e TOKEN=YOUR.BOT.TOKEN -v config:/usr/src/markbot/config -it $(docker build -q .)
|
||||||
|
# Be patient as the build output is suppressed
|
||||||
|
```
|
||||||
|
|
||||||
|
## Changelog
|
||||||
|
|
||||||
|
### 0.7.1
|
||||||
|
|
||||||
|
* Readme updates
|
||||||
|
* Config loading fix
|
||||||
|
* Fix min score
|
||||||
|
* Add generator options to config
|
||||||
|
* Document Node 12 update
|
||||||
|
|
||||||
# Changelog
|
|
||||||
### 0.7.0
|
### 0.7.0
|
||||||
|
|
||||||
* Convert project to Typescript
|
* Convert project to Typescript
|
||||||
* Optimize Docker build (smaller image)
|
* Optimize Docker build (smaller image)
|
||||||
* Load corpus from filesystem to reduce memory load
|
* Load corpus from filesystem to reduce memory load
|
||||||
|
|
||||||
### 0.6.2
|
### 0.6.2
|
||||||
|
|
||||||
* Fix MarkovDB not loading on boot
|
* Fix MarkovDB not loading on boot
|
||||||
|
|
||||||
### 0.6.1
|
### 0.6.1
|
||||||
|
|
||||||
* Fix bot crashing on scheduled regen
|
* Fix bot crashing on scheduled regen
|
||||||
|
|
||||||
### 0.6.0
|
### 0.6.0
|
||||||
|
|
||||||
* Added Docker deploy functionality.
|
* Added Docker deploy functionality.
|
||||||
* Moved config and database to `./config` directory. Existing configs will be migrated.
|
* Moved config and database to `./config` directory. Existing configs will be migrated.
|
||||||
* Config-less support via bot token located in an environment variable.
|
* Config-less support via bot token located in an environment variable.
|
||||||
@@ -121,6 +168,7 @@ npm start
|
|||||||
* Change corpus regen time to 4 AM.
|
* Change corpus regen time to 4 AM.
|
||||||
|
|
||||||
### 0.5.0
|
### 0.5.0
|
||||||
|
|
||||||
* Fixed bug where `!mark help` didn't work.
|
* Fixed bug where `!mark help` didn't work.
|
||||||
* Only admins can train.
|
* Only admins can train.
|
||||||
* The bot responds when mentioned.
|
* The bot responds when mentioned.
|
||||||
@@ -131,6 +179,7 @@ npm start
|
|||||||
* Simpler config loading.
|
* Simpler config loading.
|
||||||
|
|
||||||
### 0.4.0
|
### 0.4.0
|
||||||
|
|
||||||
* Huge refactor.
|
* Huge refactor.
|
||||||
* Added `!mark debug` which sends debug info alongside the message.
|
* Added `!mark debug` which sends debug info alongside the message.
|
||||||
* Converted the fetchMessages function to async/await (updating the requirement to Node.js 8).
|
* Converted the fetchMessages function to async/await (updating the requirement to Node.js 8).
|
||||||
@@ -139,11 +188,14 @@ npm start
|
|||||||
* Added linting and linted the project.
|
* Added linting and linted the project.
|
||||||
|
|
||||||
### 0.3.0
|
### 0.3.0
|
||||||
|
|
||||||
* Added TTS support and random message attachments.
|
* Added TTS support and random message attachments.
|
||||||
* Deleted messages no longer persist in the database longer than 24 hours.
|
* Deleted messages no longer persist in the database longer than 24 hours.
|
||||||
|
|
||||||
### 0.2.0
|
### 0.2.0
|
||||||
|
|
||||||
* Updated training algorithm and data structure.
|
* Updated training algorithm and data structure.
|
||||||
|
|
||||||
# Thanks
|
# Thanks
|
||||||
|
|
||||||
Thanks to [BotMaker-for-Discord](https://github.com/CorySanin/BotMaker-for-Discord) which I used as a reference when during development.
|
Thanks to [BotMaker-for-Discord](https://github.com/CorySanin/BotMaker-for-Discord) which I used as a reference when during development.
|
||||||
67
index.ts
67
index.ts
@@ -4,7 +4,11 @@ import * as Discord from 'discord.js';
|
|||||||
// https://discord.js.org/#/docs/main/stable/general/welcome
|
// https://discord.js.org/#/docs/main/stable/general/welcome
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
|
|
||||||
import Markov, { MarkovGenerateOptions, MarkovResult } from 'markov-strings';
|
import Markov, {
|
||||||
|
MarkovGenerateOptions,
|
||||||
|
MarkovResult,
|
||||||
|
MarkovConstructorOptions,
|
||||||
|
} from 'markov-strings';
|
||||||
|
|
||||||
import * as schedule from 'node-schedule';
|
import * as schedule from 'node-schedule';
|
||||||
|
|
||||||
@@ -23,8 +27,11 @@ interface MessagesDB {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface MarkbotConfig {
|
interface MarkbotConfig {
|
||||||
prefix: string;
|
stateSize?: number;
|
||||||
game: string;
|
minScore?: number;
|
||||||
|
maxTries?: number;
|
||||||
|
prefix?: string;
|
||||||
|
game?: string;
|
||||||
token?: string;
|
token?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,8 +44,11 @@ const client = new Discord.Client();
|
|||||||
const PAGE_SIZE = 100;
|
const PAGE_SIZE = 100;
|
||||||
// let guilds = [];
|
// let guilds = [];
|
||||||
// let connected = -1;
|
// let connected = -1;
|
||||||
let GAME = 'GAME';
|
let GAME = '!mark help';
|
||||||
let PREFIX = '! ';
|
let PREFIX = '!mark';
|
||||||
|
let STATE_SIZE = 2; // Value of 1 to 3, based on corpus quality
|
||||||
|
let MAX_TRIES = 1000;
|
||||||
|
let MIN_SCORE = 10;
|
||||||
const inviteCmd = 'invite';
|
const inviteCmd = 'invite';
|
||||||
const errors: string[] = [];
|
const errors: string[] = [];
|
||||||
|
|
||||||
@@ -49,14 +59,8 @@ let fileObj: MessagesDB = {
|
|||||||
let markovDB: MessageRecord[] = [];
|
let markovDB: MessageRecord[] = [];
|
||||||
let messageCache: MessageRecord[] = [];
|
let messageCache: MessageRecord[] = [];
|
||||||
let deletionCache: string[] = [];
|
let deletionCache: string[] = [];
|
||||||
const markovOpts = {
|
let markovOpts: MarkovConstructorOptions = {
|
||||||
stateSize: 2,
|
stateSize: STATE_SIZE,
|
||||||
maxLength: 2000,
|
|
||||||
minWords: 3,
|
|
||||||
maxWords: 0,
|
|
||||||
minScore: 10,
|
|
||||||
minScorePerWord: 0,
|
|
||||||
maxTries: 10000,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
@@ -139,15 +143,21 @@ function loadConfig(): void {
|
|||||||
PREFIX = cfg.prefix || '!mark';
|
PREFIX = cfg.prefix || '!mark';
|
||||||
GAME = cfg.game || '!mark help';
|
GAME = cfg.game || '!mark help';
|
||||||
token = cfg.token || process.env.TOKEN || token;
|
token = cfg.token || process.env.TOKEN || token;
|
||||||
|
STATE_SIZE = cfg.stateSize || STATE_SIZE;
|
||||||
|
MIN_SCORE = cfg.minScore || MIN_SCORE;
|
||||||
|
MAX_TRIES = cfg.maxTries || MAX_TRIES;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Failed to read config.json.');
|
console.warn('Failed to read config.json.');
|
||||||
throw e;
|
token = process.env.TOKEN || token;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
client.login(token);
|
client.login(token);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Failed to login with token:', token);
|
console.error('Failed to login with token:', token);
|
||||||
}
|
}
|
||||||
|
markovOpts = {
|
||||||
|
stateSize: STATE_SIZE,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -245,27 +255,16 @@ async function fetchMessages(message: Discord.Message): Promise<void> {
|
|||||||
* @param {Boolean} debug Sends debug info as a message if true.
|
* @param {Boolean} debug Sends debug info as a message if true.
|
||||||
* @param {Boolean} tts If the message should be sent as TTS. Defaults to the TTS setting of the
|
* @param {Boolean} tts If the message should be sent as TTS. Defaults to the TTS setting of the
|
||||||
* invoking message.
|
* invoking message.
|
||||||
* @param {Array<String>} filterWords Array of words that the message generated will be filtered on.
|
|
||||||
*/
|
*/
|
||||||
function generateResponse(
|
function generateResponse(message: Discord.Message, debug = false, tts = message.tts): void {
|
||||||
message: Discord.Message,
|
|
||||||
debug = false,
|
|
||||||
tts = message.tts,
|
|
||||||
filterWords?: string[]
|
|
||||||
): void {
|
|
||||||
console.log('Responding...');
|
console.log('Responding...');
|
||||||
const options: MarkovGenerateOptions = {};
|
const options: MarkovGenerateOptions = {
|
||||||
if (filterWords) {
|
filter: (result): boolean => {
|
||||||
options.filter = (result): boolean => {
|
return result.score >= MIN_SCORE;
|
||||||
for (let i = 0; i < filterWords.length; i += 1) {
|
},
|
||||||
if (result.string.includes(filterWords[i])) {
|
maxTries: MAX_TRIES,
|
||||||
return true;
|
};
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
options.maxTries = 5000;
|
|
||||||
}
|
|
||||||
const fsMarkov = new Markov([''], markovOpts);
|
const fsMarkov = new Markov([''], markovOpts);
|
||||||
const markovFile = JSON.parse(fs.readFileSync('config/markov.json', 'utf-8')) as Markov;
|
const markovFile = JSON.parse(fs.readFileSync('config/markov.json', 'utf-8')) as Markov;
|
||||||
fsMarkov.corpus = markovFile.corpus;
|
fsMarkov.corpus = markovFile.corpus;
|
||||||
|
|||||||
2
package-lock.json
generated
2
package-lock.json
generated
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "markbot",
|
"name": "markbot",
|
||||||
"version": "0.7.0",
|
"version": "0.7.1",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "markbot",
|
"name": "markbot",
|
||||||
"version": "0.7.0",
|
"version": "0.7.1",
|
||||||
"description": "A conversational Markov chain bot for Discord",
|
"description": "A conversational Markov chain bot for Discord",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
"zlib-sync": "^0.1.6"
|
"zlib-sync": "^0.1.6"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8.0.0"
|
"node": ">=12.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^12.12.21",
|
"@types/node": "^12.12.21",
|
||||||
|
|||||||
Reference in New Issue
Block a user