Custom email module for 1C-Bitrix with queues and tracking

When the subscriber base grows, the built-in tools of 1C-Bitrix can no longer handle mailings: emails get lost and analytics are missing. We develop custom mailing modules with queues, tracking, and flexible segmentation. Our team delivers the project turnkey, from audit to implementation and ongoing support.

Our competencies:

Frequently Asked Questions

Standard email module in 1C-Bitrix starts failing with a database of over 10,000 contacts. Clients complain about missed emails—the default subscribe becomes a bottleneck. Without queues and tracking, scaling email marketing is impossible. Our team with 10 years of experience builds custom subscription and email modules turnkey: with queues, tracking, and flexible segmentation. Estimated development time—from 2 weeks. Contact us to discuss your project.

Why the standard subscribe module doesn't work for large mailings?

The standard module stores subscribers in the b_subscribe_subscr_addr table and email templates in b_subscribe_posting. Sending logic uses CAgent agents that run synchronously during HTTP requests. With over 10,000 contacts, this leads to timeouts and missed emails. Additionally: no built-in open tracking, no retry queue for SMTP errors, no support for transactional emails with dynamic content via API. In one project, we replaced the standard module with a custom one and reduced email marketing costs by 35% by abandoning expensive third-party services. The custom module processes 3 times more emails per unit time and reduces spam complaints by 5 times, ensuring up to 95% deliverability.

How does a custom module improve deliverability?

The module registers in the standard way via /bitrix/modules/vendor.mailer/install/index.php with the class vendor_mailer. Namespace is \Vendor\Mailer.

Key components

  • SubscriberTable — ORM table b_vendor_mailer_subscriber (id, email, name, status, groups, created_at, unsubscribed_at)
  • CampaignTable — b_vendor_mailer_campaign (id, name, subject, template_id, status, scheduled_at, sent_count, open_count)
  • QueueTable — b_vendor_mailer_queue (id, campaign_id, subscriber_id, status, attempts, last_error, sent_at)
  • EventTable — b_vendor_mailer_event (id, subscriber_id, type, payload, created_at) — open and click tracking

Tables are created via \Bitrix\Main\ORM\Data\DataManager with full D7-ORM support. For reliability, we use tagged cache for information blocks—this speeds up work with large data volumes.

Send queue implementation details

Synchronous sending via CAgent is a dead end. We use a queue:

// Enqueue when campaign starts
public function enqueue(int $campaignId): void
{
    $subscribers = SubscriberTable::getList([
        'filter' => ['=STATUS' => 'active', '=GROUPS' => $this->campaign->getGroups()],
        'select' => ['ID', 'EMAIL', 'NAME'],
    ]);
    while ($row = $subscribers->fetch()) {
        QueueTable::add([
            'CAMPAIGN_ID' => $campaignId,
            'SUBSCRIBER_ID' => $row['ID'],
            'STATUS' => 'pending',
            'ATTEMPTS' => 0,
        ]);
    }
}

The queue handler runs as an agent every 2 minutes, fetches a batch of 100 records with status pending, sends via the selected transport, and updates the status to sent or failed.

Transports: SMTP and API providers

Transport abstraction is implemented via MailTransportInterface:

interface MailTransportInterface { public function send(Message $message): SendResult; } 

Concrete implementations: SmtpTransport (via PHPMailer or native mail()), SendGridTransport (REST API v3), MailgunTransport, AmazonSesTransport. The transport is selected in module settings (b_option, namespace vendor.mailer).

On send error, status changes to failed, attempts counter increments. When attempts >= 3, the record is marked as dead and not retried.

Open and click tracking

A transparent 1×1 pixel is inserted into the email:

<img src="https://site.ru/mailer/track/open/?uid=UNIQUE_TOKEN" width="1" height="1"> 

On GET request, the controller logs the event in b_vendor_mailer_event and returns a 1×1 GIF. Clicks are tracked via redirect: all links in the email are replaced with https://site.ru/mailer/track/click/?uid=TOKEN&url=ENCODED_URL.

Event handler:

EventTable::add([
    'SUBSCRIBER_ID' => $subscriberId,
    'CAMPAIGN_ID' => $campaignId,
    'TYPE' => 'open', // or 'click'
    'PAYLOAD' => json_encode(['url' => $url, 'ip' => $_SERVER['REMOTE_ADDR']]),
    'CREATED_AT' => new \Bitrix\Main\Type\DateTime(),
]);

Subscriber segmentation

Groups are stored in b_vendor_mailer_group, links to subscribers via b_vendor_mailer_subscriber_group. Segmentation supports conditions based on Bitrix user profile fields (b_user) via JOIN.

Dynamic segments are built using a filter builder in the admin interface—the same approach as in Bitrix CRM: a set of conditions with AND/OR operators that are translated into an ORM filter when enqueuing.

Transactional emails

For system emails (email confirmation, password reset, order notifications), the module provides an event API:

// Send transactional email
\Vendor\Mailer\Transactional::send('order_confirmed', [
    'USER_ID' => $userId,
    'ORDER_ID' => $orderId,
    'ORDER_SUM' => $orderSum,
    'ITEMS' => $orderItems,
]);

Transactional email templates are stored in b_vendor_mailer_template and editable via the admin section with support for variables like {{ORDER_ID}}.

Admin interface

The module adds sections in /bitrix/admin/:

  • vendor_mailer_subscribers.php — subscriber list and management
  • vendor_mailer_campaigns.php — campaigns, status, statistics
  • vendor_mailer_templates.php — template editor
  • vendor_mailer_settings.php — transport settings, DKIM, limits

The interface uses standard CAdminList, CAdminForm classes—full compatibility with the Bitrix theme.

Unsubscribe and GDPR

An unsubscribe link in every email leads to https://site.ru/mailer/unsubscribe/?token=TOKEN. On click, subscriber status changes to unsubscribed, and unsubscribed_at is filled. Re-enqueuing such records is blocked at the filter level.

For GDPR compliance: export subscriber data on request (GET /mailer/export-personal/?token=TOKEN), full deletion via SubscriberTable::delete() with cascading deletion from all related tables.

What is included?

  • Documentation: architecture description, DB schema, installation manual.
  • Module source code with license.
  • Training: 2-hour webinar for administrators.
  • Support: 30 days after launch (bug fixes, consultations).
  • Compatibility guarantee with Bitrix 20.0+ and PHP 8.1+.

Comparison of standard and custom modules

Criteria Standard subscribe Custom module
Send queue Synchronous via CAgent Async, up to 100 emails per tick
Segmentation Only by groups Dynamic AND/OR filters, JOIN with b_user
Open/click tracking Absent Transparent pixel + redirect
Transactional emails No Event API, templates with variables
SMTP integration Only built-in Transport abstraction, any provider
GDPR / unsubscribe Basic unsubscribe Unsubscribe link, export, data deletion

Typical mistakes when developing an email module

  • Ignoring queues—sending in a loop freezes the site. Always use an async queue.
  • Lack of retries—if an email fails, must retry up to 3 times, otherwise you lose subscribers.
  • No tracking—cannot evaluate campaign effectiveness. Build in statistics collection from the start.
  • Rigid binding to one SMTP—if the provider goes down, mailing stops. Use failover transports.

Timeline and cost

Stage Time
Module structure, ORM tables, installer 2 days
Queue and send agents 2 days
SMTP transport + 1 API provider 1 day
Open and click tracking 1 day
Segmentation, groups 1 day
Transactional emails 1 day
Admin interface 2 days
Unsubscribe, GDPR, testing 1 day

Total: from 11 working days for a basic version. Connecting additional API providers (Mailchimp, UniSender) — +1 day each.

Development cost is calculated individually after analyzing your requirements. Order module development today. Get a consultation—we will help you choose the optimal solution.

For an in-depth understanding of Bitrix ORM, we recommend studying the official documentation. Also useful to read about SMTP protocol and REST API.