BeeSection BeeSection

Mailings and client segments: who we write to, how, and when

A segment is a saved rule for "who exactly", a mailing is "what and how". Between them stand quiet hours - whatever lands at night goes out in the morning. We break down the channel cascade, the dry run, the queue and unsubscribing.

BeeSection · · 8 min read
Read in another language: Русский Українська

"Write to everyone who hasn't been in for a while" is a typical task before the off-season. The problem isn't the text, it's the two questions behind it: who exactly counts as "everyone who hasn't been in for a while", and how to reach them if half the database has nothing but a phone number. Segments answer the first question, mailings the second.

Where it is in the CRM

  • Segments: "Marketing → Segments".
  • Mailings: "Marketing → Mailings". The "Quiet hours" card sits at the top of the same page.
  • Filter by a saved segment: in the "Clients" list, next to the regular filters.

Segment: a rule or a list

A segment comes in two kinds. Dynamic is a saved rule: a tree of conditions where the top level is "All conditions" or "Any condition", and inside are fields from a ready-made catalogue. Static is simply a list of people maintained by a person.

The catalogue has dozens of fields, and they differ for clients, leads and employees. For a client these include: total spent, number of paid visits, days since the last visit, cancelled appointments, no-shows, days to birthday, loyalty tier, whether there's an email and a phone, whether there's an active package, plus relationship conditions — "visited this specialist", "visited this salon", "bought this service", "belongs to this segment". The section fills in values for lookup fields itself: the rule stores a specialist's or service's ID, not text.

The tree is limited: up to four levels of nesting, no more than 50 conditions, and no more than 500 values in a list condition. The rule comes in from the interface, and SQL is built from it, so only pre-described expressions get substituted into the query, while values are passed as parameters.

The "Count" button in the form shows how many people match the current rule — before it's even saved.

How membership is updated

The rule is evaluated as a live query only in two cases: in that same preview, and when checking a single person. Everything else — the client list filter, the mailing audience — works off a materialized membership. Otherwise a rule like "hasn't visited in 60 days and spent over 5,000" would have to run on every list opening and on every recipient.

That's why a dynamic segment has a recalculation mode — "manual" or "scheduled" — and an interval in minutes (from one minute up). Scheduled recalculation is done by the segment/refresh cron job, by default once every 15 minutes: it takes stale active segments and rewrites their membership, separately counting who joined and who left. The "Recalculate members" button in the list does the same for one segment, and the "members are stale" mark shows the interval has already passed.

Membership is checked once more before use: a small stale audience is recalculated right away, a large one (over 20,000) is queued. The section has no right to hand back "0 recipients" just because the segment was created a minute ago.

A person can be added to a segment by hand — and this survives the rule recalculation: a manual entry is marked with a separate source. For now this is API-only, there's no button for it in the section.

Mailing: audience and channels

The mailing audience is either "All clients", "All employees", or a segment. A segment also sets the recipient type: a mailing to a lead segment works without a separate mailing kind.

Channels are set as a "Channels by priority" list — it's a cascade, not a single choice: we try them in order, and whichever one we reach first sends it. The default order is Telegram, Viber, WhatsApp, email, SMS: from free to paid, because SMS costs money per message.

Every channel requires your own active integration. This matters for understanding the limits: mailings don't spend the plan's daily email quota — that quota applies to reminder emails, which go through our own mail. A mailing goes through the salon's integration instead and runs into your provider's limits, not ours.

Before sending there's a "Dry run": how many people are in the audience, how many we'll deliver to, how many opted out, and how many have no contact on any of the chosen channels, plus a breakdown by channel and a dozen examples with masked contacts. Before a mailing to three thousand people, this is the only way not to find out afterward that two thousand of them are unreachable.

Queue, statuses and retrying

Recipients are materialized into a separate list — together with those who opted out and those unreachable, marked with the "skipped" status and a reason. Without this there's no way to tell by eye why only 180 out of 218 people got the message.

From 50 recipients up, sending goes through a queue in batches of 50; below that it's synchronous. Mailing statuses: draft, sending, sent, failed. The "Retry failed" button only touches those with the "failed" status — recipients who already got it won't get a second message.

If the worker died mid-send, a mailing would get stuck in the "sending" state forever. The same mailing/dispatch cron job (once every five minutes) handles that: anything stuck for more than two hours it either finishes sending or closes based on the actual result.

Unsubscribing

An opt-out is set on the client, not on the mailing: the person unsubscribes from the salon's marketing entirely. In a marketing message, the unsubscribe link is inserted in place of {unsubscribe}, and if the template doesn't have it, it's appended at the end. The "Service message" checkbox turns this off: an appointment reminder isn't advertising. The opt-out is checked twice — while gathering recipients and at the moment of sending, because an hour can pass between the two in a large mailing.

Quiet hours

Quiet hours are a window when the salon stays silent. By default from 21:00 to 09:00 in the time zone of the company's primary salon; you can change the bounds or switch on "send around the clock" right on the "Mailings" tab, if you have the right to manage settings.

Here's how they work. A scheduled mailing whose time falls into the quiet window doesn't go out just because it's due, it gets pushed to the morning. A manual send at night isn't blocked, it double-checks: it shows when it's fine to send and offers a "Send anyway" button — because there are legitimate reasons to send at night too.

The same quiet hours are also consulted by two more mechanisms: retention campaigns (post-visit surveys, birthday greetings, bringing back clients who've disappeared) and review requests. Both run on a cron job every hour, around the clock, and without this check they would message clients at three in the morning. Lead assignment, though, has its own quiet hours — a separate setting with its own behavior; these are different things, and each is changed in a different place.

Scheduled sending (setting a mailing for a specific date and time) has no button in the section yet: the status, date and scheduling commands exist in the API, and a cron job carries them out.

What to do

Set up two or three dynamic segments for real-world reasons — "hasn't visited in a while", "visited this specialist", "birthday this week" — and set them to recalculate on a schedule. Before every mailing, run a dry run: if "will deliver" is far below "audience total", the problem isn't the text, it's that you have fewer channels connected than you thought.

Was this article helpful?

Related articles

Comments

No comments yet. Ask your question — we answer within a day.

Leave a comment

Your email is not published. We use it only to answer you.