تخطَّ إلى المحتوى

Events Extensions Overview

Events extensions let a digital worker react to signals that do not start in a chat thread. They receive external events, normalize them into Greentic event envelopes, and route them into flows where components can make decisions, call systems, and send responses.

  • Webhooks from external services such as GitHub, Stripe, Shopify, and internal systems
  • Scheduled timer ticks declared by installed event extension packs
  • Transactional email delivery through SendGrid
  • SMS delivery and inbound SMS webhooks through Twilio
  • Generic email and SMS extension packs for deployments that provide their own implementation

The Greentic catalog also contains events-email and events-sms generic extension pack entries. The pages above document the concrete SendGrid and Twilio packs because they are the providers used by the event demos.

External Service / Timer Scheduler
▼ HTTP ingress / scheduled tick
┌─────────────────────────────────────────┐
│ Events Extension Pack │
│ webhook, timer, email, sms, custom pack │
└─────────────────────────────────────────┘
▼ EventEnvelopeV1
┌─────────────────────────────────────────┐
│ Event Router │
│ tenant/team scoped routing to flows │
└─────────────────────────────────────────┘
┌─────────────────────────────────────────┐
│ Flow Executor │
│ (Process with event flows) │
└─────────────────────────────────────────┘

The standard HTTP ingress shape is:

POST /v1/events/ingress/{provider}/{tenant}/{team?}/{handler?}

Specific packs can also declare friendlier routes for demos or app-specific deployments. Use the URL produced by gtc setup for the installed pack.

Events routed into flows use the runtime event envelope:

pub struct EventEnvelopeV1 {
pub event_id: String,
pub event_type: String,
pub occurred_at: String,
pub source: EventSourceV1,
pub scope: EventScopeV1,
pub correlation_id: Option<String>,
pub payload: serde_json::Value,
pub http: Option<serde_json::Value>,
pub raw: Option<String>,
}
pub struct EventScopeV1 {
pub tenant: String,
pub team: Option<String>,
}

payload holds the parsed provider payload. http and raw are present when the event came from HTTP ingress and the extension preserves request details for validation or downstream handling.

Add event extensions with gtc wizard. Coding agents can inspect the available schema first and then replay answers:

Terminal window
gtc wizard --schema
gtc wizard --answers event-worker-answers.json

The catalog entries for the current event packs are OCI references:

oci://ghcr.io/greenticai/packs/events/events-webhook:latest
oci://ghcr.io/greenticai/packs/events/events-timer:latest
oci://ghcr.io/greenticai/packs/events/events-email:latest
oci://ghcr.io/greenticai/packs/events/events-email-sendgrid:latest
oci://ghcr.io/greenticai/packs/events/events-sms:latest
oci://ghcr.io/greenticai/packs/events/events-sms-twilio:latest

gtc setup configures the installed extensions:

setup-answers.json
{
"events-webhook": {
"enabled": true,
"public_base_url": "https://your-domain.ngrok-free.app"
},
"events-timer": {
"enabled": true,
"timezone": "UTC"
},
"events-email-sendgrid": {
"sendgrid_api_key": "SG.xxx",
"from_email": "noreply@example.com",
"from_name": "Greentic"
},
"events-sms-twilio": {
"account_sid": "ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"auth_token": "your-auth-token",
"from_number": "+10000000000"
}
}
flows/on_event.ygtc
name: handle_event
version: "1.0"
nodes:
- id: process
type: script
config:
script: |
// Process the event
let payload = event.payload;
process_payload(payload)
to: respond
triggers:
- type: event
event_type: "order.created"
target: process

Runtime transport details are deployment-specific. Do not treat internal bus subjects or queue names as a public API unless your deployment explicitly documents them.

nodes:
- id: on_order
type: branch
config:
conditions:
- expression: "event.event_type == 'order.created'"
to: send_confirmation
- expression: "event.event_type == 'order.shipped'"
to: send_tracking
nodes:
- id: daily_report
type: http
config:
method: GET
url: "https://api.example.com/reports/daily"
to: send_email
triggers:
- type: timer
handler: "daily_report"
target: daily_report