mirror of
https://github.com/pacnpal/markov-discord.git
synced 2025-12-20 03:01:04 -05:00
initial convert to TS. No major logic changes, just type safety.
This commit is contained in:
29
.eslintrc.js
Normal file
29
.eslintrc.js
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
module.exports = {
|
||||||
|
root: true,
|
||||||
|
env: {
|
||||||
|
node: true
|
||||||
|
},
|
||||||
|
extends: [
|
||||||
|
'airbnb-base',
|
||||||
|
'plugin:@typescript-eslint/recommended',
|
||||||
|
'prettier/@typescript-eslint',
|
||||||
|
'plugin:prettier/recommended',
|
||||||
|
],
|
||||||
|
parser: '@typescript-eslint/parser',
|
||||||
|
parserOptions: {
|
||||||
|
project: './tsconfig.json',
|
||||||
|
sourceType: 'module'
|
||||||
|
},
|
||||||
|
plugins: ['@typescript-eslint'],
|
||||||
|
settings: {
|
||||||
|
'import/extensions': ['.js', '.ts',],
|
||||||
|
'import/parsers': {
|
||||||
|
'@typescript-eslint/parser': ['.ts']
|
||||||
|
},
|
||||||
|
'import/resolver': {
|
||||||
|
node: {
|
||||||
|
extensions: ['.js', '.ts',]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -65,5 +65,3 @@ config.json
|
|||||||
# error output file
|
# error output file
|
||||||
error.json
|
error.json
|
||||||
markovDB.json
|
markovDB.json
|
||||||
.vscode/launch.json
|
|
||||||
.vscode/settings.json
|
|
||||||
|
|||||||
5
.prettierrc.js
Normal file
5
.prettierrc.js
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
module.exports = {
|
||||||
|
printWidth: 100,
|
||||||
|
singleQuote: true,
|
||||||
|
trailingComma: 'es5'
|
||||||
|
}
|
||||||
18
.vscode/settings.json
vendored
Normal file
18
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"eslint.validate": [
|
||||||
|
"javascript",
|
||||||
|
"typescript"
|
||||||
|
],
|
||||||
|
"editor.codeActionsOnSave": {
|
||||||
|
"source.fixAll.eslint": true
|
||||||
|
},
|
||||||
|
"editor.formatOnSave": true,
|
||||||
|
"[javascript]": {
|
||||||
|
"editor.formatOnSave": false,
|
||||||
|
},
|
||||||
|
"[typescript]": {
|
||||||
|
"editor.formatOnSave": false,
|
||||||
|
},
|
||||||
|
"eslint.enable": true,
|
||||||
|
"typescript.tsdk": "node_modules\\typescript\\lib",
|
||||||
|
}
|
||||||
@@ -1,8 +1,27 @@
|
|||||||
const Discord = require('discord.js'); // https://discord.js.org/#/docs/main/stable/general/welcome
|
/* eslint-disable no-console */
|
||||||
const fs = require('fs');
|
import * as Discord from 'discord.js';
|
||||||
const Markov = require('markov-strings');
|
// https://discord.js.org/#/docs/main/stable/general/welcome
|
||||||
const schedule = require('node-schedule');
|
import * as fs from 'fs';
|
||||||
const { version } = require('./package.json');
|
|
||||||
|
import Markov, { MarkovGenerateOptions, MarkovResult } from 'markov-strings';
|
||||||
|
|
||||||
|
import * as schedule from 'node-schedule';
|
||||||
|
|
||||||
|
interface MessageRecord {
|
||||||
|
id: string;
|
||||||
|
string: string;
|
||||||
|
attachment?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface MarkbotMarkovResult extends MarkovResult {
|
||||||
|
refs: Array<MessageRecord>;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface MessagesDB {
|
||||||
|
messages: MessageRecord[];
|
||||||
|
}
|
||||||
|
|
||||||
|
const version: string = JSON.parse(fs.readFileSync('./package.json', 'utf8')).version || '0.0.0';
|
||||||
|
|
||||||
const client = new Discord.Client();
|
const client = new Discord.Client();
|
||||||
// const ZEROWIDTH_SPACE = String.fromCharCode(parseInt('200B', 16));
|
// const ZEROWIDTH_SPACE = String.fromCharCode(parseInt('200B', 16));
|
||||||
@@ -14,15 +33,15 @@ const PAGE_SIZE = 100;
|
|||||||
let GAME = 'GAME';
|
let GAME = 'GAME';
|
||||||
let PREFIX = '! ';
|
let PREFIX = '! ';
|
||||||
const inviteCmd = 'invite';
|
const inviteCmd = 'invite';
|
||||||
const errors = [];
|
const errors: string[] = [];
|
||||||
|
|
||||||
let fileObj = {
|
let fileObj: MessagesDB = {
|
||||||
messages: [],
|
messages: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
let markovDB = [];
|
let markovDB: MessageRecord[] = [];
|
||||||
let messageCache = [];
|
let messageCache: MessageRecord[] = [];
|
||||||
let deletionCache = [];
|
let deletionCache: string[] = [];
|
||||||
const markovOpts = {
|
const markovOpts = {
|
||||||
stateSize: 2,
|
stateSize: 2,
|
||||||
maxLength: 2000,
|
maxLength: 2000,
|
||||||
@@ -32,18 +51,24 @@ const markovOpts = {
|
|||||||
minScorePerWord: 0,
|
minScorePerWord: 0,
|
||||||
maxTries: 10000,
|
maxTries: 10000,
|
||||||
};
|
};
|
||||||
let markov;
|
let markov: Markov;
|
||||||
// let markov = new Markov(markovDB, markovOpts);
|
// let markov = new Markov(markovDB, markovOpts);
|
||||||
|
|
||||||
function uniqueBy(arr, propertyName) {
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
const unique = [];
|
function uniqueBy<Record extends { [key: string]: any }, K extends keyof Record>(
|
||||||
const found = {};
|
arr: Record[],
|
||||||
|
propertyName: K
|
||||||
|
): Record[] {
|
||||||
|
const unique: Record[] = [];
|
||||||
|
const found: { [key: string]: boolean } = {};
|
||||||
|
|
||||||
for (let i = 0; i < arr.length; i++) {
|
for (let i = 0; i < arr.length; i += 1) {
|
||||||
const value = arr[i][propertyName];
|
if (arr[i][propertyName]) {
|
||||||
if (!found[value]) {
|
const value = arr[i][propertyName];
|
||||||
found[value] = true;
|
if (!found[value]) {
|
||||||
unique.push(arr[i]);
|
found[value] = true;
|
||||||
|
unique.push(arr[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return unique;
|
return unique;
|
||||||
@@ -52,7 +77,7 @@ function uniqueBy(arr, propertyName) {
|
|||||||
/**
|
/**
|
||||||
* Regenerates the corpus and saves all cached changes to disk
|
* Regenerates the corpus and saves all cached changes to disk
|
||||||
*/
|
*/
|
||||||
function regenMarkov() {
|
function regenMarkov(): void {
|
||||||
console.log('Regenerating Markov corpus...');
|
console.log('Regenerating Markov corpus...');
|
||||||
try {
|
try {
|
||||||
fileObj = JSON.parse(fs.readFileSync('config/markovDB.json', 'utf8'));
|
fileObj = JSON.parse(fs.readFileSync('config/markovDB.json', 'utf8'));
|
||||||
@@ -69,20 +94,20 @@ function regenMarkov() {
|
|||||||
}
|
}
|
||||||
// console.log("MessageCache", messageCache)
|
// console.log("MessageCache", messageCache)
|
||||||
markovDB = fileObj.messages;
|
markovDB = fileObj.messages;
|
||||||
markovDB = uniqueBy(markovDB.concat(messageCache), 'id');
|
markovDB = uniqueBy<MessageRecord, 'id'>(markovDB.concat(messageCache), 'id');
|
||||||
deletionCache.forEach((id) => {
|
deletionCache.forEach(id => {
|
||||||
const removeIndex = markovDB.map(item => item.id).indexOf(id);
|
const removeIndex = markovDB.map(item => item.id).indexOf(id);
|
||||||
// console.log('Remove Index:', removeIndex)
|
// console.log('Remove Index:', removeIndex)
|
||||||
markovDB.splice(removeIndex, 1);
|
markovDB.splice(removeIndex, 1);
|
||||||
});
|
});
|
||||||
deletionCache = [];
|
deletionCache = [];
|
||||||
markov = new Markov(markovDB, markovOpts);
|
markov = new Markov(markovDB, markovOpts);
|
||||||
markov.buildCorpusSync();
|
markov.buildCorpusAsync();
|
||||||
fileObj.messages = markovDB;
|
fileObj.messages = markovDB;
|
||||||
// console.log("WRITING THE FOLLOWING DATA:")
|
// console.log("WRITING THE FOLLOWING DATA:")
|
||||||
// console.log(fileObj)
|
// console.log(fileObj)
|
||||||
fs.writeFileSync('config/markovDB.json', JSON.stringify(fileObj), 'utf-8');
|
fs.writeFileSync('config/markovDB.json', JSON.stringify(fileObj), 'utf-8');
|
||||||
fileObj = null;
|
fileObj.messages = [];
|
||||||
messageCache = [];
|
messageCache = [];
|
||||||
console.log('Done regenerating Markov corpus.');
|
console.log('Done regenerating Markov corpus.');
|
||||||
}
|
}
|
||||||
@@ -90,7 +115,7 @@ function regenMarkov() {
|
|||||||
/**
|
/**
|
||||||
* Loads the config settings from disk
|
* Loads the config settings from disk
|
||||||
*/
|
*/
|
||||||
function loadConfig() {
|
function loadConfig(): void {
|
||||||
// Move config if in legacy location
|
// Move config if in legacy location
|
||||||
if (fs.existsSync('./config.json')) {
|
if (fs.existsSync('./config.json')) {
|
||||||
console.log('Copying config.json to new location in ./config');
|
console.log('Copying config.json to new location in ./config');
|
||||||
@@ -102,15 +127,15 @@ function loadConfig() {
|
|||||||
fs.renameSync('./markovDB.json', './config/markovDB.json');
|
fs.renameSync('./markovDB.json', './config/markovDB.json');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// eslint-disable-next-line global-require
|
const cfg = JSON.parse(fs.readFileSync('./config/config.json', 'utf8'));
|
||||||
const cfg = require('./config/config.json');
|
|
||||||
PREFIX = cfg.prefix;
|
PREFIX = cfg.prefix;
|
||||||
GAME = cfg.game;
|
GAME = cfg.game;
|
||||||
client.login(cfg.token);
|
client.login(cfg.token);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn('Failed to use config.json. using default configuration with token environment variable');
|
console.warn(
|
||||||
|
'Failed to use config.json. using default configuration with token environment variable'
|
||||||
|
);
|
||||||
PREFIX = '!mark';
|
PREFIX = '!mark';
|
||||||
GAME = '"!mark help" for help';
|
GAME = '"!mark help" for help';
|
||||||
client.login(process.env.TOKEN);
|
client.login(process.env.TOKEN);
|
||||||
@@ -122,12 +147,14 @@ function loadConfig() {
|
|||||||
* @param {Message} message Message object to get the sender of the message.
|
* @param {Message} message Message object to get the sender of the message.
|
||||||
* @return {Boolean} True if the sender is a moderator.
|
* @return {Boolean} True if the sender is a moderator.
|
||||||
*/
|
*/
|
||||||
function isModerator(message) {
|
function isModerator(message: Discord.Message): boolean {
|
||||||
const { member } = message;
|
const { member } = message;
|
||||||
return member.hasPermission('ADMINISTRATOR')
|
return (
|
||||||
|| member.hasPermission('MANAGE_CHANNELS')
|
member.hasPermission('ADMINISTRATOR') ||
|
||||||
|| member.hasPermission('KICK_MEMBERS')
|
member.hasPermission('MANAGE_CHANNELS') ||
|
||||||
|| member.hasPermission('MOVE_MEMBERS');
|
member.hasPermission('KICK_MEMBERS') ||
|
||||||
|
member.hasPermission('MOVE_MEMBERS')
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -135,7 +162,7 @@ function isModerator(message) {
|
|||||||
* @param {Message} message Message to be interpreted as a command
|
* @param {Message} message Message to be interpreted as a command
|
||||||
* @return {String} Command string
|
* @return {String} Command string
|
||||||
*/
|
*/
|
||||||
function validateMessage(message) {
|
function validateMessage(message: Discord.Message): string | null {
|
||||||
const messageText = message.content.toLowerCase();
|
const messageText = message.content.toLowerCase();
|
||||||
let command = null;
|
let command = null;
|
||||||
const thisPrefix = messageText.substring(0, PREFIX.length);
|
const thisPrefix = messageText.substring(0, PREFIX.length);
|
||||||
@@ -166,20 +193,24 @@ function validateMessage(message) {
|
|||||||
* @param {Message} message Message initiating the command, used for getting
|
* @param {Message} message Message initiating the command, used for getting
|
||||||
* channel data
|
* channel data
|
||||||
*/
|
*/
|
||||||
async function fetchMessages(message) {
|
async function fetchMessages(message: Discord.Message): Promise<void> {
|
||||||
let historyCache = [];
|
let historyCache: MessageRecord[] = [];
|
||||||
let keepGoing = true;
|
let keepGoing = true;
|
||||||
let oldestMessageID = null;
|
let oldestMessageID;
|
||||||
|
|
||||||
while (keepGoing) {
|
while (keepGoing) {
|
||||||
// eslint-disable-next-line no-await-in-loop
|
const messages: Discord.Collection<
|
||||||
const messages = await message.channel.fetchMessages({
|
string,
|
||||||
|
Discord.Message
|
||||||
|
// eslint-disable-next-line no-await-in-loop
|
||||||
|
> = await message.channel.fetchMessages({
|
||||||
before: oldestMessageID,
|
before: oldestMessageID,
|
||||||
limit: PAGE_SIZE,
|
limit: PAGE_SIZE,
|
||||||
});
|
});
|
||||||
const nonBotMessageFormatted = messages
|
const nonBotMessageFormatted = messages
|
||||||
.filter(elem => !elem.author.bot).map((elem) => {
|
.filter(elem => !elem.author.bot)
|
||||||
const dbObj = {
|
.map(elem => {
|
||||||
|
const dbObj: MessageRecord = {
|
||||||
string: elem.content,
|
string: elem.content,
|
||||||
id: elem.id,
|
id: elem.id,
|
||||||
};
|
};
|
||||||
@@ -200,7 +231,6 @@ async function fetchMessages(message) {
|
|||||||
message.reply(`Finished training from past ${historyCache.length} messages.`);
|
message.reply(`Finished training from past ${historyCache.length} messages.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* General Markov-chain response function
|
* General Markov-chain response function
|
||||||
* @param {Message} message The message that invoked the action, used for channel info.
|
* @param {Message} message The message that invoked the action, used for channel info.
|
||||||
@@ -209,12 +239,17 @@ async function fetchMessages(message) {
|
|||||||
* invoking message.
|
* invoking message.
|
||||||
* @param {Array<String>} filterWords Array of words that the message generated will be filtered on.
|
* @param {Array<String>} filterWords Array of words that the message generated will be filtered on.
|
||||||
*/
|
*/
|
||||||
function generateResponse(message, debug = false, tts = message.tts, filterWords) {
|
function generateResponse(
|
||||||
|
message: Discord.Message,
|
||||||
|
debug = false,
|
||||||
|
tts = message.tts,
|
||||||
|
filterWords?: string[]
|
||||||
|
): void {
|
||||||
console.log('Responding...');
|
console.log('Responding...');
|
||||||
const options = {};
|
const options: MarkovGenerateOptions = {};
|
||||||
if (filterWords) {
|
if (filterWords) {
|
||||||
options.filter = (result) => {
|
options.filter = (result): boolean => {
|
||||||
for (let i = 0; i < filterWords.length; i++) {
|
for (let i = 0; i < filterWords.length; i += 1) {
|
||||||
if (result.string.includes(filterWords[i])) {
|
if (result.string.includes(filterWords[i])) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -223,51 +258,57 @@ function generateResponse(message, debug = false, tts = message.tts, filterWords
|
|||||||
};
|
};
|
||||||
options.maxTries = 5000;
|
options.maxTries = 5000;
|
||||||
}
|
}
|
||||||
markov.generateSentence(options).then((result) => {
|
markov
|
||||||
console.log('Generated Result:', result);
|
.generateAsync(options)
|
||||||
const messageOpts = { tts };
|
.then(result => {
|
||||||
const attachmentRefs = result.refs.filter(ref => Object.prototype.hasOwnProperty.call(ref, 'attachment'));
|
const myResult = result as MarkbotMarkovResult;
|
||||||
if (attachmentRefs.length > 0) {
|
console.log('Generated Result:', myResult);
|
||||||
const randomRef = attachmentRefs[Math.floor(Math.random() * attachmentRefs.length)];
|
const messageOpts: Discord.MessageOptions = { tts };
|
||||||
messageOpts.files = [{ attachment: randomRef.attachment }];
|
const attachmentRefs = myResult.refs
|
||||||
} else {
|
.filter(ref => Object.prototype.hasOwnProperty.call(ref, 'attachment'))
|
||||||
const randomMessage = markovDB[Math.floor(Math.random() * markovDB.length)];
|
.map(ref => ref.attachment as string);
|
||||||
if (Object.prototype.hasOwnProperty.call(randomMessage, 'attachment')) {
|
if (attachmentRefs.length > 0) {
|
||||||
messageOpts.files = [{ attachment: randomMessage.attachment }];
|
const randomRefAttachment =
|
||||||
|
attachmentRefs[Math.floor(Math.random() * attachmentRefs.length)];
|
||||||
|
messageOpts.files = [randomRefAttachment];
|
||||||
|
} else {
|
||||||
|
const randomMessage = markovDB[Math.floor(Math.random() * markovDB.length)];
|
||||||
|
if (randomMessage.attachment) {
|
||||||
|
messageOpts.files = [{ attachment: randomMessage.attachment }];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
result.string.replace(/@everyone/g, '@everyοne'); // Replace @everyone with a homoglyph 'o'
|
myResult.string.replace(/@everyone/g, '@everyοne'); // Replace @everyone with a homoglyph 'o'
|
||||||
message.channel.send(result.string, messageOpts);
|
message.channel.send(result.string, messageOpts);
|
||||||
if (debug) message.channel.send(`\`\`\`\n${JSON.stringify(result, null, 2)}\n\`\`\``);
|
if (debug) message.channel.send(`\`\`\`\n${JSON.stringify(myResult, null, 2)}\n\`\`\``);
|
||||||
}).catch((err) => {
|
})
|
||||||
console.log(err);
|
.catch(err => {
|
||||||
if (debug) message.channel.send(`\n\`\`\`\nERROR${err}\n\`\`\``);
|
console.log(err);
|
||||||
if (err.message.includes('Cannot build sentence with current corpus')) {
|
if (debug) message.channel.send(`\n\`\`\`\nERROR${err}\n\`\`\``);
|
||||||
console.log('Not enough chat data for a response.');
|
if (err.message.includes('Cannot build sentence with current corpus')) {
|
||||||
}
|
console.log('Not enough chat data for a response.');
|
||||||
});
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
client.on('ready', () => {
|
client.on('ready', () => {
|
||||||
console.log('Markbot by Charlie Laabs');
|
console.log('Markbot by Charlie Laabs');
|
||||||
client.user.setActivity(GAME);
|
client.user.setActivity(GAME);
|
||||||
regenMarkov();
|
regenMarkov();
|
||||||
});
|
});
|
||||||
|
|
||||||
client.on('error', (err) => {
|
client.on('error', err => {
|
||||||
const errText = `ERROR: ${err.name} - ${err.message}`;
|
const errText = `ERROR: ${err.name} - ${err.message}`;
|
||||||
console.log(errText);
|
console.log(errText);
|
||||||
errors.push(errText);
|
errors.push(errText);
|
||||||
fs.writeFile('./config/error.json', JSON.stringify(errors), (fsErr) => {
|
fs.writeFile('./config/error.json', JSON.stringify(errors), fsErr => {
|
||||||
if (fsErr) {
|
if (fsErr) {
|
||||||
console.log(`error writing to error file: ${fsErr.message}`);
|
console.log(`error writing to error file: ${fsErr.message}`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
client.on('message', (message) => {
|
client.on('message', message => {
|
||||||
if (message.guild) {
|
if (message.guild) {
|
||||||
const command = validateMessage(message);
|
const command = validateMessage(message);
|
||||||
if (command === 'help') {
|
if (command === 'help') {
|
||||||
@@ -275,14 +316,26 @@ client.on('message', (message) => {
|
|||||||
.setAuthor(client.user.username, client.user.avatarURL)
|
.setAuthor(client.user.username, client.user.avatarURL)
|
||||||
.setThumbnail(client.user.avatarURL)
|
.setThumbnail(client.user.avatarURL)
|
||||||
.setDescription('A Markov chain chatbot that speaks based on previous chat input.')
|
.setDescription('A Markov chain chatbot that speaks based on previous chat input.')
|
||||||
.addField('!mark', 'Generates a sentence to say based on the chat database. Send your '
|
.addField(
|
||||||
+ 'message as TTS to recieve it as TTS.')
|
'!mark',
|
||||||
.addField('!mark train', 'Fetches the maximum amount of previous messages in the current '
|
'Generates a sentence to say based on the chat database. Send your ' +
|
||||||
+ 'text channel, adds it to the database, and regenerates the corpus. Takes some time.')
|
'message as TTS to recieve it as TTS.'
|
||||||
.addField('!mark regen', 'Manually regenerates the corpus to add recent chat info. Run '
|
)
|
||||||
+ 'this before shutting down to avoid any data loss. This automatically runs at midnight.')
|
.addField(
|
||||||
.addField('!mark invite', 'Don\'t invite this bot to other servers. The database is shared '
|
'!mark train',
|
||||||
+ 'between all servers and text channels.')
|
'Fetches the maximum amount of previous messages in the current ' +
|
||||||
|
'text channel, adds it to the database, and regenerates the corpus. Takes some time.'
|
||||||
|
)
|
||||||
|
.addField(
|
||||||
|
'!mark regen',
|
||||||
|
'Manually regenerates the corpus to add recent chat info. Run ' +
|
||||||
|
'this before shutting down to avoid any data loss. This automatically runs at midnight.'
|
||||||
|
)
|
||||||
|
.addField(
|
||||||
|
'!mark invite',
|
||||||
|
"Don't invite this bot to other servers. The database is shared " +
|
||||||
|
'between all servers and text channels.'
|
||||||
|
)
|
||||||
.addField('!mark debug', 'Runs the !mark command and follows it up with debug info.')
|
.addField('!mark debug', 'Runs the !mark command and follows it up with debug info.')
|
||||||
.setFooter(`Markov Discord v${version} by Charlie Laabs`);
|
.setFooter(`Markov Discord v${version} by Charlie Laabs`);
|
||||||
message.channel.send(richem).catch(() => {
|
message.channel.send(richem).catch(() => {
|
||||||
@@ -314,7 +367,7 @@ client.on('message', (message) => {
|
|||||||
if (command === null) {
|
if (command === null) {
|
||||||
console.log('Listening...');
|
console.log('Listening...');
|
||||||
if (!message.author.bot) {
|
if (!message.author.bot) {
|
||||||
const dbObj = {
|
const dbObj: MessageRecord = {
|
||||||
string: message.content,
|
string: message.content,
|
||||||
id: message.id,
|
id: message.id,
|
||||||
};
|
};
|
||||||
@@ -331,17 +384,19 @@ client.on('message', (message) => {
|
|||||||
const richem = new Discord.RichEmbed()
|
const richem = new Discord.RichEmbed()
|
||||||
.setAuthor(`Invite ${client.user.username}`, client.user.avatarURL)
|
.setAuthor(`Invite ${client.user.username}`, client.user.avatarURL)
|
||||||
.setThumbnail(client.user.avatarURL)
|
.setThumbnail(client.user.avatarURL)
|
||||||
.addField('Invite', `[Invite ${client.user.username} to your server](https://discordapp.com/oauth2/authorize?client_id=${client.user.id}&scope=bot)`);
|
.addField(
|
||||||
|
'Invite',
|
||||||
|
`[Invite ${client.user.username} to your server](https://discordapp.com/oauth2/authorize?client_id=${client.user.id}&scope=bot)`
|
||||||
|
);
|
||||||
|
|
||||||
message.channel.send(richem)
|
message.channel.send(richem).catch(() => {
|
||||||
.catch(() => {
|
message.author.send(richem);
|
||||||
message.author.send(richem);
|
});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
client.on('messageDelete', (message) => {
|
client.on('messageDelete', message => {
|
||||||
// console.log('Adding message ' + message.id + ' to deletion cache.')
|
// console.log('Adding message ' + message.id + ' to deletion cache.')
|
||||||
deletionCache.push(message.id);
|
deletionCache.push(message.id);
|
||||||
console.log('deletionCache:', deletionCache);
|
console.log('deletionCache:', deletionCache);
|
||||||
1025
package-lock.json
generated
1025
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
43
package.json
43
package.json
@@ -23,38 +23,29 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bufferutil": "^4.0.1",
|
"bufferutil": "^4.0.1",
|
||||||
"discord.js": "^11.4.2",
|
"discord.js": "^11.5.1",
|
||||||
"erlpack": "github:discordapp/erlpack",
|
"erlpack": "github:discordapp/erlpack",
|
||||||
"markov-strings": "^1.5.2",
|
"markov-strings": "^2.1.0",
|
||||||
"node-schedule": "^1.3.2",
|
"node-schedule": "^1.3.2",
|
||||||
"zlib-sync": "^0.1.4"
|
"zlib-sync": "^0.1.6"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8.0.0"
|
"node": ">=8.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"eslint": "^5.16.0",
|
"@types/node": "^12.12.21",
|
||||||
"eslint-config-airbnb-base": "^13.1.0",
|
"@types/node-schedule": "^1.3.0",
|
||||||
"eslint-plugin-import": "^2.17.2"
|
"@typescript-eslint/eslint-plugin": "^2.12.0",
|
||||||
|
"@typescript-eslint/parser": "^2.12.0",
|
||||||
|
"eslint": "^6.8.0",
|
||||||
|
"eslint-config-airbnb-base": "^14.0.0",
|
||||||
|
"eslint-config-prettier": "^6.7.0",
|
||||||
|
"eslint-plugin-import": "^2.19.1",
|
||||||
|
"eslint-plugin-prettier": "^3.1.2",
|
||||||
|
"prettier": "^1.19.1",
|
||||||
|
"typescript": "^3.7.4"
|
||||||
},
|
},
|
||||||
"eslintConfig": {
|
"eslintIgnore": [
|
||||||
"parserOptions": {
|
"**/*.js"
|
||||||
"ecmaVersion": 2017
|
]
|
||||||
},
|
|
||||||
"env": {
|
|
||||||
"node": true
|
|
||||||
},
|
|
||||||
"extends": [
|
|
||||||
"airbnb-base"
|
|
||||||
],
|
|
||||||
"rules": {
|
|
||||||
"no-console": 0,
|
|
||||||
"no-plusplus": [
|
|
||||||
"error",
|
|
||||||
{
|
|
||||||
"allowForLoopAfterthoughts": true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
22
tsconfig.json
Normal file
22
tsconfig.json
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ES2019", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
|
||||||
|
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
|
||||||
|
"outDir": "./dist", /* Redirect output structure to the directory. */
|
||||||
|
"removeComments": true, /* Do not emit comments to output. */
|
||||||
|
"strict": true, /* Enable all strict type-checking options. */
|
||||||
|
"moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
|
||||||
|
"typeRoots": [
|
||||||
|
"node_modules/@types"
|
||||||
|
], /* List of folders to include type definitions from. */
|
||||||
|
"inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
|
||||||
|
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"**/*.ts"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"node_modules",
|
||||||
|
"dist"
|
||||||
|
]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user