Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dockerize event reminder script #2

Merged
merged 17 commits into from
Jun 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .env.template
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
OWLBOT_SECRET=
OP_START_CHANNEL_ID=
OP_START_CHANNEL_ID=<OP_START_CHANNEL_ID>
31 changes: 31 additions & 0 deletions .github/workflows/dev-image-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Build Owlbot DEV Docker image

on:
push:
branches: [ "dockerize", "dev" ]

jobs:

build:

runs-on: ubuntu-latest
environment: dev

steps:
-
name: Checkout repository
uses: actions/checkout@v4
with:
path: 'owlbot-repo'
-
name: Build the Docker image
run: docker build . --file owlbot-repo/Dockerfile --tag cntoarma/owlbot:dev
-
name: Authenticate to CNTO DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Publish image to DockerHub
run: docker image push cntoarma/owlbot:dev
31 changes: 31 additions & 0 deletions .github/workflows/stable-image-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Build Owlbot Docker image

on:
push:
branches: [ "main" ]

jobs:

build:

runs-on: ubuntu-latest
environment: stable

steps:
-
name: Checkout repository
uses: actions/checkout@v4
with:
path: 'owlbot-repo'
-
name: Build the Docker image
run: docker build . --file owlbot-repo/Dockerfile --tag cntoarma/owlbot:latest
-
name: Authenticate to CNTO DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Publish image to DockerHub
run: docker image push cntoarma/owlbot:latest
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# CNTO Custom
log
*.log
.env.local*
discord-token.txt

# Byte-compiled / optimized / DLL files
__pycache__/
Expand Down
10 changes: 10 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
FROM alpine:3.19

ADD owlbot-repo /owlbot
WORKDIR /owlbot

RUN apk add --no-cache python3 py3-pip
RUN pip install --break-system-packages -r requirements.txt
RUN crontab crontab.txt

CMD ["crond", "-f"]
51 changes: 51 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# CNTO Owlbot

## What is the Owlbot

Owlbot is CNTO's omnipresent assistant. It is currently implemented as a TeamSpeak user for populating our `stats` pages, and on Discord for automated member pings before our operations begin. R&D has plans to expand the Discord presence to enable staff members to carry out their tasks directly from our Discord, but this is a WIP.

## Installation guide

Owlbot is available as [a Docker image](https://hub.docker.com/repository/docker/cntoarma/owlbot/general), published on CNTO's DockerHub registry.

### 1. Create a Discord application from the Discord Developer Portal

You can follow [this guide](https://discordpy.readthedocs.io/en/stable/discord.html) to create a bot application. CNTO has two versions of the Owlbot managed by R&D: OWL and OWL Dev. The key takeaway from this step is to obtain the bot's secret, used to authenticate the bot against Discord's API.

### 2. Gather the required parameters

Within CNTO, the Owlbot is deployed on the `Tools Server`. It requires a few parameters as described in the `.env.template` file, namely:

```language=config
OWLBOT_SECRET=<OWLBOT_SECRET> # The bot's secret obtained on the Discord Developer Portal
OP_START_CHANNEL_ID=<OP_START_CHANNEL_ID> # The ID of the channel where operations reminders will be posted
```

These parameters can be passed to Owlbot in two different ways:

1. As system environment variables, for example `export OWLBOT_SECRET=1234`
2. As `.env` file in the same directory as the `.env.template`

Owlbot will try to load from a `.env` file, falling back to system variables. If both are present, system variables are used.

**Note** if you use the Owlbot Docker image from our public registry, the `.env` file is not yet created by the build process so you need to rely on environment variables. The `.env` file mechanism is supported for local development environments. We do not plan on adding `.env` file support for staging / production environments.

### 3. Run the Docker image

Launch a container based on the Owlbot Docker image, for example:

```bash
docker run -d -e OWLBOT_SECRET=<YOUR_SECRET_HERE> -e OP_START_CHANNEL_ID=<YOUR_CHANNEL_ID_HERE> cntoarma/owlbot:[stable|dev]
```

If you still want to use a `.env` you can avoid passing environment variables to the run command, for example:

```bash
docker run -d --env-file .env cntoarma/owlbot:[stable|dev]
```

**Note** using `docker-compose` is preferred in production environments as it can also handle container restarts, ensuring the Owlbot is operational all the time.

#### Update the crontab file

By default, the Owlbot will send join reminders 10 minutes before our events start (19:35 CET / CEST). This is configured in the `crontab.txt` file that gets installed inside the Owlbot container upon build. If you need to change the
1 change: 1 addition & 0 deletions crontab.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
35 19 * * 2,5 sh /owlbot/op-reminder.sh
1 change: 1 addition & 0 deletions discord-token.txt.template
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DISCORD_TOKEN_HERE
13 changes: 13 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
version: "3"
services:
owlbot:
container_name: owlbot
# restart: unless-stopped
env_file: .env
image: cntoarma/owlbot:dev
secrets:
- discord_token

secrets:
discord_token:
file: ./discord-token.txt
4 changes: 1 addition & 3 deletions op-reminder.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
source ~/miniconda3/etc/profile.d/conda.sh
conda activate discord-owlbot
python /home/carpenoctem/discord-owlbot/op-start-reminder.py
python /owlbot/op-start-reminder.py > /owlbot/cron.log 2>&1
21 changes: 16 additions & 5 deletions op-start-reminder.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,29 @@
import discord
from dotenv import load_dotenv
from dotenv import dotenv_values
import os

load_dotenv()
# Load from .env (for local dev environments) or override with environment variables (for production)
config = {
**dotenv_values('.env'),
**os.environ
}

CHANNEL_ID = os.enivon['OP_START_CHANNEL_ID']
BOT_SECRET = os.environ['OWLBOT_SECRET']
CHANNEL_ID = config['OP_START_CHANNEL_ID']

# Read bot token for Discord auth from docker-compose secrets
BOT_SECRET = None
with open('/run/secrets/discord_token', 'r') as f:
BOT_SECRET = f.read()

if BOT_SECRET is None:
raise ValueError("Unable to read Discord token")

class MyClient(discord.Client):
async def on_ready(self):
# async for guild in client.fetch_guilds(limit=150):
# print(guild.name)

channel = self.get_channel(CHANNEL_ID)
channel = await self.fetch_channel(CHANNEL_ID)
await channel.send("Tonight's OP is about to start, @here grab a drink and join us!")
await self.close()

Expand Down