From f22627e8cf8c2823127091a2b1153f9035412923 Mon Sep 17 00:00:00 2001 From: Chip Wasson Date: Mon, 18 Sep 2023 22:51:41 -0600 Subject: [PATCH] Add irc bot --- package.json | 5 ++- src/app.module.ts | 5 ++- src/config/configuration.ts | 7 +++ src/domainrproxy/domainrproxy.module.ts | 3 +- src/ircbot/ircbot.module.ts | 9 ++++ src/ircbot/ircbot.service.ts | 59 +++++++++++++++++++++++++ yarn.lock | 30 ++++++++++++- 7 files changed, 114 insertions(+), 4 deletions(-) create mode 100644 src/ircbot/ircbot.module.ts create mode 100644 src/ircbot/ircbot.service.ts diff --git a/package.json b/package.json index 7f7a211..99e8165 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,8 @@ "minio": "^7.1.3", "ramda": "^0.29.0", "reflect-metadata": "^0.1.13", - "rxjs": "^7.8.1" + "rxjs": "^7.8.1", + "slate-irc": "^0.9.3" }, "devDependencies": { "@nestjs/cli": "^10.0.0", @@ -46,6 +47,7 @@ "@types/jest": "^29.5.2", "@types/node": "^20.3.1", "@types/ramda": "^0.29.3", + "@types/slate-irc": "^0.0.29", "@types/supertest": "^2.0.12", "@typescript-eslint/eslint-plugin": "^6.0.0", "@typescript-eslint/parser": "^6.0.0", @@ -54,6 +56,7 @@ "eslint-plugin-prettier": "^5.0.0", "jest": "^29.5.0", "prettier": "^3.0.0", + "slate-irc-parser": "^0.1.4", "source-map-support": "^0.5.21", "supertest": "^6.3.3", "ts-jest": "^29.1.0", diff --git a/src/app.module.ts b/src/app.module.ts index 85b6549..56386d5 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -9,6 +9,8 @@ import { ConfigModule } from '@nestjs/config'; import { DomainrproxyModule } from './domainrproxy/domainrproxy.module'; import configuration from './config/configuration'; import { CacheModule } from '@nestjs/cache-manager'; +import { IrcbotModule } from './ircbot/ircbot.module'; +import { IrcbotService } from './ircbot/ircbot.service'; @Module({ imports: [ @@ -22,8 +24,9 @@ import { CacheModule } from '@nestjs/cache-manager'; AuthModule, UsersModule, DomainrproxyModule, + IrcbotModule, ], controllers: [AppController], - providers: [AppService], + providers: [AppService, IrcbotService], }) export class AppModule {} diff --git a/src/config/configuration.ts b/src/config/configuration.ts index 8e652a3..aa6d352 100644 --- a/src/config/configuration.ts +++ b/src/config/configuration.ts @@ -3,4 +3,11 @@ export default () => ({ // UserAgent should be added to calls made to third party apis userAgent: 'api.us.dev/@chip@talking.dev', rapidApiKey: process.env.RAPID_API_KEY || '', + irc: { + enabled: process.env.IRC_SERVER !== undefined, + server: process.env.IRC_SERVER, + tls: process.env.IRC_TLS === 'true', + port: parseInt(process.env.IRC_PORT ?? '6697'), + channel: process.env.IRC_CHANNEL ?? '#usdev', + }, }); diff --git a/src/domainrproxy/domainrproxy.module.ts b/src/domainrproxy/domainrproxy.module.ts index 9878dea..99c5143 100644 --- a/src/domainrproxy/domainrproxy.module.ts +++ b/src/domainrproxy/domainrproxy.module.ts @@ -4,6 +4,7 @@ import { DomainrproxyController } from './domainrproxy.controller'; @Module({ providers: [DomainrproxyService], - controllers: [DomainrproxyController] + controllers: [DomainrproxyController], + exports: [DomainrproxyService], }) export class DomainrproxyModule {} diff --git a/src/ircbot/ircbot.module.ts b/src/ircbot/ircbot.module.ts new file mode 100644 index 0000000..cfad9ec --- /dev/null +++ b/src/ircbot/ircbot.module.ts @@ -0,0 +1,9 @@ +import { Module } from '@nestjs/common'; +import { IrcbotService } from './ircbot.service'; +import { DomainrproxyService } from 'src/domainrproxy/domainrproxy.service'; + +@Module({ + providers: [IrcbotService, DomainrproxyService], + exports: [IrcbotService], +}) +export class IrcbotModule {} diff --git a/src/ircbot/ircbot.service.ts b/src/ircbot/ircbot.service.ts new file mode 100644 index 0000000..fcd83d6 --- /dev/null +++ b/src/ircbot/ircbot.service.ts @@ -0,0 +1,59 @@ +import { Injectable, Logger } from '@nestjs/common'; +import { ConfigService } from '@nestjs/config'; +import { TLSSocket, connect } from 'tls'; +import * as irc from 'slate-irc'; +import { DomainrproxyService } from 'src/domainrproxy/domainrproxy.service'; + +@Injectable() +export class IrcbotService { + private readonly socket: TLSSocket; + private readonly client: irc.Client; + private readonly logger: Logger = new Logger(IrcbotService.name); + + constructor( + public readonly configService: ConfigService, + public readonly domainrProxy: DomainrproxyService, + ) { + if (!this.configService.get('irc.enabled')) return; + this.socket = connect({ + port: this.configService.get('irc.port'), + host: this.configService.get('irc.server'), + rejectUnauthorized: false, + }); + this.client = irc(this.socket); + this.client.nick(process.env.NODE_ENV === 'production' ? 'usbot' : 'usdev'); + this.client.user('usbot', 'usbot'); + const channel: string = this.configService.get( + 'irc.channel', + ) as string; + this.client.join(channel); + this.client.names(channel, (err, names) => { + this.logger.verbose(`${channel} contains ${JSON.stringify(names)}`); + }); + + this.client.on('errors', this.logger.error); + + this.client.on('message', async (message) => { + console.log(message); + if (message.to !== channel) return; + if (message.message[0] !== '.') return; + this.logger.verbose(`Handling ${message.message}`); + + const [command, ...args] = message.message.substring(1).split(' '); + + switch (command) { + case 'domain': + const domain = args[0]; + const queryResult = await this.domainrProxy.queryForDomain(domain); + this.client.send( + channel, + `${queryResult[0].domain} ${queryResult[0].status}`, + ); + return; + default: + this.client.send(channel, `Dunno what ${command} means`); + return; + } + }); + } +} diff --git a/yarn.lock b/yarn.lock index d84bc52..c39e07a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1113,6 +1113,13 @@ "@types/mime" "*" "@types/node" "*" +"@types/slate-irc@^0.0.29": + version "0.0.29" + resolved "https://registry.yarnpkg.com/@types/slate-irc/-/slate-irc-0.0.29.tgz#5f9cdbf0640eb1040f43eaa29933579d20347d8a" + integrity sha512-ToNIHt5d0C6Pj3YNY99y34QFxibNN9Gmd3AzHYDeGwDklZjsKxJvG894nsGheShjcCMSVdYlSYaaMhnThiBHag== + dependencies: + "@types/node" "*" + "@types/stack-utils@^2.0.0": version "2.0.1" resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" @@ -2118,7 +2125,7 @@ debug@2.6.9: dependencies: ms "2.0.0" -debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: +debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.2.0, debug@^4.3.2, debug@^4.3.4: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -3833,6 +3840,11 @@ lines-and-columns@^1.1.6: resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== +linewise@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/linewise/-/linewise-0.0.3.tgz#bf967ba0dd31faaf09ab5bdb3676ad7f2aa18493" + integrity sha512-8oI90ziJlcTi4k2DnQ0o0Waa2Uk00xbIN8ylvhstEqfJtiRaB4LJ6u8H63If7zTrnnuhCw8SjTJoHf+wLs3ICg== + loader-runner@^4.2.0: version "4.3.0" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1" @@ -4851,6 +4863,22 @@ slash@^3.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== +slate-irc-parser@^0.1.3, slate-irc-parser@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/slate-irc-parser/-/slate-irc-parser-0.1.4.tgz#63090c424e65d468621afaa8e3d0e812d7b8624e" + integrity sha512-JBuxwhsdOA2OhLtJpHbBZH6uRVvn27SDV1J7M8Mvdv8vEa/LnXxXFMDLLeiLJKUa2Ld+xuu45nmL7wZv5tFQvw== + dependencies: + debug "^4.2.0" + linewise "0.0.3" + +slate-irc@^0.9.3: + version "0.9.3" + resolved "https://registry.yarnpkg.com/slate-irc/-/slate-irc-0.9.3.tgz#9e37450485ca1466a1237172e32d0ec12563bafe" + integrity sha512-aNmMkSN/hIMI9Mz8rqHLLySrxcDSlfy0soyfYUhlZSyW5S7u3VPA5YxMmrv9qcxs22rnsdD1uMJvxMdyUkgEMA== + dependencies: + debug "^4.2.0" + slate-irc-parser "^0.1.3" + source-map-support@0.5.13: version "0.5.13" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932"