Skip to content

Commit

Permalink
Bugfix
Browse files Browse the repository at this point in the history
  • Loading branch information
Nikoh77 committed May 20, 2024
1 parent 7bb07f6 commit 8d72b82
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 38 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Now Shinogramma integrates a complete notification system via Telegram, so it's
You only need to enable event notifications via webhook in your account settings on the Shinobi interface; the URL will be:
`http://SHINOGRAMMA-IP:5001/notifier/?message={{INNER_EVENT_INFO}}`\
Please replace the IP address with the actual one; the port can be changed through the appropriate parameter in the configuration file (more information can be found on this page).\
Shinogramma will be listening on that endpoint for POST and GET requests; to receive images with GET notifications, you also need to enable the JPG API in the settings of each monitor (so I recommend choosing POST).\
Shinogramma will be listening on that endpoint for POST and GET requests (I recommend choosing POST); to receive images of events, you also need to enable the JPG API in the settings of each monitor.\
This notification system seems to perform much better than the one integrated in Shinobi, but the choice is yours.
## Commands:
Shinogramma is always under development, although it already works very well and has many functions, so commands and things he can do can increase, also maybe with your help; a good place to start is the /help command\
Expand Down Expand Up @@ -58,10 +58,9 @@ loglevel - optional - default: info - the debug level of the app. If you encount
persistence - optional - default: false - old buttons in the chat with the bot will remain functional even after the bot restarts. This consumes more system resources.
webhook_server - optional - default: false - set to true (or 1) to enable event notifications.
webhook_port - optional - default: 5001 - the port for the endpoint (webhook) where Shinogramma listens for event notifications sent by your Shinobi (requires enabling webhook notifications).
```

bans - optional - default: none - this parameters are particularly useful for restricting (banning) specific Telegram user IDs from accessing certain functions.
Below is a table detailing the possible keys within the `bans` dictionary of the configuration file:\
```
Below is a table detailing the possible keys within the `bans` dictionary of the configuration file:

| Parameter | Description |
|-------------------|-------------|
Expand Down Expand Up @@ -112,6 +111,7 @@ Feel free to expand my code with new features or simply clean it up and/or make

### FINAL NOTES:
I already implemented the code for:
* Restrict API/webhooks calls to single or a list of IPs
* webhook call when an event is triggered,
* Configurable webhooks calls through the bot/chat like to open a gate or to arm an alarm system.\
* monitors configuration through conversation/chat, but I need better API documentation.
Expand Down
71 changes: 37 additions & 34 deletions src/notify.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
import hashlib
import time
import json
# from werkzeug.datastructures import FileStorage
from quart import Quart, request, Response, abort
from urllib.parse import unquote, parse_qs

logger = logging.getLogger(name=__name__)
'''
Expand All @@ -34,7 +34,7 @@ def __init__(
self.shinobiApiKey = shinobiApiKey
self.groupKey = groupKey
self.APPLICATION: Application = application
self.snapshotUrl = "".join([baseUrl.url, ":", str(object=self.port), "/", shinobiApiKey, "/jpeg/", groupKey])
self.snapshotUrl = "".join([baseUrl.url, ":", str(object=self.shinobiPort), "/", shinobiApiKey, "/jpeg/", groupKey])
self.toNotify = toNotify
self.app.add_url_rule(
rule="/notifier/",
Expand All @@ -50,8 +50,7 @@ def calculate_md5(self, content) -> str:

async def runServer(self) -> None:
try:
await self.app.run_task(host="0.0.0.0", port=self.port, debug=True)
print("ciao")
await self.app.run_task(host="0.0.0.0", port=self.port, debug=False)
except Exception as e:
logger.warning(msg=f"Error running HTTP Server: {e}")

Expand All @@ -61,30 +60,31 @@ async def stopServer(self):

async def notifier(self) -> Response:
try:
message = request.args.get(key="message")
message = unquote(string=request.query_string).lstrip("message=")
if not message:
logger.error(msg=f"Missing message query parameter...")
abort(code=400, description="Missing message query parameter")
messageDict = json.loads(s=message)
logger.debug(msg=f"Received message: {message}")
files = await request.files
mid = messageDict["info"]["mid"]
description = messageDict["info"]["description"]
reason = messageDict["info"]["eventDetails"]["reason"]
confidence = messageDict["info"]["eventDetails"]["confidence"]
url = f"{self.baseUrl}:{self.shinobiPort}/{self.shinobiApiKey}/monitor/{self.groupKey}/{mid}"
data = await queryUrl(url=url)
if not data:
abort(
code=204
) # no log because queryUrl already should have logged something
dataInJson = data.json()
if not dataInJson:
logger.warning(
msg=f"Error getting data from {url} about monitor {mid}..."
)
abort(code=204)
name = dataInJson[0].get("name")
mid = messageDict["info"].get("mid", None)
description = messageDict["info"].get("description", None)
title = messageDict["info"].get("title", None)
if "eventDetails" in messageDict["info"].keys():
reason = messageDict["info"]["eventDetails"].get("reason", None)
confidence = messageDict["info"]["eventDetails"].get("confidence", None)
if mid:
url = f"{self.baseUrl}:{self.shinobiPort}/{self.shinobiApiKey}/monitor/{self.groupKey}/{mid}"
data = await queryUrl(url=url)
if not data:
logger.error(
msg=f"Error querying/getting data from {url} about monitor {mid}..."
)
abort(
code=204
)
dataInJson = data.json()
name = dataInJson[0].get("name")
except json.JSONDecodeError:
logger.error(
msg=f"{message}\n is not a valid JSON object, returning 400 error code..."
Expand All @@ -94,23 +94,26 @@ async def notifier(self) -> Response:
logger.error(msg=f"Error executing notifier func: {e}")
abort(code=204)
messageToSend = (
f"<b>WARNING:</b>\n"
f"Description: <b>{description}</b>\n"
f"Reason: <b>{reason}</b>\n"
f"Name: <b>{name}</b>\n"
f"Confidence: <b>{confidence}</b>"
"<b>WARNING:</b>\n"
+ (f"Title: <b>{title}</b>\n" if 'title' in locals() else "")
+ (f"Description: <b>{description}</b>\n" if 'description' in locals() else "")
+ (f"Reason: <b>{reason}</b>\n" if 'reason' in locals() else "")
+ (f"Name: <b>{name}</b>\n" if 'name' in locals() else "")
+ (f"Confidence: <b>{confidence}</b>\n" if 'confidence' in locals() else "")
)
for user in self.toNotify:
if files:
mediaGroup = self.mediaGroupFormatter(
files=files, messageToSend=messageToSend
)
if files:
mediaGroup = self.mediaGroupFormatter(
files=files, messageToSend=messageToSend
)
for user in self.toNotify:
await self.APPLICATION.bot.send_media_group(
chat_id=user, media=mediaGroup
)
else:
else:
if mid:
snapshotUrl = await self.getSnapshot(mid=mid)
if snapshotUrl:
for user in self.toNotify:
if "snapshotUrl" in locals().keys() and snapshotUrl is not None:
await self.APPLICATION.bot.send_photo(
chat_id=user,
photo=snapshotUrl,
Expand Down

0 comments on commit 8d72b82

Please sign in to comment.