ytptube/app/Webhooks.py
2024-02-03 00:39:05 +03:00

71 lines
2.3 KiB
Python

import asyncio
import json
import logging
import os
from ItemDTO import ItemDTO
from aiohttp import client
LOG = logging.getLogger('Webhooks')
class Webhooks:
targets: list[dict] = {}
def __init__(self, file: str):
if os.path.exists(file):
self.load(file)
def load(self, file: str):
try:
if os.path.getsize(file) < 2:
raise Exception(f'file is empty.')
LOG.info(f'Loading webhooks from {file}')
with open(file, 'r') as f:
self.targets = json.load(f)
except Exception as e:
LOG.error(f'Error loading webhooks from {file}: {e}')
pass
async def send(self, event: str, item: ItemDTO) -> list[dict]:
if len(self.targets) == 0:
return []
if not isinstance(item, ItemDTO):
return []
tasks = []
for target in self.targets:
allowed_events = target.get('on') if 'on' in target else []
if len(allowed_events) > 0 and event not in allowed_events:
continue
tasks.append(self.__send(event, target, item))
return await asyncio.gather(*tasks)
async def __send(self, event: str, target: dict, item: ItemDTO) -> dict:
req: dict = target.get('request')
try:
LOG.info(f"Sending {event=} {item.id=} to [{target.get('name')}]")
async with client.ClientSession() as session:
headers = req.get('headers', {}) if 'headers' in req else {}
async with session.request(method=req.get('method', 'POST'), url=req.get('url'), json=item.__dict__, headers=headers) as response:
respData = {
'url': req.get('url'),
'status': response.status,
'text': await response.text()
}
msg = f"[{target.get('name')}] Response to [{event=} {item.id=}] [status: {response.status}]."
if respData.get('text'):
msg += f" [Body: {respData.get('text','??')}]"
LOG.info(msg)
return respData
except Exception as e:
return {
'url': req.get('url'),
'status': 500,
'text': str(e)
}