Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Der-Henning
GitHub Repository: Der-Henning/tgtg
Path: blob/main/tgtg_scanner/notifiers/webhook.py
1494 views
1
import json
2
import logging
3
4
import requests
5
from requests.auth import HTTPBasicAuth
6
7
from tgtg_scanner.errors import MaskConfigurationError, WebHookConfigurationError
8
from tgtg_scanner.models import Config, Favorites, Item, Reservations
9
from tgtg_scanner.models.reservations import Reservation
10
from tgtg_scanner.notifiers.base import Notifier
11
12
log = logging.getLogger("tgtg")
13
14
15
class WebHook(Notifier):
16
"""Notifier for custom Webhooks."""
17
18
def __init__(self, config: Config, reservations: Reservations, favorites: Favorites):
19
super().__init__(config, reservations, favorites)
20
self.enabled: bool = config.webhook.enabled
21
self.method: str = config.webhook.method
22
self.url: str | None = config.webhook.url
23
self.body: str | None = config.webhook.body
24
self.type: str | None = config.webhook.type
25
self.headers: dict[str, str | bytes] = config.webhook.headers
26
self.auth = None
27
self.username: str | None = config.webhook.username
28
self.password: str | None = config.webhook.password
29
self.timeout: int = config.webhook.timeout
30
self.cron = config.webhook.cron
31
if self.enabled:
32
if self.method is None or self.url is None:
33
raise WebHookConfigurationError()
34
if self.username is not None and self.password is not None:
35
self.auth = HTTPBasicAuth(self.username, self.password)
36
log.debug("Using basic auth with user '%s' for webhook", self.username)
37
try:
38
Item.check_mask(self.body)
39
Item.check_mask(self.url)
40
except MaskConfigurationError as exc:
41
raise WebHookConfigurationError(exc.message) from exc
42
43
def _send(self, item: Item | Reservation) -> None:
44
"""Sends item information via configured Webhook endpoint."""
45
if isinstance(item, Item):
46
if self.url is None:
47
raise WebHookConfigurationError()
48
url = item.unmask(self.url)
49
log.debug("%s url: %s", self.name, url)
50
body: bytes | None = None
51
headers = self.headers or dict()
52
if self.type:
53
headers["Content-Type"] = self.type
54
if self.body:
55
if self.type is not None and "json" in self.type:
56
body = json.dumps(json.loads(item.unmask(self.body).replace("\n", "\\n"))).encode("utf-8")
57
else:
58
body = item.unmask(self.body).encode("utf-8")
59
log.debug("%s body: %s", self.name, body)
60
# body = item.unmask(self.body)
61
# if isinstance(body, bytes):
62
# pass
63
# elif self.type and "json" in self.type:
64
# body = json.dumps(json.loads(body.replace("\n", "\\n")))
65
# log.debug("%s body: %s", self.name, body)
66
# else:
67
# body = body.encode("utf-8")
68
# log.debug("%s body: %s", self.name, body)
69
log.debug("%s headers: %s", self.name, headers)
70
res = requests.request(
71
method=self.method,
72
url=url,
73
timeout=self.timeout,
74
data=body,
75
headers=headers,
76
auth=self.auth,
77
)
78
if not res.ok:
79
log.error("%s Request failed with status code %s", self.name, res.status_code)
80
log.debug("%s Response content: %s", self.name, res.text)
81
82
def __repr__(self) -> str:
83
return f"WebHook: {self.url}"
84
85