Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image Upload data

222
LINES

< > BotCompany Repo | #1023434 - Discord Include [just Discord reading & posting]

JavaX fragment (include)

import net.dv8tion.jda.core.events.guild.member.*;

switchable S discordToken;
S discordBotName;
long discordBotID;
bool reactToBots = true;
  
transient JDA discord;
transient Color discordImageEmbedMysteriousLineColor = colorFromHex("36393f");

void startDiscord {
  if (!discordEnabled()) 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
  discord = discordBot(new ListenerAdapter {
    @Override
    public void onMessageUpdate(MessageUpdateEvent e) pcall {
      temp enter();
      ret if !discordEnabled() || !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);
    }
    
    @Override
    public void onMessageReceived(MessageReceivedEvent e) pcall {
      temp enter();
      ret if !discordEnabled() || !licensed();
      
      User user = e.getAuthor();
      if (!reactToUser(user)) ret;
      bool bot = user.isBot();

      long msgID = e.getMessage().getIdLong();
      long userID = user.getIdLong();
      long guildID = toLong(call(e.getGuild(), '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();
      
      MessageChannel channel = e.getChannel();
      long channelID = channel.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, event := e, +guildID,
          +content, +isPrivate, +channelID, +channel));
    }
    
    @Override
    public void onMessageReactionAdd(MessageReactionAddEvent e) pcall {
      temp enter();
      ret if !discordEnabled() || !licensed();
      MessageReaction r = e.getReaction();
      
      if (!reactToUser(e.getUser())) ret;
      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 
      ));
    }
    
    @Override
    public void onGuildMemberJoin(GuildMemberJoinEvent event) pcall {
      temp enter();
      print("Got guild join");
      ret if !discordEnabled() || !licensed();
      
      print("Join >> getting user ID");
      long userID = rcall_long getIdLong(rcall getUser(event.getMember()));
      print("Join >> sending");
      vmBus_send('discordGuildJoin, litmapparams(
        module := dm_me(), +event, +userID, guildID := discord_guildIDFromEvent_gen(event)
      ));
    }
    
    @Override
    public void onGuildMemberLeave(GuildMemberLeaveEvent event) pcall {
      temp enter();
      print("Got guild leave");
      ret if !discordEnabled() || !licensed();

      long userID = rcall_long getIdLong(rcall getUser(event.getMember()));
      vmBus_send('discordGuildLeave, litmapparams(
        module := dm_me(), +event, +userID
      ));
    }
  }, token := discordToken);
  
  dm_registerAs('liveDiscordModule);
  dm_vmBus_answerToMessage activeDiscordTokens(func -> LS { ll(discordToken) });
  pcall {
    setField(discordBotName := jda_selfUserName(discord));
    setField(discordBotID := jda_selfUserID(discord));
  }
  print("Bot name: " + discordBotName);
}

void cleanMeUp {
  if (discord != null) pcall {
    print("Shutting down discord");
    discord.shutdown();
    print("Bot shut down");
  }
  discord = 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 discord.getTextChannelById(channelID);
}

void postInChannel(long channelID, S msg) {
  if (channelID == 0) ret;
  postInChannel(getChannel(channelID), msg);
}

void postInChannel(MessageChannel channel, S msg) {
  msg = shortenForDiscord(msg);
  S postID = cast dm_call(gazelle_postedLinesCRUD(), 'postingLine, channel.getId(), msg);
  print("Posting in channel " + channel + ": " + 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<Message> 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(Map msgMap, S url) {
  postImage(msgMap, url, "");
}

void postImage(Map msgMap, S url, S description) {
  postImage((MessageChannel) get channel(msgMap), url, description);
}

void postImage(MessageChannel channel, S url, S description) {
  channel.sendMessage(
    new EmbedBuilder()
      .setImage(absoluteURL(url))
      //.setTitle(unnull(title))
      .setDescription(unnull(description))
      .setColor(discordImageEmbedMysteriousLineColor)
      .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) {
  discord.getUserById(userID).openPrivateChannel().queue(channel -> {
    channel.sendMessage(shortenForDiscord(text)).queue();
  });
}

void reply(Map msgMap, S text) {
  if (empty(text = trim(text))) ret;
  postInChannel((MessageChannel) msgMap.get('channel), text);
}

void iAmTyping(Map msgMap) pcall {
  ((MessageChannel) msgMap.get('channel)).sendTyping().queue();
}

S startKeepAliveModule() enter {
  ret dm_discord_startKeepAliveModule(module());
}

bool reactToUser(User user) {
  bool bot = user.isBot();
  
  // don't react to other bots
  if (bot && !reactToBots) false;
  
  // don't read msgs from myself
  if (user.getIdLong() == discordBotID) false;
  
  true;
}

Author comment

Began life as a copy of #1022869

download  show line numbers  debug dex   

Travelled to 3 computer(s): cfunsshuasjs, mqqgnosmbjvj, tvejysmllsmz

No comments. add comment

Snippet ID: #1023434
Snippet name: Discord Include [just Discord reading & posting]
Eternal ID of this version: #1023434/44
Text MD5: d5fa2dd98b49e673021e2c03de3f7a1e
Author: stefan
Category: javax / discord
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2019-09-10 17:48:34
Source code size: 7283 bytes / 222 lines
Pitched / IR pitched: No / No
Views / Downloads: 116 / 560
Version history: 43 change(s)
Referenced in: [show references]