Skip to content
This repository has been archived by the owner on Apr 24, 2024. It is now read-only.

Commit

Permalink
Implement /names as command object
Browse files Browse the repository at this point in the history
  • Loading branch information
aronson committed Oct 17, 2023
1 parent 3f2fb3d commit cb718e9
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 40 deletions.
5 changes: 2 additions & 3 deletions lib/bot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,11 +128,10 @@ export default class Bot {

this.attachIrcListeners();

// IRC handlers wil
this.logger.info('Connecting to Discord');
// Begin connection to remote servers
await this.discord.connect();
await this.ircClient.connect(this.config.server, this.config.port, this.config.tls);
this.logger.info('Connecting to Discord');
await this.discord.connect();

// Extract id and token from Webhook urls and connect.
this.channelMapping = await ChannelMapper.CreateAsync(this.config, this, this.discord);
Expand Down
6 changes: 3 additions & 3 deletions lib/channelMapping.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Bot from './bot.ts';
import { Config } from './config.ts';
import { Client, GuildTextChannel, Webhook } from './deps.ts';
import { CommandClient, GuildTextChannel, Webhook } from './deps.ts';

type Hook = {
id: string;
Expand All @@ -20,7 +20,7 @@ export class ChannelMapper {
discordIdToMapping: Map<string, ChannelMapping> = new Map<string, ChannelMapping>();
ircNameToMapping: Map<string, ChannelMapping> = new Map<string, ChannelMapping>();

public static CreateAsync = async (config: Config, bot: Bot, discord: Client) => {
public static CreateAsync = async (config: Config, bot: Bot, discord: CommandClient) => {
const me = new ChannelMapper();

for (const [discordChannelNameOrId, ircChannelNameAndOrPassword] of Object.entries(config.channelMapping)) {
Expand Down Expand Up @@ -82,7 +82,7 @@ export class ChannelMapper {
}
}

private static async findDiscordChannel(discordChannelName: string, discord: Client) {
private static async findDiscordChannel(discordChannelName: string, discord: CommandClient) {
const discordChannel = await discord.channels.get(discordChannelName);

if (!discordChannel && discordChannelName.startsWith('#')) {
Expand Down
4 changes: 3 additions & 1 deletion lib/deps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ export type { AnyRawCommand } from 'https://deno.land/x/irc@v0.15.0/core/protoco
// Harmony/Discord exports
export {
AllowedMentionType,
Client,
Command,
CommandClient,
DiscordAPIError,
event,
GatewayIntents,
Expand All @@ -27,6 +28,7 @@ export {
User,
Webhook,
} from 'https://raw.githubusercontent.com/harmonyland/harmony/main/mod.ts';
export type { CommandContext } from 'https://raw.githubusercontent.com/harmonyland/harmony/main/mod.ts';
export type { AllWebhookMessageOptions } from 'https://raw.githubusercontent.com/harmonyland/harmony/main/src/structures/webhook.ts';
// std exports
export { resolve as resolvePath } from 'https://deno.land/std@0.203.0/path/mod.ts';
Expand Down
79 changes: 46 additions & 33 deletions lib/discordClient.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,44 @@
import Bot from './bot.ts';
import { escapeMarkdown } from './helpers.ts';
import { Client, event, GatewayIntents, Message } from './deps.ts';
import { Command, CommandClient, CommandContext, event, GatewayIntents, Message } from './deps.ts';

export class DiscordClient extends Client {
class Names extends Command {
name = 'names';
private bot: Bot;

constructor(bot: Bot) {
super();
this.bot = bot;
}

async execute(ctx: CommandContext): Promise<void> {
const ircChannel = this.bot?.channelMapping?.discordIdToMapping.get(ctx.channel.id)?.ircChannel;
// return early if message was in channel we don't post to
if (!ircChannel) return;
const users = this.bot?.channelUsers[ircChannel];
if (users && users.length > 0) {
const ircNamesArr = new Array(...users);
await ctx.message.reply(
`Users in ${ircChannel}\n> ${
ircNamesArr
.map(escapeMarkdown)
.join(', ')
}`,
);
} else {
this.bot.logger.warn(
`No channelUsers found for ${ircChannel} when /names requested`,
);
}
}
}

export class DiscordClient extends CommandClient {
private bot: Bot;
constructor(bot: Bot) {
super({
prefix: '/',
caseSensitive: false,
intents: [
GatewayIntents.GUILDS,
GatewayIntents.GUILD_MEMBERS,
Expand All @@ -16,7 +49,8 @@ export class DiscordClient extends Client {
});
this.bot = bot;
// Reconnect event has to be hooked manually due to naming conflict
this.on('reconnect', (shardId) => this.bot.logger.info(`Reconnected to Discord (shard ID ${shardId})`));
this.on('reconnect', (shardId) => this.bot?.logger.info(`Reconnected to Discord (shard ID ${shardId})`));
this.commands.add(new Names(bot));
}

@event()
Expand All @@ -32,37 +66,16 @@ export class DiscordClient extends Client {

@event()
async messageCreate(message: Message): Promise<void> {
// Show the IRC channel's /names list when asked for in Discord
if (message.content.toLowerCase() === '/names') {
if (!message.channel.isGuildText()) return;
// return early if message was in channel we don't post to
if (!(this.bot.channelMapping?.discordIdToMapping.get(message.channel.id))) {
return;
}
const ircChannel = this.bot.channelMapping?.discordIdToMapping.get(message.channel.id)?.ircChannel;
if (!ircChannel) return;
if (this.bot.channelUsers[ircChannel]) {
const ircNames = this.bot.channelUsers[ircChannel].values();
const ircNamesArr = new Array(...ircNames);
await this.bot.sendExactToDiscord(
ircChannel,
`Users in ${ircChannel}\n> ${
ircNamesArr
.map(escapeMarkdown) //TODO: Switch to discord.js escape markdown
.join(', ')
}`,
);
} else {
this.bot.logger.warn(
`No channelUsers found for ${ircChannel} when /names requested`,
);
// Pass the command through if channelUsers is empty
await this.bot.sendToIRC(message);
}
} else {
// Ignore this.bot messages and people leaving/joining
await this.bot.sendToIRC(message);
if (message.content.trim() === '/names') return;
if (!message.channel.isGuildText()) return;
// return early if message was in channel we don't post to
if (!(this.bot.channelMapping?.discordIdToMapping.get(message.channel.id))) {
return;
}
const ircChannel = this.bot?.channelMapping?.discordIdToMapping.get(message.channel.id)?.ircChannel;
if (!ircChannel) return;
// Ignore this.bot? messages and people leaving/joining
await this.bot.sendToIRC(message);
}

@event()
Expand Down

0 comments on commit cb718e9

Please sign in to comment.