Docs/Recipes/Sync email to CRM

Sync customer email to CRM.

The recipe that retires the "did you log that?" question. Every inbound customer email is parsed, tagged, and attached to the right CRM record. The assistant flags sentiment shifts and proposes the next action.

The goal

Inbound email lands in your inbox. Within sixty seconds:

  1. The email is matched to a CRM account by sender domain or signature line.
  2. An Activity is written on the account with the full body, attachments, and a one-line summary.
  3. If the sentiment shifted (positive → negative is the common one), a Slack ping goes to the AE.

The workflow

[workflow]
name = "email-to-crm"

[trigger]
event   = "email.received"
filter  = "!email.from.domain.endsWith('acme.com')"     # external only

[scope]
read  = ["crm:accounts", "crm:contacts"]
write = ["crm:activities.create", "slack.post_message"]

[[steps]]
name      = "classify"
assistant = "email-classifier"
input     = { message_id = "$trigger.message.id" }

[[steps]]
name = "log"
tool = "crm.activities.create"
input = {
  account_id = "$steps.classify.account_id",
  type       = "email_in",
  summary    = "$steps.classify.summary",
  message_id = "$trigger.message.id",
  sentiment  = "$steps.classify.sentiment",
}

[[steps]]
name = "alert"
tool = "slack.post_message"
when = "$steps.classify.sentiment_delta == 'negative'"
input = {
  channel = "@$steps.classify.account_owner",
  text    = "⚠ Sentiment shift on $steps.classify.account_name. Latest: $steps.classify.summary",
}

Account matching

Three strategies, tried in order:

  1. Domain match. The sender's email domain matches an existing Account's primary_domain.
  2. Contact match. The sender is a known Contact with an Account.
  3. Signature parse. The assistant reads the signature line and matches a company name.

If none match, the email lands in the "Unmatched" queue with a one-click "Match to account" affordance.

Sentiment tracking

Sentiment is a per-message label (positive, neutral, negative, urgent). The delta is what matters. A long-tail positive thread suddenly going negative is the signal you want. The classifier computes the delta as part of step 1.

Privacy

The full body is stored under the same retention policy as any wrxstack document. If you've configured a retention rule (e.g. delete after 18 months), it applies here. If your customers are GDPR data subjects, the standard subject access flow covers these activities.