def on_fire(ctx): """Fire outbound webhook with optional connection credentials.""" data = ctx["stage_data"] url = data.get("webhook_url", "") # Fallback to configured connection if not url: conn = connections.get("webhook") if conn: url = conn.get("url", "") if not url: return {"error": "No webhook URL configured"} payload = json.encode({ "event": data.get("event_name", "workflow.notify"), "instance_id": ctx["instance_id"], "workflow_id": ctx["workflow_id"], "data": data, }) resp = http.post(url, body=payload, headers={ "Content-Type": "application/json", "X-Armature-Event": data.get("event_name", "workflow.notify"), }) # Log the delivery db.insert("webhook_log", { "url": url, "status_code": str(resp["status"]), "event": data.get("event_name", ""), "instance_id": ctx["instance_id"], }) status = "delivered" if int(resp["status"]) < 400 else "failed" return {"advance": True, "data": { "delivery_status": status, "status_code": str(resp["status"]), "response_body": resp["body"][:500], }}