commit f8bf749c6bde65dc00a2a01d4bd30a649f057fc7
parent c7f656f166503a2ee6832b4b89f4c7f95693f8c6
Author: Demonstrandum <moi@knutsen.co>
Date: Mon, 16 Mar 2020 21:02:36 +0000
History expansion for messages.
Diffstat:
2 files changed, 45 insertions(+), 21 deletions(-)
diff --git a/lib/extensions.ts b/lib/extensions.ts
@@ -5,6 +5,7 @@ declare global {
tail(): Array<T>
first(): T
last(off? : number | undefined): T
+ get(i : number): T
unique(): Array<T>
squeeze(): Array<T>
each(callbackfn : (value : T, index : number, array : T[]) => void, thisArg? : T): void
@@ -42,6 +43,8 @@ Array.prototype.last = function (off=0) {
return this[this.length - 1 - off];
};
+Array.prototype.get = function (i) { return this[i] };
+
Array.prototype.unique = function () {
return this.filter((e, i) => this.indexOf(e) === i)
};
diff --git a/lib/main.ts b/lib/main.ts
@@ -24,6 +24,10 @@ import DEFAULT_CONFIG from './default';
import web_search from './api/contextual';
import oed_lookup from './api/oxford';
import urban_search from './api/urban';
+import { Channel } from 'discord.js';
+import { resolve } from 'dns';
+import { TextChannel } from 'discord.js';
+import { Collection } from 'discord.js';
// Anything that hasn't been defined in `bot.json`
@@ -88,6 +92,9 @@ export class SimpOMatic {
process_command(message : Message) {
this._COMMAND_HISTORY.push(message);
+ if (this._COMMAND_HISTORY.length > CONFIG.commands.max_history) {
+ this._COMMAND_HISTORY.shift();
+ }
const content = message.content.trim().squeeze();
const words = content.tail().split(' ');
@@ -327,31 +334,43 @@ export class SimpOMatic {
// TODO: Process _rules_ appropriately.
}
- last_message(opts) : string {
+ async last_message(opts) : Promise<string> {
+ const channel = opts.channel as TextChannel;
+
if (!opts.offset) opts.offset = 1;
if (opts.mention) opts.mentioning = opts.mentioning.trim();
if (opts.command) {
let commands = this._COMMAND_HISTORY
- .filter(m => m.channel.id === opts.channel.id)
+ .filter(m => m.channel.id === channel.id)
if (opts.mention) commands = commands.filter(m =>
m.author.toString() === opts.mentioning);
const command = commands.last(opts.offset - 1);
if (!command) {
- opts.channel.send('Cannot expand, no such'
+ channel.send('Cannot expand, no such'
+ ' command exists in history.');
- return 'EXPANSION_ERROR';
+ return Promise.reject('COMMAND_NOT_IN_HISTORY');
}
- return command.content;
+ return Promise.resolve(command.content);
}
- // TODO: Deal with non command expansions, i.e. !!^
- return 'last-message';
+ let filter = _ => true;
+ if (opts.mention)
+ filter = m => m.author.toString() === opts.mentioning;
+
+ const messages = await channel.fetchMessages({
+ limit: CONFIG.commands.max_history
+ });
+ // Remember that the _latest_ message, is the one that
+ // the user has _just_ sent. This means we ignore the first message.
+ return messages.array()
+ .filter(filter)
+ .get(opts.offset).content;
}
- expand(message : Message) : string {
+ async expand(message : Message) : Promise<string> {
// History expansion with !!, !!@, !!^@, !!<ordinal>, etc.
const expansions = message.content
.replace(/(!!@?\^?\d*)/g, '@EXP$1@EXP')
@@ -361,7 +380,7 @@ export class SimpOMatic {
for (let i = 0; i < expansions.length; ++i) {
if (expansions[i].startsWith('!!')) {
if (expansions[i].length === 2) { // !! expansion
- expansions[i] = this.last_message({
+ expansions[i] = await this.last_message({
command: true,
channel: message.channel
});
@@ -376,7 +395,7 @@ export class SimpOMatic {
const mentioning = expansions[i + 2];
if (mention) expansions[i + 2] = '';
- expansions[i] = this.last_message({
+ expansions[i] = await this.last_message({
command: !opts.includes('^'),
mention: mention,
mentioning: mentioning,
@@ -401,17 +420,19 @@ export class SimpOMatic {
const trimmed = message.content.trim();
message.content = trimmed;
- message.content = this.expand(message);
-
- console.log('Expanded message:', message.content);
-
- if (message.content[0] === CONFIG.commands.prefix) {
- console.log('Message type: command.')
- this.process_command(message);
- } else {
- console.log('Message type: generic.')
- this.process_generic(message);
- }
+ // When finished expanding...
+ this.expand(message).then(content => {
+ message.content = content;
+ console.log('Expanded message:', message.content);
+
+ if (message.content[0] === CONFIG.commands.prefix) {
+ console.log('Message type: command.')
+ this.process_command(message);
+ } else {
+ console.log('Message type: generic.')
+ this.process_generic(message);
+ }
+ });
}
}