feat: webhook event firing on issue creation (background task)
This commit is contained in:
56
app/services/webhook.py
Normal file
56
app/services/webhook.py
Normal file
@@ -0,0 +1,56 @@
|
||||
import json
|
||||
import hmac
|
||||
import hashlib
|
||||
import logging
|
||||
from sqlalchemy.orm import Session
|
||||
from app.models.webhook import Webhook, WebhookLog
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def fire_webhooks_sync(event: str, payload: dict, project_id: int, db: Session):
|
||||
"""Find matching webhooks and send payloads (sync version)."""
|
||||
import httpx
|
||||
|
||||
webhooks = db.query(Webhook).filter(Webhook.is_active == True).all()
|
||||
|
||||
matched = []
|
||||
for wh in webhooks:
|
||||
events = [e.strip() for e in wh.events.split(",")]
|
||||
if event not in events:
|
||||
continue
|
||||
if wh.project_id is not None and wh.project_id != project_id:
|
||||
continue
|
||||
matched.append(wh)
|
||||
|
||||
if not matched:
|
||||
return
|
||||
|
||||
payload_json = json.dumps(payload, default=str)
|
||||
|
||||
for wh in matched:
|
||||
log = WebhookLog(
|
||||
webhook_id=wh.id,
|
||||
event=event,
|
||||
payload=payload_json,
|
||||
)
|
||||
try:
|
||||
headers = {"Content-Type": "application/json"}
|
||||
if wh.secret:
|
||||
sig = hmac.new(
|
||||
wh.secret.encode(), payload_json.encode(), hashlib.sha256
|
||||
).hexdigest()
|
||||
headers["X-Webhook-Signature"] = sig
|
||||
|
||||
with httpx.Client(timeout=10.0) as client:
|
||||
resp = client.post(wh.url, content=payload_json, headers=headers)
|
||||
log.response_status = resp.status_code
|
||||
log.response_body = resp.text[:1000]
|
||||
log.success = 200 <= resp.status_code < 300
|
||||
except Exception as e:
|
||||
log.response_body = str(e)[:1000]
|
||||
log.success = False
|
||||
logger.warning(f"Webhook delivery failed for {wh.url}: {e}")
|
||||
|
||||
db.add(log)
|
||||
db.commit()
|
||||
Reference in New Issue
Block a user