A Discord Bot which implements API calls into your server. Allowing you to create messages, edit channels, and edit users with any information available on the web!
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
API Bot
.gitignore
API Bot.sln
LICENSE
README.md

README.md

API Bot

This is a discord bot for implementing API calls into your server.

This bot is fully configurable and allows you to make any API call and update your Discord server with the result.

What API calls can I make?

  • Either HTTP/HTTP
  • Must be a JSON response
  • Can use GET/POST/DELETE/PATCH and more
  • Can have request headers
  • Can have request parameters

What can I update within Discord from the API calls?

  • Post a new text message to any channel
  • Post a new embed to any channel
  • Change any channel's topic
  • Set any user's nickname
  • Set the bot account's game message
  • Set the bot account's avatar

What can trigger the API calls?

  • User typed command
  • CRON entry

Setup

Prerequisites

The first thing you will need to do is to go onto the Discord Developer's page and create a bot account and add it to your server. When you create the bot account, make note of it's "Token" - you should be aware to never share your bot's token with anyone else!

Bot Setup

When the bot is first run it will throw an error telling you:

Open the file "Bot.json" and add your bot account's token to the line "Token:". This will also create the Bot.json file for you in the same directory as your .exe.

By default it will look like this:

{
  "Token": null,
  "Game": null,
  "Interactions": null
}

Update the Token to your bot's Token, and if you wish to, add a message for your bot account's game message.

Interactions (Quick Guide)

Interactions are how the bot will interact with your Discord server. In the Bot.json file, the Interactions will need to be an array even if you only have one interaction.

Triggers

An interaction can have two types of tigger, a command or a CRON, below shows you an Interaction with no actions but both a command and a CRON entry.

"Interactions": [
  {
    "command": "!weather",
    "cron": "* * * * *"
  }
]

Actions

There are a few Interaction actions and they use the following basic syntaxes. They are all optional and any number of the Messages, Channels, and Users can be added:

"Interactions": [
  {
    "command": "!weather",
    "cron": "* * * * *",
    "avatar": "<NEW_BOT_AVATAR_URL>",
    "game": "This is what the bot will show as 'Playing'",
    "status": {
      "data": "anything",
      "idle": "anything"
    },
    "messages": [
      {
        "channelName": "general",
        "message": "This is a weather update!"
      }
    ],
    "channels": [
      {
        "channelName": "general",
        "newTopic": "This is a weather update!"
      }
    ],
    "users": [
      {
        "username": "Someone",
        "discriminator": "1075",
        "newNickname": "Weather"
      }
    ]
  }
]

API calls

So far we have an interaction which has triggers and actions, this will technically work but the actions will be static, as in they will always be the same. Actions can be modified by giving an interaction APIs calls like so:

"Interactions": [
  {
    "command": "!weather",
    "cron": "* * * * *",
    "apis": [
      {
        "name": "Weather",
        "url": "http://api.openweathermap.org/data/2.5/forecast?q=London"
      }
    ],
    "messages": [
      {
        "channelName": "general",
        "isTTS": false,
        "message": "This is a weather update!"
      }
    ]
  }
]

The API call above will be completed before any of the actions are executed. To use the API response data within the actions enclose a reference to the data in curley braces as shown below:

The API call http://api.openweathermap.org/data/2.5/forecast?q=London returns with:

{
  "cod": 401,
  "message": "Invalid API key. Please see http://openweathermap.org/faq#error401 for more info."
}

To use the message do the following:

"Interactions": [
  {
    "command": "!weather",
    "cron": "* * * * *",
    "apis": [
      {
        "name": "Weather",
        "url": "http://api.openweathermap.org/data/2.5/forecast?q=London"
      }
    ],
    "messages": [
      {
        "channelName": "general",
        "isTTS": false,
        "message": "This is a weather update: It is {Weather.list.0.main.temp} degrees!"
      }
    ]
  }
]

You can access the elements in listed elements by passing in their index.

As you see above, this API call wants you to provide an API Key with your requests, it will vary between all different APIs but this particular one wants the key provided as a parameter with the key "appid". We can do this via the following:

"Interactions": [
  {
    "command": "!weather",
    "cron": "* * * * *",
    "apis": [
      {
        "name": "Weather",
        "url": "http://api.openweathermap.org/data/2.5/forecast?q=London",
        "parameters": [
          {
            "key": "appid",
            "value": "<YOUR_API_KEY_HERE>"
          }
        ]
      }
    ],
    "messages": [
      {
        "channelName": "general",
        "isTTS": false,
        "message": "This is a weather update: It is {Weather.list.0.main.temp} degrees!"
      }
    ]
  }
]

Interactions can have as many API calls or actions as you want.

Interactions (In-depth)

Messages can also optionally have a single embed, all components of embeds are optional.
Below is an example of a config file using every possible feature, including an embed:

{
  "Token": "<YOUR_BOT_TOKEN>",
  "Game": "Game message for your bot account",
  "Interactions": [
    {
      "command": "!weather",
      "cron": "* * * * *",
      "apis": [
        {
          "name": "Weather",
          "url": "http://api.openweathermap.org/data/2.5/forecast?q=London",
          "method": "get",
          "headers": [
            {
              "key": "appid",
              "value": "<API_KEY>"
            }
          ],
          "parameters": [
            {
              "key": "Other data",
              "value": "<OTHER_DATA>"
            }
          ]
        }
      ],
      "avatar": "<NEW_BOT_AVATAR_URL>",
      "game": "New game message for your bot account",
      "status": {
        "data": "{Weather.cod}",
        "online": "something",
        "idle": "stuff",
        "donotdisturb": "some text",
        "invisible": "more text",
        "default": "online"
      },
      "messages": [
        {
          "channelName": "general",
          "message": "This is a weather update!",
          "isTTS": false,
          "embed": {
            "author": {
              "iconURL": "<IMAGE_URL>",
              "name": "OpenWeatherMap",
              "url": "<AUTHOR_HYPERLINK_URL>"
            },
            "color": "4286f4",
            "description": "Here is your current weather info:",
            "fields": [
              {
                "isInline": false,
                "name": "Status:",
                "value": "{Weather.cod}"
              },
              {
                "isInline": true,
                "name": "Temperature:",
                "value": "{Weather.list.0.main.temp} degrees"
              }
            ],
            "imageURL": "<IMAGE_URL>",
            "thumbnailURL": "<IMAGE_URL>",
            "footer": {
              "iconURL": "<IMAGE_URL>",
              "text": "This is the footer"
            },
            "unixTimestamp": 1534099293,
            "title": "Weather Update",
            "URL": "<HYPERLINK_URL>"
          }
        }
      ],
      "channels": [
        {
          "channelName": "general",
          "newTopic": "It is {Weather.list.0.main.temp} degrees!"
        }
      ],
      "users": [
        {
          "username": "WeatherBoy",
          "discriminator": "1075",
          "newNickname": "{Weather.list.0.main.temp} degrees!"
        }
      ]
    }
  ]
}

Variables

The command of an Interaction can be any text message and does not need to begin with an ! of any other prefixing character.

The cron of an Interaction can be any standard CRON entry, for more info on CRON entries Click here!

The method of an API request is not case-sensitive, the following are the accepted HTTP methods:

  • Copy
  • Delete
  • Get
  • Head
  • Merge
  • Options
  • Patch
  • Post
  • Put

The status of the bot account can be set via a status object, as been below:

"status": {
  "data": "{weather.cod}",
  "online": "something",
  "idle": "stuff",
  "donotdisturb": "some text",
  "invisible": "more text",
  "default": "online"
}

This works by matching the content within data with the content of online/idle/donotdisturb/invisible. If a default value is given and none of the statuses match data then the default status will be set. All the components of the status object are optional but obviously it will do nothing if no data is given. To always set the same status with an Interaction, use a syntax like the one below:

"status": {
  "data": "literally any matching text",
  "idle": "literally any matching text",
}

By default message/embed posts, as well as channel topic changes, are configured with their own channels. When using commands rather than CRON entries this may not be particularly useful - a command may have unwarted results if it is used in channel A where the config says to always post the response in channel B. If you wish, you can use the overrideChannels boolean to overcome this like so:

"Interactions": [
  {
    "command": "!weather",
    "overrideChannels": true,
    "cron": "* * * * *",
    "messages": [
      {
        "channelName": "general",
        "message": "This is a weather update!"
      }
    ],
    "channels": [
      {
        "channelName": "general",
        "newTopic": "This is a weather update"
      }
    ]
  }
]

Using the above configuration, when the Interaction runs from the CRON entry, the Message and Channel updates will run in their own set channels (in this case they're both set to general). But as the "overrideChannels" entry is included and set to true, whenever the !weather command is all actions within the interaction will affect the channel that !weather was typed into.