buddy

node MVC discord bot
Log | Files | Refs | README

MessageCollector.js (4407B)


      1 'use strict';
      2 
      3 const Collector = require('./interfaces/Collector');
      4 const { Events } = require('../util/Constants');
      5 
      6 /**
      7  * @typedef {CollectorOptions} MessageCollectorOptions
      8  * @property {number} max The maximum amount of messages to collect
      9  * @property {number} maxProcessed The maximum amount of messages to process
     10  */
     11 
     12 /**
     13  * Collects messages on a channel.
     14  * Will automatically stop if the channel (`'channelDelete'`) or guild (`'guildDelete'`) are deleted.
     15  * @extends {Collector}
     16  */
     17 class MessageCollector extends Collector {
     18   /**
     19    * @param {TextChannel|DMChannel} channel The channel
     20    * @param {CollectorFilter} filter The filter to be applied to this collector
     21    * @param {MessageCollectorOptions} options The options to be applied to this collector
     22    * @emits MessageCollector#message
     23    */
     24   constructor(channel, filter, options = {}) {
     25     super(channel.client, filter, options);
     26 
     27     /**
     28      * The channel
     29      * @type {TextBasedChannel}
     30      */
     31     this.channel = channel;
     32 
     33     /**
     34      * Total number of messages that were received in the channel during message collection
     35      * @type {number}
     36      */
     37     this.received = 0;
     38 
     39     const bulkDeleteListener = messages => {
     40       for (const message of messages.values()) this.handleDispose(message);
     41     };
     42     this._handleChannelDeletion = this._handleChannelDeletion.bind(this);
     43     this._handleGuildDeletion = this._handleGuildDeletion.bind(this);
     44 
     45     if (this.client.getMaxListeners() !== 0) this.client.setMaxListeners(this.client.getMaxListeners() + 1);
     46     this.client.on(Events.MESSAGE_CREATE, this.handleCollect);
     47     this.client.on(Events.MESSAGE_DELETE, this.handleDispose);
     48     this.client.on(Events.MESSAGE_BULK_DELETE, bulkDeleteListener);
     49     this.client.on(Events.CHANNEL_DELETE, this._handleChannelDeletion);
     50     this.client.on(Events.GUILD_DELETE, this._handleGuildDeletion);
     51 
     52     this.once('end', () => {
     53       this.client.removeListener(Events.MESSAGE_CREATE, this.handleCollect);
     54       this.client.removeListener(Events.MESSAGE_DELETE, this.handleDispose);
     55       this.client.removeListener(Events.MESSAGE_BULK_DELETE, bulkDeleteListener);
     56       this.client.removeListener(Events.CHANNEL_DELETE, this._handleChannelDeletion);
     57       this.client.removeListener(Events.GUILD_DELETE, this._handleGuildDeletion);
     58       if (this.client.getMaxListeners() !== 0) this.client.setMaxListeners(this.client.getMaxListeners() - 1);
     59     });
     60   }
     61 
     62   /**
     63    * Handles a message for possible collection.
     64    * @param {Message} message The message that could be collected
     65    * @returns {?Snowflake}
     66    * @private
     67    */
     68   collect(message) {
     69     /**
     70      * Emitted whenever a message is collected.
     71      * @event MessageCollector#collect
     72      * @param {Message} message The message that was collected
     73      */
     74     if (message.channel.id !== this.channel.id) return null;
     75     this.received++;
     76     return message.id;
     77   }
     78 
     79   /**
     80    * Handles a message for possible disposal.
     81    * @param {Message} message The message that could be disposed of
     82    * @returns {?Snowflake}
     83    */
     84   dispose(message) {
     85     /**
     86      * Emitted whenever a message is disposed of.
     87      * @event MessageCollector#dispose
     88      * @param {Message} message The message that was disposed of
     89      */
     90     return message.channel.id === this.channel.id ? message.id : null;
     91   }
     92 
     93   /**
     94    * Checks after un/collection to see if the collector is done.
     95    * @returns {?string}
     96    * @private
     97    */
     98   endReason() {
     99     if (this.options.max && this.collected.size >= this.options.max) return 'limit';
    100     if (this.options.maxProcessed && this.received === this.options.maxProcessed) return 'processedLimit';
    101     return null;
    102   }
    103 
    104   /**
    105    * Handles checking if the channel has been deleted, and if so, stops the collector with the reason 'channelDelete'.
    106    * @private
    107    * @param {GuildChannel} channel The channel that was deleted
    108    * @returns {void}
    109    */
    110   _handleChannelDeletion(channel) {
    111     if (channel.id === this.channel.id) {
    112       this.stop('channelDelete');
    113     }
    114   }
    115 
    116   /**
    117    * Handles checking if the guild has been deleted, and if so, stops the collector with the reason 'guildDelete'.
    118    * @private
    119    * @param {Guild} guild The guild that was deleted
    120    * @returns {void}
    121    */
    122   _handleGuildDeletion(guild) {
    123     if (this.channel.guild && guild.id === this.channel.guild.id) {
    124       this.stop('guildDelete');
    125     }
    126   }
    127 }
    128 
    129 module.exports = MessageCollector;