Skip to content

Commit e959044

Browse files
authored
Add Discord notifier plugin (#74)
* Add Discord notifier plugin * Ignore R0801 warning - similar lines in code * Fix blank lines
1 parent 4f23b4a commit e959044

4 files changed

Lines changed: 131 additions & 1 deletion

File tree

.github/workflows/pylint.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jobs:
2020
pip install -r requirements.txt
2121
- name: Analysing the code with pylint
2222
run: |
23-
pylint app --disable=C0116,C0114,C0115,C0411,E0401,W0611,W0622,W0719,C0103,W1514,R0903,R1732,R0914
23+
pylint app --disable=C0116,C0114,C0115,C0411,E0401,W0611,W0622,W0719,C0103,W1514,R0903,R1732,R0914,R0801
2424
- name: Analysing the code with pycodestyle
2525
run: |
2626
pycodestyle app
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
"""
2+
Discord Notifier Plugin
3+
======================
4+
Notify members about tools and doors usage statistics in Discord
5+
6+
How to use?
7+
-----------
8+
1. Setup WebHooks for your channel.
9+
HOWTO: https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks
10+
2. Create new branch in settings, e.g:
11+
"PLUGINS": {
12+
"slack_notifier": {
13+
"SLACK_DOOR_CHANNEL": "#prismo-door-channel",
14+
"SLACK_TOKEN": "xoxb-this-is-not-areal-slack-token",
15+
"SLACK_TOOL_CHANNEL": "#prismo-debug"
16+
},
17+
"discord_notifier": {
18+
"DISCORD_DOOR_EVENT_WEBHOOK": "https://discord.com/api/webhooks/your-webhook"
19+
},
20+
"""
21+
from flask import Flask
22+
23+
from .discord_notifier import DiscordNotifierPlugin
24+
25+
26+
def init_plugin(app: Flask):
27+
DiscordNotifierPlugin(app.app_context())
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import sqlite3
2+
from discord import SyncWebhook
3+
4+
# pylint: disable=consider-using-f-string
5+
6+
7+
class DiscordNotifierPlugin:
8+
def __init__(self, app_context):
9+
try:
10+
self.app_context = app_context
11+
self.logger = self.app_context.app.logger
12+
self.ee = self.app_context.app.ee # Event emitter, used for event-based communication
13+
self.config = self.app_context.app.config["PRISMO"]["PLUGINS"]["discord_notifier"]
14+
self.db_uri = self.app_context.app.config["DATABASE_URI"]
15+
self.ee.add_listener('access-log-entry-added', self.access_log_entry_added)
16+
self.app_context.app.logger.info("Discord Notifier Plugin initialized")
17+
except Exception as e:
18+
self.logger.error("Error in DiscordNotifierPlugin.__init__: %s", e)
19+
raise e
20+
21+
def get_user_name(self, user_key):
22+
"""
23+
Get user name and id based on user key info
24+
"""
25+
connection = sqlite3.connect(self.db_uri)
26+
cursor = connection.cursor()
27+
28+
cursor.execute("SELECT name from users WHERE key = ?",
29+
(user_key,),
30+
)
31+
connection.commit()
32+
result = cursor.fetchone()
33+
34+
connection.close()
35+
if result:
36+
return result[0]
37+
38+
return None
39+
40+
def get_device_name(self, device_id):
41+
"""
42+
Get device name based on its ID
43+
"""
44+
connection = sqlite3.connect(self.db_uri)
45+
cursor = connection.cursor()
46+
47+
cursor.execute("SELECT name from devices WHERE id = ?",
48+
(device_id,),
49+
)
50+
connection.commit()
51+
result = cursor.fetchone()
52+
53+
connection.close()
54+
if result:
55+
return result[0]
56+
57+
return None
58+
59+
def get_device_type(self, device_id):
60+
"""
61+
Get device name based on its ID
62+
"""
63+
connection = sqlite3.connect(self.db_uri)
64+
cursor = connection.cursor()
65+
66+
cursor.execute("SELECT type from devices WHERE id = ?",
67+
(device_id,),
68+
)
69+
connection.commit()
70+
result = cursor.fetchone()
71+
72+
connection.close()
73+
if result:
74+
return result[0]
75+
76+
return None
77+
78+
def access_log_entry_added(self, event):
79+
try:
80+
if event["operation"] == "unlock":
81+
user_name = self.get_user_name(event["user_key"])
82+
device_name = self.get_device_name(event["device_id"])
83+
device_type = self.get_device_type(event["device_id"])
84+
self.logger.info("Access log entry added")
85+
self.logger.info("User name: %s", user_name)
86+
if device_type == "tool":
87+
self.logger.info("Device name: %s", device_name)
88+
text_message = "🔩**%s** was unlocked by **%s**" % (device_name, user_name)
89+
webhook = SyncWebhook.from_url(self.config["DISCORD_TOOL_EVENT_WEBHOOK"])
90+
webhook.send(text_message)
91+
92+
elif device_type == "door":
93+
self.logger.info("Door opened: %s", device_name)
94+
text_message = "🔐**%s** was opened by **%s**" % (device_name, user_name)
95+
webhook = SyncWebhook.from_url(self.config["DISCORD_DOOR_EVENT_WEBHOOK"])
96+
webhook.send(text_message)
97+
else:
98+
self.logger.error("Unknown reader type! %s", device_type)
99+
100+
except Exception as e:
101+
self.logger.error("Error in DiscordNotifierPlugin.access_log_entry_added: %s", e)
102+
raise e

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@ intelhex
1717
pyserial
1818
rshell
1919
esptool
20+
discord

0 commit comments

Comments
 (0)