This ioBroker adapter integrates a Discord bot into ioBroker.
The adapter will create an object tree including objects and states for server and channel where the bot is on.
Also an object tree with all users seen by the bot will be created.
Using this states, it's possible to receive and send messages and files on Discord.
Additionally, the adapter can register Discord slash commands to get and set ioBroker state values.
- ioBroker.discord
- Features
- Creating a Discord bot
- Adding the bot to a server
- States
- Authorization
- Messages
- Slash commands
- Blockly
- Usage in scripts
- Send a message from a script
- Edit a message from a script
- Delete a message from a script
- Add a reaction emoji to a message from a script
- Await reactions to a message in a script
- Reply to a custom slash command from a script
- Get information about a server in a script
- Get information about a server channel in a script
- Get information about a user in a script
- Get information about a server member in a script
- Get information about a previous message in a script
- ioBroker states for all servers of the bot to receive and send messages
- ioBroker states for all users seen by the bot to receive and send direct messages
- Simplified Discord server join and leave for the bot
- Set the bot status including actions
- Optional observe user presence status
- Optional observe server member voice status
- Server member voice actions (mute, deafen, disconnect)
- Handle all messages or only messages with bot mentions on server channels
- Handle direct messages
- Optional automatic react with a emoji on mentions
.json
states for channel, user and message data- Send messages, files, reactions (emojis), reply messages, or custom json-formated message contents
- List server and channel members including member roles
- Support for Discord slash commands to get and set state values
- Support for user defined Discord slash commands to be handled by custom scripts
- Support for text2command (has to be enabled for each
.message
state where it should be used) - Send, edit and delete messages, add and await message reactions using Scripts
- Optional raw states to allow more flexibility in custom scripts
- Support for Blockly with custom blocks to send and edit messages and to handle custom slash commands
What's not supported and not intended:
- Messages in threads
- Send and receive voice messages
Missing some feature? Feel free to submit a feature request on GitHub.
To use this adapter, you need to create a Discord bot application.
- Got to the Discord Developer Portal and login with your Discord account if not already logged in.
- In the Applications view, click the button New Application in the top right.
- Choose a name for your application (this will be the name of your bot) and click Create.
- (Optional) Upload an App Icon, edit the Name, edit the Description, add some Tags and Save Changes.
- Navigate to Bot in the left menu and click the Add Bot button.
In the following dialog click Yes, do it! to confirm the bot creation. - When the bot is created, you need to click the Reset Token button once to get you bot token.
Since this will invalidate any former token, you need to confirm this by clicking the Yes, do it! button in the dialog popping up.
After this, your token is displayed once and you should copy it to a secure place (e.g. the adapter instance configuration). - Scroll down a bit at the Bot page to the Privileged Gateway Intents and enable Presence Intent, Server Members Intent and Message Content Intent. Don't forget to click Save Changes.
Note: Once your bot reaches 100 or more servers, the intents will require verification and approval. - Now you are ready to start the adapter instance and add the bot to a Discord server.
To add the bot to a server, you need to go to the adapter instance configuration to the tab Add bot to server. There you get a link which you can use to add the bot to a server, while setting the correct scopes and permissions.
The following bot permissions are required:
- Change Nickname
- Read Messages/View Channels
- Moderate Members
- Send Messages
- Embed Links
- Attach Files
- Read Message History
- Mention Everyone
- Add Reactions
- Mute Members
- Deafen Members
- Move Members
Also the following scopes are required:
- bot
- applications.commands
If some of the above permissions or scopes are missing, some features of the adapter might not work.
To remove the bot from a server, you may use the server select field on the same adapter instance configuration page. Just select the server and click the button to instruct the bot to leave the server.
Each server, channel and user is identified by its unique numeric ID.
Because names may change, the object tree created by the adapter uses these IDs
to create a reliable structure.
The whole object tree is built from what bot can see. So it is possible, for example, that a server has more channels as displayed.
Name | Description |
---|---|
activityType |
The type of the bot activity. One of Playing , Streaming , Listening , Watching , Competing , Custom or an empty string. |
activityName |
The name of the bot activity. Only used if a type is set. |
status |
The presence status of the bot. One of online , idle , dnd and invisible . |
This is used to set the presence status and activity of the bot which should be displayed to users.
Name | Description |
---|---|
channels.* |
Channels of the server. |
members.* |
Members of the server. |
Name | Description |
---|---|
channels.* |
Only present if the channel is a category. Structure is the same as in server channels. |
memberCount |
Number of members in the channel. |
members |
Comma separated list of members (display names) in the channel. |
message |
Last received message in the channel. |
messageId |
The ID of the last received message. |
messageAuthor |
The author (unique username or tag) of the last received message. |
messageTimestamp |
Timestamp of the last received message. |
messageJson |
JSON data for the last received message. |
send |
Send some text or JSON formated message. |
sendFile |
Send a File. |
sendReply |
Send a reply to a message. |
sendReaction |
Send a reaction (emoji) to a message. |
json |
JSON data of the channel information. |
For all message*
and send*
states see Messages section below.
Name | Description |
---|---|
tag |
The unique tag of the user in discord. |
name |
The name of the user in discord. (unique if the tag ends with #0 ) |
displayName |
The display name of the user on the server. |
roles |
Comma separated list of roles of this member on the server. |
joinedAt |
Time when the user joined the server. |
voiceChannel |
Currently connected voice channel of the user. Empty string if not connected. |
voiceDisconnect |
Button to disconnet the user from voice. |
voiceSelfDeaf |
Indicator if the users voice is deafened by the user. |
voiceSelfMute |
Indicator if the users voice is muted by the user. |
voiceServerDeaf |
Indicator if the users voice is deafened by the server. Can also be used to set the server deafen state. |
voiceServerMute |
Indicator if the users voice is muted by the server. Can also be used to set the server mute state. |
json |
JSON data of the member information. |
For the voice*
states to be up to date, the option Observe user voice state in the instance configuration must be enabled.
To use the voiceDisconnect
, voiceServerDeaf
and voiceServerMute
actions, the bot needs to have the related permissions on the server.
Name | Description |
---|---|
tag |
The unique tag of the user in discord. |
name |
The name of the user in discord. (unique if the tag ends with #0 ) |
status |
The presence status of the user. One of online , offline , idle , dnd |
activityType |
The type of the current user activity. One of Playing , Streaming , Listening , Watching , Competing , Custom or an empty string. |
activityName |
The name of the current user activity. E.g. the name of a game while Playing . |
avatarUrl |
URL to the avatar of the user. |
bot |
Indicator if the user is a bot. |
message |
Last received direct message from the user. |
messageId |
The ID of the last received direct message from the user. |
messageTimestamp |
Timestamp of the last received direct message from the user. |
messageJson |
JSON data for the last received direct message from the user. |
send |
Send some text or JSON formated message. |
sendFile |
Send a File. |
sendReply |
Send a reply to a received message. |
sendReaction |
Send a reaction (emoji) to a received message. |
json |
JSON data of the user information. |
For the status
and activity*
states to be up to date, the option Observe user presence in the instance configuration must be enabled.
For all message*
and send*
states see messages section below.
If custom commands are enabled in the adapter instance configuration, the following states will be present.
All this states will be updated on each call of the custom command.
Name | Description |
---|---|
json |
JSON data of the last use of the command. This contains some additional information which are not present in the single states. |
interactionId |
ID of the last use of the command. |
userId |
ID of the user, who called the command. |
userTag |
Tag of the user, who called the command. |
userName |
The name of the user, who called the command. (unique if the userTag ends with #0 ) |
channelId |
ID of the channel, where the command is called. |
serverId |
ID of the server, where the command is called or null if the command is used in a direct message. |
timestamp |
Timestamp of the last use of the command. |
option-* |
Options which are configured for the command. |
option-*.value |
The last value provided to this option on command call. If an option is not provided, this state will be set to null . |
option-*.choices |
JSON array containing predefined choices for this option. Only present on options of type string. Example: ["Value 1", "Value 2", { "name": "Value 3", "value": "val3" }] |
sendReply |
Send a reply to a called command. Like in .send states of a channel or user, this may be sting or stringified JSON object. See Messages section below. |
Note: It's recommended to use the json
state in custom scripts to prevent
overlaps.
Example: A custom script reads the single option-*
states while
some user called the command again and the options from the first and the
second command get mixed up.
If raw states are enabled in the adapter instance configuration, the following states will be present.
Note: These states contain raw data without any checks, filters or modifications by the adapter. A server will be named guild.
Name | Description |
---|---|
messageJson |
Raw JSON data of the last received message. (Channel messages and direct messages) |
interactionJson |
Raw JSON data of the last received interaction. (e.g. slash commands) |
By default, authorization is enabled and only authorized users are able to interact with the adapter.
The authorized users and server roles can be configured in the adapter instance
configuration including some per user/role permissions.
For server roles, the permissions only apply to the specific
server and not to other servers or direct messages.
If permissions are given per user and server role, they will be
merged for the corresponding server.
The users and roles are identified by their internal ID, so changes of the user tag, user name or role name don't affect the authorized users/roles lists.
It's possible to disable the authorization, but this should be done only if any user on any server of the bot can be trusted!
The adapter is able to receive and send messages from/to discord text channels and users.
By default, in channels only messages with mentions of the bot are processed. To process messages without mentions too, the option Process all messages in server channels needs to be enabled in the instance configuration.
When a messages with a bot mention is received, the adapter will react to the message with an emoji.
This can be customized in the adapter instance configuration.
If authorization is enabled, the bot will only react on mentions of authorized users.
Received messages will be stored in the .message*
states of the channel object
for server channel messages or of the user object for direct messages.
If authorization is enabled, by default only messages from authorized users will be stored. This can be configured using the option Process messages from unauthorized users in the adapter instance configuration, so that all received messages, even from unauthorized users, will be stored.
The last received message per channel/user is always stored in the .message
state.
The timestamp, author and ID of the last received message is stored in the appropriate states.
Additionally all these information are stored in json format in the .messageJson
state.
To use text2command, a text2command instance must be selected in the adapter instance configuration.
For each .message
state the custom option Enable text2command for this state can be activated.
When activated, each received message will be send to the selected text2command instance.
The response from text2command is send as a reply, send as a normal message or not send, depending on the adapter instance configuration.
To send a message, you can write contents to the .send*
states of a channel or a user.
To send a simple text, just write the text into the .send
state of your target.
You may use Discord Markdown for text formatting like in your Discord client.
To mention a user, you can use the user ID in the form <@user-id>
.
For group mentions use <@&group-id>
and for channel mentions use <#channel-id>
.
Examples: This is my message.
, This is _my_ **formatted** message.
, Hey <@490222742801481728>!
To send a file as an attachment, you can write the file location into the .sendFile
state of your target.
The file location may be a β¦
-
Absolute or relative path to a local file.
Relative paths are relative to the adapter directory of your ioBroker installation.
The path may optionally be prepended byfile://
. Examples:/home/user/image.png
,../../iobroker-data/files/myfile.txt
,file:///tmp/image.jpg
-
URL to a remote file.
Example:https://www.iobroker.dev/images/iobroker.png
-
Base64 encoded file content.
Example:data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACzklEQVQ4y3WTy2tcdRTHP+d3753HncncmbaJiYvEhZrU+ii2urJgFCyCLnykpbQrsbR/gRQaXPUPUHBlH4ogUsRSqq7qLtlZrQpKg6Uu1OCkSWZ65859zfzucTExsYLf3Tl8zznf85JHZ5+cVuGcMebg0YXXHN/3UVVAqfk1VJV+HCMiAKRpyuXPr1hrixsCZ10VzgEnXMeRF+afJwgaFIUC0Go1UYVOp4OYUYIoivjiyjWszecUMMaYAyXPk7m5R8jznCjqk2YpjuMQhj1AcT2XLM3oR30GgyFB0KDkeWKMOeAeP7ZgDh16jizNeO/9Dwh7PR7ft5ejRxa49tXXvPnG6yRJzNWrX/LDjz8xMTHOu4tnKJXLLC0tG1OtViVoNKhWK9wLQ9pr6yRJwtTUJC/Oz3P9+jckccrk5APcXd+g3V6jUqkwiqmKKwKIMBrbCKpw585vvHNmkT17dvHQzAylUhkjZocnggi4I0+BAML9sEXBX+27XLj0MXGSMLR2h6cFKLh+zSdoNlHYXtW/oaq019a3bRGhPlYnaDbxaz5GVflHV7lcYlcrYJRH+V9s8VUVN4r6bG5ugginT52k2+ny/c2bADjGMDG+m073HlmWbyvq9XoURUEU9TGO4+C4DsPBgI31DZIkwVqLAs8+8zQnjh/j1Vdevq84Iriei+M4GABByLKMTz+7zMWPPuHBqSkGgwGdbpeZ6WmiXu+/g9nu0E2SRMMwJMty6rUa+596gsOHX+L8hUvEcUyp5PH7H38yMb4bgMbYGFmWE4YhSZKozO3b/7PruI/Nzj7MybffotVqYYwhjmPq9TpBo8Hq6iqFjkpmWcaH5y+ysnKboR3+4lpbfGdtvvfWrV+lUi5T8jyKoqBeq9FqBqiC7/sYM7qAnggrK7fJ8lyBG67AWQWstQeXlpd33lmhVt96535/60aENE0YWmuBbwUW/wZQx0cNXLu4ygAAAABJRU5ErkJggg==
Additionally, you may add a text message to the file. To do so, just write the file
location, followed by a pipe character |
and your message into the .sendFile
state.
Examples: /tmp/image.png|This is my file
, https://www.iobroker.dev/images/iobroker.png|The ioBroker logo
Using the .sendReaction
state you can react to a previous message with an emoji.
To do so, just write the emoji into the state.
By default, the reaction will be send for the message which is currently in the
corresponding .messageId
state.
If you want to react to a specific message, you can write the message ID, followed
by pipe character |
and the emoji into the .sendReaction
state.
Examples: π
, 971032590515568660|π
Using the .sendReply
state you can send a reply to a previous message.
To do so, just write the reply message into the state.
By default, the reply will be send for the message which is currently in the
corresponding .messageId
state.
If you want to reply to a specific message, you can write the message ID, followed
by pipe character |
and the reply message into the .sendReply
state.
Examples: This is a reply.
, 971032590515568660|This is a reply.
You can send special custom messages writing a stringified JSON message object
into the .send
or .sendReply
states.
The JSON object must of type MessageOptions
.
For more information read the discord.js MessageOptions documentation.
Examples:
Send an image:
{
"files": [
{
"attachment": "/tmp/image.jpg",
"name": "image.jpg",
"description": "My super image"
}
]
}
Send embedded content:
{
"content": "Use this:",
"embeds": [
{
"title": "ioBorker.discord",
"description": "Discord adapter for ioBroker",
"color": "#5865f2",
"url": "https://github.com/crycode-de/ioBroker.discord",
"author": {
"name": "Peter MΓΌller",
"url": "https://github.com/crycode-de"
},
"image": {
"url": "https://github.com/crycode-de/ioBroker.discord/raw/main/admin/discord.png"
},
"footer": {
"text": "β€π"
}
}
]
}
Send embedded image from local source:
{
"embeds": [
{
"title": "IP-Cam Alert",
"description": "Look at this:",
"color": "#ff0000",
"image": {
"url": "attachment://cam.jpg"
}
}
],
"files": [
{
"attachment": "http://192.168.1.50:8080/ip-cam.jpg",
"name": "cam.jpg"
}
]
}
If enabled in the adapter instance configuration, the adapter is able to handle Discord slash commands. These commands can be used to get or set ioBroker states.
Note: You need to configure the states individually, which you want to be available for Discord slash commands. See below.
Discord slash commands can be registered as server commands (default) or as
global commands by the adapter. This can be configured in the adapter
instance configuration.
Using server commands has the benefit, that changes to the commands (e.g. added states)
are applied instant without any delay. But server commands can't be used in
direct messages between a user and the bot.
Global commands can be used in direct messages too, but any change to the commands
may take up to one hour to apply. This is a limitation from Discord and not the adapter.
The default used slash commands are /iob-get
and /iob-set
. The command names
and descriptions can be configured in the adapter configuration.
For each state which should be available for Discord slash commands, you need to enable this in the custom settings of the state. To do so, just click the Custom settings gear icon in the Objects view in admin, enable the settings for your adapter instance and activate Enable discord commands for this state.
You can define a Name and an Alias for each state to be used in Discord. The Name will be shown in autocomplete options for the commands and the Alias is used as an internal identifier. Both must not exceed 100 characters.
For each state you can define individually if it should be available for set
and/or get commands.
Also you can enable to show an information on get commands if the state is not
acknowledged and to set a state with ack flag.
For string
type state objects you may choose to treat the value as a file (file location).
If this is enabled, the state value will be send like in the .sendFile
states.
Using this you can request images via get commands, for example.
For number
type state objects you can define the number of decimals to round a value to on get commands.
For boolean
type state objects you can define custom values for true
and false
values to show on get commands.
To get a state just call /iob-get state-alias
in your Discord client.
For the state-alias
an autocomplete will be shown while entering the command.
Any value will be formated as configured in the state object and the custom state settings. Optionally an information about a missing ack flag can be added.
To set a state just call /iob-set state-alias new-value
in your Discord client.
For the state-alias
an autocomplete will be shown while entering the command.
The new-value
will be parsed by the adapter, if the state type is boolean
or
number
.
You may configure per state, if the value should be set with or without ack flag.
For boolean
type states, the values true
, on
, yes
, 1
and their corresponding
translations of your language, as well as your per state configured True value
will be treated as true
.
Any other value would be treated as false
.
For number
type states, the provided value will be parsed as float number.
If your ioBroker is configured to use a comma in float numbers, you may provide
the number with a comma or dot as float separator. Otherwise only a dot is allowed.
If min
and max
values are defined in the state object, they are also checked.
To get an overview about all states where slash commands are enabled, you can simply click the button Log state objects configured for commands in the adapter instance configuration and see the log output.
In the adapter instance configuration, custom slash commands can be enabled and configured. The configured custom commands will be registered on Discord together with the default get and set commands.
For each custom command some options may be added, which will be shown in the
Discord client when calling the command.
If an option is not provided on command call, the option value will be null
.
For options of type string you may dynamically set predefined choices in the
corresponding option-*.choices
state as JSON array.
When a custom command gets called, the data will be written into re corresponding states. See the description of the states in the States section above.
All information including the option values will be stored in the .json
state
of the command.
This state should mainly be used to get the command data in scripts since all
needed information are stored in a single place and can't get mixed up on
multiple command calls within a short time.
For options of type user, role, channel or mentionable additional
properties of the option object will be filled.
Note: It's up to you to handle the command data and send a reply to the
command, i.e. using a custom script.
You have up to 15 minutes to send a reply using the .sendReply
state or the
corresponding sendTo(...)
action.
If you don't send a reply in time, the Discord client will show the error
message The application did not respond.
Hint: You may send a reply to one command call multiple times. This will edit the reply and set it to the new content.
{
interactionId: string,
commandName: string,
user: {
id: string,
tag: string,
name: string,
displayName: string,
},
channelId: string,
serverId: string | null,
timestamp: number,
options: {
[string]: {
value: string | number | boolean | null,
type: 'String' | 'Number' | 'Boolean' | 'User' | 'Role' | 'Channel' | 'Mentionable' | null,
user?: { // if type is USER or MENIONABLE
id: string,
tag: string,
name: string,
bot: boolean,
},
member?: { // if type is USER or MENIONABLE and command is called on a server
id: string,
tag: string,
name: string,
displayName: string,
roles: { id: string, name: string }[],
},
role?: { // if type is ROLE or MENTIONABLE
id: string,
name: string,
},
channel?: { // if type is CHANNEL
id: string,
name: string,
type: 'GuildCategory' | 'GuildNews' | 'GuildStageVoice' | 'GuildStore' | 'GuildText' | 'GuildVoice',
lastMessageId: string | null,
},
},
// ...
}
}
The adapter ships with it's own Blockly blocks for ...
- Sending messages to users or server channels
- Edit messages in direct messages or server channels
- Add a reaction emoji to messages
- Compose message contents with optional embeds, attachments and reply reference
- Compose message embeds
- Compose message attachments
- Listen to custom slash commands
- Reply to custom slash commands
Blockly Code
<xml xmlns="https://developers.google.com/blockly/xml">
<variables>
<variable id="KIILW$,(eB?pT`;GDuMF">messageId</variable>
</variables>
<block type="discord_send_message_user" id="?xkCV};-Lk_-|Q`]%(Gt" x="163" y="38">
<field name="instance">.0</field>
<field name="logResultOk">FALSE</field>
<value name="user">
<shadow type="text" id="jXN@CluUy_M/ig@4[(Uk">
<field name="TEXT">crycode</field>
</shadow>
</value>
<value name="content">
<shadow type="text" id="uLWu1CJ$;k}|VTyw1-8}">
<field name="TEXT">Hallo!</field>
</shadow>
</value>
<value name="varMessageId">
<shadow type="logic_null" id="bJ2lJW0qOa@Zjv%(]mFU"></shadow>
<block type="variables_get" id="xkJ(vH/;@7%)cDo0HU/~">
<field name="VAR" id="KIILW$,(eB?pT`;GDuMF">messageId</field>
</block>
</value>
<value name="varError">
<shadow type="logic_null" id="H:f+1-:p9-YkmpehJoco"></shadow>
</value>
<next>
<block type="timeouts_wait" id="OM8gv}Pl#_mHQ|)([mUe">
<field name="DELAY">3</field>
<field name="UNIT">sec</field>
<next>
<block type="discord_edit_message_user" id="|L3A+9{s_H8j`AF@,*VF">
<field name="instance">.0</field>
<field name="logResultOk">FALSE</field>
<value name="user">
<shadow type="text" id="voJ:{uuYtbBZ!Xe,rtV|">
<field name="TEXT">crycode</field>
</shadow>
</value>
<value name="messageId">
<shadow type="text" id="64L=tOKvKwoqGHadRgDm">
<field name="TEXT"></field>
</shadow>
<block type="variables_get" id="(M^6xk74LUEsPdH=LagL">
<field name="VAR" id="KIILW$,(eB?pT`;GDuMF">messageId</field>
</block>
</value>
<value name="content">
<shadow type="text" id="rvnV^RF,g$M/3+(npHNC">
<field name="TEXT">Moin!</field>
</shadow>
</value>
<value name="varError">
<shadow type="logic_null" id="{H4Q^vl400kxRKrffDz)"></shadow>
</value>
</block>
</next>
</block>
</next>
</block>
</xml>
Blockly Code
<xml xmlns="https://developers.google.com/blockly/xml">
<block type="discord_send_message_server_channel" id="Mnc=pB-8%Dr/nsen|SC`" x="63" y="38">
<field name="instance">.0</field>
<field name="logResultOk">FALSE</field>
<value name="serverId">
<shadow type="text" id="PA4]t;7CuDrKtwa|oB?L">
<field name="TEXT">813364154118963251</field>
</shadow>
</value>
<value name="channelId">
<shadow type="text" id="x^vm,CRT`z2AhDT#ZcUC">
<field name="TEXT">813364154559102998</field>
</shadow>
</value>
<value name="content">
<shadow type="text" id="ebdEp~G?:_gInjN47g@f">
<field name="TEXT"></field>
</shadow>
<block type="discord_create_content" id="kY,/zwmwkjo:U;cT?eN*">
<value name="content">
<shadow type="text" id="D|y(g`oE@H#gu+deGbv2">
<field name="TEXT"></field>
</shadow>
</value>
<value name="embeds">
<shadow type="logic_null" id="Qt[pG25wLoI8+3/jN66C"></shadow>
<block type="discord_create_embed" id="cXAWtP-36uYlAxLhIBhN">
<value name="description">
<shadow type="text" id="^D%m:ic9]AcUUQP8~U#6">
<field name="TEXT">Embedded attachment</field>
</shadow>
</value>
<value name="title">
<shadow type="logic_null" id="_Wm.(^Ff6^u%K+gVz$^Z"></shadow>
</value>
<value name="url">
<shadow type="logic_null" id="0,08A!7[kJ-nJPnPH$L5"></shadow>
</value>
<value name="color">
<shadow type="colour_picker" id="V0}MlQJvN._LHFhG2K%@">
<field name="COLOUR">#5865f2</field>
</shadow>
</value>
<value name="imageUrl">
<shadow type="logic_null" id="xXr:E++u0;@2#e]r;_`]"></shadow>
<block type="text" id="76;;p-5{pls%KmrI!ar{">
<field name="TEXT">attachment://file1.jpg</field>
</block>
</value>
<value name="footerText">
<shadow type="logic_null" id="#BS`MgkNWbrQ@*m/kNdw"></shadow>
</value>
</block>
</value>
<value name="files">
<shadow type="logic_null" id="4u@7^DXCI~J$r{Qx}1Ql"></shadow>
<block type="lists_create_with" id="42g8r-+[xWw`|^.qOF!*">
<mutation items="2"></mutation>
<value name="ADD0">
<block type="discord_create_file" id="EzK4NA^+bu4vChH/vj-b">
<value name="attachment">
<shadow type="text" id="=OEkBZ:LFXvT2$S++21(">
<field name="TEXT">/tmp/file1.jpg</field>
</shadow>
</value>
<value name="name">
<shadow type="text" id="zum#q*|`aD%A2s/N@/Ow">
<field name="TEXT">file1.jpg</field>
</shadow>
</value>
<value name="description">
<shadow type="text" id="#ZZOq%3EHO/_GC+w.,-^">
<field name="TEXT"></field>
</shadow>
</value>
</block>
</value>
<value name="ADD1">
<block type="discord_create_file" id="wIKo-2??SX@WcYc7e/5s">
<value name="attachment">
<shadow type="text" id=")4lvYv.)IhU/p+~KUDym">
<field name="TEXT">/tmp/logfile.txt</field>
</shadow>
</value>
<value name="name">
<shadow type="text" id="#)t#lK6{$RuZt34O;@Ag">
<field name="TEXT">log.txt</field>
</shadow>
</value>
<value name="description">
<shadow type="text" id="^UKzs+$TQ!tiE:`(=%}}">
<field name="TEXT"></field>
</shadow>
</value>
</block>
</value>
</block>
</value>
<value name="replyToId">
<shadow type="logic_null" id="#1:[?d^x=)ZH.!uyxRI:"></shadow>
</value>
</block>
</value>
<value name="varMessageId">
<shadow type="logic_null" id="@D^#9^84UknOfV|c$NK~"></shadow>
</value>
<value name="varError">
<shadow type="logic_null" id="mJu{Fa9+]+Ml,{_OqIOh"></shadow>
</value>
</block>
</xml>
Blockly Code
<xml xmlns="https://developers.google.com/blockly/xml">
<variables>
<variable id="Wcj[Gmy,vX]b,)s,O)`U">interactionId</variable>
<variable id="{sXn[Mn@ZN#fWtTV6O^;">userName</variable>
<variable id="ULmVI=-QcXLnD!e60KTV">camID</variable>
</variables>
<block type="discord_on_custom_cmd" id="GE,i32wKhz%KGlBhV$j=" x="63" y="13">
<mutation xmlns="http://www.w3.org/1999/xhtml" options="cam"></mutation>
<field name="instance">.0</field>
<field name="varInteractionId" id="Wcj[Gmy,vX]b,)s,O)`U">interactionId</field>
<field name="log">FALSE</field>
<field name="commandName">super-command</field>
<value name="varUserId">
<shadow type="logic_null" id="/}0,E!Gq=C2U]C^.8m1@"></shadow>
</value>
<value name="varUserName">
<block type="variables_get" id="Q=v?u?yU}Tw*@FH*|x7.">
<field name="VAR" id="{sXn[Mn@ZN#fWtTV6O^;">userName</field>
</block>
</value>
<value name="varUserTag">
<shadow type="logic_null" id="+r2I4SpfhuW%9DE21,[c"></shadow>
</value>
<value name="option0">
<shadow type="logic_null" id="hL^g}gJg-b.+SOH0s9m1"></shadow>
<block type="variables_get" id="z/Lf|chD)~Ge0N~@EWG%">
<field name="VAR" id="ULmVI=-QcXLnD!e60KTV">camID</field>
</block>
</value>
<statement name="STATEMENT">
<block type="discord_send_custom_command_reply" id="zJXF!F=|Xt4.kG/6ctl(">
<field name="instance">.0</field>
<field name="interactionId" id="Wcj[Gmy,vX]b,)s,O)`U">interactionId</field>
<field name="logResultOk">FALSE</field>
<value name="content">
<shadow type="text" id="bdVm59S9_U*GFB(IBO6x">
<field name="TEXT"></field>
</shadow>
<block type="discord_create_content" id="6m8gBtp;K@t8}{`9gPd1">
<value name="content">
<shadow type="text" id=".c}Z71nQ8LlQ@h}_Z?qR">
<field name="TEXT"></field>
</shadow>
<block type="text_join" id="Z{wQ$[1g7z?KPMSHB],Y">
<mutation items="3"></mutation>
<value name="ADD0">
<block type="text" id="cuzUE7GB$#gC*;nOQ|Ke">
<field name="TEXT">Hi </field>
</block>
</value>
<value name="ADD1">
<block type="variables_get" id="|[[T@|n1Ro{EU56/jJ@P">
<field name="VAR" id="{sXn[Mn@ZN#fWtTV6O^;">userName</field>
</block>
</value>
<value name="ADD2">
<block type="text" id="LV$kS:Gzv#cJ#gXe/{4a">
<field name="TEXT">!</field>
</block>
</value>
</block>
</value>
<value name="embeds">
<shadow type="logic_null" id="p8S?*FLv4a6aIJogCKU;"></shadow>
</value>
<value name="files">
<shadow type="logic_null" id="y#a8q/mr^)Ymt*j)S:H/"></shadow>
<block type="discord_create_file" id="vN%eoP74=*)f63CQiJ__">
<value name="attachment">
<shadow type="text" id="2$9y5yj3.GHx.ms*:Ce2">
<field name="TEXT"></field>
</shadow>
<block type="text_join" id="K9zuKTz?-b8VT$8XUVQ8">
<mutation items="3"></mutation>
<value name="ADD0">
<block type="text" id="p3f^[{6t+UuDJN=49+#Z">
<field name="TEXT">/tmp/cam</field>
</block>
</value>
<value name="ADD1">
<block type="variables_get" id="oVmVHEX[iT(-X#]m=[U@">
<field name="VAR" id="ULmVI=-QcXLnD!e60KTV">camID</field>
</block>
</value>
<value name="ADD2">
<block type="text" id="wUXx)@u6*2,+9!q{W`n`">
<field name="TEXT">.jpg</field>
</block>
</value>
</block>
</value>
<value name="name">
<shadow type="text" id="L5fO_+by.^Z:se~6|xCj">
<field name="TEXT">cam.jpg</field>
</shadow>
</value>
<value name="description">
<shadow type="text" id="ku}h+v)9oY;1`[9Rr)w%">
<field name="TEXT"></field>
</shadow>
</value>
</block>
</value>
<value name="replyToId">
<shadow type="logic_null" id="Ou%Gd6C*+2OaIPUxPp}t"></shadow>
</value>
</block>
</value>
<value name="varMessageId">
<shadow type="logic_null" id="RUb!i][5`[t0*mzLwBvN"></shadow>
</value>
<value name="varError">
<shadow type="logic_null" id="SLsj^+8=[Bp%/X8n]$?Z"></shadow>
</value>
</block>
</statement>
</block>
</xml>
You may use the sendTo(...)
function in scripts to interact with the adapter instance.
Note: All used IDs are strings.
To send a message you can use the send
or sendMessage
command. They are the same.
The message
part of sendTo(...)
needs to be an object with the content
to
send and one of the following parameters to identify the target:
userId
userTag
userName
serverId
andchannelId
The content
may be a simple string, or a MessageOptions object.
The return value in the sendTo(...)
callback is an object containing your message parameters and a result
string and the messageId
of the sent discord message on success or an error
message if there was an error.
Examples:
// send to user using the unique user name
sendTo('discord.0', 'sendMessage', {
userName: 'crycode',
content: 'Hi!',
}, (ret) => {
log(ret);
// {'result':'Message sent to user crycode','userName':'crycode','content':'Hi!','messageId':'971779972052155891'}
if (ret.error) {
log(ret.error, 'error');
return;
}
log(`Message sent with ID ${ret.messageId}`);
});
// send to user using the user tag (for bots or users not migrated to unique user name)
sendTo('discord.0', 'sendMessage', {
userTag: 'cryCode#9911',
content: 'Hi!',
}, (ret) => {
log(ret);
// {'result':'Message sent to user cryCode#9911','userTag':'cryCode#9911','content':'Hi!','messageId':'971779972052160552'}
if (ret.error) {
log(ret.error, 'error');
return;
}
log(`Message sent with ID ${ret.messageId}`);
});
// send a reply message to a user
sendTo('discord.0', 'sendMessage', {
userId: '490222742801481728',
content: {
content: 'Ok!',
reply: {
messageReference: '971779972052160552', // ID of the message you want to reply to
},
},
}, (ret) => {
log(ret);
// {'result':'Message sent to user crycode','userId':'490222742801481728','content':{'content':'Ok!','reply':{'messageReference':'971779972052160552'}},'messageId':'971786369401761832'}
});
// send a file to a server channel
sendTo('discord.0', 'sendMessage', {
serverId: '813364154118963251',
channelId: '813364154559102998',
content: {
content: 'Look at this:',
files: [
{
attachment: "/tmp/image.jpg",
name: "image.jpg",
description: "My super image"
},
],
},
}, (ret) => {
log(ret);
// {'result':'Message sent to channel Allgemein','serverId':'813364154118963251','channelId':'813364154559102998','content':{'content':'Look at this:','files':[{'attachment':'/tmp/image.jpg','name':'image.jpg','description':'My super image'}]},'messageId':'971780152759558234'}
});
Using the editMessage
command, you are able to edit a previous message.
Of course, you can only edit messages send by the bot.
The message
part of sendTo(...)
is the same as for sendMessage
(see above)
with the messageId
of the message you want to edit as additional parameter.
The return value is the same as for sendMessage
.
Examples:
// edit a message
sendTo('discord.0', 'editMessage', {
userName: 'crycode',
content: 'Hello!',
messageId: '971495175367049276',
}, (ret) => {
log(ret);
// {'result':'Message edited','userName':'crycode','content':'Hello!','messageId':'971495175367049276'}
});
// send a message and edit it after five seconds
sendTo('discord.0', 'sendMessage', {
userName: 'crycode',
content: 'Now: ' + new Date().toLocaleString(),
}, (ret) => {
if (ret.error) {
log(ret.error, 'error');
return;
}
setTimeout(() => {
sendTo('discord.0', 'editMessage', {
userName: 'crycode',
content: 'Now: ' + new Date().toLocaleString(),
messageId: ret.messageId,
}, (ret2) => {
log(ret2);
// {'result':'Message edited','userName':'crycode','content':'Now: 5.5.2022, 16:25:38','messageId':'971779692166266920'}
});
}, 5000);
});
Using the delteMessage
command, you are able to delete a previous message.
Of course, you can only delete messages send by the bot.
The message
part of sendTo(...)
is the same as for sendMessage
(see above)
without the content
but with the messageId
of the message you want to delete
as additional parameter.
The return value is the same as for sendMessage
.
Example:
// delete a message
sendTo('discord.0', 'deleteMessage', {
userName: 'crycode',
messageId: '971495175367049276',
}, (ret) => {
log(ret);
// {'result':'Message deleted','userName':'crycode','messageId':'971495175367049276'}
});
Using the addReaction
command, you are able to add a reaction emoji to a
previous message.
The message
part of sendTo(...)
is the same as for sendMessage
(see above)
without the content
but with the messageId
of the message you want react to
and the emoji
as additional parameters.
The return value is the same as for sendMessage
.
Example:
// add a reaction to a message
sendTo('discord.0', 'addReaction', {
userName: 'crycode',
messageId: '971786369401761832',
emoji: 'π',
}, (ret) => {
log(ret);
// {'result':'Reaction added to message','userName':'crycode','messageId':'971786369401761832','emoji':'π'}
});
You are able to await reactions (emojis) to a previous message using the
awaitMessageReaction
command.
The message
part of sendTo(...)
is the same as for editMessage
(see above)
without the content
parameter but with timeout
and max
number as
additional parameters.
The timeout
is the maximum wait time to collect the reactions in a range from 100 to 60000 ms.
The max
parameter defines the maximum number of reactions to collect.
Default is 1 if not provided.
The callback of sendTo(...)
will be called if either the timeout is reached or
the specified number of reactions is collected.
The return value is an object containing your message parameters and a
reactions
array. Each reaction is an object of emoji
, emojiId
and users
,
where users
is an array of objects with id
and tag
.
If a reaction is simple emoji, the emojiId
will be null
. For custom emojis,
emoji
will be the emoji name and emojiId
will be set.
sendTo('discord.0', 'awaitMessageReaction', {
serverId: '813364154118963251',
channelId: '813364154559102998',
messageId: '970754574879162458',
timeout: 10000,
max: 3,
}, (ret) => {
log(ret);
// {'reactions':[{'emoji':'π','emojiId':null,'users':[{'id':'490222742801481728', 'name': 'crycode','tag':'crycode#0'}]}],'serverId':'813364154118963251','channelId':'813364154559102998','messageId':'970754574879162458','timeout':10000,'max':3}
});
Using the sendCustomCommandReply
command, you can send a reply to a custom
slash command call.
The message
part of sendTo(...)
needs to be an object with the content
to
send and the interactionId
of the command call:
The content
may be a simple string, or a MessageOptions object
(like in sendMessage
).
on({ id: 'discord.0.slashCommands.iob-test.json', change: 'any', ack: true }, (obj) => {
log(`Got custom slash command ${obj.state.val}`);
// Got custom slash command {"interactionId":"977265764136517725","commandName":"iob-test","channelId":"813364154559102998","serverId":"813364154118963251","user":{"id":"490222742801481728","tag":"crycode#0", "name": "crycode","displayName":"Peter"},"timestamp":1653068714890,"options":{"myopt":{"value":"test","type":"String"}}}
const data = JSON.parse(obj.state.val);
let reply;
if (data.options.myopt.value) {
reply = {
content: `You gave me "${data.options.myopt.value}".`,
embeds: [
{
title: 'This is awesome!',
color: '#00AA00',
},
],
};
} else {
reply = `You gave me nothing. π€¨`;
}
sendTo('discord.0', 'sendCustomCommandReply', {
interactionId: data.interactionId,
content: reply,
}, (ret) => {
log(ret);
// {'result':'Reply sent','interactionId':'977265764136517725','content':{'content':'You gave me \'test\'.','embeds':[{'title':'This is awesome!','color':'#00AA00'}]},'messageId':'977265765122183248'}
});
});
sendTo('discord.0', 'getServerInfo', {
serverId: '813364154118963251',
}, (ret) => {
log(ret);
});
sendTo('discord.0', 'getChannelInfo', {
serverId: '813364154118963251',
channelId: '813364154559102998',
}, (ret) => {
log(ret);
});
sendTo('discord.0', 'getUserInfo', {
userId: '490222742801481728',
}, (ret) => {
log(ret);
});
sendTo('discord.0', 'getUserInfo', {
userTag: 'cryCode#9911',
}, (ret) => {
log(ret);
});
sendTo('discord.0', 'getServerMemberInfo', {
serverId: '813364154118963251',
userId: '490222742801481728',
}, (ret) => {
log(ret);
});
sendTo('discord.0', 'getServerMemberInfo', {
serverId: '813364154118963251',
userTag: 'cryCode#9911',
}, (ret) => {
log(ret);
});
sendTo('discord.0', 'getMessageInfo', {
serverId: '813364154118963251',
channelId: '813364154559102998',
messageId: '978252795763359794',
}, (ret) => {
log(ret);
});
sendTo('discord.0', 'getMessageInfo', {
userId: '490222742801481728',
messageId: '976090572760694814',
}, (ret) => {
log(ret);
});
sendTo('discord.0', 'getMessageInfo', {
userTag: 'cryCode#9911',
messageId: '976090572760694814',
}, (ret) => {
log(ret);
});