diff --git a/ai-hub/app/api/routes/agents.py b/ai-hub/app/api/routes/agents.py index 62b6e2a..24401be 100644 --- a/ai-hub/app/api/routes/agents.py +++ b/ai-hub/app/api/routes/agents.py @@ -165,13 +165,28 @@ @router.post("/{id}/webhook", status_code=202) def webhook_receiver(id: str, payload: dict, background_tasks: BackgroundTasks, token: str = None, db: Session = Depends(get_db)): - # Validate instance instance = db.query(AgentInstance).filter(AgentInstance.id == id).first() if not instance: raise HTTPException(status_code=404, detail="Instance not found") + + # Verify webhook secret if a webhook trigger is defined for this instance + webhook_triggers = db.query(AgentTrigger).filter( + AgentTrigger.instance_id == id, + AgentTrigger.trigger_type == "webhook" + ).all() + + if webhook_triggers: + secrets = [t.webhook_secret for t in webhook_triggers if t.webhook_secret] + if secrets and token not in secrets: + raise HTTPException(status_code=403, detail="Invalid webhook token") + + # Extract prompt from payload if provided (Design Doc Requirement) + if "prompt" in payload: + prompt = payload["prompt"] + else: + # Fallback to serialised payload + prompt = f"Webhook Event: {json.dumps(payload)}" - # Pass webhook event directly to the Agent Executor to process - prompt = f"Webhook Event: {json.dumps(payload)}" background_tasks.add_task(AgentExecutor.run, instance.id, prompt, services.rag_service, services.user_service) return {"message": "Accepted"} diff --git a/frontend/src/features/agents/components/AgentDrillDown.js b/frontend/src/features/agents/components/AgentDrillDown.js index 9ce0d3a..62be952 100644 --- a/frontend/src/features/agents/components/AgentDrillDown.js +++ b/frontend/src/features/agents/components/AgentDrillDown.js @@ -283,6 +283,19 @@ } }; + const handleFireWebhook = async (token, triggerPrompt) => { + try { + await fetchWithAuth(`/agents/${agentId}/webhook?token=${token}`, { + method: 'POST', + body: { prompt: triggerPrompt || "Manual test from UI" } + }); + setModalConfig({ title: 'Success', message: 'Webhook test trigger sent successfully!', type: 'success' }); + fetchData(); + } catch (err) { + setModalConfig({ title: 'Webhook Failed', message: err.message, type: 'error' }); + } + }; + if (loading && !agent) return (
+ {`${window.location.origin}/api/v1/agents/${agentId}/webhook?token=${t.webhook_secret}`}
+
+
+ {"{"}"prompt": "..."{"}"} in the body.
+
+