!7 cmodule DiscordModule > DynPrintLogAndEnabled { switchable S token; transient JDA bot; transient Color imageEmbedMysteriousLineColor = colorFromHex("36393f"); start { if (!enabled) ret with print("Not enabled"); vm_cleanPrints(); // avoid Swing Unicode problem logModuleOutput(); // good idea for chat bots // TODO: log JDA output going to System.out/err bot = discordBot(new ListenerAdapter { public void onMessageUpdate(MessageUpdateEvent e) pcall { temp enter(); ret if !enabled || !licensed(); long msgID = e.getMessage().getIdLong(); S content = e.getMessage().getContentRaw(); O lineConcept = dm_discord_lineForMsgID_unimported(msgID); S rendered = msgID + ": " + content; if (lineConcept == null) ret with print("Weird: Message edited, but not found: " + rendered); call(lineConcept, '_setField, editedText := content); print("Message edited: " + rendered); } public void onMessageReceived(MessageReceivedEvent e) pcall { temp enter(); ret if !enabled || !licensed(); bool bot = e.getAuthor().isBot(); long msgID = e.getMessage().getIdLong(); long userID = e.getAuthor().getIdLong(); Member member = e.getMember(); S userName = member == null ? null : member.getNickname(); // the changeable nick name - null sometimes? if (userName == null && member != null) userName = member.getEffectiveName(); if (userName == null) userName = e.getAuthor().getName(); final Message msg = e.getMessage(); long channelID = e.getChannel().getIdLong(); print("Channel type: " + e.getChannelType()); bool isPrivate = e.getChannelType() == ChannelType.PRIVATE; S content = trim(msg.getContentRaw()); print("Msg from " + userName + ": " + content); if (empty(content)) ret; vmBus_send('incomingDiscordMessage, litmapparams(fromBot := bot, module := dm_me(), +msgID, +userID, +userName, +content, +isPrivate, +channelID)); } public void onMessageReactionAdd(MessageReactionAddEvent e) pcall { temp enter(); ret if !enabled || !licensed(); MessageReaction r = e.getReaction(); bool bot = e.getUser().isBot(); long msgID = r.getMessageIdLong(); S emoji = r.getReactionEmote().getName(); vmBus_send('incomingDiscordReaction, litmapparams( fromBot := bot, module := dm_me(), +msgID, +emoji )); } }, +token); dm_registerAs('liveDiscordModule); } void cleanMeUp { if (bot != null) pcall { print("Shutting down bot"); bot.shutdown(); print("Bot shut down"); } bot = null; } O userConcept(User user) { S crud = dm_gazelle_linesCRUD(); O userConcept = dm_call(crud, 'uniqUser, user.getIdLong()); dm_call(crud, 'cset, userConcept, litobjectarray(name := user.getName())); ret userConcept; } // API MessageChannel getChannel(long channelID) { ret bot.getTextChannelById(channelID); } void postInChannel(long channelID, S msg) { postInChannel(getChannel(channelID), msg); } void postInChannel(MessageChannel channel, S msg) { S postID = cast dm_call(gazelle_postedLinesCRUD(), 'postingLine, channel.getId(), msg); channel.sendMessage(msg).queue(m -> { dm_call(gazelle_postedLinesCRUD(), 'donePosting, postID, "discord msg " + m.getId()); }); } void postInChannel(S channel, S msg) { long id = dm_discord_channelID(channel); if (id == 0) fail("Channel not found: " + channel); postInChannel(id, msg); } void postInChannel(MessageChannel channel, S msg, IVF1 onPost) { S postID = cast dm_call(gazelle_postedLinesCRUD(), 'postingLine, channel.getId(), msg); channel.sendMessage(msg).queue(msg2 -> { dm_pcall(gazelle_postedLinesCRUD(), 'donePosting, postID, "discord msg " + msg2.getId()); pcallF(onPost, msg2); final long msgId = msg2.getIdLong(); print("I sent msg: " + msgId); }, error -> _handleException(error)); } void postImage(MessageChannel channel, S url, S description) { channel.sendMessage( new EmbedBuilder() .setImage(absoluteURL(url)) //.setTitle(unnull(title)) .setDescription(unnull(description)) .setColor(imageEmbedMysteriousLineColor) .build()).queue(); // TODO: posted lines } void editMessage(long channelID, long msgID, S text) { getChannel(channelID).editMessageById(str(msgID), text).queue(); } void sendPM(long userID, S text) { bot.getUserById(userID).openPrivateChannel().queue(channel -> { channel.sendMessage(text).queue(); }); } }