Skip to main content

Salesforce integration

Create, query, and react to record changes across your clients' Salesforce orgs from any TaskJuice workflow.

What it does

The Salesforce integration lets your agency move data in and out of every client's Salesforce org from a single workflow. Connect a client's org once and TaskJuice can create, read, update, and delete records on any standard or custom object, run SOQL queries, manage Leads, Contacts, Opportunities, Cases, and Tasks, kick off Flows, work with Bulk API 2.0 query jobs, run reports, and trigger a workflow whenever a record changes.

Connect a Salesforce account

  1. Open your workspace in TaskJuice and navigate to Connections.
  2. Choose Salesforce and click Connect.
  3. Sign in with the Salesforce user whose org you want to manage on behalf of your client. Production orgs authenticate against login.salesforce.com; sandbox orgs authenticate against test.salesforce.com and need a separate connection.
  4. Approve the requested scopes (api for REST access and refresh_token so TaskJuice can refresh access tokens without re-prompting).
  5. TaskJuice returns you to the workspace with the connection ready to use in any workflow.

To revoke access at any time, the connected user can visit Setup, open the Connected Apps OAuth Usage page in their Salesforce org, and revoke the TaskJuice entry.

Triggers

  • salesforce/record-changed polls a configurable Salesforce object on an interval and emits one cycle per poll containing every record whose LastModifiedDate advanced past the prior watermark. Configure the object name (e.g. Opportunity, Lead, Contact, Account), the SELECT field list, and an optional extra WHERE predicate. Drop a Loop node downstream to fan out one branch per record.

Salesforce also publishes the Streaming API, Platform Events, and Change Data Capture for real-time delivery. Those channels require per-org provisioning and a Platform Events license, so TaskJuice ships polling as the default declarative path. Reach out if your client's org needs the streaming path and we will provision the dedicated workflow.

Actions

  • salesforce/create-record inserts a new record on any standard or custom object you specify.
  • salesforce/get-record reads a single record by ID, with an optional projection of the fields to return.
  • salesforce/update-record patches one or more fields on an existing record.
  • salesforce/delete-record removes a record from the org.
  • salesforce/upsert-record inserts or updates a record keyed by an external ID field.
  • salesforce/bulk-create inserts many records in one step. You hand it an array of records; TaskJuice writes them in batches and returns a per-record result.
  • salesforce/bulk-update updates many records in one step. Each record carries its own Id; the result reports success or failure per record.
  • salesforce/composite-upsert inserts or updates many records keyed on an external ID field, so re-running the same step converges on the external ID instead of creating duplicates.
  • salesforce/execute-soql runs a SOQL query and returns the first batch of records.
  • salesforce/find-record runs a SOQL query and returns one record (use LIMIT 1 in the query).
  • salesforce/find-records runs a SOQL query and returns the matching records (use LIMIT to bound the batch).
  • salesforce/create-lead, salesforce/update-lead write Lead records without needing to name the object on every call.
  • salesforce/create-contact, salesforce/update-contact write Contact records the same way.
  • salesforce/create-opportunity, salesforce/create-case, salesforce/create-task write the matching object kinds.
  • salesforce/add-note-to-record, salesforce/get-record-attachments work with the file and note surfaces.
  • salesforce/add-lead-to-campaign, salesforce/add-contact-to-campaign write CampaignMember rows.
  • salesforce/list-flows, salesforce/invoke-flow discover and run autolaunched Flows.
  • salesforce/create-query-job, salesforce/get-query-job, salesforce/get-query-job-results, salesforce/abort-query-job, salesforce/list-query-jobs drive the Bulk API 2.0 query surface for large result sets.
  • salesforce/run-report executes a Salesforce report by ID.
  • salesforce/get-user, salesforce/list-users look up org members.
  • salesforce/api-call runs an arbitrary authenticated request against the org's REST surface for endpoints not covered by a typed action.

Recompute rollups and write them back in batches

Salesforce caps each object at 25 native roll-up summary fields, and those only roll up master-detail children with a fixed set of functions. When you need more rollups than that, or a sum across a lookup relationship, or any custom rollup logic, you compute it yourself and write the result back to the parent record. The bulk actions make that a single step instead of one API call per record.

The pattern is a scheduled recompute-from-source:

  1. A Schedule trigger runs the workflow on a cadence (nightly, hourly).
  2. A Bulk query job (create-query-job, then poll get-query-job, then get-query-job-results) reads the child records. The query job handles large result sets that a single SOQL call cannot.
  3. An Aggregate node groups the child rows by their parent ID and computes each rollup (sum of amounts, count of records, latest date).
  4. A composite-upsert step writes one record per parent back to Salesforce, keyed on the parent's external ID.

Because the write is an upsert keyed on the parent ID and every run recomputes from the source children, the workflow is idempotent: re-running it converges on the correct value instead of double-counting.

What the bulk write returns

You hand bulk-create, bulk-update, or composite-upsert an array of records. TaskJuice writes them in batches of 200 (Salesforce's per-call limit for this surface) and folds every batch into one result:

{
  "successes": [{ "index": 0, "id": "001...", "success": true }],
  "errors": [
    {
      "index": 14,
      "success": false,
      "error": { "code": "FIELD_CUSTOM_VALIDATION_EXCEPTION", "message": "Amount must be positive" }
    }
  ],
  "summary": { "total": 350, "succeeded": 349, "failed": 1 }
}

The index on each entry is the position of that record in the array you sent, so you can branch on summary.failed and retry or report exactly the records that did not write. The allOrNone toggle on each action controls partial success: leave it off and the records that pass are committed while failures are reported individually; turn it on and the whole batch rolls back if any single record fails.

Quota visibility and the floor guard

Every Salesforce response carries the org's remaining daily API budget. TaskJuice captures it onto each bulk step's run detail, so you can see exactly how much quota a run consumed. The bulk actions also stop themselves before they exhaust the org: when the remaining quota drops below a floor, the step fails with a clear QUOTA_FLOOR_BREACH rather than running the org dry mid-write.

Beyond 10,000 writes per run

The bulk actions are sized for write-backs in the hundreds-to-low-thousands per run, which covers the parent-record count of almost every rollup. If a single run needs to write more than about 10,000 records, window the workflow into smaller runs (for example, by region or by date range). A dedicated high-volume ingest path is available on request for genuinely larger loads.

Known limitations

  • Each Salesforce edition enforces per-org API call quotas. When the org returns a 429, TaskJuice surfaces it as a retryable rate-limit error and waits exactly as long as the org's Retry-After response asks before retrying, clamped to a sensible ceiling so a single throttled call can never stall a run indefinitely.
  • Production and sandbox orgs are separate environments and require separate connections. Pick the correct login host when connecting (login.salesforce.com vs test.salesforce.com).
  • The polling trigger watermarks on LastModifiedDate, which has one-second resolution. Records modified within the same second as the prior watermark may be emitted twice; the connected workflow should dedupe on Id if exactly-once semantics matter.
  • Real-time delivery via Platform Events, Change Data Capture, or the Streaming API is out of scope for the declarative connector. Those channels need per-org channel provisioning and are tracked separately.
Was this helpful?