Package overview
Overview
Activity Sync saves Five9 activity as Salesforce Tasks.
- The first event for a call creates a Task.
- Later events for the same call update that Task.
- Five9 can send the event and move on. QuickFlo finishes the Salesforce work in the background.
Keep the main activity-sync workflow set to Async and its sub-workflows set to Auto. All built-in sub-workflow calls, including the failure handler, run inline inside the parent's worker.
Set up
- Install Activity Sync.
- Connect Salesforce and name the connection
salesforce. - Review the
salesforcerecord in theactivity_sync_settingsdata store. Use a Salesforce Task text field marked Unique forsession_id_fieldif events for the same call can arrive at the same time. - Send a test event to the installed
activity-syncwebhook. - Check the Activity Sync dashboard for the result.
Settings
The package installs this record:
- Data store:
activity_sync_settings - Record key:
salesforce
{
"saveTaskWithoutInvalidWhoIdOrWhatId": true
}
The setting has two choices:
| Value | What Activity Sync does |
|---|---|
true |
If Salesforce rejects WhoId or WhatId because the related record is invalid or deleted, remove the rejected relationship and save the Task anyway. |
false |
Do not remove either relationship. The Salesforce create or update fails, and Activity Sync records the error. |
true is installed by default. This is usually the best choice because the call activity is still saved even when its contact, lead, account, opportunity, or other related record is no longer available.
This setting only applies after Salesforce rejects a valid WhoId or WhatId field with ENTITY_IS_DELETED or INVALID_CROSS_REFERENCE_KEY. It does not remove unrelated fields.
If Salesforce cannot identify which relationship is bad and both fields are present, Activity Sync first tries again without WhatId. If Salesforce still rejects the relationship, it tries once more without both WhoId and WhatId.
Send an activity
{
"session_id": "abcd-efgh-aaaa-bbbb-cccc",
"session_id_field": "Five9__Five9SessionId__c",
"field": {
"Description": "Call notes",
"RecordingLink__c": "https://example.com/recording",
"WhoId": "003000000000001AAA",
"WhatId": "001000000000001AAA"
}
}
| Field | Required | What it does |
|---|---|---|
session_id |
yes | Identifies the call. The same value updates the same Salesforce Task. |
session_id_field |
no | Salesforce Task field that stores the ID. Defaults to Five9__Five9SessionId__c. |
field |
yes | Salesforce Task fields to save. |
field.Subject |
no | Sets the Task subject. If omitted, Activity Sync creates one and keeps it on later updates. |
Send a non-empty session_id without curly braces ({ or }). The session field must exist in the cached Task field list. Activity Sync rejects an invalid session field before querying or writing Salesforce. A value in field cannot override the session ID used to match the Task.
Check the result
Five9 does not wait for the completed Salesforce response. The webhook acknowledgement means QuickFlo accepted the event and queued it.
Use the Activity Sync dashboard to see the final result:
success: Salesforce saved the Task on the first attempt.recovered: Salesforce rejected the first attempt, but Activity Sync fixed the problem and saved the Task.error: Salesforce did not save the requested change.
For more detail, open the workflow execution or the matching record in activity_sync_history.
The history table shows Time → Status → Action → Explanation → Session ID → Fields → Salesforce ID → Salesforce Task, with the newest activity first. Session ID identifies the activity; Fields shows the final Task fields sent, and Salesforce ID is shown when available. The explanation tells you whether the Task was saved, saved after recovery, or failed. A recovered result can include an omitted invalid WhoId (Name) or WhatId (Related To) value; it is not the same as a first-attempt success.
Raw error, recovery, and Salesforce response objects stay in drill-down. Click a status slice in the counts chart to drill into the full records, or open activity_sync_history for the session ID, fields sent, execution ID, and raw error, recovery, and Salesforce response details. Nothing is removed from the history record.
The explanation is calculated from the existing history when the dashboard is queried. It does not run another workflow or call Salesforce.
Handle failed activities
When a Salesforce write still fails after Activity Sync finishes its built-in recovery, Activity Sync first records the final result in activity_sync_history. It then starts the optional Handle Failed Activity workflow inline, as part of the same run. This does not add a separately metered workflow execution.
The installed handler only writes a warning to the QuickFlo logs. Customize or replace it when you want to take an action. For example, add a Switch step that checks {{ initial.errorCode }}, then send selected failures to Slack, email, a ticketing system, or a review data store.
The handler receives the session ID, attempted create or update action, Task fields, error code and message, HTTP status, recovery details, Salesforce record details when available, and a unique failure ID.
Use those inputs directly; you do not need to fetch the history record again. When history uses analytics-backed storage, new records can take a few seconds to appear in reads and dashboards even though the write has completed.
The handler runs only when the final status is error. It does not run for success or recovered. The call uses Continue on error, so a handler error does not replace the recorded Salesforce result.
Keep inline actions short: the parent waits for them, and they share its worker and overall timeout. For long-running or independent work, add a sub-workflow call inside your handler and enable Run in background on that call. That dispatched work is a separate, metered execution. The parent itself remains async, so Five9 does not wait for either approach.
Use {{ initial.failureId }} as the unique key for your ticket or review record. Replaying the handler can repeat an action, so check that key before sending another notification or creating another ticket. A new Activity Sync execution has a new failure ID, even for the same session.
The handler also receives INVALID_ACTIVITY_INPUT when the writer rejects an empty session ID or invalid session field; its action is validate. For Salesforce write failures, action is create or update.
This handler does not catch failures that stop the workflow before the writer returns a result, such as a failed schema refresh, enrichment, connection, or Salesforce lookup. Check failed Activity Sync executions for those problems. If saving history or calling the handler fails, check the parent execution and its inline child trace. After fixing the problem, replay only the handler with the same failure payload when appropriate. Routing is best effort, not a guaranteed review queue.
How fields are handled
Activity Sync automatically removes field names that do not exist on the Salesforce Task object.
The valid Task field names are stored here:
- Data store:
activity_sync_schema_cache - Record key:
salesforce-task-fields
The first activity refreshes this record if it does not exist. A daily schedule refreshes it again at 03:17 UTC. Normal activity runs read the cached list and do not request the full Task schema from Salesforce.
With a warm cache, a normal activity uses two Salesforce API calls: one lookup to decide whether to create or update, followed by the create or update.
WhoId and WhatId are different: the field names are valid, but the IDs inside them can point to deleted or invalid records. The saveTaskWithoutInvalidWhoIdOrWhatId setting controls what happens in that case.
How retries work
- Salesforce reads and the first write retry up to three times when a request fails temporarily.
- Retries start one second apart and wait longer after each failure.
- If a create may have reached Salesforce but its response was lost, Activity Sync checks for the Task before trying another create. This reduces duplicate creates; it does not make simultaneous requests atomic.
- Activity Sync makes only a small, fixed number of recovery attempts. It does not retry forever.
To prevent duplicate Tasks when two events for the same call arrive together, the Salesforce field named by session_id_field must be marked Unique. An External ID field alone does not guarantee uniqueness. Without a Unique field, both requests can find no existing Task and create one. With a Unique field, Salesforce rejects the second create; that request is recorded as an error and can be retried after the first create finishes.
Activity history
activity_sync_history keeps the latest result for each session_id. A new event for the same call replaces that history record.
The record includes the action, final status, Salesforce Task ID and URL, fields sent, execution ID, Salesforce response, error details, and recovery details.
Customize fields
Use the optional Enrich Task Fields sub-workflow to add or override Salesforce Task fields. Activity Sync checks the combined fields against the cached Task field list before saving them.
Salesforce is currently the supported CRM. For help, contact support@quickflo.app.