feat: add clip-vault clipboard history daemon with webhook fanout
This commit is contained in:
commit
013c550047
8 files changed
+549
No files matched your search
@@ -0,0 +1,61 @@
|
||||
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()
|
||||
Reference in new issue
Block a user