Script outcome variables vanishing in conversation:script:completed webhook payload

Building the Rails ingestion layer for script events and the conversation:script:completed payload keeps dropping the variable data. The middleware uses Faraday to fetch context if needed, but the webhook itself should carry the state. The setup handles conversation:analyzed without issues, so the pipeline’s solid. Script events are the outlier here.

The verification routine runs first. Signature checks out using OpenSSL::HMAC.new(secret, 'SHA256'). Timestamp drift’s under 300ms. No replay attacks, no tampering. Body’s just lacking the expected structure.

Inspecting the raw JSON in the Sidekiq worker reveals the gap. The scriptId and outcome are present. Variables key’s completely absent. Architect flow’s got Set Variable blocks wired up before the script ends. customer_risk_score’s assigned a value. UI shows the variable updated during the call. Webhook fires milliseconds later, but the payload looks like:

{
 "event": "conversation:script:completed",
 "conversationId": "a1b2c3d4-5678-90ab-cdef-123456789012",
 "scriptId": "script-xyz-123",
 "outcome": "completed"
}

Should’ve expected the variables array to populate alongside the outcome. Docs mention an includeVariables flag for data actions, but the webhook configuration UI doesn’t expose that toggle for script events. Might be a timing issue where the script engine commits variables after the event trigger. Tried adding a Delay block of 5 seconds at the end of the flow. Webhook still shows up empty. Sidekiq retries burn out without luck.

Middleware config:

  • Rails 7.1.3
  • Sidekiq 7.2.4
  • Genesys Cloud Org Version: 2024-10-15
  • Webhook Subscription: conversation:script:completed
  • Payload Format: application/json
  • Faraday 2.9.0 for fallback API calls

The conversation:script:started event includes the initial variables if any exist. Completion event feels incomplete. Is there a specific webhook property or Architect setting that forces variable serialization on completion?

def process_script_completion(payload)
 data = JSON.parse(payload)
 vars = data['variables'] || []
 Rails.logger.warn "Script #{data['scriptId']} completed with #{vars.count} variables"
 # vars.count is consistently 0 even when script sets values
 ActiveJob::Base.enqueue(ScriptOutcomeJob, data)
end

Logs scream the count hitting zero every time. The script definitely modifies state.

You’re chasing a ghost in the webhook payload. Script outcomes don’t ship in the default conversation:script:completed body unless you explicitly tell the platform to expand them. The middleware drops them because the event definition lacks the right expansions array. Stop parsing the raw payload and force the platform to attach the variable state.

  1. Grab the webhook definition ID from your org settings.
  2. Update the event configuration to include the outcomes expansion.
  3. Test with a fresh script run.
curl -X PATCH "https://api.mypurecloud.com/api/v2/webhook/definitions/{webhookDefinitionId}" \
 -H "Authorization: Bearer {access_token}" \
 -H "Content-Type: application/json" \
 -d '{
 "eventDefinitions": [
 {
 "events": ["conversation:script:completed"],
 "expansions": ["outcomes", "transcript"]
 }
 ]
 }'

You’ll need the webhook:edit scope on that bearer token. If the patch still leaves outcomes empty, your script probably doesn’t mark variables as outcome type in Architect. Regular flowVariables stay local. You’ll need to hit /api/v2/conversations/scripts/{conversationId} directly. The response dumps every custom variable into the outcomes array. Just map the name and value fields. Don’t trust the webhook body for complex state. It’s notoriously sparse.

PureCloudPlatformClientV2 actually enforces strict expansion rules when the webhook definition lacks the explicit outcomes directive. The suggestion above correctly identifies the missing expansion array as the root cause. You’ll need to update the event configuration to force the platform to attach the script variable state before the Rails middleware processes the body.

  • First, locate the webhook definition ID within the org settings to ensure you’re targeting the active routing strategy.
  • Second, apply the expansion patch using the API endpoint below. This forces the payload generation logic to include the outcome data.
{
 "expansions": ["outcomes"]
}

Don’t overlook the scope requirements on the service account. State drift happens fast. You’ll want to watch the logs.