{
  "_class" : "hudson.maven.MavenModuleSet",
  "actions" : [
    None,
    {
      
    },
    {
      
    },
    {
      
    },
    {
      
    },
    {
      
    },
    {
      
    },
    {
      
    },
    {
      "_class" : "org.jenkinsci.plugins.displayurlapi.actions.JobDisplayAction"
    },
    {
      "_class" : "com.cloudbees.plugins.credentials.ViewCredentialsAction"
    }
  ],
  "description" : "This is an extension for the CommandHelper plugin that uses the JDA library to talk to your Discord server.\u000a\u000a## Download\u000a[CHDiscord 2.15.0](https://letsbuild.net/jenkins/job/CHDiscord/)\u000a\u000aThe latest version requires CommandHelper 3.3.4 build #3978 or later.\u000a\u000aThe CHDiscord branch named [3.3.2](https://github.com/PseudoKnight/CHDiscord/tree/3.3.2) is back-ported for CommandHelper 3.3.2.\u000a\u000a## Instructions\u000a\u000aYou'll first need to create a Discord application [here](https://discordapp.com/developers/applications/me).\u000aThen add a Bot to it. Copy the TOKEN for the Bot, as you'll use this later in your connection script.\u000aBe sure to enable `SERVER MEMBERS INTENT` and `MESSAGE CONTENT INTENT` of the Privileged Gateway Intents.\u000a\u000aNext you'll need to add the bot to your Discord guild server. Go to the URL Generator under OAuth2.\u000aSelect the scope 'bot', and optionally check any permissions you want the bot to start with. (see functions below)\u000aGo to the generated URL in your browser to authorize the bot for your guild server.\u000a\u000aFinally, to connect this extension to Discord you'll need your Discord guild server id, which you can get by right-clicking\u000ayour server name in Discord and clicking \"Copy ID\". (only visible when Developer Mode is enabled in Advanced User Settings)\u000aUse this together with the TOKEN above to run `discord_connect()` in your connection script.\u000a\u000a## Bot Functions\u000a\u000a### discord_connect(token, serverId, [callback] | profile, [callback])\u000aConnects to Discord server via token and default guild server id.\u000aThe optional callback closure will be executed when a connection is made.\u000aThe profile may be a string, which should refer to a profile defined in profiles.xml,\u000awith the keys token and serverId, or an array, with the same keys.\u000a\u000aThe profile should be defined such as\u000a\u000a    <profile id=\"discordCredentials\">\u000a        <type>discord</type>\u000a        <token>abcdefg</token>\u000a        <serverId>12345</serverId>\u000a    </profile>\u000a\u000aYou have to run discord_connect() before you can use the other functionality of this extension, otherwise a\u000aNotFoundException will be thrown. You cannot use other functions until the callback closure is executed.\u000a\u000a### discord_disconnect()\u000aDisconnects from the Discord server.\u000a\u000a### discord_set_activity(type, string, [url])\u000aSets the activity tag for the bot.  \u000aActivity type can be one of PLAYER, STREAMING, LISTENING, WATCHING, CUSTOM_STATUS, COMPETING.  \u000aActivity string can be anything but an empty string.  \u000aIf streaming, a valid Twitch URL must also be provided.  \u000aIf not, or it's invalid, type will revert to PLAYING.\u000a\u000a### discord_private_message(user, message)\u000aSends a private message to the specified Discord user.  \u000aSee discord_broadcast() documentation for message format.  \u000aWill fail if the user is not a cached member on one of the connected servers.  \u000aMessages have a 2000-character limit.\u000a\u000a### discord_set_allowed_mentions(array, [replied_user])\u000aSets mentions that are allowed by default in sent messages.  \u000aArray can include 'USER', 'ROLE', and 'EVERYONE' for parsed mentions.  \u000aIf null, it resets the default to all types.  \u000aThe replied_user argument is a boolean for whether users in referenced messages are mentioned. (default: true)\u000a\u000a### discord_get_servers()\u000aGets an array of ids for all the guild servers that the bot is added to.\u000a\u000a### discord_request(method, route, [dataObject], [onSuccess], [onFailure])\u000aSends a custom HTTP request to Discord.  \u000aThis is for advanced users that need to use Discord API that is not yet added to this extension.  \u000aYou must refer to the Discord documentation for routes, methods, parameters, and permissions.  \u000aThe method argument can be one of GET, PATCH, DELETE, PUT or POST.  \u000aThe route must not start with a forward slash.  \u000aThe dataObject argument is the JSON parameters, and can be an array, string or null.  \u000aIf the request was successful, the onSuccess closure will be executed and passed an array of response data.  \u000aIf the request failed, the onFailure closure will instead be executed and passed a failure message.  \u000aIf not provided, the default handler will instead log any failures.\u000a\u000aExample GET:\u000a```\u000adiscord_request('GET', 'guilds/'.@guildId.'/members?limit=20', null, closure(@result) {\u000a\u0009foreach(@member in @result) {\u000a\u0009\u0009msg(@member['username']);\u000a\u0009}\u000a}, closure(@failure) {\u000a\u0009msg('Request failed: '.@failure);\u000a});\u000a```\u000a\u000aExample POST:\u000a```\u000adiscord_request('POST', 'channels/'.@channelId.'/messages', array(content: @message));\u000a```\u000a\u000a## Guild Server Functions\u000a* The `server` argument is the guild server's unique int id. It is always optional and will fall back to event bind context or the default server.\u000a\u000a### discord_get_members([server])\u000aGets an array of all cached members in this guild server.  \u000aArray contains a list of user int ids.  \u000aMembers may not be cached immediately upon bot connection.\u000a\u000a### discord_get_members_with_role([server], role)\u000aLike discord_get_members(), but returns only members with a given role.\u000a\u000a### discord_retrieve_invites([server], closure)\u000aRetrieves an array of invite arrays for this guild server.  \u000aPasses the array to the callback closure.  \u000aEach invite array contains data about the invite, which has the keys 'code', 'channelid', inviter 'userid', 'uses' and 'max_uses'.  \u000aRequires the `Manage Server` permission.\u000a\u000a## Channel Functions\u000a* The `channel` argument can be a channel's unique int id. A channel's exact name can also be used, but if it's not unique,\u000athe first matching channel will be used. If a channel is omitted, it will attempt to use the channel from the event bind context.\u000aIf not in an event bind, it will use the default channel.\u000a\u000a### discord_broadcast([server], [channel], message, [callback])\u000aBroadcasts text and embeds to the specified channel.  \u000aIf channel is omitted, the channel from an event or first publicly viewable channel will be used.  \u000aMessage can be a string or a message array object.  \u000aCallback closure is eventually executed with the message id for this message. (cannot be null)  \u000aMessage array must contain at least one of the following keys: 'content', 'embed', or 'embeds'.  \u000aIt can also contain 'reference_id' (int) for replies,\u000aand 'allowed_mentions' (array with optional 'parse', 'users', 'roles', and 'replied_user' keys)\u000ato override default behavior set by discord_set_allowed_mentions().  \u000aEmbed array can include any of the following keys: 'title', 'url', 'description', 'timestamp' (int),\u000a'image' (URL), 'thumbnail' (URL), 'color' (rgb array), 'footer' (array with 'text' and optionally 'icon_url' keys),\u000a'author' (array with 'name' and optionally 'url' and/or 'icon_url' keys), and 'fields'\u000a(an array of field arrays, each with 'name', 'value', and optionally an 'inline' boolean).  \u000aMessages have a 2000-character limit.  \u000aRequires the `View Channels` and `Send Messages` permissions. (or `Send Messages in Threads` for thread channels)  \u000aAlso requires `Read Message History` permission for channel replies using 'reference_id'.\u000a\u000aExample message/embed object array format: (embeds are as displayed, top to bottom, left to right)\u000a```\u000aarray(\u000a  content: \"This displays above the embed as normal text.\",\u000a  embeds: array(\u000a    array(\u000a      color: array(\u000a        r: 255,\u000a        g: 255,\u000a        b: 255,\u000a      ),\u000a      author: array(\u000a        icon_url: \"https://website.com/author_avatar.png\",\u000a        name: \"PseudoKnight\",\u000a        url: \"https://website.com/author_link/\",\u000a      ),\u000a      thumbnail: \"https://website.com/top_right_thumbnail.png\",\u000a      title: \"Large Bold Text\",\u000a      url: \"https://website.com/title_link/\",\u000a      description: \"Normal sized text just under title.\",\u000a      fields: array(\u000a        array(\u000a          name: \"Field A\",\u000a          value: \"Value A Below Name\",\u000a          inline: true,\u000a        )\u000a      ),\u000a      image: \"https://website.com/image.png\",\u000a      footer: array(\u000a          icon_url: \"https://website.com/footer_icon.png\",\u000a          text: \"Small text at the bottom.\",\u000a      ),\u000a      timestamp: 1698213238389,\u000a    ),\u000a  ),\u000a  allowed_mentions: array(\u000a    parse: array(),\u000a    users: array(\"PseudoKnight\"),\u000a    roles: array(\"moderator\"),\u000a    replied_user: true,\u000a  ),\u000a  reference_id: 1167309410398388254,\u000a)\u000a```\u000a\u000a### discord_delete_message([server], channel, id)\u000aDeletes a message with the given id on a channel.  \u000aRequires the `View Channels` permission. (and `Manage Messages` if message is from other user)\u000a\u000a### discord_set_channel_topic([server], channel, string)\u000aSets a topic for a text or news channel.  \u000aStandard channels have a 1024-character limit for topics.  \u000aOnly Text and News channels support topics, otherwise an IllegalArgumentException is thrown.  \u000aRequires the `Manage Channels` permission.\u000a\u000a### discord_channel_members([server], channel)\u000aReturns an array of ids for members in a channel.  \u000aFor voice channels, this returns all members that are currently connected to the channel.  \u000aOtherwise, for text channels this returns all members with the `View Channels` permission.\u000a\u000a## Member Functions\u000a* The `member` argument is a user's unique int id (or username). Throws NotFoundException if a member by that id doesn't exist.\u000a\u000a### discord_member_info([server], member)\u000aGets an array of data for Discord user.  \u000aArray contains 'userid', 'username', 'displayname', and 'bot' (boolean).  \u000aFor this guild server it also contains:  \u000a'nickname' (empty if not set), 'color' array (null if none), 'joined_at' timestamp, and 'avatar' effective url.\u000a\u000a### discord_member_get_roles([server], member)\u000aGets an associative array of all guild server roles for a member.  \u000aThe key is the role name, and the value is the role int id.\u000a\u000a### discord_member_set_roles([server], member, role(s), [reason])\u000aSets the roles for a guild server member.  \u000aThe role argument can be an array or a single role.  \u000aA role is either a unique int id or name.  \u000aOptional reason string is supported.  \u000aThrows NotFoundException if a role by that id doesn't exist.  \u000aRequires the `Manage Roles` permission and a role higher than any set roles.\u000a\u000a### discord_member_get_nickname([server], member)\u000aGet the server nickname for a guild server member. (empty if not set)  \u000a\u000a### discord_member_set_nickname([server], member, string)\u000aSet the server nickname for a guild server member.  \u000aRequires the `Manage Nicknames` permission and a role higher than the target member.\u000a\u000a## Voice Functions\u000a\u000a### discord_member_get_voice_channel([server], member)\u000aGet the ID of member's current voice channel.  \u000aIf the member is not connected to a voice channel, null is returned.\u000a\u000a### discord_member_move_voice_channel([server], member, channel)\u000aMoves a member to another voice channel.  \u000aThe member must already be connected to a voice channel in the guild server.  \u000aChannel can be null to disconnect user.  \u000aThrows IllegalArgumentException if member is not connected to a voice channel.  \u000aThrows InsufficientPermissionException if the member and bot do not have access to the destination channel.  \u000aRequires the `Move Members` permission.\u000a\u000a### discord_member_is_muted([server], member)\u000aCheck if a user is muted, either self muted or server muted.\u000a\u000a### discord_member_set_muted([server], member, boolean)\u000aSet a user's guild server's muted state.  \u000aThrows IllegalArgumentException if member is not connected to a voice channel.  \u000aRequires the `Mute Members` permission.\u000a\u000a## Events\u000a\u000a### discord_message_received\u000aThis event is called when a user sends a message in a guild server.  \u000a**Prefilters:** username, channel (name)  \u000a**Data:** userid, username, nickname, bot (boolean), serverid, channel (name), channelid, channeltype, message, id (of message), webhook, attachments {{url, filename, description}}, reference {{id, userid, username, message}}\u000a\u000a### discord_message_updated\u000aThis event is called when a user edits a message in a Discord server.\u000a**Prefilters:** channel (name)  \u000a**Data:** userid, username, nickname, bot (boolean), serverid, channel (name), channelid, channeltype, message, id (of message), webhook, attachments {{url, filename, description}}, reference {{id, userid, username, message}}\u000a\u000a### discord_private_message_received\u000aThis event is called when a user sends a private message to the bot.  \u000a**Data:** userid, username, displayname, message, id (of message), attachments {{url, filename, description}}, reference {{id, userid, username, message}}\u000a\u000a### discord_reaction_added\u000aThis event is called when a user adds a reaction to a message.  \u000a**Prefilters:** channel (name)  \u000a**Data:** userid, username, nickname, bot (boolean), serverid, channel (name), channelid, messageid, messageuserid, emoji (unicode character or custom emoji code)\u000a\u000a### discord_reaction_removed\u000aThis event is called when a user removes a reaction on a message.  \u000a**Prefilters:** channel (name)  \u000a**Data:** userid, username, nickname, bot (boolean), serverid, channel (name), channelid, messageid, emoji (unicode character or custom emoji code)\u000a\u000a### discord_voice_joined\u000aThis event is called when a user joined a voice channel.  \u000a**Data:** userid, username, nickname, serverid, channel (name), channelid\u000a\u000a### discord_voice_left\u000aThis event is called when a user left a voice channel.  \u000a**Data:** userid, username, nickname, serverid, channel (name), channelid\u000a\u000a### discord_voice_moved\u000aThis event is called when a user moves between voice channels.\u000a**Data:** userid, username, nickname, serverid, joined, joinedid, left, leftid.\u000a\u000a### discord_member_joined\u000aThis event is called when a user joined the guild server.  \u000a**Data:** userid, username, nickname. serverid\u000a\u000a### discord_member_left\u000aThis event is called when a user left the guild server, including kick/ban.  \u000a**Data:** userid, username, nickname. serverid\u000a",
  "displayName" : "CHDiscord",
  "displayNameOrNull" : None,
  "fullDisplayName" : "CHDiscord",
  "fullName" : "CHDiscord",
  "name" : "CHDiscord",
  "url" : "https://letsbuild.net/jenkins/view/all/job/CHDiscord/",
  "buildable" : True,
  "builds" : [
    {
      "_class" : "hudson.maven.MavenModuleSetBuild",
      "number" : 14,
      "url" : "https://letsbuild.net/jenkins/view/all/job/CHDiscord/14/"
    },
    {
      "_class" : "hudson.maven.MavenModuleSetBuild",
      "number" : 13,
      "url" : "https://letsbuild.net/jenkins/view/all/job/CHDiscord/13/"
    },
    {
      "_class" : "hudson.maven.MavenModuleSetBuild",
      "number" : 12,
      "url" : "https://letsbuild.net/jenkins/view/all/job/CHDiscord/12/"
    },
    {
      "_class" : "hudson.maven.MavenModuleSetBuild",
      "number" : 11,
      "url" : "https://letsbuild.net/jenkins/view/all/job/CHDiscord/11/"
    },
    {
      "_class" : "hudson.maven.MavenModuleSetBuild",
      "number" : 10,
      "url" : "https://letsbuild.net/jenkins/view/all/job/CHDiscord/10/"
    },
    {
      "_class" : "hudson.maven.MavenModuleSetBuild",
      "number" : 9,
      "url" : "https://letsbuild.net/jenkins/view/all/job/CHDiscord/9/"
    },
    {
      "_class" : "hudson.maven.MavenModuleSetBuild",
      "number" : 8,
      "url" : "https://letsbuild.net/jenkins/view/all/job/CHDiscord/8/"
    },
    {
      "_class" : "hudson.maven.MavenModuleSetBuild",
      "number" : 7,
      "url" : "https://letsbuild.net/jenkins/view/all/job/CHDiscord/7/"
    },
    {
      "_class" : "hudson.maven.MavenModuleSetBuild",
      "number" : 6,
      "url" : "https://letsbuild.net/jenkins/view/all/job/CHDiscord/6/"
    },
    {
      "_class" : "hudson.maven.MavenModuleSetBuild",
      "number" : 5,
      "url" : "https://letsbuild.net/jenkins/view/all/job/CHDiscord/5/"
    },
    {
      "_class" : "hudson.maven.MavenModuleSetBuild",
      "number" : 4,
      "url" : "https://letsbuild.net/jenkins/view/all/job/CHDiscord/4/"
    },
    {
      "_class" : "hudson.maven.MavenModuleSetBuild",
      "number" : 3,
      "url" : "https://letsbuild.net/jenkins/view/all/job/CHDiscord/3/"
    },
    {
      "_class" : "hudson.maven.MavenModuleSetBuild",
      "number" : 2,
      "url" : "https://letsbuild.net/jenkins/view/all/job/CHDiscord/2/"
    },
    {
      "_class" : "hudson.maven.MavenModuleSetBuild",
      "number" : 1,
      "url" : "https://letsbuild.net/jenkins/view/all/job/CHDiscord/1/"
    }
  ],
  "color" : "blue",
  "firstBuild" : {
    "_class" : "hudson.maven.MavenModuleSetBuild",
    "number" : 1,
    "url" : "https://letsbuild.net/jenkins/view/all/job/CHDiscord/1/"
  },
  "healthReport" : [
    {
      "description" : "Build stability: No recent builds failed.",
      "iconClassName" : "icon-health-80plus",
      "iconUrl" : "health-80plus.png",
      "score" : 100
    }
  ],
  "inQueue" : False,
  "keepDependencies" : False,
  "lastBuild" : {
    "_class" : "hudson.maven.MavenModuleSetBuild",
    "number" : 14,
    "url" : "https://letsbuild.net/jenkins/view/all/job/CHDiscord/14/"
  },
  "lastCompletedBuild" : {
    "_class" : "hudson.maven.MavenModuleSetBuild",
    "number" : 14,
    "url" : "https://letsbuild.net/jenkins/view/all/job/CHDiscord/14/"
  },
  "lastFailedBuild" : None,
  "lastStableBuild" : {
    "_class" : "hudson.maven.MavenModuleSetBuild",
    "number" : 14,
    "url" : "https://letsbuild.net/jenkins/view/all/job/CHDiscord/14/"
  },
  "lastSuccessfulBuild" : {
    "_class" : "hudson.maven.MavenModuleSetBuild",
    "number" : 14,
    "url" : "https://letsbuild.net/jenkins/view/all/job/CHDiscord/14/"
  },
  "lastUnstableBuild" : None,
  "lastUnsuccessfulBuild" : None,
  "nextBuildNumber" : 15,
  "property" : [
    {
      "_class" : "com.coravy.hudson.plugins.github.GithubProjectProperty"
    },
    {
      "_class" : "com.dabsquared.gitlabjenkins.connection.GitLabConnectionProperty"
    }
  ],
  "queueItem" : None,
  "concurrentBuild" : False,
  "disabled" : False,
  "downstreamProjects" : [
    
  ],
  "labelExpression" : None,
  "scm" : {
    "_class" : "hudson.plugins.git.GitSCM"
  },
  "upstreamProjects" : [
    
  ],
  "modules" : [
    {
      "name" : "me.pseudoknight:CHDiscord",
      "url" : "https://letsbuild.net/jenkins/view/all/job/CHDiscord/me.pseudoknight$CHDiscord/",
      "color" : "blue",
      "displayName" : "CHDiscord"
    }
  ]
}