Skip to content

Commit bfe9f81

Browse files
artczcybit
andauthored
Discord channel router v1 (#10)
First version of the discord channel router for the bot – allowing us to send messages from webhooks to different channels. v1 focused mostly on github integration and pushing messages from different github boards to different channels on discord. Co-authored-by: Cyril Bitterich <cebit-github@gunnet.de>
1 parent 27e8eee commit bfe9f81

20 files changed

+1210
-275
lines changed

.github/workflows/build_and_deploy.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ jobs:
3333
run: |
3434
docker run --rm \
3535
-e DJANGO_SETTINGS_MODULE=intbot.settings \
36-
-e DATABASE_URL=postgres://testuser:testpassword@localhost:5432/testdb \
3736
--network host \
3837
intbot \
3938
make in-container/tests

deploy/templates/app/intbot.env.example

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,24 @@ POSTGRES_PASSWORD="RandomPasswordPleaseChange"
1313
DISCORD_BOT_TOKEN="Token Goes Here"
1414
DISCORD_TEST_CHANNEL_ID="123123123123123123123123"
1515
DISCORD_TEST_CHANNEL_NAME="#test-channel"
16+
DISCORD_BOARD_CHANNEL_ID="DISCORD_BOARD_CHANNEL_ID"
17+
DISCORD_BOARD_CHANNEL_NAME="DISCORD_BOARD_CHANNEL_NAME"
18+
DISCORD_EP2025_CHANNEL_ID="DISCORD_EP2025_CHANNEL_ID"
19+
DISCORD_EP2025_CHANNEL_NAME="DISCORD_EP2025_CHANNEL_NAME"
20+
DISCORD_EM_CHANNEL_ID="DISCORD_EM_CHANNEL_ID"
21+
DISCORD_EM_CHANNEL_NAME="DISCORD_EM_CHANNEL_NAME"
22+
DISCORD_WEBSITE_CHANNEL_ID="DISCORD_WEBSITE_CHANNEL_ID"
23+
DISCORD_WEBSITE_CHANNEL_NAME="DISCORD_WEBSITE_CHANNEL_NAME"
24+
DISCORD_BOT_CHANNEL_ID="DISCORD_BOT_CHANNEL_ID"
25+
DISCORD_BOT_CHANNEL_NAME="DISCORD_BOT_CHANNEL_NAME"
1626

1727
# Webhooks
1828
WEBHOOK_INTERNAL_TOKEN="asdf"
1929

2030
# Github
2131
GITHUB_API_TOKEN="github-api-token-goes-here"
2232
GITHUB_WEBHOOK_SECRET_TOKEN="github-webhook-secret-token"
33+
34+
GITHUB_BOARD_PROJECT_ID="GITHUB_BOARD_PROJECT_ID"
35+
GITHUB_EP2025_PROJECT_ID="GITHUB_EP2025_PROJECT_ID"
36+
GITHUB_EM_PROJECT_ID="GITHUB_EM_PROJECT_ID"

intbot/conftest.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import json
2+
3+
import pytest
4+
from django.conf import settings
5+
6+
7+
@pytest.fixture(scope="session")
8+
def github_data():
9+
"""Pytest fixture with examples of webhooks from github"""
10+
base_path = settings.BASE_DIR / "tests" / "test_integrations" / "github"
11+
12+
return {
13+
"project_v2_item.edited": json.load(
14+
open(base_path / "project_v2_item.edited.json"),
15+
),
16+
"query_result": json.load(
17+
open(base_path / "query_result.json"),
18+
)["data"]["node"],
19+
}

intbot/core/bot/channel_router.py

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
"""
2+
Channel router that decides where to send particular message
3+
"""
4+
5+
from dataclasses import dataclass
6+
7+
from core.integrations.github import (
8+
GithubProjects,
9+
GithubRepositories,
10+
parse_github_webhook,
11+
)
12+
from core.models import Webhook
13+
from django.conf import settings
14+
15+
16+
@dataclass
17+
class DiscordChannel:
18+
channel_id: str
19+
channel_name: str
20+
21+
22+
dont_send_it = DiscordChannel(channel_id="0", channel_name="DONT_SEND_IT")
23+
24+
25+
class Channels:
26+
test_channel = DiscordChannel(
27+
channel_id=settings.DISCORD_TEST_CHANNEL_ID,
28+
channel_name=settings.DISCORD_TEST_CHANNEL_NAME,
29+
)
30+
31+
board_channel = DiscordChannel(
32+
channel_id=settings.DISCORD_BOARD_CHANNEL_ID,
33+
channel_name=settings.DISCORD_BOARD_CHANNEL_NAME,
34+
)
35+
ep2025_channel = DiscordChannel(
36+
channel_id=settings.DISCORD_EP2025_CHANNEL_ID,
37+
channel_name=settings.DISCORD_EP2025_CHANNEL_NAME,
38+
)
39+
em_channel = DiscordChannel(
40+
channel_id=settings.DISCORD_EM_CHANNEL_ID,
41+
channel_name=settings.DISCORD_EM_CHANNEL_NAME,
42+
)
43+
website_channel = DiscordChannel(
44+
channel_id=settings.DISCORD_WEBSITE_CHANNEL_ID,
45+
channel_name=settings.DISCORD_WEBSITE_CHANNEL_NAME,
46+
)
47+
bot_channel = DiscordChannel(
48+
channel_id=settings.DISCORD_BOT_CHANNEL_ID,
49+
channel_name=settings.DISCORD_BOT_CHANNEL_NAME,
50+
)
51+
52+
53+
def discord_channel_router(wh: Webhook) -> DiscordChannel:
54+
if wh.source == "github":
55+
return github_router(wh)
56+
57+
elif wh.source == "internal":
58+
return internal_router(wh)
59+
60+
return dont_send_it
61+
62+
63+
def github_router(wh: Webhook) -> DiscordChannel:
64+
gwh = parse_github_webhook(wh)
65+
project = gwh.get_project()
66+
repository = gwh.get_repository()
67+
68+
# We have three github projects, that we want to route to three different
69+
# channels - one for ep2025, one for EM, and one for the board.
70+
PROJECTS = {
71+
GithubProjects.board_project: Channels.board_channel,
72+
GithubProjects.ep2025_project: Channels.ep2025_channel,
73+
GithubProjects.em_project: Channels.em_channel,
74+
}
75+
76+
if channel := PROJECTS.get(project.id):
77+
return channel
78+
79+
# Then we have our open source repositories, like website, this bot, and
80+
# some others, that we also might want to route to different channels
81+
REPOSITORIES = {
82+
GithubRepositories.website_repo: Channels.website_channel,
83+
GithubRepositories.bot_repo: Channels.bot_channel,
84+
}
85+
86+
if channel := REPOSITORIES.get(repository.id):
87+
return channel
88+
89+
# Finally, we can use this to drop notifications that we don't want to
90+
# support, by not sending them.
91+
return dont_send_it
92+
93+
94+
def internal_router(wh: Webhook) -> DiscordChannel:
95+
# For now just send all the internal messages to a test channel
96+
return Channels.test_channel

intbot/core/endpoints/webhooks.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ def internal_webhook_endpoint(request):
2121
wh = Webhook.objects.create(
2222
source="internal",
2323
content=json.loads(request.body),
24+
extra={},
2425
)
2526
process_webhook.enqueue(str(wh.uuid))
2627

@@ -58,6 +59,7 @@ def github_webhook_endpoint(request):
5859
meta=github_headers,
5960
signature=signature,
6061
content=json.loads(request.body),
62+
extra={},
6163
)
6264
process_webhook.enqueue(str(wh.uuid))
6365
return JsonResponse({"status": "ok"})

0 commit comments

Comments
 (0)