From 72d2316b334d15387f339d802a19bbeb0e164725 Mon Sep 17 00:00:00 2001 From: Hri7566 Date: Tue, 5 Dec 2023 23:57:59 -0500 Subject: [PATCH] Add Discord support --- .env.template | 1 + bun.lockb | Bin 16792 -> 26942 bytes config/ascii.txt | 10 ++++ config/ascii.yml | 1 + config/services.yml | 4 +- package.json | 1 + src/index.ts | 2 + src/services/discord/index.ts | 102 ++++++++++++++++++++++++++++++++++ src/services/index.ts | 8 +++ src/services/mpp/index.ts | 1 - src/util/ascii.ts | 18 ++++++ src/util/env.ts | 3 +- 12 files changed, 147 insertions(+), 4 deletions(-) create mode 100644 config/ascii.txt create mode 100644 config/ascii.yml create mode 100644 src/services/discord/index.ts create mode 100644 src/util/ascii.ts diff --git a/.env.template b/.env.template index 175a02a..6676a03 100644 --- a/.env.template +++ b/.env.template @@ -1,3 +1,4 @@ DATABASE_URL="postgresql://user:password@localhost/cosmic" MPPNET_TOKEN="" CHATBOX_LICENSE_KEY="" +DISCORD_TOKEN="bot token" diff --git a/bun.lockb b/bun.lockb index 18433abd50f50978d67b915f983ce8656861d905..b8009414198d1659a64e65d9d39cb9c9660bf330 100755 GIT binary patch delta 8450 zcmeG>d0bOhv-gGo3Hzc#LNRYZk1bCV0P>ihlP_uilH{BrKxnKLtI&YU?X=geI( zi#~pZULx+9E&G@G#YdxWjVl=WTm8kGOVVGb^c+<27u>xU0GXuV~ zxa>(O(3WSY!BYXEf$;!Q@i2fk00RM{Ua7Xdm$uze3#|Z}QEIBN28L@5jKR}WmoK?|Br-s|A3zkyR*BM-d5SE1z_BA&3ySIhFf}7FP6adT26P~` z>0>)$4Rr&fu-yS58ur+VqROi1PmN&@3y^kWdblYRRGJeCE?|vS#w88kj zhfCevi~Fsl#it&f>7=eolJmTH0Y_?6W;*PfvOIWg?e_IHN1Il>U;Uu!!7iS3S$D~T zkY87CljOd+8scDiZtUZSV=u&Gs0%}5@Nxz9kt_T^3$}YZ-sdW?p(W3=lqq| z)MsBUznIY~IJcBvJ7>?12d0BZ{5g1`)yW6B{%iV9>S$Ag9NZ5O|i5B6!{)l?HNsHwafRQmyApr;rdsIlY|}8Or(BfePVK$R%N1 z87(Ayo}5l4A@GEDc)lW)@N^}7zMLLSLilq2A_IyV2of~0T!VG0}XHo>TCB*4RtgU|Aq?uHh|3n1AxZqt`QMT@oG(2P&NAFSs;bkcrXWPTlLloV?D3R9OUEg|f)Mp|(L&gsM#C#b;XZ{0Au58+lYx!^u{c6S zL1(Dg?gAAHLd3gjVK;z$GTvNBQq3*2m8V7ycc@rC2O+d5f2gqJaE_UR5b=>3l!2&c zlotOVK-l=Tf~X)2DniY`H4yP|sPI2UjfILu7vj)k80yCm<;H92x)Av%Kt&h_e|$`d z(*Pi}7o2dcSUv|)!T);lwf%o?_L+|VPbVKViW#l#kYt*h{C_;O$AfmF**J(RduuV< zG_a*($BRJ@yRGI`T5a99`taG`p4=-pGI{lT75_;>murzNy}He788K|;qU_hQjFFD- zy3Fm~*ztm$%+XYfc?$$~Pwgxs z;5u24Tafa2#__kdrw1-}YuH+ywq#MoF0%IDMfDSo22uJB2VFz2Hoq6lQJ?9poWgZk z_mwnhfx(m8^G;v437x??{2fUX+N#&&A3G)QvHgJlz*D`3XM4W#w$2+CHA>>TCTRYg z@0)$&984ES@b9?X&iN&vv~Jl3^PV-+mR}a;kN&B`a(vqN`LA@W>#b{DocH{gBXtkQ z^>(XTz45gFfE^7vR;m=_)RA@B90k5!UX1)$v2?x+>poEbec%H#}ssqRMjUq3xt$*N3W3 zoI9?L$<1Sj>dE4a-s{=({-~WX{oF6^J35@NFV@j3qS$=^h}@>_gWsA&hnF3Cc0BE_ z@?qc>L6TX)(FZ4tY8N!s7Aj^%^se+OSbW=Mg2<(O@v3PV(yLj+lk1;eOk16xn6l4u zkB(w?wV~ZyD%ew4TW=fQ@L|{bF(#c}?oS_8WO+4WOb>^5GCj3^V`jKn;Im!wip_QB zb~R z@?fiB3Je4#%tHT zTPB=&+2ul~-*;}%|LdEJbM>oASMQ#@dg7sK-|kM;n}Zhpy))H6{BhSKI*Pq?6?g1= zY|x$AZsYg+>*eRTSBUKVYYIxT!frLMaa>k(r^&)+LZZ?1m}T}ouBJ8~E}htWYLnC8 z%T9}vt7fPh!V`yVmOGj749_~OB1^9|HVRI@D{z)XuFE`-RqNF{EOMC(&%EXE>#z-dBYuq9P_rZSU>XU3PF9Z7bZElHJZFDMeX&j}|7Ef2bMdMPw!Kul;+t@zm9OOs&>My!@c= z*Jom8VnUCVz4l!)FI6Aee4%CN%LA>a9WPtFAC&hEsAA_1j%{s)>pE(oZ^Mt-K}Ord zrjYf*$ifbhlO)g2`c}#B|DBt?L$-CV)8kRgM^txpKQ?ga`IcUw_&Psw=K%wjfI#}1jKc-B~W$tRI3h}dZp^JTwC99Jt`gRXWZ$#YR3!TW>xw? zp-sB9F!k*HXL~#IB$o<*i4**FOf9ndu4~0R!&6=_0$b@cYr*?%amx?suc*

x3uoJ$5MB#<6Jxw$T@Zid zJ(DNrr3MC%?L2(<4D03ZZ+~&{#5*4{;{)CalqSxOrdxMKR?BGV^!qxBF`(JP9qO`` zC)oU=@$%sOBR2F+-&VdL)L!fJ`P4c*m#Y;1Wf+jeJYW~{rtjQK`|25<5 zJJa@a9FBbZqt&iQB&Szn)WmZU%$}#eUW267}xP z+S50mA2Bvc`7{9(v3dhor2x6b2PY>4|NNaz?TEE4yAR|Ug|1eo-XH#_qQ$Yn$!+DE zMGspmd@BDOm^FM%QHx!5&X(}P>ZCOd+S724XYU0Z23+np&1drtld(N$ICc}SPaP#+}qQk2;suHaK=r0XBqKr7IoNRDp zTXjr5ZVs%)fx3!ABAafXUN|*p(e;w$cMl)g-=nIYI^MIP^W?A&f|-A)cGupv&7=rKyfZ9lQ0?#H?S2D2bu18M`eh3 zJ-{m%Ho{Gjp`FBw3Y4pZ$ykvq+3Myt2zjBY#!I6`%TY6lhX zet6dz2h|0tGt@3n?V$>x+Cs&XC|qu-5m3=XIMB{eagZGthoW{UvqNBX&ZamoIB@h* ze^Mmctqz1Yj82rsF{1tGf3yaVQs`S88;%iAlyDcOdO&4;fIdMvqu0D&SMQhhoS)6IU0wPkNn!0YQ-Vr`=JncfwC-|j264 zR@x#vhA5l1<3K=QA$P@HAcyo$ETO}QySsp%KtkLlkeQm{-pi1V^%hISUZm9BhmIzX z+$G+NA*Reg&1LTnW1{c8GVDMH_x5??QY9h=oH z$SSK0y1A(wBs@LDQn7@Rk_<0_H=6|>d@}aCX&rlKacF20W1zEnV&$~hji(-&{|J&E zVi}Gxo*VP;Aha!W?$KK zC5M(k3x*Aw?`0F39J&v*U|g`NVm6P;p*_SBnb^mZVspN1k`%RhiY00gV$;5Co)m}Z z$#leKqS-VphxQWt!1PiSo3myUx*QtjPliowKHrcVGUL!9zYA!brxaV*G&GyHMOUlA zW8e`sQ_ZG!8DC1!4Q$e!%_yS~6JivbMrU)(?fzvG?rb)?U4}`SLtL`?WR4ouLCk*6 zsj*tGvUztlDa~}`g(Ld1yFc|DOg`hfkNrbTJa}sK&Zltz0!);Dd7NMN%_rk*8|J4` z6|2_9)qgTh_8SG8z-L^|`18vi_-E`yw+GLcNAzX?u%AuXZwk!xFrH)f8ujP*8Xs80 zU!Fep%Lw}^0dz{leK8)tEc59K0~t@T8id#nFYK2JQ0D`a%d}{|^|Y@rHctMNCGj~E zoN$>_6#I>b{U`z^z$%9o>&bYDbd^Xu;P)K(Q!eaVI$(eWXW?QFeZY#ON*s;ug~O7E zGI0zkkpz+J5-<81;Y;P6uK^L#`GvFlcvsPRW-Uv`FnrYJNhDqxZKpqRdJb_layHscU5}E)TGq7 z$qFr-C@xbe%FfSJsFLDT*`h>+B2%Q8k`tGz8LwEC4!j9*Dh28tiN=89_#9iGZ{G`Z@`XnP=n#&!fpiei2`tZWzqBl`;d z!vE>Vv8S382g_rUG6}*fz|Mx`Z#T>iOA+nCxHE(!4KhHj+$qN`lmo!>S!*e|;+;54D*bzRyX S<-pmFFmnWBDU-{iIsXM@0L5ki delta 2227 zcmcIlU2IfU5I*P9W$$ixX)7&syI`RZ)7zhG_phzc_O?`Q>9#=9#lnO9)bg`vp-{vc zkX=GCG$0BS|1mMe2Ueq`tPdCsfhQrLt~`hl{0WA{Ypg{fR?p+^@C@)Mh^PQP< zX6D?vbIv(_PQJ8LKBsHL$=@rguSK8!@p|jP<*^q&C_K9Dqj!J$bKRnmw^yqdUf!p+ z2$QPz_mnEvEB6nT$9iFK3K4%|Ff+AK3gLjB0_FlID?+${1Dm3Q{VRnSg`Nj}F_yc5 zS-;qXj6M%o0Q=yEM;_&nk(`WwbRZMI7&_-uZRYw|yaxkL{VO-GU5B~#_Ke;OXZ>dL=LFx~~`(D0t1s6*@63lu@ub2$c{6?Y%c>dF|t0(!r4F+R#bzT{vUZO zw^%5tacXId)7F3){a~hlBHQjz9b>m!NZ!L8sAH=c_cjW7>vd)wr~hXilkb%byQ$h2 zrrqUk+T{yNjXw4DP`&1+kUuOdlRNx*QeA-{sB=7dHP|d^hAoFK237SG4kS)P#+nS) z$5m%DUofC;Rdnou2AtNL;~8ROIhdOUr_!XX&O4l9*)$-pIcx=5R83#CmC=a@tK7H{ z`F1v&VmA5OW<61S3N8D=J zcAXP)9#IL#Ar|H2Za-3DeaJZPkjFzh2B5tG+Bg3mIyQeT&FLt?{j<0u;BCVM7i{9j z)ajN_b~qKe%%}VGfDnu6P)7ha-T96RJAXKc)Nrj_NJco|-Gy&wzf`C&vh?CF_Cndz z7}9HWzaV-h?2#!d==R`VK8f)tT?l);*(c_WzU5Dic5diKCcp02eL~Emyv~3(`-Xjg zZs(Tj=imQXk=uO;h?7-J4|jIS2))(m@meoe{EyQ+FMW5zwhB==Emrl=*PR|&OxLhh zrM9jBf*@-;N(XYF5C{5wnk2+lgf_ zZY`?Zq{yHi(1R#M3*A8E?4!5H;m%XGM;!1BU@y3gd&#%JgLfyqz~jljaIQB~sW~|Z z*J4$T?hEQQq;-dy+HwE#gL&UOt*!aW-e(nA3=5L~{pL?NaD2zTHNU0vCI4ck&+&Jd zmIUcw_dNQhyGEX&f{0Oa21Ybre7HVzRt` { + constructor(private token: string) { + const cl = new Discord.Client({ + intents: ["Guilds", "GuildMessages", "MessageContent"] + }); + + super("discord", cl); + } + + private wasDestroyed = false; + + public start(): void { + this.wasDestroyed + ? (this.client = new Discord.Client({ + intents: ["Guilds", "GuildMessages", "MessageContent"] + })) + : undefined; + + this.wasDestroyed = false; + + this.client.login(this.token); + } + + public stop(): void { + this.client.destroy(); + this.wasDestroyed = true; + } + + private lastChannelId: string | undefined; + + public getLastChannelId() { + return this.lastChannelId; + } + + protected bindEventListeners(): void { + this.client.on("ready", () => {}); + + this.client.on("messageCreate", async msg => { + const _id = "DISCORD_" + msg.author.id; + + this.emit("chat", { + m: "a", + a: msg.content, + p: { + _id, + name: msg.author.username, + color: msg.author.hexAccentColor || "#000000", + platformId: msg.author.id + } + } as ChatMessage); + + let args = msg.content.split(" "); + + const str = await CommandHandler.handleCommand( + { + m: "command", + a: msg.content, + argc: args.length, + argv: args, + p: { + _id, + name: msg.author.username, + color: msg.author.hexAccentColor || "#000000", + platformId: msg.author.id + }, + originalMessage: msg + }, + this + ); + + if (str) { + if (typeof str == "string") { + const channel = await this.client.channels.fetch( + msg.channelId + ); + + if (!channel) return; + if (!channel.isTextBased()) return; + channel.send(`\u034f${str}`); + } + } + }); + + this.on("send chat", async text => { + if (!this.lastChannelId) return; + + const channel = await this.client.channels.fetch( + this.lastChannelId + ); + + if (!channel) return; + if (!channel.isTextBased()) return; + + channel.send(`\u034f${text}`); + }); + } +} diff --git a/src/services/index.ts b/src/services/index.ts index c3348c6..f2ac3cc 100644 --- a/src/services/index.ts +++ b/src/services/index.ts @@ -4,6 +4,7 @@ import { ServiceAgent } from "./ServiceAgent"; import { loadConfig } from "../util/config"; import { SwitchChatAgent } from "./switchchat"; import { ConsoleAgent } from "./console"; +import { DiscordAgent } from "./discord"; /** * Services are anything (any platforms or environments) that the bot will directly communicate to users with @@ -79,6 +80,13 @@ export class ServiceLoader { this.addAgent(switchChatAgent); } + if (config.enableDiscord) { + const discordAgent = new DiscordAgent(env.DISCORD_TOKEN); + + discordAgent.start(); + this.addAgent(discordAgent); + } + if (config.enableConsole) { const consoleAgent = new ConsoleAgent(); diff --git a/src/services/mpp/index.ts b/src/services/mpp/index.ts index e329c7e..6c3164c 100644 --- a/src/services/mpp/index.ts +++ b/src/services/mpp/index.ts @@ -73,7 +73,6 @@ export class MPPAgent extends ServiceAgent { ); if (str) { - this.logger.debug(str); if (typeof str == "string") { if (str.includes("\n")) { let sp = str.split("\n"); diff --git a/src/util/ascii.ts b/src/util/ascii.ts new file mode 100644 index 0000000..29f8e06 --- /dev/null +++ b/src/util/ascii.ts @@ -0,0 +1,18 @@ +import { loadConfig } from "./config"; +import { readFileSync } from "fs"; + +const config = loadConfig("config/ascii.yml", { + path: "config/ascii.txt" +}); + +export function printStartupASCII() { + const data = readFileSync(config.path); + + // To make a compromise with PM2's logs, + // we will attempt to write every line + // with a color character so the entire + // file is printed in color. + for (const line of data.toString().split("\n")) { + process.stdout.write(`\x1b[35m${line}\x1b[0m\n`); + } +} diff --git a/src/util/env.ts b/src/util/env.ts index f4be196..1de7e20 100644 --- a/src/util/env.ts +++ b/src/util/env.ts @@ -8,7 +8,8 @@ export const env = createEnv({ isServer: true, server: { MPPNET_TOKEN: z.string(), - CHATBOX_LICENSE_KEY: z.string() + CHATBOX_LICENSE_KEY: z.string(), + DISCORD_TOKEN: z.string() }, runtimeEnv: process.env });