Skip to content

Tutorial: Campaign Automation Extension

This tutorial walks through building a production-ready marketing automation extension. You will:

  1. Capture campaign approvals from Kiket.
  2. Push approved campaigns to an external automation API.
  3. Store API tokens securely via the secret store.
  4. Instrument handlers with telemetry and health checks.

Prerequisites: familiarity with manifests, access to a workspace token, and the Python SDK installed (uv add kiket-sdk).

Step 1 – Define the manifest

.kiket/extension.yaml
model_version: "1.0"
extension:
  id: dev.example.campaign-automation
  name: Campaign Automation
  version: 1.0.0
  delivery: http
  callback:
    url: https://automation.example.com/webhooks
    secret: env.KIKET_WEBHOOK_SECRET
  activationEvents:
    - campaign.approved
    - campaign.rejected
  configuration:
    automationBaseUrl:
      type: string
      label: Automation API URL
      default: https://automation.example.com/api
    AUTOMATION_API_KEY:
      type: string
      secret: true
      required: true
      label: Automation API Key
      description: API key for automation platform

Store KIKET_WEBHOOK_SECRET and AUTOMATION_API_KEY via kiket secrets set.

Step 2 – Bootstrap the handler

extension.py
from kiket_sdk import KiketSDK, TelemetryRecord
import httpx

async def feedback(record: TelemetryRecord) -> None:
    print(f"[telemetry] {record.event} {record.status} {record.duration_ms:.1f}ms")

sdk = KiketSDK(
    manifest_path=".kiket/extension.yaml",
    feedback_hook=feedback,
)

async def push_to_automation(campaign, context):
    api_key = await context.secrets.get("AUTOMATION_API_KEY")
    base_url = context.settings.get("automationBaseUrl")
    async with httpx.AsyncClient(base_url=base_url, headers={"Authorization": f"Bearer {api_key.value}"}) as client:
        await client.post("/campaigns", json=campaign)

@sdk.webhook("campaign.approved", version="v1")
async def handle_approved(payload, context):
    await push_to_automation(payload["campaign"], context)
    await context.endpoints.notify(
        title="Campaign approved",
        body=f"{payload['campaign']['name']} pushed to automation",
    )
    return {"ok": True}

@sdk.webhook("campaign.rejected", version="v1")
async def handle_rejected(payload, context):
    await context.endpoints.log_event(
        "campaign.rejected",
        reason=payload["reason"],
        campaign_id=payload["campaign"]["id"],
    )
    return {"ok": True}

if __name__ == "__main__":
    sdk.run(host="0.0.0.0", port=8080)

Step 3 – Test locally

Use the FastAPI test client or send signed webhooks via curl. Example payload:

python scripts/send_webhook.py \
  --event campaign.approved \
  --version v1 \
  --secret "$KIKET_WEBHOOK_SECRET" \
  --payload '{"campaign":{"id":42,"name":"Spring Launch"}}'

Check http://localhost:8080/health to verify registered events before deploying.

Step 4 – Deploy

  1. Create a Dockerfile or use the CLI scaffold (kiket extensions scaffold my-extension --sdk python).
  2. Deploy to your preferred runtime (Cloud Run, Kubernetes, Fly.io, etc.).
  3. Configure the webhook URL in the manifest (delivery.callback.url).
  4. Register the extension in Kiket (kiket extensions publish or via the UI).

Step 5 – Monitor & iterate

  • Use kiket marketplace status to view missing secrets, repository sync issues, and extension health.
  • Telemetry hooks feed your console/log analytics and can be forwarded to a hosted endpoint with KIKET_SDK_TELEMETRY_URL.
  • Add additional handlers by calling @sdk.webhook("campaign.rescheduled", version="v1") and redeploying.

You now have a fully working automation extension that reacts to campaign activity, integrates with external APIs, and exposes rich telemetry. Explore the Cookbook for more recipes or plug the SDK into CI via the CLI.