Skip to content

Instantly share code, notes, and snippets.

@Fyko
Last active September 4, 2020 04:22
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Fyko/83b9b9a23986530e75783262da584c04 to your computer and use it in GitHub Desktop.
Save Fyko/83b9b9a23986530e75783262da584c04 to your computer and use it in GitHub Desktop.
collector for guild member add event in discord.js
import { Client, Collection, GuildMember, Snowflake, Structures, Guild as ImportedGuild } from 'discord.js';
import GuildMemberCollector, { GuildMemberCollectorOptions } from './GuildMemberCollector';
type MemberCollection = Collection<Snowflake, GuildMember>;
declare module 'discord.js' {
interface Guild {
awaitMembers(
filter: (member: GuildMember) => boolean,
options?: GuildMemberCollectorOptions,
): Promise<MemberCollection>;
}
}
export default Structures.extend('Guild', (Guild): typeof Guild => {
class MyGuild extends Guild {
public createMemberCollector(
filter: (member: GuildMember) => boolean,
options?: GuildMemberCollectorOptions,
): GuildMemberCollector {
return new GuildMemberCollector((this as unknown) as ImportedGuild, filter, options);
}
public async awaitMembers(
filter: (member: GuildMember) => boolean,
options?: GuildMemberCollectorOptions,
): Promise<MemberCollection> {
return new Promise((resolve) => {
const collector = this.createMemberCollector(filter, options);
collector.once('end', (collection) => {
resolve(collection);
});
});
}
}
return MyGuild;
});
/**
* Copyright 2020 Carter "Fyko" Himmel
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this
* software and associated documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the rights to use, copy, modify,
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be included in all copies
* or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
* FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
import {
Collector,
CollectorFilter,
CollectorOptions,
GuildMember,
Snowflake,
Guild,
Constants,
Collection,
} from 'discord.js';
const { Events } = Constants;
export interface GuildMemberCollectorOptions extends CollectorOptions {
max?: number;
}
export default class GuildMemberCollector extends Collector<Snowflake, GuildMember> {
public options!: GuildMemberCollectorOptions;
protected guild;
protected received = 0;
public constructor(guild: Guild, filter: CollectorFilter, options?: GuildMemberCollectorOptions) {
super(guild.client, filter, options);
this.guild = guild;
// @ts-ignore
this.client.incrementMaxListeners();
this.client.on(Events.GUILD_MEMBER_ADD, this.handleCollect);
this.client.on(Events.GUILD_MEMBER_REMOVE, this.handleDispose);
this.client.on(Events.GUILD_DELETE, this._handleGuildDeletion);
this.once('end', () => {
this.client.removeListener(Events.GUILD_MEMBER_ADD, this.handleCollect);
this.client.removeListener(Events.GUILD_MEMBER_REMOVE, this.handleDispose);
this.client.removeListener(Events.GUILD_DELETE, this._handleGuildDeletion);
// @ts-ignore
this.client.decrementMaxListeners();
});
}
public on(event: 'collect' | 'dispose' | 'remove', listener: (member: GuildMember) => void): this;
public on(event: 'end', listener: (collected: Collection<Snowflake, GuildMember>, reason: string) => void): this;
public on(event: string, listener: (...args: any[]) => void): this {
// @ts-ignore
return super.on(event, listener);
}
public once(event: 'collect' | 'dispose' | 'remove', listener: (member: GuildMember) => void): this;
public once(event: 'end', listener: (collected: Collection<Snowflake, GuildMember>, reason: string) => void): this;
public once(event: string, listener: (...args: any[]) => void): this {
// @ts-ignore
return super.once(event, listener);
}
public collect(member: GuildMember): Snowflake | string {
/**
* Emitted whenever a member is collected.
* @event GuildMemberCollector#collect
* @param {GuildMember} member The member that was collected
*/
if (member.guild.id !== this.guild.id) return '';
this.received++;
return member.id;
}
public dispose(member: GuildMember): Snowflake | string {
/**
* Emitted whenever a mmeber is disposed of.
* @event GuildMemberCollector#dispose
* @param {GuildMember} member The mmeber that was disposed of
*/
return member.guild.id === this.guild.id ? member.id : '';
}
public endReason(): string | null {
if (this.options.max && this.collected.size >= this.options.max) return 'limit';
return null;
}
private _handleGuildDeletion({ id }: Guild) {
if (id === this.guild.id) {
this.stop('guildDelete');
}
}
}
import { Client, Intents } from 'discord.js';
import './ExtendedGuild'; // required to import before we init our client
const intents = [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES];
const client = new Client({ ws: { intents } });
// implement your business logic
void client.login(process.env.DISCORD_TOKEN);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment