80 lines
2.2 KiB
Python
80 lines
2.2 KiB
Python
"""
|
|
Webhook handlers for JIRA and Bitbucket events.
|
|
"""
|
|
from fastapi import APIRouter, Request, HTTPException, Header
|
|
from typing import Optional
|
|
import hmac
|
|
import hashlib
|
|
import logging
|
|
|
|
logger = logging.getLogger(__name__)
|
|
router = APIRouter()
|
|
|
|
|
|
def verify_jira_signature(payload: bytes, signature: str, secret: str) -> bool:
|
|
"""Verify JIRA webhook signature."""
|
|
expected = hmac.new(secret.encode(), payload, hashlib.sha256).hexdigest()
|
|
return hmac.compare_digest(expected, signature)
|
|
|
|
|
|
@router.post("/jira")
|
|
async def jira_webhook(
|
|
request: Request,
|
|
x_atlassian_webhook_identifier: Optional[str] = Header(None),
|
|
):
|
|
"""
|
|
Handle JIRA webhook events.
|
|
|
|
Events processed:
|
|
- jira:issue_created
|
|
- jira:issue_updated
|
|
"""
|
|
body = await request.body()
|
|
data = await request.json()
|
|
|
|
event_type = data.get("webhookEvent", "unknown")
|
|
issue = data.get("issue", {})
|
|
issue_key = issue.get("key", "unknown")
|
|
|
|
logger.info(f"📥 JIRA webhook: {event_type} - {issue_key}")
|
|
|
|
# Filter: only process Support Cases
|
|
issue_type = issue.get("fields", {}).get("issuetype", {}).get("name", "")
|
|
if issue_type != "Support Case":
|
|
logger.info(f"⏭️ Skipping non-Support Case issue: {issue_key} ({issue_type})")
|
|
return {"status": "skipped", "reason": "not a Support Case"}
|
|
|
|
# Queue for analysis
|
|
# TODO: Implement queue system
|
|
logger.info(f"📋 Queuing Support Case for analysis: {issue_key}")
|
|
|
|
return {
|
|
"status": "accepted",
|
|
"issue": issue_key,
|
|
"event": event_type,
|
|
}
|
|
|
|
|
|
@router.post("/bitbucket")
|
|
async def bitbucket_webhook(request: Request):
|
|
"""
|
|
Handle Bitbucket webhook events.
|
|
|
|
Events processed:
|
|
- repo:refs_changed (push)
|
|
- pr:merged
|
|
"""
|
|
data = await request.json()
|
|
event_type = data.get("eventKey", "unknown")
|
|
|
|
logger.info(f"📥 Bitbucket webhook: {event_type}")
|
|
|
|
if event_type == "repo:refs_changed":
|
|
# Re-index affected files
|
|
changes = data.get("changes", [])
|
|
for change in changes:
|
|
ref = change.get("ref", {}).get("displayId", "")
|
|
logger.info(f"🔄 Branch updated: {ref}")
|
|
|
|
return {"status": "accepted", "event": event_type}
|