62 lines
2.0 KiB
Python
62 lines
2.0 KiB
Python
import json
|
|
import re
|
|
import threading
|
|
import time
|
|
import urllib.request
|
|
|
|
from clip_vault.config import logPath
|
|
|
|
|
|
def logLine(line):
|
|
with open(logPath, "a") as logFile:
|
|
logFile.write(f"{time.strftime('%Y-%m-%d %H:%M:%S')} {line}\n")
|
|
|
|
|
|
def matchingWebhooks(content, config):
|
|
matches = []
|
|
for webhook in config.get("webhooks", []):
|
|
if not webhook.get("enabled"):
|
|
continue
|
|
pattern = webhook.get("matchPattern", ".*")
|
|
try:
|
|
if re.search(pattern, content):
|
|
matches.append(webhook)
|
|
except re.error as regexError:
|
|
logLine(f"invalid matchPattern in webhook '{webhook.get('name')}': {regexError}")
|
|
return matches
|
|
|
|
|
|
def sendWebhook(webhook, content, sourceWindow):
|
|
body = {"content": content, "timestamp": time.time()}
|
|
if webhook.get("includeSourceWindow", True):
|
|
body["sourceWindow"] = sourceWindow
|
|
data = json.dumps(body).encode("utf-8")
|
|
headers = {"Content-Type": "application/json"}
|
|
headers.update(webhook.get("headers", {}))
|
|
request = urllib.request.Request(webhook["url"], data=data, headers=headers, method=webhook.get("method", "POST"))
|
|
try:
|
|
with urllib.request.urlopen(request, timeout=webhook.get("timeoutSeconds", 4)) as response:
|
|
logLine(f"webhook '{webhook.get('name')}' -> {response.status}")
|
|
return True
|
|
except Exception as sendError:
|
|
logLine(f"webhook '{webhook.get('name')}' failed: {sendError}")
|
|
return False
|
|
|
|
|
|
def dispatchAsync(content, sourceWindow, config, onDone=None):
|
|
matches = matchingWebhooks(content, config)
|
|
if not matches:
|
|
if onDone:
|
|
onDone([])
|
|
return
|
|
|
|
def worker():
|
|
sentNames = []
|
|
for webhook in matches:
|
|
if sendWebhook(webhook, content, sourceWindow):
|
|
sentNames.append(webhook.get("name", webhook["url"]))
|
|
if onDone:
|
|
onDone(sentNames)
|
|
|
|
threading.Thread(target=worker, daemon=True).start()
|