salesbeginner8 min setupby Mantle

New Salesforce lead to Slack

Poll Salesforce for new leads and post each one into the sales channel as it arrives.

New leadPost to #sales

Drag to pan, pinch to zoom. This is the real graph the template installs.

Purpose

Poll Salesforce for new leads and post each one into the sales channel as it arrives.

How it works

What it does

  • Polls Salesforce every two minutes for Lead records created since the last check.
  • Posts the lead's name, company, source and e-mail to a Slack channel.

Validation

This template is contract-validated: the unit suite checks every node type, every config key and the whole graph against the same rules a saved workflow passes. It has not been run against the live provider — the ids, names and columns below are placeholders to replace with your own.

Nodes 2

  1. 01New leadtrigger.salesforce_eventTrigger
  2. 02Post to #salesslack.post_messageApp
View template JSON
{
  "format": "mantle-workflow/v1",
  "id": "salesforce-new-lead-to-slack",
  "name": "New Salesforce lead to Slack",
  "graph": {
    "nodes": [
      {
        "id": "lead",
        "type": "trigger.salesforce_event",
        "label": "New lead",
        "config": {
          "object_name": "Lead",
          "mode": "created",
          "fields": "Id, Name, Company, Email, LeadSource, Status",
          "poll_interval_sec": 120
        },
        "worker_type": "generic-worker",
        "position": {
          "x": 60,
          "y": 220
        }
      },
      {
        "id": "post",
        "type": "slack.post_message",
        "label": "Post to #sales",
        "config": {
          "channel": "#sales",
          "text": "*New lead* {{ $json.record.Name }} — {{ $json.record.Company }}\nSource: {{ $json.record.LeadSource }} · {{ $json.record.Email }}\nRecord {{ $json.record_id }}"
        },
        "worker_type": "generic-worker",
        "position": {
          "x": 380,
          "y": 220
        }
      }
    ],
    "edges": [
      {
        "from": "lead",
        "to": "post"
      }
    ]
  }
}

Requirements

The connections and permissions each step needs, from the node contracts in the catalog.

  • SalesforceOAuth 2.0

    Used by New lead.

    Credential: {"client_id", "client_secret", "refresh_token"}

    • This polls SOQL — it is not the Streaming or Pub/Sub API. Salesforce's push mechanisms need a process holding a long-lived subscription, which Mantle has no role for, so latency is up to one poll interval (30 s minimum).
    • The poll reads current state, not a change log: a field changed and changed back within one interval is seen once, at its final value.
    • SystemModstamp also moves for system writes (roll-up recalculations, archive jobs), so `updated` can fire without a person having edited the record.
    • Existing records are never replayed: the first poll only sets the cursor to the org's newest SystemModstamp.
    • Bulk updates share one millisecond; the cursor keeps the ids at its instant so none of them is dropped. Runs are idempotent per record id + modstamp, so a re-poll of the same change cannot start a second run.
    • `created` is CreatedDate == LastModifiedDate. A record created and edited between two polls arrives once, as an update.
  • SlackAPI key

    Used by Post to #sales.

    Credential: the bot token (xoxb-…), or {"token": "xoxb-…"}

    • The bot must be a member of a private channel before it can post there (Slack error not_in_channel otherwise).

Setup

  • fields is the SOQL field list the poll selects — every field the Slack message reads must be in it.
  • Use where_clause (for example LeadSource = 'Web') to narrow what triggers a run.
  • Pick Salesforce and Slack connections and set the channel.

Sample input and output

Synthetic examples: node-contract samples or placeholders, never customer data.

Input

What the New lead trigger receives, as its node contract samples it.

{
  "created": false,
  "object_name": "Lead",
  "record": {},
  "record_id": "00Q5f000004abcEAA",
  "system_modstamp": ""
}

Output

Post to #sales slack.post_message

{
  "channel": "",
  "ok": true,
  "ts": ""
}

Failure handling

What the graph does when a step fails, read from its retry settings, error branches and error policies.

  • A step that fails, after any retries, fails the run. The failed step is kept with its input and error.

See it run, then make it yours.

Templates install as drafts. Edit any step, and Workflow Health re-checks the graph on every save.