AWS Lambda serverless function Discord Bot to track Diablo III leaderboard
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
Joshua Westerheide 39b6f9f570
Make season configurable
3 years ago
__mocks__/blizzard-api/diablo-3-game-data-api Add Battlenet API response mocks 3 years ago
scripts Add Battlenet API response mocks 3 years ago
test Add general tests for internal functions 3 years ago
.gitignore Initialize npm package 3 years ago
README.md Make season configurable 3 years ago
index.js Make season configurable 3 years ago
package-lock.json Setup testing 3 years ago
package.json Setup testing 3 years ago

README.md

AWS Lambda Diablo III Discord Bot

A AWS Lambda powered Discord bot which tracks players on the leaderboard. With AWS CloudWatch this function can be configured to repeatedly (e.g. every 4 hours) fetch rift leaderboards and track your "Heroes" positions.

E.g.:

Leaderboard stats from Mon, 28 Jan 2019 09:36:17 GMT

Leaderboard for rift barbarian:
* Anon#1234 at rank 140
* Anon#1244 not in list

NOTE: At the moment the leadboard is only searched by players' BattleTags. However it is possible to have multiple "Heros" in one rift leaderboard with the same BattleTags. This would cause only the first "Hero" to be found.

Costs

Since this function requests the Battle.net API the runtime highly depends on the response time of the API. You should definitely set a timout for your Lambda function (e.g. 3 seconds).

To be precise: 1 request is made to obtain an access_token. Additionally for each rift another request is made.

The response JSON has a size of about ~500kb per leaderboard and needs to be parsed internally.

Stats

Monitoring stats using 1 leaderboard for 1 player:

  • execution time: ~1500 ms
  • memory usage: ~50 MB

Prerequisites

  1. Follow the guide at https://develop.battle.net/documentation/guides/getting-started to create a Battle.net API Client.
    1. Obtain the Client ID and Client Secret from your newly created client
  2. Create a Webbhook for a channel in your Discord server
    1. Edit a channel you wish to be notified in
    2. Create a new "Webhook"
    3. Copy the URL

Deployment

  1. Create a new Lambda function either through the AWS Console or using the AWS CLI:
    $ aws cli lambda create-function \
        --function-name YOUR-FUNCTION-NAME \
        --runtime nodejs8.10 \
        --role YOUR-ROLE \
        --handler index.trackLeaderboard \
        --environment 'Variables={BATTLENET_CLIENT_ID=<YOUR-CLIENT-ID>,BATTLENET_CLIENT_SECRET=<YOUR-CLIENT-SECRET>,DISCORD_BOT_WEBHOOK_URL=<YOUR-WEBHOOK-URL>}'
    
  2. Archive the lambda function and publish it:
    $ zip pkg.zip index.js
    $ aws lambda update-function-code \
        --function-name YOUR-FUNCTION-NAME \
        --zip-file pkg.zip
    
  3. Create a CloudWatch Event Rule, add the lambda function as target and select "Constant (JSON text)" under "Configure input":
    {
      "rifts": {
        "barbarian": [
          "Anon#1234"
        ]
      }
    }
    

    WARNING: Please note that Battle.net API Clients are limited to 36,000 requests per hour at a rate of 100 requests per second (see Throttling).

API Documentation

Environemnt variables

The lambda function uses the following environment variables which can be set in the "Environment variables" section:

  • BATTLENET_CLIENT_ID Battle.net API Client ID
  • BATTLENET_CLIENT_SECRET Battle.net API Client ID
  • BATTLENET_REGION Battle.net region (default: eu)
  • BATTLENET_SEASON Current season to track (default: 16)
  • DISCORD_BOT_WEBHOOK_URL The Discord Webhook URL to post leaderboard messages to
  • DISCORD_BOT_NAME Name of the Discord bot, displayed in the channel (default: Leaderboard BOT)

Input

The lambda function accepts the following input from an event payload:

interface payload {
    rifts: { [riftName: string]: string[] }
}

For each riftName all given player BattleTags will be searched in the rift leaderboard.

E.g:

{
  "rifts": {
    "barbarian": [
      "Anon#1234",
      "Anon#4321"
    ],
    "wizard": [
      "Anon#1237"
    ]
  }
}