Pipelines

Automate your workflows with event-driven pipelines — get notified, trigger actions, and save time.

What Is a Pipeline?

A Pipeline is an automation rule that listens for specific events (triggers) and executes actions in response. For example, you can set up a pipeline that sends a Telegram message every time a new payment is received or a new application is submitted. Pipelines are managed in CRM → Pipeline.

How Pipelines Work

Trigger (Event)ConditionsPayload MappingAction(s)
  • Trigger — the event that starts the pipeline (e.g., "payment created").
  • Conditions — optional filters that must all match for the pipeline to continue.
  • Payload mapping — maps data from the trigger event to the action input fields.
  • Actions — what happens when the trigger fires (e.g., send a Telegram message, email, or webhook).

Available Triggers

Triggers are events that start a pipeline. Currently available:

  • Payment Created — fires when a new payment is submitted (status: pending).
  • Payment Accepted — fires when a payment is verified and accepted.
  • Payment Rejected — fires when a payment is rejected.
  • Application Created — fires when a user submits a rental application.
  • User Created — fires when a new user registers (admin only).
  • Media Published — fires when a media file is published for the first time.
  • Incoming Webhook Received — fires when an incoming webhook endpoint receives a request from an external service.
  • Review Submitted — fires when a user submits a new review for a unit.
  • Review Verified — fires when a moderator verifies and approves a review.
  • Review Rejected — fires when a moderator rejects a review.

Trigger Payload Fields

When a trigger fires, it produces a payload with data you can use in your actions. Each trigger type provides a different set of fields.

Payment Trigger Payload

Triggers: Payment Created, Payment Accepted, Payment Rejected

Field PathDescription
[payment][id]Payment ID
[payment][status]Current status (pending, accepted, rejected)
[payment][value]Amount (raw number)
[payment][valueFormatted]Formatted amount (e.g., "IDR 500,000.00")
[payment][currency]Currency code (IDR)
[user][id]User ID
[user][email]User email
[user][firstName]First name
[user][lastName]Last name
[user][fullName]Full name
[user][active]Whether the account is active
[user][telegramChatId]User's Telegram chat ID
[user][telegramUsername]User's Telegram username

Application Trigger Payload

Trigger: Application Created

Field PathDescription
[application][id]Application ID
[application][status]Application status (pending)
[application][nights]Number of nights requested
[application][budget]Budget amount
[application][displayName]Applicant full name
[user][id]User ID
[user][email]User email
[user][firstName]First name
[user][lastName]Last name
[user][fullName]Full name
[user][telegramChatId]User's Telegram chat ID
[user][telegramUsername]User's Telegram username
[unit][id]Unit ID
[unit][title]Unit name
[complex][id]Complex ID
[complex][title]Complex name

User Trigger Payload

Trigger: User Created

Field PathDescription
[user][id]User ID
[user][email]User email
[user][firstName]First name
[user][lastName]Last name
[user][fullName]Full name
[user][active]Whether the account is active
[user][telegramChatId]User's Telegram chat ID
[user][telegramUsername]User's Telegram username

Media Trigger Payload

Trigger: Media Published

Field PathDescription
[media][id]Media ID
[media][type]Media type (image, video)
[media][displayName]Display name or filename
[media][entityType]Parent entity type (vendor-media, unit-media, etc.)
[media][filename]Stored filename (for building URLs)
[entity][id]Parent entity ID
[entity][title]Parent entity name

Incoming Webhook Trigger Payload

Trigger: Incoming Webhook Received

Field PathDescription
[webhook][id]Incoming webhook ID
[webhook][name]Webhook name
[webhook][token]Webhook token
[payload]Full JSON payload sent by the external service
[meta][sourceIp]IP address of the sender
[meta][receivedAt]Timestamp when the request was received

Review Trigger Payload

Triggers: Review Submitted, Review Verified, Review Rejected

Field PathDescription
[review][id]Review ID
[review][rating]Star rating (1-5)
[review][title]Review title
[review][body]Review text body
[review][status]Review status (pending, verified, rejected)
[unit][id]Unit ID
[unit][name]Unit name
[user][id]User ID
[user][email]User email
[user][firstName]First name
[user][lastName]Last name
[user][fullName]Full name
[user][telegramChatId]User's Telegram chat ID
[user][telegramUsername]User's Telegram username

Message Templates

Message templates use Twig syntax for dynamic variables. Pre-built templates are loaded automatically when you select a trigger type. You can customize them or write your own from scratch.

Payment Created

pipeline/payment_created.html.twig
 1<b>💳 Payment created</b>
 2 
 3<b>👤 Customer:</b> {{ customer_name }}
 4<b>📧 Email:</b> {{ customer_email }}
 5 
 6<b>🆔 Payment ID:</b> {{ payment_id }}
 7<b>💰 Amount:</b>
 8{{ payment_amount|number_format(2, '.', ' ') }} {{ payment_currency }}
 9<b>📌 Status:</b> {{ payment_status }}
10 
11<i>Hunico · Payments</i>

Application Created

pipeline/application.html.twig
 1<b>📝 New application submitted</b>
 2 
 3<b>👤 Applicant:</b> {{ user_name }}
 4<b>📧 Email:</b> {{ user_email }}
 5 
 6<b>🏠 Unit:</b> {{ unit_title }}
 7<b>🏢 Complex:</b> {{ complex_title }}
 8 
 9<b>🆔 Application ID:</b> {{ application_id }}
10<b>📌 Status:</b> {{ application_status }}
11 
12<i>Hunico · Applications</i>

Media Published

pipeline/media_published.html.twig
1<b>🖼 New media published</b>
2 
3<b>📂 Type:</b> {{ media_type }}
4<b>🏷 Title:</b> {{ entity_title }}
5 
6<b>🆔 Media ID:</b> {{ media_id }}
7 
8<i>Hunico · Media</i>

Payload Mapping

Mapping connects trigger payload fields to action input fields. When you configure an action (e.g., Telegram message), the system:

  1. Extracts template variables from your message template. Message templates use Twig syntax. For example, if your message contains {{ payment.valueFormatted }}, the system creates a mapping field for [message][valueFormatted].
  2. Shows a dropdown for each extracted variable. The dropdown label shows the action path (e.g., [message][payment]) and lists all available trigger fields as options.
  3. You select which trigger field should fill each template variable. For example, map [message][valueFormatted] to [payment][valueFormatted].

When the pipeline runs, the system replaces each template variable with the actual value from the trigger payload.

Creating a Pipeline

Navigate to CRM → Pipeline and click the create button.

  1. Configure the subscription — select which event triggers this pipeline.
  2. Add one or more actions (up to 20) — choose the action type and configure its parameters.
  3. Write your message template using Twig variables (e.g., {{ payment.valueFormatted }}).
  4. Map each template variable to a trigger payload field using the dropdown selectors.
  5. Save and activate the pipeline.

Action Types

Each pipeline action defines what happens when the trigger fires. All three action types are available to any user who has access to at least one trigger:

Action TypeDescription
Telegram MessageSend a message to a Telegram chat or group
EmailSend an email notification with customizable subject and body
WebhookSend an HTTP request to an external service
WhatsApp MessageSend a WhatsApp message via Meta Cloud API (admin only)
Invoice PDFGenerate and attach a branded invoice PDF
Facebook PostPublish a post with photos to a Facebook Page (admin only)

Trigger Access by Role

Each trigger type is available to specific roles. You can only create pipelines with triggers you have access to:

TriggerAvailable For
Payment Created / Accepted / RejectedAdmin, Accountant
Application CreatedAdmin, Vendor
User CreatedAdmin
Media PublishedAdmin, Vendor
Incoming Webhook ReceivedAdmin, Vendor
Review Submitted / VerifiedAdmin, Vendor
Review RejectedAdmin

Telegram Message Action

Sends a message to a specified Telegram chat. Configuration fields:

  • Message template — the message text with Twig variables for dynamic data.
  • Telegram Chat ID — the numeric ID of the chat where messages will be sent.
  • Mapping fields — one dropdown per template variable, connecting it to trigger data.

Email Action

Sends an email notification when the pipeline triggers. Configuration fields:

  • Email body template — HTML content with Twig variables. A default template is loaded automatically.
  • Email subject — the subject line. Supports Twig variables, e.g. Payment {{ payment_id }} received
  • Recipient email — the email address that receives the notification.
  • Mapping fields — one dropdown per template variable, connecting it to trigger data.

Tip: The email body uses HTML formatting. You can use Twig filters like {{ amount|number_format(2, '.', ' ') }} to format numbers in your email templates.

Webhook Action

Sends an HTTP request to an external URL when the pipeline triggers. Useful for integrating with third-party services, CRMs, or custom APIs. Configuration fields:

  • Request body template — JSON payload with Twig variables. Must produce valid JSON.
  • Webhook URL — the HTTPS endpoint that receives the request (e.g., https://example.com/webhook).
  • HTTP Method — POST or PUT.
  • Request headers (optional) — custom HTTP headers as a JSON object (e.g., {"Authorization": "Bearer token"}).
  • Mapping fields — one dropdown per template variable, connecting it to trigger data.

Important: External services must respond within 10 seconds, otherwise the request will time out.

How to Find Your Telegram Chat ID

The Telegram Chat ID is a numeric identifier for your chat, group, or channel. Here is how to get it:

  1. Open Telegram and start a conversation with @hunico_bot.
  2. Send the command /chatid — the bot will reply with your personal chat ID.
  3. For group chats: add @hunico_bot to the group, then send /chatid in the group — the bot will reply with the group's chat ID.
  4. Copy the numeric ID and paste it into the Telegram Chat ID field in your pipeline action.

Important: The bot @hunico_bot must remain a member of the chat for messages to be delivered. If the bot is removed from the group, pipeline messages to that chat will fail.

Setting Up Facebook Page Posting

The Facebook Post action allows you to publish property listings with photos directly to your Facebook Page. This requires a Facebook Page and a long-lived Page Access Token.

Step 1: Get Your Facebook Page ID

  1. Open your Facebook Page.
  2. Go to Page SettingsPage Transparency.
  3. Your Page ID is a numeric value displayed in the transparency section (e.g., 123456789).
  4. Copy this ID and paste it into the Facebook Page ID field in your pipeline action.

Step 2: Generate a Page Access Token

  1. Go to Facebook Graph API Explorer.
  2. Select your App (or create one at developers.facebook.com/apps).
  3. Click Generate Access Token and grant these permissions: pages_manage_posts, pages_read_engagement.
  4. Select your Page from the dropdown to get a Page Access Token (not a User token).
  5. To make the token long-lived (60 days), use the Access Token Debugger and click Extend Access Token.
  6. Copy the token and paste it into the Facebook Access Token field in your pipeline action.

Step 3: Configure the Pipeline Action

  1. In your pipeline, add a new action and select Facebook post.
  2. Fill in the Page ID and Access Token.
  3. Write a message template using Twig syntax for dynamic variables (e.g., {{ unit.title }}).
  4. Optionally, add media slots to attach property photos. Drag and drop to reorder.
  5. Map the payload fields from the trigger to your template variables.
  6. Activate the pipeline subscription.

Rate Limits

To prevent spam, publishing is rate-limited per property per vendor:

  • Pro vendors — 1 post per property per week
  • Free vendors — 1 post per property per month
  • Admins — no limits

Important: Page Access Tokens expire after 60 days. Set a reminder to regenerate the token before it expires, or your pipeline posts will fail.

Editing Active Pipelines

When a pipeline is active, its configuration fields are locked to prevent accidental changes while the pipeline is processing events. You can still view all settings, but to make changes:

  1. Open the pipeline and toggle the Active switch to off.
  2. Edit the trigger, actions, message template, or mappings as needed.
  3. When ready, toggle Active back on to resume processing.

Tip: While the pipeline is disabled, no events will be processed. Re-activate as soon as your changes are complete to avoid missing events.

Conditional Execution

Conditions let you filter when a pipeline runs. You can add one or more conditions that must all be true (AND logic) for the pipeline actions to execute. If conditions don't match, the trigger is skipped and a log entry is created with "Skipped" status.

Each condition has three parts:

  • Field — the trigger payload field to check (e.g., [payment][status]).
  • Operator — the comparison type.
  • Value — the expected value to compare against.

Available Operators

OperatorDescription
equalsField value matches exactly
not_equalsField value does not match
containsField value contains the specified text
greater_thanField value is greater than (numeric comparison)
less_thanField value is less than (numeric comparison)

Example: To only trigger on accepted payments, add a condition with field [payment][status], operator equals, and value accepted.

Automatic Retries

If a pipeline action fails (e.g., Telegram API error, webhook timeout), the system can automatically retry it. You can configure the maximum number of retry attempts (0 to 5) per pipeline.

  • Retry count — set the Max Retries field on the pipeline (default: 0, meaning no retries).
  • Increasing delays — each retry waits longer than the previous one to avoid overloading external services. The delay doubles with each attempt (approximately 10s, 20s, 40s, 80s, 160s).
  • Attempt tracking — each retry attempt is logged in the execution history with its attempt number, status, and any error details.

Tip: Set retries to 2-3 for actions that depend on external services (Telegram, webhooks). This handles temporary outages without manual intervention.

Testing Pipelines

Each pipeline has a test trigger feature that lets you fire the pipeline with a sample payload to verify it works correctly before going live. The test input area shows a JSON payload that simulates the real event data. If an action fails, the error payload is captured and displayed on the pipeline detail page for easy debugging.

Execution Logs

Every pipeline execution is tracked in the Execution Logs section at the bottom of the pipeline view page. Each log entry shows:

  • Status — Completed, Error, or Skipped (when conditions didn't match).
  • Attempt number — which retry attempt this was (1 for the first run).
  • Error payload — if the action failed, a read-only code viewer shows the full error details.
  • Test input — the payload data that was sent to the action, shown as read-only code.

Template fields and payload data are displayed using a syntax-highlighted code viewer for easier reading. Editable template fields (message body, request body) use a code editor with Twig syntax support.

Deleting Pipelines

You can delete a pipeline from the pipeline view page using the delete action. Deletion follows the standard 14-day grace period — the pipeline is scheduled for removal and can be restored within that period. All associated actions, subscriptions, and execution logs are removed together with the pipeline.