Add support for custom URLs in the retry webhook API (#4329)

This commit is contained in:
Marc Kelechava
2025-12-18 10:38:51 -08:00
committed by GitHub
parent c61bd26c8c
commit 8ebe0f2bfb
6 changed files with 86 additions and 13 deletions

View File

@@ -1,12 +1,12 @@
from fastapi import HTTPException, status
from skyvern.config import settings
from skyvern.exceptions import TaskNotFound, WorkflowRunNotFound
from skyvern.exceptions import OrganizationNotFound, TaskNotFound, WorkflowRunNotFound
from skyvern.forge import app
from skyvern.forge.sdk.schemas.tasks import TaskStatus
from skyvern.forge.sdk.workflow.models.workflow import WorkflowRunStatus
from skyvern.schemas.runs import RunEngine, RunResponse, RunType, TaskRunRequest, TaskRunResponse
from skyvern.services import task_v1_service, task_v2_service, workflow_service
from skyvern.services import task_v1_service, task_v2_service, webhook_service, workflow_service
async def get_run_response(run_id: str, organization_id: str | None = None) -> RunResponse | None:
@@ -147,7 +147,12 @@ async def cancel_run(run_id: str, organization_id: str | None = None, api_key: s
)
async def retry_run_webhook(run_id: str, organization_id: str | None = None, api_key: str | None = None) -> None:
async def retry_run_webhook(
run_id: str,
organization_id: str | None = None,
api_key: str | None = None,
webhook_url: str | None = None,
) -> None:
"""Retry sending the webhook for a run."""
run = await app.DATABASE.get_run(run_id, organization_id=organization_id)
@@ -157,6 +162,17 @@ async def retry_run_webhook(run_id: str, organization_id: str | None = None, api
detail=f"Run not found {run_id}",
)
if webhook_url:
if not organization_id:
raise OrganizationNotFound(organization_id="")
await webhook_service.replay_run_webhook(
organization_id=organization_id,
run_id=run_id,
target_url=webhook_url,
api_key=api_key,
)
return
if run.task_run_type in [RunType.task_v1, RunType.openai_cua, RunType.anthropic_cua, RunType.ui_tars]:
task = await app.DATABASE.get_task(run_id, organization_id=organization_id)
if not task:

View File

@@ -222,13 +222,22 @@ async def build_run_preview(organization_id: str, run_id: str) -> RunWebhookPrev
)
async def replay_run_webhook(organization_id: str, run_id: str, target_url: str | None) -> RunWebhookReplayResponse:
async def replay_run_webhook(
organization_id: str,
run_id: str,
target_url: str | None,
api_key: str | None = None,
) -> RunWebhookReplayResponse:
"""
Send the webhook payload for a run to either the stored URL or a caller-provided override.
If `api_key` is provided, it will be used to sign the webhook payload instead of looking up the organization's
API key from the database. This is useful for endpoints that authenticate with an API key and want the replay
signature to match the caller-provided key.
"""
payload = await _build_webhook_payload(organization_id=organization_id, run_id=run_id)
api_key = await _get_api_key(organization_id=organization_id)
signed_data = generate_skyvern_webhook_signature(payload=payload.payload, api_key=api_key)
signing_key = api_key if api_key else await _get_api_key(organization_id=organization_id)
signed_data = generate_skyvern_webhook_signature(payload=payload.payload, api_key=signing_key)
url_to_use: str | None = target_url if target_url else payload.default_webhook_url