11const { SlashCommandBuilder, MessageFlags, ActivityType } = require ( 'discord.js' ) ;
2- const fetch = require ( 'node-fetch' ) ;
3- const fs = require ( 'node:fs' ) ;
2+ const { fetchNewMessages } = require ( './../../backend/fetchNewMessages.js' )
43const { setChatPullInterval, clearChatPullInterval, getChatPullInterval } = require ( './../../backend/pullInterval' ) ;
5- const path = require ( 'path' ) ;
6- const { readFile } = require ( 'fs/promises' ) ;
7-
8- // Full Hackmud-to-Discord color mapping // = U+001B
9- const hackmudToDiscordColors = {
10- 'reset' : '\[0;0m' , // Reset text formatting
11- '0' : '[0;30m' , // Hackmud: #9B9B9B | Discord: Gray
12- '1' : '[0;37m' , // Hackmud: #FFFFFF | Discord: White
13- '2' : '[0;32m' , // Hackmud: #1EFF00 | Discord: Green
14- '3' : '[0;34m' , // Hackmud: #0070DD | Discord: Blue
15- '4' : '[0;35m' , // Hackmud: #B035EE | Discord: Pink
16- '5' : '[0;33m' , // Hackmud: #FF8000 | Discord: Yellow
17- '6' : '[0;33m' , // Hackmud: #FF8000 | Discord: Yellow
18- '7' : '[0;33m' , // Hackmud: #FF8000 | Discord: Yellow
19- '8' : '[0;33m' , // Hackmud: #FF8000 | Discord: Yellow
20- '9' : '[0;33m' , // Hackmud: #FF8000 | Discord: Yellow
21- 'a' : '[0;30m' , // Hackmud: #000000 | Discord: Gray
22- 'b' : '[0;30m' , // Hackmud: #3F3F3F | Discord: Gray
23- 'c' : '[0;30m' , // Hackmud: #676767 | Discord: Gray
24- 'd' : '[0;31m' , // Hackmud: #7D0000 | Discord: Red
25- 'e' : '[0;31m' , // Hackmud: #8E3434 | Discord: Red
26- 'f' : '[0;33m' , // Hackmud: #A34F00 | Discord: Yellow
27- 'g' : '[0;33m' , // Hackmud: #725437 | Discord: Yellow
28- 'h' : '[0;33m' , // Hackmud: #A88600 | Discord: Yellow
29- 'i' : '[0;33m' , // Hackmud: #B2934A | Discord: Yellow
30- 'j' : '[0;32m' , // Hackmud: #939500 | Discord: Green
31- 'k' : '[0;32m' , // Hackmud: #495225 | Discord: Green
32- 'l' : '[0;32m' , // Hackmud: #299400 | Discord: Green
33- 'm' : '[0;30m' , // Hackmud: #23381B | Discord: Gray
34- 'n' : '[0;36m' , // Hackmud: #00535B | Discord: Cyan
35- 'o' : '[0;36m' , // Hackmud: #324A4C | Discord: Cyan
36- 'p' : '[0;34m' , // Hackmud: #0073A6 | Discord: Blue
37- 'q' : '[0;34m' , // Hackmud: #385A6C | Discord: Blue
38- 'r' : '[0;34m' , // Hackmud: #010067 | Discord: Blue
39- 's' : '[0;34m' , // Hackmud: #507AA1 | Discord: Blue
40- 't' : '[0;35m' , // Hackmud: #601C81 | Discord: Pink
41- 'u' : '[0;30m' , // Hackmud: #43314C | Discord: Gray
42- 'v' : '[0;35m' , // Hackmud: #8C0069 | Discord: Pink
43- 'w' : '[0;35m' , // Hackmud: #973984 | Discord: Pink
44- 'x' : '[0;31m' , // Hackmud: #880024 | Discord: Red
45- 'y' : '[0;31m' , // Hackmud: #762E4A | Discord: Red
46- 'z' : '[0;30m' , // Hackmud: #101215 | Discord: Gray
47- 'A' : '[0;37m' , // Hackmud: #FFFFFF | Discord: White
48- 'B' : '[0;37m' , // Hackmud: #CACACA | Discord: White
49- 'C' : '[0;30m' , // Hackmud: #9B9B9B | Discord: Gray
50- 'D' : '[0;31m' , // Hackmud: #FF0000 | Discord: Red
51- 'E' : '[0;31m' , // Hackmud: #FF8383 | Discord: Red
52- 'F' : '[0;33m' , // Hackmud: #FF8000 | Discord: Yellow
53- 'G' : '[0;33m' , // Hackmud: #F3AA6F | Discord: Yellow
54- 'H' : '[0;33m' , // Hackmud: #FBC803 | Discord: Yellow
55- 'I' : '[0;33m' , // Hackmud: #FFD863 | Discord: Yellow
56- 'J' : '[0;33m' , // Hackmud: #FFF404 | Discord: Yellow
57- 'K' : '[0;32m' , // Hackmud: #F3F998 | Discord: Green
58- 'L' : '[0;32m' , // Hackmud: #1EFF00 | Discord: Green
59- 'M' : '[0;32m' , // Hackmud: #B3FF9B | Discord: Green
60- 'N' : '[0;36m' , // Hackmud: #00FFFF | Discord: Cyan
61- 'O' : '[0;36m' , // Hackmud: #8FE6FF | Discord: Cyan
62- 'P' : '[0;34m' , // Hackmud: #0070DD | Discord: Blue
63- 'Q' : '[0;34m' , // Hackmud: #A4E3FF | Discord: Blue
64- 'R' : '[0;34m' , // Hackmud: #0000FF | Discord: Blue
65- 'S' : '[0;34m' , // Hackmud: #7AB2F4 | Discord: Blue
66- 'T' : '[0;35m' , // Hackmud: #B035EE | Discord: Pink
67- 'U' : '[0;35m' , // Hackmud: #E6C4FF | Discord: Pink
68- 'V' : '[0;35m' , // Hackmud: #FF00EC | Discord: Pink
69- 'W' : '[0;35m' , // Hackmud: #FF96E0 | Discord: Pink
70- 'X' : '[0;31m' , // Hackmud: #FF0070 | Discord: Red
71- 'Y' : '[0;31m' , // Hackmud: #FF6A98 | Discord: Red
72- 'Z' : '[0;30m' , // Hackmud: #0C112B | Discord: Gray
73- } ;
74-
75- function Formatter ( message ) {
76- function convertHackmudColors ( text ) {
77- // Regex to detect backtick-wrapped strings with a leading color code
78- const regex = / ` ( [ a - z A - Z 0 - 9 ] ) ( [ ^ ` ] * ) ` / g;
79- return text . replace ( regex , ( match , code , content ) => {
80- // Map the color code to the corresponding Discord color if it exists
81- const discordColor = hackmudToDiscordColors [ code ] ;
82- if ( discordColor ) {
83- return `${ discordColor } ${ content } ${ hackmudToDiscordColors . reset } ` ;
84- }
85- // If no color is found, return the original match
86- return match ;
87- } ) ;
88- }
89-
90- // Extract timestamp and format it
91- const timestamp = new Date ( message . t * 1000 ) ;
92- const hours = timestamp . getHours ( ) . toString ( ) . padStart ( 2 , '0' ) ;
93- const minutes = timestamp . getMinutes ( ) . toString ( ) . padStart ( 2 , '0' ) ;
94- const formattedTime = `[0;30m${ hours } ${ minutes } [0;0m` ;
95-
96- // Format user, channel, and other elements
97- const formattedUser = `[0;33m${ message . from_user } [0;0m` ;
98- const formattedChnlBlue = `[0;34m${ message . channel } [0;0m` ;
99- const formattedChnlPink = `[0;35m${ message . channel } [0;0m` ;
100- const formattedTell = `[0;34mtell[0;0m` ;
101- const messageBord = `[1;30m:::[0;0m` ;
102-
103- let formattedMessage = "" ;
104-
105- // Apply color conversion to the message text
106- const convertedMessage = convertHackmudColors ( message . msg ) ;
107-
108- if ( message . is_join ) {
109- formattedMessage = `\`\`\`ansi\n${ formattedTime } ${ formattedChnlBlue } ${ formattedUser } ${ messageBord } ${ convertedMessage } ${ messageBord } \n\`\`\`` ;
110- } else {
111- if ( ! message . channel ) {
112- formattedMessage = `\`\`\`ansi\n${ formattedTime } ${ formattedTell } ${ formattedUser } ${ messageBord } ${ convertedMessage } ${ messageBord } \n\`\`\`` ;
113- } else {
114- formattedMessage = `\`\`\`ansi\n${ formattedTime } ${ formattedChnlPink } ${ formattedUser } ${ messageBord } ${ convertedMessage } ${ messageBord } \n\`\`\`` ;
115- }
116- }
117-
118- return formattedMessage ;
119- }
120-
121- function NowToRubyTS ( ) {
122- return Math . floor ( Date . now ( ) / 1000 ) ;
123- }
124-
125- function fiveMinutesAgoToRubyTS ( ) {
126- const fiveMinutesAgo = Date . now ( ) - 5 * 60 * 1000 ;
127- return Math . floor ( fiveMinutesAgo / 1000 ) ;
128- }
129-
130- async function loadChannelMappings ( ) {
131- const mapRaw = await readFile ( path . resolve ( __dirname , '../../channelMappings.json' ) , 'utf8' ) ;
132- return JSON . parse ( mapRaw ) ;
133- }
134-
135- async function loadPullUsers ( ) {
136- const configRaw = await readFile ( path . resolve ( __dirname , '../../config.json' ) , 'utf8' ) ;
137- const config = JSON . parse ( configRaw ) ;
138- return config . pullusers || [ ] ;
139- }
140-
141- async function loadMudToken ( ) {
142- const configRaw = await readFile ( path . resolve ( __dirname , '../../config.json' ) , 'utf8' ) ;
143- const config = JSON . parse ( configRaw ) ;
144- return config . mudtoken || [ ] ;
145- }
1464
1475module . exports = {
1486 category : 'mud' ,
@@ -168,70 +26,11 @@ module.exports = {
16826 }
16927
17028 await interaction . client . user . setStatus ( 'online' ) ;
171- await interaction . client . user . setActivity ( ' for new messages...' , { type : ActivityType . Custom , name : "custom" , state : "Listening for new messages..." } ) ;
29+ await interaction . client . user . setActivity ( { type : ActivityType . Custom , name : "custom" , state : "Listening for new messages..." } ) ;
17230
17331 await interaction . reply ( { content : 'Bot initialized. Listening for new messages...' , flags : MessageFlags . Ephemeral } ) ;
17432
175- let lastTimestamp = fiveMinutesAgoToRubyTS ( ) ;
176-
177- async function fetchNewMessages ( ) {
178- const channelMappings = await loadChannelMappings ( ) ;
179- const pullusers = await loadPullUsers ( ) ;
180- const mudtoken = await loadMudToken ( ) ;
181-
182- const apiUrl = 'https://www.hackmud.com/mobile/chats.json' ;
183- const payload = {
184- chat_token : mudtoken ,
185- usernames : pullusers ,
186- after : lastTimestamp ,
187- } ;
188-
189- try {
190- const response = await fetch ( apiUrl , {
191- method : 'POST' ,
192- headers : { 'Content-Type' : 'application/json' } ,
193- body : JSON . stringify ( payload ) ,
194- } ) ;
195-
196- const result = await response . json ( ) ;
197-
198- if ( result . ok ) {
199- Object . entries ( result . chats ) . forEach ( ( [ user , messages ] ) => {
200- if ( messages . length === 0 ) {
201- //console.log(`No new messages for user: ${user}`);
202- } else {
203- messages . forEach ( async ( message ) => {
204- const discordChannelId = channelMappings [ user ] ;
205-
206- if ( discordChannelId ) {
207- const formattedMessage = Formatter ( message ) ;
208-
209- // Fetch the Discord channel and send the message
210- const channel = interaction . client . channels . cache . get ( discordChannelId ) ;
211-
212- if ( channel ) {
213- const result = await channel . send ( formattedMessage ) ;
214- if ( result . code === 50013 ) {
215- console . log ( `No permission to send message in ${ channel . name } , message not sent` ) ;
216- return
217- }
218- }
219- }
220- } ) ;
221- }
222- } ) ;
223-
224- // Update the last timestamp
225- lastTimestamp = NowToRubyTS ( ) ;
226- } else {
227- console . error ( 'Hackmud API error:' , result . msg || 'Unknown error' ) ;
228- }
229- } catch ( error ) {
230- console . error ( 'Error fetching messages:' , error ) ;
231- }
232- }
233-
234- const interval = setInterval ( fetchNewMessages , 5000 ) ;
33+ const interval = setInterval ( ( ) => fetchNewMessages ( interaction . client ) , 5000 ) ;
23534 setChatPullInterval ( interval ) ;
23635 }
23736 if ( option === 'stop' ) {
0 commit comments