Smart Automated Notifications: Trigger System with AI Optimization

Problem: Lost Sales from Untimely Communications

AI Development Areas

Frequently Asked Questions

Latest works

  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1284
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1240
  • image_logo-advance_0.webp
    B2B Advance company logo design
    696
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    982
  • image_logo-aider_0.webp
    AIDER company logo development
    917
  • image_crm_chasseurs_493_0.webp
    CRM development for Chasseurs
    1031

Problem: Lost Sales from Untimely Communications

An e-commerce store with 50,000 daily visitors loses up to 70% of potential sales due to delayed communications. Dozens of abandoned carts every day, hundreds of users leave without buying. Manual mailings can't keep up—the moment is lost. We develop an AI trigger communication system that analyzes each user's behavior in real-time and sends a personalized message via the right channel at the optimal time. Result: conversion from triggers increases 2-4x, retention improves by 30%.

The ML-based trigger system solves three tasks: channel selection (email/SMS/push), send time determination, and content generation. Unlike static rules, AI adapts to each user—their activity patterns, preferences, and purchase history. We use LLMs (Claude, GPT-4) to generate text that sounds like a real manager, not a template mailing. The system achieves open rates up to 55% for abandoned carts and CTR of 15-25% for personalized push. AI is 3-5 times more effective than rule-based approaches for these metrics.

How the ML Model Selects Channel and Send Time?

The ML model considers many factors: historical channel effectiveness for the event type, user preferences, current channel load. For example, email works best for abandoned carts (open rate 40-55%), while push or SMS is better for urgent price change notifications. Send time is determined based on activity patterns: if a user opens emails in the evening, the system sends around 6 PM. The model trains on historical interaction data using features: hour of day, day of week, event type, previous responses. We use gradient boosting (CatBoost) for send time regression and channel classification.

Code: Base System Class with Channel and Time Selection

from anthropic import Anthropic import pandas as pd import numpy as np from dataclasses import dataclass from enum import Enum import json class Channel(Enum): EMAIL = "email" SMS = "sms" PUSH = "push" IN_APP = "in_app" @dataclass class TriggerEvent: user_id: str event_type: str event_data: dict timestamp: float class TriggerCommunicationSystem: def __init__(self): self.llm = Anthropic() self.send_time_model = None self.channel_model = None def process_trigger(self, event: TriggerEvent, user_profile: dict) -> dict: """Full trigger processing: channel + time + content""" channel = self._select_channel(user_profile, event.event_type) send_delay_hours = self._optimal_send_time(user_profile, event.event_type) content = self._generate_content(event, user_profile, channel) if self._is_communication_fatigue(user_profile): return {'send': False, 'reason': 'communication_fatigue'} return { 'send': True, 'channel': channel.value, 'send_delay_hours': send_delay_hours, 'content': content, 'event_type': event.event_type } def _select_channel(self, user: dict, event_type: str) -> Channel: preferred = user.get('preferred_channel') if preferred: return Channel[preferred.upper()] channel_effectiveness = { 'abandoned_cart': {'email': 0.15, 'push': 0.08, 'sms': 0.12}, 'inactivity': {'email': 0.05, 'push': 0.06, 'sms': 0.04}, 'price_drop': {'push': 0.12, 'email': 0.10, 'sms': 0.08}, 'order_shipped': {'sms': 0.25, 'email': 0.20, 'push': 0.18}, } effectiveness = channel_effectiveness.get(event_type, {'email': 0.1}) best_channel = max(effectiveness, key=effectiveness.get) return Channel[best_channel.upper()] def _optimal_send_time(self, user: dict, event_type: str) -> float: active_hours = user.get('active_hours', list(range(9, 22))) if event_type == 'abandoned_cart': return 1.5 elif event_type == 'price_drop': return 0.1 elif event_type == 'inactivity': return 24 if 9 in active_hours else 48 else: return 2.0 def _generate_content(self, event: TriggerEvent, user: dict, channel: Channel) -> dict: channel_constraints = { Channel.SMS: {'max_chars': 160, 'format': 'plain'}, Channel.PUSH: {'max_chars': 100, 'format': 'title+body'}, Channel.EMAIL: {'max_chars': 2000, 'format': 'html'}, Channel.IN_APP: {'max_chars': 200, 'format': 'markdown'}, } constraint = channel_constraints[channel] event_context = json.dumps(event.event_data, ensure_ascii=False)[:300] response = self.llm.messages.create( model="claude-3-5-sonnet-20241022", max_tokens=300, messages=[{ "role": "user", "content": f"""Generate a {channel.value} message for trigger event. Event: {event.event_type} Event data: {event_context} User name: {user.get('first_name', 'Customer')} User purchase history: {user.get('total_orders', 0)} orders, avg order ${user.get('avg_order_value', 0):.0f} Channel: {channel.value} (max {constraint['max_chars']} chars) Return JSON: {{ "subject": "email subject or push title", "body": "message body", "cta": "call to action text", "cta_url": "URL path" }} Tone: friendly, personal. Mention specific item if available. No generic marketing language.""" }] ) try: return json.loads(response.content[0].text) except Exception: return { 'subject': f"We have something for you, {user.get('first_name', '')}!", 'body': response.content[0].text[:constraint['max_chars']], 'cta': 'View Now' } def _is_communication_fatigue(self, user: dict) -> bool: messages_last_7d = user.get('messages_received_7d', 0) opens_last_7d = user.get('messages_opened_7d', 0) if messages_last_7d >= 5: return True if messages_last_7d >= 3 and opens_last_7d == 0: return True return False 

A/B Testing Trigger Messages: Compare Variants

To find optimal strategies, we run A/B tests across channels, timing, and content. Results update in real time—you can adjust parameters on the fly. For example, a test may show that push with emojis yields 20% higher CTR than without.

class TriggerABTest: """Testing variants of trigger messages""" def __init__(self, test_name: str, variants: list[dict]): self.test_name = test_name self.variants = variants self.results = {v['name']: {'sent': 0, 'opened': 0, 'clicked': 0, 'converted': 0} for v in variants} def assign_variant(self, user_id: str) -> dict: """Deterministic variant assignment""" idx = hash(f"{self.test_name}_{user_id}") % len(self.variants) return self.variants[idx] def compute_results(self) -> dict: results_summary = {} for variant_name, stats in self.results.items(): sent = stats['sent'] if sent == 0: continue results_summary[variant_name] = { 'open_rate': stats['opened'] / sent, 'click_rate': stats['clicked'] / sent, 'conversion_rate': stats['converted'] / sent, 'sample_size': sent } return results_summary 

Channel Effectiveness Comparison

Channel Open rate CTR Conversion Best for
Email 40-55% (abandoned cart) 10-20% 5-12% Long messages, details
SMS 95%+ within 5 min 15-25% 8-15% Urgent alerts (order status)
Push 8-15% (personalized) 5-10% 3-7% Short reminders, promotions
In-app 60-80% 20-30% 10-20% Retention, onboarding

Rule-based vs ML: Which is More Effective?

Criterion Rule-based ML approach
Time to launch Days Weeks
Adaptation to user None Full personalization
Open rate (abandoned cart) 10-20% 40-55%
Frequency control Static Dynamic (ML)
Content generation Templates LLM, context-aware

Rule-based works for simple scenarios with low variability. ML is for complex, personalization-critical cases. In practice, we often combine them: rule-based as a fallback, ML as the main engine.

Example of Economic Efficiency Calculation

For an e-commerce store with 10,000 abandoned carts per month, average order $50, and trigger conversion of 5%, additional revenue is $25,000 per month. The system pays for itself in 2-3 months. Implementation cost is typically $15,000-$30,000, so ROI exceeds 10x in the first year.

Key Advantages of the AI System

LLM-driven content personalization—the model generates text considering purchase history, current browsing, and user name. Open rates are 2-3x higher than bulk mailings. ML time optimization—the model analyzes when a specific user is active and sends the message at the moment of maximum read probability. Frequency control—a built-in communication fatigue detector prevents sending more than 3-4 messages per week, reducing unsubscribes. As a result, retention increases and spam complaints drop 5-10x. Using RAG message generation, we fetch relevant product data for each user, making content even more personalized. MLOps practices ensure the system is reliable and scalable.

What's Included in System Development?

  1. Analytics — audit of current communications, collection of user activity patterns.
  2. Design — event-driven system architecture, stack selection (PyTorch, Hugging Face, ChromaDB).
  3. Development — implementation of ML modules for channel and time selection, content generation via LLM.
  4. Integration — connection to CRM (Bitrix24, AmoCRM), ESP (SendGrid, Unisender) and SMS gateways.
  5. A/B Testing — experiments to find optimal strategies.
  6. Documentation & Training — API docs, instructions for marketers.

We have 5+ years of experience in ML systems for e-commerce, having delivered over 30 projects. We use a modern stack: PyTorch, LangChain, Triton Inference Server. We guarantee measurable results—we track open rate, conversion, and compare against baseline. Implementation typically pays back within 2-3 months, generating $50,000 to $200,000 in additional annual revenue for an average e-commerce project.

We'll assess your project in 1-2 days—contact us for a consultation. Get a cost and timeline estimate tailored to your needs. The additional revenue from the AI system can exceed costs by 5-10x in the first year.