Discord Chat Relay & Channel Message

Hydra

Helper
Staff member
Helper
Jan 26, 2019
23
6
3
30
Last Edited: 2020-03-26 - change-log:
Just implemented the new tags:
<&hover[HoverText]>/<&end_hover> | Returns a special chat code that makes the following text display the input hover text when the mouse is left over it!
<&click[/CommandName].type[suggest_command]>/<&end_click> | Returns a special chat code that makes the following text execute the input command when clicked!
Script is also more modernized, removing <def[definition] with <[definition]>, as well as pointless sub-tags such as playertag.name.*[/b] for their explicit unique tags, ie playertag.*_name. <context.author> also now has a fallback - webhooks can cause this tag to be invalid. thewith BotID switch changed to for:BotID Also, went ahead and added a command to message channels listed in the config!
Connects your discord bot to your Minecraft Server, and relays the chat two-ways as well as player events to your discord channel of choice. This script requires the plugin dDiscordBot found here: https://ci.citizensnpcs.co/job/dDiscordBot/ Preview:
6h9e2q8.png
Animated Emoji's Want animated Emojis? Discord bots are nitro-equiped! Here's a quick guide for that:
4035c07f33f17c0252aee25b228b50e3.gif
The most important part is adding it to your server, here's the flashy siren I use for my Admin-Bot commands: https://cdn.discordapp.com/emojis/537308050827116565.gif?v=1 When you add it to your server, if you have Nitro, you can take the easy way out: just type the emoji with a \ in-front of the emoji to escape the tag and collect the emoji ID. It should look something like this: <a:WeeWoo:537308050827116565> If you don't have Nitro, don't worry. You'll just have to do it the hard way. Open up the discord Developer Console using Ctrl-Shift-i, then toggle the Targeting tool by pressing Ctrl-Shift-C, and then click the emoji. On the right hand side, you'll see a link that looks something like this: https://cdn.discordapp.com/emojis/537308050827116565.gif?v=1 You want that number. Lastly, to narrate your fancy emoji, you have to have the bot send this combination: <&lt>a:Emoji_Name:Emoji_ID<&gt> for the above example, that looks more like this: <&lt>a:WeeWoo:537308050827116565<&gt> Be Warned - if these print back into minecraft, you see the full escaped emoji.
Instructions: 1 ) Drop main script into denizen/scripts/ 2a) Drop config file into denizen/data/Discord_Chat_Relay_Config.yml [make sure it's named this as well] 2b) If this directory doesn't exist, create it 3 ) Plug your bot token & channel ID into Discord_Chat_Relay_Config.yml 4 ) Restart server or reload scripts, followed by issuing the /discord reload -a command This script also has Votifier compatibility; if you want notifications in discord chat of votes, leave it as is, elsewise delete these lines (found on line 77-78):
Code:
# ███ [ Discord Player Events | Addons  ] ███
      on votifier vote:
        - discord id:discord_chat_relay message channel:<server.flag[discord.mainchat]> "<&co>diamond_shape_with_a_dot_inside<&co> **<context.username>** voted!"
Note: This event requires the plugin(s) DepenizenBukkit, Votifier. Here are the two scripts in a link you'll need Separately: *Click Here for the main script *Click Here for the configuration script Additionally, they can be copied here:
Main Script:
Code:
# ███████████████████████████████████████████████████████████
# ██ [           dDiscord Chat Relay                     ] ██
# ██ [                                                   ] ██
# ██ [   The config for this file should be              ] ██
# ██ [   SEPARATE from this script; you do               ] ██
# ██ [   NOT want to keep your bot token in ram,         ] ██
# ██ [   keep it separate. Anyone with your              ] ██
# ██ [   token has full access to your bot.              ] ██
# ██ [                                                   ] ██
# ██ [   Step one: Create a discord bot. If you          ] ██
# ██ [     need further instructions, you should         ] ██
# ██ [     seek a guide online.                          ] ██
# ██ [                                                   ] ██
# ██ [   You need to obtain # ID's:                      ] ██
# ██ [   * Your Bot Token. Can be obtained here:         ] ██
# ██ [   https://discordapp.com/developers/applications/ ] ██
# ██ [   * Your Discord Channel ID's.                    ] ██
# ██ [   Right click the channel > Copy ID               ] ██
# ██ [                                                   ] ██
# ██ [   Create a directory in your denizen folder:      ] ██
# ██ [   * /plugins/denizen/Data/                        ] ██
# ██ [                                                   ] ██
# ██ [   Create the external file inside:                ] ██
# ██ [   * Discord_Chat_Relay_Config.yml                 ] ██
# ██ [                                                   ] ██
# ██ [   Paste the bot's information                     ] ██
# ██ [                                                   ] ██
# ███████████████████████████████████████████████████████████

# ███ [ Discord chat format             ] ███
DiscordRelayChatFormat:
  type: format
  debug: false
  format: "<&3><&l>[<&r><&b>Discord<&3><&l>]<&r><&f><text>"

# ███ [ DiscordBot | Discord Control    ] ███
Discord_Relay_Chat_Handler:
  type: world
  debug: false
  events:

# ███ [ Server Startup                  ] ███
    on server start:
      - wait 5s
      - run Discord_Chat_Relay_Config instantly context:-a
      - wait 1s
      - discord id:discord_chat_relay message channel:<server.flag[discord.channel.mainchat]> "<&co>white_check_mark<&co> **Server has started**"

# ███ [ Ingame Chat Relay               ] ███
    on player chats:
      - discord id:discord_chat_relay channel:<server.flag[discord.channel.mainchat]> message "**<player.groups.get[1]||[Player]>** **<player.display_name.strip_color>**: <context.message.strip_color>"
    #$                                                     Don't have Permission Groups? Remove: <player.groups.get[1]>
# ███ [ Discord Chat Relay              ] ███
    on discord message received for:discord_chat_relay:
      #@ Check if the author is the bot, or if the message received is a webhook.
      - if <context.author||webhook> == <context.bot.self_user>:
        - stop
      #@ Check if the channel is being sent in the mainchat, if the message is blank
      - if <context.channel.id> == <server.flag[discord.channel.mainchat]> && <context.message> != "":
        - announce format:DiscordRelayChatFormat " | <context.author.nickname[<context.group>]||<context.author.name>><&r> <&8>»<&f> <context.message.parse_color>"


# ███ [ Discord Player Events           ] ███
    on player first logs in:
      - discord id:discord_chat_relay message channel:<server.flag[discord.channel.mainchat]> "<&co>confetti_ball<&co> **<player.name> has logged in for the first time. Welcome them!** <&co>confetti_ball<&co>"
    on player joins:
      - discord id:discord_chat_relay message channel:<server.flag[discord.channel.mainchat]> "<&co>heavy_plus_sign<&co> **<player.display_name.strip_color> has logged in.**"
    on player quits:
      - discord id:discord_chat_relay message channel:<server.flag[discord.channel.mainchat]> "<&co>heavy_multiplication_x<&co> **<player.display_name.strip_color> has left the server.**"
    on player dies:
      - discord id:discord_chat_relay message channel:<server.flag[discord.channel.mainchat]> "<&co>skull<&co> **<context.message>**"
    on shutdown:
      - discord id:discord_chat_relay message channel:<server.flag[discord.channel.mainchat]> "<&co>octagonal_sign<&co> **Server is restarting - Please wait**"
      - flag server discord.botstatus:!

# ███ [ Discord Player Events | Addons  ] ███
    on votifier vote:
      - discord id:discord_chat_relay message channel:<server.flag[discord.channel.mainchat]> "<&co>diamond_shape_with_a_dot_inside<&co> **<context.username>** voted!"

# ███ [ Discord Channel Command/Update  ] ███
Discord_Link_And_Configuration_Command:
  type: command
  name: discord
  debug: false
  description: Sends you the discord join link
  permission: discord.command
  permission message: "You do not have permission"
  usage: /discord
  aliases:
    - disc
  tab complete:
    - if <player.is_op>:
      - define Args <list[reload|message]>
      - define messageArgs <server.flag[discord.channels]||>
      #@ /discord█
      - if <context.args.size> == 0:
        - determine <[Args]>
      #@ /discord█Arg
      - else if <context.args.size> == 1 && !<context.raw_args.ends_with[<&sp>]>:
        - determine <[Args].filter[starts_with[<context.args.get[1]>]]>
      - if <context.args.get[1]> != Message:
        - stop
      #@ /discord█Arg█
      - if <context.args.size> == 1 && <context.raw_args.ends_with[<&sp>]>:
        - determine <[messageArgs]>
      #@ /discord█Arg█Arg
      - else if <context.args.size> == 2 && !<context.raw_args.ends_with[<&sp>]>:
        - determine <[messageArgs].filter[starts_with[<context.args.get[2]>]]>

  syntax message:
    #@ Message Hint event - inserts /discord
    - define Hover0 "<&a>Click to enter<&2>:<&nl><&6>/<&e>Discord"
    - define Text0 "<&6>/<&e>discord"
    - define Hint0 "discord"
    - define ClickEvent0 <&hover[<[Hover0]>]><&click[/<[Hint0]>].type[suggest_command]><[Text0]><&end_click><&end_hover>
    #@ Check if Player is Operator for Command Syntax
    - if <player.is_op>:
      #@ Message Hint event - inserts /discord reload
      - define Hover1 "<&a>Click to enter<&2>:<&nl><&6>/<&e>Discord Reload"
      - define Text1 "<&6>(<&e>reload<&6>)"
      - define Hint1 "discord reload"
      - define ClickEvent1 <&hover[<[Hover1]>]><&click[/<[Hint1]>].type[suggest_command]><[Text1]><&end_click><&end_hover>
      #@ Message Hint event - inserts /discord reload -a
      - define Hover2 "<&a>Click to enter Reload All command!"
      - define Text2 "<&6>(<&e>-a<&6>)"
      - define Hint2 "discord reload -a"
      - define ClickEvent2 <&hover[<[Hover2]>]><&click[/<[Hint2]>].type[suggest_command]><[Text2]><&end_click><&end_hover>
      #@ Message Hint event - inserts /discord message
      - define Hover3 "<&a>Click to enter Message Channel command!"
      - define Text3 "<&6>(<&e>Message ChannelName<&6>)"
      - define Hint3 "discord message "
      - define ClickEvent3 <&hover[<[Hover3]>]><&click[/<[Hint3]>].type[suggest_command]><[Text3]><&end_click><&end_hover>
    #@ Narrate Syntaxes
      - narrate "<&e>Syntax<&co> <[ClickEvent0]> <[ClickEvent1]> <[ClickEvent2]>/<[ClickEvent3]><&nl><&3><script.yaml_key[description]> as well as reloads the discord configuration if specified to reload, optionally includes reloading the discord bot token (-a)."
    - else:
      - narrate "<&e>Syntax<&co> <[ClickEvent0]><&nl><&3><script.yaml_key[description]>"
  script:
    #@ Check args; "/discord" or "/discord link"
    - define Arg1 <context.args.get[1]||null>
    - if <context.args.size> == 0 || <[Arg1]> == "link":
      - if !<server.has_flag[discord.link]>:
        - narrate "<&c>No link has been set up! Contact your server administrator to have them fix this!"
        - stop
      - define Hover "<&a>Click to follow the discord link!<&nl><&b><&n><server.flag[discord.link]>"
      - define Text " <&a>Link<&2>: <&b><&n><server.flag[discord.link]>"
      - define URL "<server.flag[discord.link]>"
      - narrate format:DiscordRelayChatFormat "<&hover[<[Hover]>]><&click[<[URL]>].type[OPEN_URL]><[Text]><&end_click><&end_hover>"
      - stop
    #@ Check args; "/discord ARG" requires operator
    - else if <context.args.size> > 1 && !<player.is_op>:
      - inject locally "syntax message" instantly
      - stop
    #@ Check args; "/discord reload -a" or "/discord reload"
    - else if <[Arg1]> == reload:
      - if <list[-a|null].contains[<context.args.get[2]||null>]>:
        - run Discord_Chat_Relay_Config instantly context:<context.args.get[2]||null>
        - stop
      - else:
        - inject locally "syntax message" instantly
    #@ Check args; "/discord message"
    - else if <[Arg1]> == "message":
      #@ Check args; did the player only specify "/discord message"?
      - if <context.args.size> == 1:
        - narrate "<&c>You must specify a channel to message!"
        - stop
      #@ Check args; did the player only specify "/discord message channelname"?
      - else if <context.args.size> == 2:
        #@ Does the channel even exist?
        - if <server.flag[discord.channels].contains[<context.args.get[2]>]>:
          #@ Okay, the channel exists but you still typed it wrong
          - narrate "<&c>You must specify a message to send!"
        - else:
          #@ Not only did you type a bad channel, you didn't even type a message
          - narrate "<&6>[<&e><context.args.get[2]><&6>]<&c> is an invalid channel, and you must specify a message to send!"
        - stop
      - else:
        #@ Check if the bot running
        - if <server.has_flag[discord.botstatus]>:
          - if <server.flag[discord.botstatus]> == running:
            #@ Check if the channel exists
            - define Channel <context.args.get[2]>
            - if <server.flag[discord.channels].contains[<[Channel]>]>:
              #@ Send!
              - discord id:discord_chat_relay message channel:<server.flag[discord.channel.<[Channel]>]> <context.args.remove[1|2].separated_by[<&sp>].parse_color.strip_color>
            - else:
              - narrate "<&6>[<&e><[Channel]><&6>]<&c> is an invalid channel!"
          - else:
            - narrate "<&c>Bot is not running!"
            - stop
        - else:
          - narrate "<&c>Bot is not running!"
          - stop
    - else:
      - narrate "<&6>[<&e><[Arg1]><&6>]<&c> is an invalid Discord Command!"
      - stop

# ███ [ DiscordBot | Configuration      ] ███
Discord_Chat_Relay_Config:
  type: task
  debug: false
  definitions: Arg2
  script:
    #@ Check if the Configuration file exists
    - if !<server.list_files[data].contains[Discord_Chat_Relay_Config.yml]>:
      - announce to_console "<&2>ERROR: CONFIGURATION FILE NOT FOUND.<&nl>For Support, ask in the <&e>Denizen Discord<&6>:<&nl> <&b>https://discord.gg/Q6pZGSR"
      - stop
    #@ Load the Configuration file
    - yaml load:data/Discord_Chat_Relay_Config.yml id:discord_chat_relay_temp
    - flag server discord.key:loaded
    #@ Check if doing a full reload
    - if <[Arg2]> == "-a":
      #@ Check if the bot is running; Disconnect if it is
      - if <server.flag[discord.botstatus]||false> == "running":
        - flag server discord:!
        - discord id:discord_chat_relay disconnect
      #@ Connect the bot
      - discord id:discord_chat_relay connect code:<yaml[discord_chat_relay_temp].read[bots.discord.botToken]>
      - flag server discord.botstatus:running
    #@ Flag the link and channels
    - flag server discord.link:<yaml[discord_chat_relay_temp].read[bots.discord.discordlink]>
    - flag server discord.channels:!
    - define Channels <yaml[discord_Chat_relay_temp].list_keys[bots.discord.channel]>
    - flag server discord.channels:|:<[Channels]>
    - foreach <[Channels].exclude[mainchat]> as:Channel:
      - flag server discord.channel.<[Channel]>:<yaml[discord_chat_relay_temp].read[bots.discord.channel.<[Channel]>]>
    - flag server discord.channel.mainchat:<yaml[discord_chat_relay_temp].read[bots.discord.channel.mainchat]>
    - yaml unload id:discord_chat_relay_temp
    - flag server discord.key:!
Configuration Script:
Code:
# ████████████████████████████████████████████████████ 
# ██ [           dDiscord Chat Relay              ] ██ 
# ██ [                                            ] ██ 
# ██ [   1] your bot token is placed in:          ] ██ 
# ██ [      [botToken: ]                          ] ██ 
# ██ [                                            ] ██ 
# ██ [   2] your channel ID is placed in:         ] ██ 
# ██ [      [mainchat: ]                          ] ██ 
# ██ [                                            ] ██ 
# ██ [   3] your discord link is placed in:       ] ██ 
# ██ [      [discordlink: ]                       ] ██ 
# ██ [                                            ] ██ 
# ██ [   4] your paypal/bank account information  ] ██ 
# ██ [      is placed in:                         ] ██ 
# ██ [      [the link through DonateLink]         ] ██ 
# ██ [                                            ] ██ 
# ████████████████████████████████████████████████████ 
bots: 
  discord: 
    botToken: '69.69.666.This.Is.Your.Bot.Token.666.69.69' 
    channel: 
     # Keep the main relay chat as "mainchat" 
      mainchat: '123456789012345678' 
     #YourChannelHere: `123456789012345678' 
    discordlink: 'https://discord.gg/4beFHHv' 
    DonateLink: 'https://one.denizenscript.com/donate'
Commands: /discord / /discord link | Gives you the discord link from your Config /discord reload | Reloads the discord configurations (Requires Operator) /discord reload -a | Reloads the discord configurations and completely restarts the bot (Requires Operator) /discord Message Channel <Message> | Messages a channel you put in your config as the bot (Requires Operator) Things to note:
  • You need to have your own bot, or at least a token to a bot with access to the discord channel you wish to relay chat to.
  • Your bot must have permission to send messages in the channel you wish to relay chat to.
  • you NEED to separate these files; never keep your discord token in ram. This second file is configured to be saved in as well as named: /plugins/denizen/data/Discord_Chat_Relay_Config.yml
 

n0nnie

Active member
This script is not working anymore. Since the Changes in the Tags. I had a hard time to figure out what is wrong and I came up with this in lines 58 and following:

# ███ [ Discord Chat Relay ] ███ on discord message received for:discord_chat_relay channel:<server.flag[discord.mainchat]>: - if <context.author> != <context.bot.self_user> && <context.is_direct.not>: - announce format:DiscordRelayChatFormat " | <context.author.name><&3><&l>]<&r> <&8>»<&f> <context.message.parse_color>"

This is a working solution but I think it can be made better. <context.is_direct.not> seems not to be necessary here, but I am not sure, since I did not test it further as it started to work again. Maybe the Author itself will update this to the new Tagsyntax (player.name.display <=> player.display_name) and the replace deprecated methods
 

Hydra

Helper
Staff member
Helper
Jan 26, 2019
23
6
3
30
n0nnie said:
This script is not working anymore. Since the Changes in the Tags. I had a hard time to figure out what is wrong and I came up with this in lines 58 and following:

# ███ [ Discord Chat Relay ] ███ on discord message received for:discord_chat_relay channel:<server.flag[discord.mainchat]>: - if <context.author> != <context.bot.self_user> && <context.is_direct.not>: - announce format:DiscordRelayChatFormat " | <context.author.name><&3><&l>]<&r> <&8>»<&f> <context.message.parse_color>"

This is a working solution but I think it can be made better. <context.is_direct.not> seems not to be necessary here, but I am not sure, since I did not test it further as it started to work again. Maybe the Author itself will update this to the new Tagsyntax (player.name.display <=> player.display_name) and the replace deprecated methods

Sorry to hear you had the issues you did. I've updated the script, and tested to verify the script works fully. I've also added some additional features, as well as lots of comments to explain how it works.

In regards to your code snippet here, the Channel: switch should actually Not work, it's invalid input. Event lines cannot contain tags, only static text and regex. I'd recommend checking the channel in the script with the tag in-case the ID of the channel you want firing the script changes.

I've also modernized the script entirely, replacing the playertag.name.* sub-tags with the new explicit unique tags, such as playertag.display_name and including the new hover and command click events :)
 

n0nnie

Active member
bear said:
n0nnie said:
This script is not working anymore. Since the Changes in the Tags. I had a hard time to figure out what is wrong and I came up with this in lines 58 and following:

# ███ [ Discord Chat Relay ] ███ on discord message received for:discord_chat_relay channel:<server.flag[discord.mainchat]>: - if <context.author> != <context.bot.self_user> && <context.is_direct.not>: - announce format:DiscordRelayChatFormat " | <context.author.name><&3><&l>]<&r> <&8>»<&f> <context.message.parse_color>"

This is a working solution but I think it can be made better. <context.is_direct.not> seems not to be necessary here, but I am not sure, since I did not test it further as it started to work again. Maybe the Author itself will update this to the new Tagsyntax (player.name.display <=> player.display_name) and the replace deprecated methods

Sorry to hear you had the issues you did. I've updated the script, and tested to verify the script works fully. I've also added some additional features, as well as lots of comments to explain how it works.

In regards to your code snippet here, the Channel: switch should actually Not work, it's invalid input. Event lines cannot contain tags, only static text and regex. I'd recommend checking the channel in the script with the tag in-case the ID of the channel you want firing the script changes.

I've also modernized the script entirely, replacing the playertag.name.* sub-tags with the new explicit unique tags, such as playertag.display_name and including the new hover and command click events :)

Thank you very much for updating and do not be concerned about my issues. In fact it was good for me to learn the changes and what I have to change in my own scripts :grin:

Regarding the tag in the event:
You might be right. In my version of the script that works is the channel "hard coded" since I do only have one and the - if command was in my way to get the script working again (to much debug messages). I changed it to the tag as I posted the snippet and was not aware of the point you showed. Thank you for pointing this out.