Skip to main content

Communications and channels

IncentIA sends messages to members through several native channels, with automatic selection of the best channel based on preferences and availability.

Supported channels

ChannelProviderTypical use
EmailConfigurable SMTPLong communications, invoices, newsletter
SMSTwilioShort alerts, OTP, reminders
WhatsAppMeta Business APIConversational, urgent, high CTR
TelegramBot APIB2B niche, communities
PushWeb Push (VAPID) / APNs / FCMApp / PWA notifications

Each channel requires provider configuration (API keys, sender numbers, VAPID keys, etc.) at tenant level.

Channel Router

The ChannelRouter decides which channel to use for each message based on:

  1. Member preference — if they said "I prefer WhatsApp", try that first.
  2. Availability — if the member has no phone or hasn't accepted push, it's skipped.
  3. Opt-in — respects GDPR / privacy consents.
  4. Message type — some types are tied to specific channels (e.g. OTP via SMS).
  5. Fallback — if the preferred channel fails, try the next.

Templates

Every message is built from a template per channel:

  • Text with variables: Hello {{member.name}}, you have {{points}} points available.
  • HTML for email (with layout, images, CTA).
  • Media (images, PDFs) attachable depending on channel.

Templates are scoped:

  • Tenant-global — used by default.
  • Per campaign — specific to a given activation.
  • Per event typeEvidenceApproved, EvidenceRejected, RewardRedeemed, etc.

When an event fires, template is looked up in this order:

  1. Campaign template (if applicable).
  2. Tenant global template.
  3. Default text in code (fallback).

Visual flows

The visual flow editor lets you design message sequences with:

  • Triggers — "when a member signs up", "on birthday", "when points > X".
  • Conditions — "if VIP", "if in Madrid", "if 30d inactive".
  • Waits — "wait 3 days before next step".
  • Actions — send message, update attribute, add to segment, etc.

Flow example:

[Trigger] Member signs up

[Action] Send welcome email (welcome_email template)

[Wait] 7 days

[Condition] Any purchase yet?
├─ Yes → [Action] Send WhatsApp thank-you
└─ No → [Action] Send push with reactivation offer

Flows run in background (via Hangfire) and are idempotent — a member doesn't receive the same step twice.

Communications typically include URLs. If you point directly to the landing and WhatsApp bans it, members see an error.

Solution: Dynamic Links — short URLs on your domain (https://your-domain.app/r/summer) that redirect to the real target. If WhatsApp blocks the redirected domain, you change the Dynamic Link target and new clicks work without re-sending the message.

See Dynamic Links.

Metrics

Per message we track:

  • Sent / Delivered / Opened / Clicked / Bounced.
  • Channel used.
  • Response time (email / WhatsApp only).
  • Opt-out triggered.

Aggregable by campaign, template, or segment.

Opt-in and compliance

  • Every member has channel and message-type preferences (marketing, transactional).
  • Transactional messages (OTP, evidence approved) are always sent.
  • Marketing requires explicit opt-in.
  • Every change is logged for GDPR / privacy compliance.

Testing and simulation

Before launching a big flow:

  • Dry-run mode — simulate the flow without sending real messages.
  • Test audience — run against an internal-only segment.
  • Template preview with sample data.