evo-crm

n8n community nodes for EVO CRM: leads, contacts, opportunities, activities, tasks, appointments, email/SMS/WhatsApp sending, templates, sequences and a webhook trigger for every CRM event.

Documentation

@cypherlenn/n8n-nodes-evo-crm

n8n community nodes for EVO CRM – a German sales CRM (setter → appointment → closer → back office)
with leads, contacts, opportunities, activities, tasks, appointments, email/SMS/WhatsApp sending,
templates, sequences and an event log with signed webhooks.

The package contains:

  • EVO CRM – an action node (also usable as an AI agent tool) for the EVO CRM REST API v1.
  • EVO CRM Trigger – starts a workflow for any event of the CRM (signed webhooks, created and
    removed automatically).
  • EVO CRM API credentials (API key).

Not to be confused with n8n-nodes-evocrm. That is an unrelated package for "Evolution API /
EvoCRM". This package (@cypherlenn/n8n-nodes-evo-crm) is for EVO CRM.

n8n is a fair-code licensed
workflow automation platform.

Installation

n8n (self-hosted or cloud with community nodes enabled): Settings → Community Nodes → Install,
enter @cypherlenn/n8n-nodes-evo-crm, confirm the risk notice and install. See the
n8n community nodes guide.

Manual installation (self-hosted):

mkdir -p ~/.n8n/nodes && cd ~/.n8n/nodes
npm install @cypherlenn/n8n-nodes-evo-crm
# restart n8n

With Docker, run the same inside the container (/home/node/.n8n/nodes) or mount that folder, then
restart the container. A local tarball (npm pack) can be installed the same way:
npm install /path/to/cypherlenn-n8n-nodes-evo-crm-0.6.0.tgz.

Credentials

  1. In EVO CRM open Einstellungen → KI & API → API-Schlüssel and create a key. It is shown exactly
    once and looks like evo_live_…. Creating keys needs the permission "API-Schlüssel nutzen"
    (api.use; team leads, managing directors, owners/admins by default).
  2. In n8n create credentials EVO CRM API:
    • Base URL – the address of your CRM without /api/v1, e.g. https://crm.example.com.
    • API Key – the evo_live_… key.
  3. Test calls GET /api/v1/me.

The key acts with the permissions and data scope of its owner – a team lead only sees their team,
a managing director everything. Sensitive fields (IBAN, account holder, date of birth) are never
available through the API. Two-factor authentication does not apply to API keys, so treat keys like
passwords and use one key per integration.

Operations

Resource Operations
Lead Create (with contacts and custom fields), Get (with contacts, opportunities, open tasks, tags), Get Many (search, status, owner incl. "me", saved view, created after/before, order), Update, Delete, Merge
Contact Create (name, title, up to 3 emails/phones, lead, company, custom fields), Get, Get Many (lead, search, saved view), Update (emails/phones replace all), Delete
Opportunity Create, Get, Get Many (lead, status active/won/lost, pipeline, stage, owner, search, saved view, created after/before), Update (stage change, value in cents, owner, confidence, expected close date, custom fields), Delete
Company Create, Get, Get Many (search), Update
Activity Create Note, Log Call (call result/disposition, duration, callback, set status/stage), Log Email, Log SMS, Log Meeting (these only log, they do not send), Create Custom Activity, Get Many (timeline of a lead/contact/opportunity, type filter, search), Delete
Task Create, Get Many (of a lead or your own: open/today/future/all), Update, Complete, Delete
Appointment Create (fixed closer or automatic distribution), Get, Get Many (lead or period, view, closer, setter, status), Update/Reschedule, Cancel, Set Outcome (held with protocol, or no-show)
Email Send (text or template, to/cc, mailbox, attachments of the lead, reply in thread), Get Many Accounts
SMS Send (text or template), Get Recipients
WhatsApp Send Text (24-hour window), Send Template (approved template + parameters, optional media header), Send File (24-hour window), Get Recipients (opt-in, window_open, window_expires_at)
Email Template / SMS Template Create, Get, Get Many, Update, Delete, Render (placeholders filled for a record)
WhatsApp Template Create (text header only, buttons), Get, Get Many (approved / all), Update, Delete, Sync with Meta
Tag Get Many (per record type), Add to Record (existing tag or by name), Remove From Record
Sequence Get Many, Subscribe (enroll lead/contact), Pause, Resume, Stop
Event Get, Get Many (object types, actions, lead, object, user, source, request ID, period, "newer than event" for polling)
Custom Field Get Many (definitions per record type)
User Get Me, Get Many
Pipeline, Stage, Lead Status, Disposition Get Many (read only)

Dropdowns are loaded live from the CRM: lead statuses, pipelines and stages, users (incl. "Me"), call
results, email/SMS/WhatsApp templates and template parameters, mailboxes, sequences, tags, saved views
and custom field keys. Every dropdown also accepts an ID via expression.

All "Get Many" operations support Return All (follows next_cursor while has_more) or a
Limit. Every item of a list becomes its own n8n item.

Trigger

EVO CRM Trigger registers a webhook subscription in the CRM when the workflow is activated
(POST /api/v1/webhook, name n8n: <workflow name>) and removes it on deactivation.

  • Events: multi-select loaded from GET /api/v1/event_type. Values are object_type:action
    (e.g. lead:created, opportunity:won, activity.call:created), object_type:* for every action of
    a type, activity.*:* for every timeline entry and * for all events.
  • Output: one item per delivery – the event as in GET /event/{id} (id, object_type,
    action, object_id, lead_id, user_id, source, changed_fields, data, previous_data,
    date_created …) plus webhook: { subscription_id, event_id, delivery_id }.
  • Signature: every delivery carries EVO-Signature: t=<unix>,v1=<hex> (HMAC-SHA256 over
    "<t>.<raw body>" with the whsec_… key). The trigger verifies it with a 5-minute tolerance and
    answers forged/old requests with 401 (Options → Verify Signature, on by default). The key is
    stored in the workflow's static data; if it got lost, deactivate and activate the workflow.
  • Ignore Test Events: skip deliveries of "Test senden" in the CRM (webhook:test).

Requirements and limits:

  • The API key owner needs "API und Webhooks verwalten" (api.manage).
  • The webhook URL must be public https (no localhost, no private networks). Run n8n behind a public
    https address (WEBHOOK_URL) or a tunnel.
  • n8n's test URL and production URL each create their own subscription (the test one is named
    … (test) and removed when listening stops).
  • The CRM allows at most 20 subscriptions per organisation and 50 object types per subscription.
  • Deliveries are retried up to 21 times over about three days; after 20 failures in a row the CRM pauses
    the subscription. Re-activating the workflow resumes it.
  • Order is not guaranteed; deduplicate with webhook.event_id and sort by date_created.

View trigger

EVO CRM View Trigger checks a saved view ("Ansicht") regularly and starts the workflow for every lead,
contact or opportunity that entered (or left) the view, e.g. "leads with status interested and no
appointment". Choose the record type and the view from the list; Trigger On: entered, left or both.

  • The first poll after activation only remembers the records currently in the view; afterwards every change
    is reported once, with the full record in data (option Include Details).
  • A record that leaves the view and comes back later triggers again. With the option Only Once per Record
    each record triggers at most once (per entered/left); the trigger then remembers up to 20,000 reported
    records per event.
  • Poll Times: every minute is the shortest preset; a custom cron such as */30 * * * * * checks every
    30 seconds.
  • Records also enter a view without being changed (time-based filters like "last contact more than 7 days
    ago"); the polling catches these too. Views with more than 20,000 records are rejected.
  • The test run in the editor ("Fetch Test Event") returns the newest records of the view.

Output per record: event (entered/left), object_type, object_id, saved_view_id,
saved_view_name, date, data.

Usage notes

  • IDs are prefixed (lead_…, con_…, opp_…, act_…, tsk_…, apt_…, tmpl_…, wat_…);
    people are UUIDs, me means the key owner.
  • Records (lead, contact, opportunity, company, appointment, task, templates) are picked From List
    (searchable, live from the CRM) or By ID; expressions work in both. In the CRM every list with IDs
    needed here has Copy ID in its three-dot menu.
  • Opportunity value is in cents (150000 = 1,500.00 €).
  • Dates: date/time fields without time zone are read in the workflow time zone and sent as UTC.
  • Custom fields (also the fields of a custom activity): choose the field; for choice fields the value
    is a list of the options (Option / Options), otherwise text. As text: options by name, dates as
    YYYY-MM-DD, booleans as true/false, people as me, user ID or email. Empty value = clear the
    field. Several multi-select options as text: comma-separated or JSON array (["Strom","Gas"]).
  • Idempotency-Key (Request Options of every write operation): with the same key the CRM answers a
    repeated request within 24 hours with the stored result instead of creating or sending again – ideal
    for Retry On Fail. Use a value unique per item and run, e.g.
    {{ $execution.id }}-{{ $runIndex }}-{{ $itemIndex }}.
  • Errors show the German message of the CRM, the code (validation_error, not_found,
    precondition_failed …), field errors and the request ID. 429/503 with a short Retry-After are
    retried automatically. With Continue On Fail the error becomes an item (error, description,
    httpCode).
  • Sending vs. logging: Email → Send, SMS → Send and WhatsApp → Send … really send (blocklist,
    limits, consent and the WhatsApp 24-hour window apply). Activity → Log Email/SMS only adds a
    timeline entry.

Example workflows

WhatsApp: text if the window is open, otherwise a template

  1. EVO CRM Trigger – event appointment:created.

  2. EVO CRM – WhatsApp → Get Recipients, Lead ID {{ $json.lead_id }}.

  3. IF – {{ $json.window_open }} is true.

    • true → EVO CRM – WhatsApp → Send Text, Lead ID from the trigger, To {{ $json.e164 }}.
    • false → EVO CRM – WhatsApp → Send Template, template termin_bestaetigung, To
      {{ $json.e164 }}, parameter body.1 = {{ $json.contact_name }}.

    Tip: Get Recipients returns one item per number; keep only the first one (e.g. Limit node) or filter
    on is_primary before the IF.

New lead → task for the owner

  1. EVO CRM Trigger – event lead:created.
  2. EVO CRM – Task → Create, Title Erstkontakt: {{ $json.data.display_name }}, Additional Fields:
    Lead ID {{ $json.object_id }}, Assigned To (expression) {{ $json.data.owner_id || 'me' }},
    Due Date {{ $now.plus(1, 'hour') }}.

Won deal → hand-over email from a template

  1. EVO CRM Trigger – event opportunity:won.
  2. EVO CRM – Email → Send, To backoffice@example.com, Content Template, Additional Fields:
    Opportunity ID {{ $json.object_id }}, Lead ID {{ $json.lead_id }}, Request Options:
    Idempotency Key won-{{ $json.object_id }}.

Website form → lead with contact

Webhook/Form → EVO CRM – Lead → Create with Contacts (name, email, phone) and custom fields
(e.g. evo_jahresverbrauch_kwh).

Compatibility

  • n8n 1.x and later (community node API version 1, strict mode). Built and type-checked against
    n8n-workflow 2.16.
  • No runtime dependencies (n8n-workflow is a peer dependency).
  • Requires an EVO CRM with REST API v1. The send and template endpoints (email/SMS/WhatsApp, templates,
    /event_type) need a current CRM version; with an older CRM the trigger falls back to a built-in
    event list.

Development

npm install
npm run build      # n8n-node build → dist/
npm run lint       # n8n-node lint (community node rules)
npm test           # vitest (signature, events, pagination, mapping, execute, trigger)
npm run typecheck  # tsc incl. tests
npm run dev        # n8n with the node linked, http://localhost:5678
npm pack           # cypherlenn-n8n-nodes-evo-crm-<version>.tgz

Publishing to npm

Published by hand from this folder (no GitHub release workflow; prepublishOnly builds and tests first):

npm login
npm version patch   # only for later releases: 0.1.0 → 0.1.1 (also update CHANGELOG.md)
npm publish         # account with a passkey: no --otp, npm opens the browser confirmation

Self-hosted n8n installs unverified community packages without npm provenance. Listing as a verified
node on n8n Cloud would additionally need an author email, a homepage and publishing via GitHub
Actions with provenance (npm run lint reports the missing package fields).


Deutsch

@cypherlenn/n8n-nodes-evo-crm verbindet n8n mit dem EVO CRM (REST API v1). Nicht verwechseln mit dem
fremden Paket n8n-nodes-evocrm (Evolution API).

Installation: In n8n Settings → Community Nodes → Install und @cypherlenn/n8n-nodes-evo-crm eingeben.
Selbst gehostet alternativ npm install @cypherlenn/n8n-nodes-evo-crm in ~/.n8n/nodes und n8n neu starten.

Zugang: Im CRM unter Einstellungen → KI & API → API-Schlüssel einen Schlüssel (evo_live_…)
anlegen und in n8n als Credential „EVO CRM API" mit der CRM-Adresse (ohne /api/v1) hinterlegen. Der
Schlüssel arbeitet mit den Rechten und dem Datenumfang seiner Inhaberin; sensible Felder (IBAN …) gibt
es über die API nie.

Knoten „EVO CRM": Leads, Kontakte, Opportunities, Unternehmen, Aktivitäten (Notiz, Anruf mit
Gesprächsergebnis, E-Mail-/SMS-/Meeting-Eintrag, eigene Aktivität), Aufgaben, Termine, Versand von
E-Mail/SMS/WhatsApp, Vorlagen (E-Mail, SMS, WhatsApp), Tags, Sequenzen, Ereignisse, eigene Felder und
Konfiguration (Pipelines, Phasen, Lead-Status, Gesprächsergebnisse, Personen). Auswahllisten kommen live
aus dem CRM; Datensätze (Lead, Kontakt, Opportunity, Unternehmen, Termin, Aufgabe, Vorlagen) wählst du
From List (Suche) oder By ID, bei eigenen Feldern und Feldern eigener Aktivitäten erscheinen die
Optionen von Auswahlfeldern als Liste. IDs kopierst du im CRM über das Drei-Punkte-Menü („ID kopieren“).
Opportunity-Werte in Cent. Datums-/Zeitfelder ohne Zeitzone gelten in der Zeitzone des
Workflows. Für sichere Wiederholungen unter Request Options einen Idempotency-Key setzen, z. B.
{{ $execution.id }}-{{ $runIndex }}-{{ $itemIndex }}.

Knoten „EVO CRM Trigger": Beim Aktivieren legt der Knoten ein Webhook-Abo an (n8n: <Workflow>),
beim Deaktivieren löscht er es. Ereignisse als objektart:aktion, objektart:* oder * (alle). Jede
Zustellung wird über die Kopfzeile EVO-Signature geprüft (5 Minuten Toleranz, abschaltbar).
Voraussetzungen: Recht „API und Webhooks verwalten" (api.manage), öffentliche https://-Adresse von
n8n, höchstens 20 Abos je Organisation (Test- und Produktiv-URL von n8n zählen je als eigenes Abo).

Knoten „EVO CRM View Trigger": fragt eine gespeicherte Ansicht regelmäßig ab (Polling) und startet den
Workflow für jeden Lead, Kontakt bzw. jede Opportunity, die neu in die Ansicht kommt (oder sie verlässt). Art
und Ansicht wählst du aus der Liste. Der erste Lauf merkt sich nur den aktuellen Stand, danach meldet er jede
Änderung einmal mit dem vollständigen Datensatz. Kommt ein Datensatz später erneut in die Ansicht, löst er
wieder aus; mit der Option Only Once per Record höchstens einmal. Jede Minute ist das kürzeste Raster; mit eigenem Cron
*/30 * * * * * alle 30 Sekunden. Auch zeitabhängige Filter („letzter Kontakt vor mehr als 7 Tagen“) werden
erkannt; Ansichten über 20 000 Datensätze lehnt der Knoten ab.

Beispiel: Termin angelegt → WhatsApp-Empfänger abrufen → Fenster offen? Dann Text senden, sonst
die freigegebene Vorlage „termin_bestaetigung".

License

MIT

Discussion