Custom Discord Bots powering the KlimaDAO community.
This is a monorepo containing multiple bots.
src/
- each folder corresponds to a specific bot
Each bot requires a separate application to be defined in the Discord Developer Portal. For each, do the following:
- Access the Discord developer portal: https://discord.com/developers/applications
- Create a new application: enter in the name of the bot (e.g. next-rewards)
- Create a bot: Click on "bot" in the sidebar and define a bot with the corresponding username.
- Check the "presence" and "server members" intents.
- Authorise the bot:
- Click on OAuth2 -> URL Generator in the sidebar.
- Select the "bot" scope.
- Copy the generated URL and open it.
- Select your server from the list and click on "Authorize". (You'll know that this has worked, as the bot user will appear in your Discord server.)
- Obtain the token for the bot: Settings -> Bot -> Token -> Copy
This project requires some API keys to run. When developing locally, you can create your own API keys from the following services:
- Infura: create a new project - https://infura.io/dashboard
- Note that you need to enable the Polygon add-on: https://infura.io/payment?chosenAddon=ethereum_polygon_addon
- PolygonScan: create an account - https://polygonscan.com/myapikey
- Discord webhook URL: create a personal server, channel settings -> integrations, create webhook
The bots are hosted on Digital Ocean App Platform under a single app. Upon any commit to the main or staging branches, the bots are deployed automatically.
Before this, the app must be created. It can be done through the DigitalOcean App Platform web interface, or through the make create command.
Deployment follows this process:
- A Docker image is built and pushed to DOCR using the
Dockerfile.- Note: This Docker image contains the source code to the bots. Do NOT include any confidential or proprietary information in the repository or build artifacts.
- The app is deployed to Digital Ocean, using the built Docker image as the basis.
To deploy manually, run:
DIGITALOCEAN_APP_ID=<INSERT ID> DIGITALOCEAN_ACCESS_TOKEN=<INSERT TOKEN> make deploy
The following environment variables must be defined in GitHub Actions:
DIGITALOCEAN_ACCESS_TOKEN- Generate a personal access token at the following URL: https://cloud.digitalocean.com/account/api/tokens
DIGITALOCEAN_APP_NAMEDIGITALOCEAN_APP_ID- In the Digital Ocean web interface, go to project -> apps, and copy the ID from the URL, e.g.
SOME-222-random-stringin https://cloud.digitalocean.com/apps/SOME-222-random-string/settings
- In the Digital Ocean web interface, go to project -> apps, and copy the ID from the URL, e.g.
DIGITALOCEAN_CONTAINER_REPO- Name of the Docker image registry hosted by Digital Ocean. It will be the name listed on this page: https://cloud.digitalocean.com/registry
These variables must also be defined, and will be used to replace variables in the app-spec.yml file:
POLYGONSCAN_API_KEYWEB3_PROVIDER_ETH_URLWEB3_PROVIDER_POLYGON_URLDISCORD_BOT_TOKEN_KLIMA_PRICEDISCORD_BOT_TOKEN_BCT_PRICEDISCORD_BOT_TOKEN_MCO2_PRICEDISCORD_BOT_TOKEN_STAKING_REWARDSDISCORD_BOT_TOKEN_MANIC_PRICEDISCORD_BOT_TOKEN_WOOD_PRICE
NOTE: in order for environment variables defined as GitHub Actions Secrets/Variables to be propagated properly from GitHub Actions into the deployed Docker containers, they must be mapped in several places:
- Into the build environment via the
.github/workflows/deploy.yamlfileenvsection of theDeploystep - Into the k8s build via
k8s/secret.properties.template - Into the actual k8s secret via
k8s/base/deployment.yamlor the corresponding bot-specificdeployment_set_<bot_name>.yamlfile in the appropriate bot-specific directory underk8s
The above environment variables are used in the production deployment to DO k8s clusters. They are injected into the k8s/secret.properties file for the following reasons:
- It is cumbersome to include the secret in the configuration file, deploy it and then copy/paste the encrypted value into the file again.
- Updating secrets becomes cumbersome as well.
Instead, it is much easier to define and rotate secrets through the GitHub Actions secrets. We use the envsubst tool to achieve this.
Sometimes you need to do something to one of the Discord bots - troubleshoot why it stopped working randomly, or it needs to be manually deleted because it is being deprecated.
To access the k8s cluster, you'll need a kubeconfig file generated by DO. Follow this guide to generate one from your DO account that has access to the Klima org on DO.
Then you just install kubectl and set up the KUBECONFIG environment variable to point to the kubeconfig file you got from DO.
Now you can interact with the k8s cluster via kubectl to execute common maintenance operations.
To list the pods in the discord-bots namespace:
kubectl get pods -n discord-botsTo delete a specific pod and trigger a restart:
kubectl delete pods to-be-deleted-bot-abc123 -n discord-botsTo delete an entire Deployment, which will decommission that bot:
kubectl delete deployments to-be-deleted-bot -n discord-botsNOTE: if the bot's code hasn't been deprecated from the codebase yet, it will be redeployed on the next commit to main. When cleaning up after a deprecated bot, be sure to remove any unnecessary environment variables from the relevant mappings and from GitHub Actions settings.
Each Docker image is tagged with the GitHub commit SHA, which prevents parallel deployments (main and staging) from clobbering each other.
In order for parallel deployments to work, however, the following must be implemented:
- Define the "default" (non-production) environment variables for the GitHub repository. This ensures that any new branches will use non-production variables by default.
- Create an environment called "main" and define any variables that differ from the default variables. At a minimum, this should include:
DIGITALOCEAN_APP_ID(or else different branches will be the same DigitalOcean app and clobber each other).- All of the
DISCORD_BOT_*tokens (or else those bots will be clobbered).