Campaigns
Registering Campaign Events
Mautic dispatches the Event \Mautic\CampaignBundle\CampaignEvents::CAMPAIGN_ON_BUILD
for Plugins to register their Campaign Actions, Conditions and Decisions. Listeners receive a Mautic\CampaignBundle\Events\CampaignBuilderEvent
object. Register the Event using the appropriate add
method as described below.
- Mautic\CampaignBundle\Events\CampaignBuilderEvent
- public addAction(string $key, array $action)
- Parameters:
$key (
string
) – Unique key for the Action.$action (
array
) – Action definition.
- Return type:
void
- public addCondition(string $key, array $condition)
- Parameters:
$key (
string
) – Unique key for the Condition.$condition (
array
) – Condition definition.
- Return type:
void
- public addDecision(string $key, array $decision)
- Parameters:
$key (
string
) – Unique key for the Decision.$decision (
array
) – Decision definition.
- Return type:
void
- public getActions()
- Returns:
Array of registered Actions.
- Return type:
array
- public getConditions()
- Returns:
Array of registered Conditions.
- Return type:
array
- public getDecisions()
- Returns:
Array of registered Decisions.
- Return type:
array
Registering a Campaign Action
<?php
declare(strict_types=1);
namespace MauticPlugin\HelloWorldBundle\EventListener;
use Mautic\CampaignBundle\CampaignEvents;
use Mautic\CampaignBundle\Event\CampaignBuilderEvent;
use MauticPlugin\HelloWorldBundle\HelloWorldEvents;
use MauticPlugin\HelloWorldBundle\Form\Type\TravelType;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class CampaignActionSubscriber implements EventSubscriberInterface
{
public const TYPE = 'helloworld.action';
public static function getSubscribedEvents(): array
{
return [
CampaignEvents::CAMPAIGN_ON_BUILD => ['onCampaignBuild', 0],
];
}
public function onCampaignBuild(CampaignBuilderEvent $event): void
{
$event->addAction(
self::TYPE,
[
'label' => 'helloworld.campaign.event.action',
'description' => 'helloworld.campaign.event.action.descr',
'batchEventName' => HelloWorldEvents::EXECUTE_CAMPAIGN_ACTION,
'formType' => TravelType::class,
]
);
}
}
Campaign Action definition
Key |
Is required? |
Type |
Description |
---|---|---|---|
|
yes |
string |
Display name for the UI. |
|
yes |
string |
The Campaign engine dispatches this Event through the |
|
no |
string |
Displays as the tool-tip for this Event. |
|
no |
string |
Symfony form type class for the Event’s configuration. |
|
no |
array |
Array of options passed into the given Symfony form type. |
|
no |
array |
Array of field:filter pairs of input masks supported by |
|
no |
string |
PHP template to customize the UI of the given form type. |
|
no |
array |
Array of restrictions defining the Events and anchors this Event is compatible with. |
|
no |
array |
Array of Event anchors this Event isn’t allowed to connect to. Names of anchors are |
|
no |
array[] |
Array with keys as Event types of |
|
no |
array[] |
Array with keys as Event types of |
|
no |
string |
PHP template to customize the UI for this Event in the Contact’s timeline. |
Registering a Campaign Condition
<?php
declare(strict_types=1);
namespace MauticPlugin\HelloWorldBundle\EventListener;
use Mautic\CampaignBundle\CampaignEvents;
use Mautic\CampaignBundle\Event\CampaignBuilderEvent;
use MauticPlugin\HelloWorldBundle\HelloWorldEvents;
use MauticPlugin\HelloWorldBundle\Form\Type\TravelType;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class CampaignConditionSubscriber implements EventSubscriberInterface
{
public const TYPE = 'helloworld.condition';
public static function getSubscribedEvents(): array
{
return [
CampaignEvents::CAMPAIGN_ON_BUILD => ['onCampaignBuild', 0],
];
}
public function onCampaignBuild(CampaignBuilderEvent $event): void
{
$event->addCondition(
self::TYPE,
[
'label' => 'helloworld.campaign.event.condition',
'description' => 'helloworld.campaign.event.condition.descr',
'eventName' => HelloWorldEvents::EVALUATE_CAMPAIGN_CONDITION,
'formType' => TravelType::class,
]
);
}
}
Campaign Condition definition
Key |
Is required? |
Type |
Description |
---|---|---|---|
|
yes |
string |
Display name for the UI. |
|
yes |
string |
The Campaign engine dispatches this Event through the |
|
no |
string |
Displays as the tool-tip for this Event. |
|
no |
string |
Symfony form type class for the Event’s configuration. |
|
no |
array |
Array of options passed into the given Symfony form type. |
|
no |
array |
Array of field:filter pairs of input masks supported by |
|
no |
string |
PHP template to customize the UI of the given form type. |
|
no |
array |
Array of restrictions defining the Events and anchors this Event is compatible with. |
|
no |
array |
Array of Event anchors this Event isn’t allowed to connect to. Names of anchors are |
|
no |
array[] |
Array with keys as Event types of |
|
no |
array[] |
Array with keys as Event types of |
|
no |
string |
PHP template to customize the UI for this Event in the Contact’s timeline. |
Registering a Campaign Decision
<?php
declare(strict_types=1);
namespace MauticPlugin\HelloWorldBundle\EventListener;
use Mautic\CampaignBundle\CampaignEvents;
use Mautic\CampaignBundle\Event\CampaignBuilderEvent;
use MauticPlugin\HelloWorldBundle\HelloWorldEvents;
use MauticPlugin\HelloWorldBundle\Form\Type\TravelType;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class CampaignDecisionSubscriber implements EventSubscriberInterface
{
public const TYPE = 'helloworld.decision';
public static function getSubscribedEvents(): array
{
return [
CampaignEvents::CAMPAIGN_ON_BUILD => ['onCampaignBuild', 0],
];
}
public function onCampaignBuild(CampaignBuilderEvent $event): void
{
$event->addCondition(
self::TYPE,
[
'label' => 'helloworld.campaign.event.decision',
'description' => 'helloworld.campaign.event.decision.descr',
'eventName' => HelloWorldEvents::EVALUATE_CAMPAIGN_DECISION,
'formType' => TravelType::class,
]
);
}
}
Campaign Decision definition
Key |
Is required? |
Type |
Description |
---|---|---|---|
|
yes |
string |
Display name for the UI. |
|
yes |
string |
The Campaign engine dispatches this Event through the |
|
no |
string |
Displays as the tool-tip for this Event. |
|
no |
string |
Symfony form type class for the Event’s configuration. |
|
no |
array |
Array of options passed into the given Symfony form type. |
|
no |
array |
Array of field:filter pairs of input masks supported by |
|
no |
string |
PHP template to customize the UI of the given form type. |
|
no |
array |
Array of restrictions defining the Events and anchors this Event is compatible with. |
|
no |
array |
Array of Event anchors this Event isn’t allowed to connect to. Names of anchors are |
|
no |
array[] |
Array with keys as Event types of |
|
no |
array[] |
Array with keys as Event types of |
|
no |
string |
PHP template to customize the UI for this Event in the Contact’s timeline. |
Executing or evaluating Campaign Events
Implement a listener to the event name defined in either batchEventName
or eventName
to execute or evaluate the Campaign Event.
Executing a Campaign Action
Listeners to the event’s batchEventName
receives a \Mautic\CampaignBundle\Event\PendingEvent
object. This object contains the Contacts that are at this point in their journey. Listeners must process the batch of Contacts and mark their respective \Mautic\CampaignBundle\Entity\LeadEventLog
as passed or failed. You must mark each LeadEventLog as passed or failed. The campaign_time_wait_on_event_false
configuration option determines the rescheduling of failed events.
<?php
declare(strict_types=1);
namespace MauticPlugin\HelloWorldBundle\EventListener;
use Mautic\CampaignBundle\CampaignEvents;
use Mautic\CampaignBundle\Event\CampaignBuilderEvent;
use Mautic\CampaignBundle\Event\PendingEvent;
use MauticPlugin\HelloWorldBundle\HelloWorldEvents;
use MauticPlugin\HelloWorldBundle\Form\Type\TravelType;
use MauticPlugin\HelloWorldBundle\Helper\TravelService;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Translation\TranslatorInterface;
class CampaignActionSubscriber implements EventSubscriberInterface
{
public const TYPE = 'helloworld.action';
private TranslatorInterface $translator;
private TravelService $travelService;
public function __construct(TranslatorInterface $translator, TravelService $travelService)
{
$this->translator = $translator;
$this->travelService = $travelService;
}
public static function getSubscribedEvents(): array
{
return [
CampaignEvents::CAMPAIGN_ON_BUILD => ['onCampaignBuild', 0],
HelloWorldEvents::EXECUTE_CAMPAIGN_ACTION => ['onExecuteCampaignAction', 0],
];
}
public function onCampaignBuild(CampaignBuilderEvent $event): void
{
$event->addAction(
self::TYPE,
[
'label' => 'helloworld.campaign.event.action',
'description' => 'helloworld.campaign.event.action.descr',
'batchEventName' => HelloWorldEvents::EXECUTE_CAMPAIGN_ACTION,
'formType' => TravelType::class,
]
);
}
public function onExecuteCampaignAction(PendingEvent $pendingEvent): void
{
$worldToVisit = $pendingEvent->getConfig()->getProperty('worldToVisit');
$pendingEvent->setChannel('world', $worldToVisit);
$contacts = $pendingEvent->getContactsKeyedById();
$emails = [];
foreach ($contacts as $contact) {
if (!$contact->getEmail()) {
// Don't reschedule these events
$pendingEvent->passWithError(
$pendingEvent->findLogByContactId($contact->getId()),
$this->translator->trans('helloworld.validation.email_required', [], 'validators')
);
$emails[] = $contact->getEmail();
}
}
$this->travelService->doSomethingWithThese($emails, $worldToVisit);
$pendingEvent->passRemaining();
}
}
- Mautic\CampaignBundle\Events\PendingEvent
- public checkContext(string $eventType)
Checks if the given Event type matches the Event executed or evaluated. This is useful if listeners for different Campaign Events are listening to the same name defined as
batchEventName
in the Event’s definition.- Returns:
TRUE
if the context matches.- Return type:
bool
- public fail(\Mautic\CampaignBundle\Entity\LeadEventLog $log, string $reason)
Mark a specific LeadEventLog object as failed and retry again later.
- Parameters:
$log (
\Mautic\CampaignBundle\Entity\LeadEventLog
) – Event log to fail.$reason (
string
) – Reason the Event failed.
- Return type:
void
- public failAll(string $reason)
Fail the entire batch of LeadEventLog objects and retry again later.
- Parameters:
$reason (
string
) – Reason the Events failed.
- Return type:
void
- public failLogs(\Doctrine\Common\Collections\ArrayCollection $logs, string $reason)
Fail a collection of LeadEventLog objects and try again later.
- Parameters:
\Doctrine\Common\Collections\ArrayCollection (
string $logs
) – Collection to mark as failed.$reason (
string
) – Reason the Events failed.
- Return type:
void
- public failRemaining(string $reason)
Fail all remaining LeadEventLog objects that are not marked as passed.
- Parameters:
$reason (
string
) – Reason the Events failed.
- Return type:
void
- public findLogByContactId(int $id)
Returns a LeadEventLog object for the given contact ID.
- Parameters:
$id (
int
) –
- Returns:
Event log for the given contact.
- Return type:
\Mautic\CampaignBundle\Entity\LeadEventLog
- public getConfig()
Use the returned
AbstractEventAccessor
object to access properties configured for this Event.- Returns:
Object to fetch the configuration options for the Campaign Event.
- Return type:
\Mautic\CampaignBundle\EventCollector\Accessor\Event\AbstractEventAccessor
- public getContactIds()
- Returns:
Array of Contact IDs for the current batch of LeadEventLog objects to process.
- Return type:
array
- public getContacts()
Returns the Lead objects for all Contacts in the current batch of LeadEventLog objecdts to process.
- Returns:
Collection of Lead objects.
- Return type:
\Doctrine\Common\Collections\ArrayCollection
- public getContactsKeyedById()
Same as
getContacts
except keyed by Contact ID.- Returns:
Collection of Lead objects.
- Return type:
\Doctrine\Common\Collections\ArrayCollection
- public getEvent()
Returns the current Event entity.
- Returns:
Event entity.
- Return type:
\Mautic\CampaignBundle\Entity\Event
- public pass(\Mautic\CampaignBundle\Entity\LeadEventLog $log)
Mark a specific LeadEventLog as successful.
- Parameters:
$log (
\Mautic\CampaignBundle\Entity\LeadEventLog
) – Event log to pass.
- Return type:
void
- public passAll()
Mark all LeadEventLog objects as successful for the current batch.
- Return type:
void
- public passAllWithError(string $reason)
Mark all LeadEventLog objects with an error and they will not be retried later.
- Return type:
void
- public passLogs(\Doctrine\Common\Collections\ArrayCollection $logs)
Mark a collection of LeadEventLog objects as successful.
- Parameters:
\Doctrine\Common\Collections\ArrayCollection (
string $logs
) – Collection to mark as successful.
- Return type:
void
- public passRemaining()
Mark remaining LeadEventLog objects that are not marked as failed.
- Return type:
void
- public passRemainingWithError(string $reason)
Mark remaining LeadEventLog objects that are not already marked as failed.
- Parameters:
$reason (
string
) – The error message.
- Return type:
void
- public passWithError(\Mautic\CampaignBundle\Entity\LeadEventLog $log, string $reason)
Mark a specific LeadEventLog with an error and do not try again.
- Parameters:
$log (
\Mautic\CampaignBundle\Entity\LeadEventLog
) – Event log to pass.$reason (
string
) – The error message.
- Return type:
void
- public setChannel(string $channel[, $channelId = null)
Set the Channel to attribute to the Event.
- Parameters:
$channel (
string
) – Name of the Channel this Event relates to. For example,email
,page
,form
, and so forth.$channelId (
mixed
) – ID of the Channel entity.
- Return type:
void
Evaluating a Campaign Condition
Listeners to the event’s eventName
receives a \Mautic\CampaignBundle\Event\ConditionEvent
object. This object contains the single LeadEventLog object for the Contact to evaluate this condition. The listener must call ConditionEvent::pass()
or ConditionEvent::fail()
after evaluating the condition.
<?php
declare(strict_types=1);
namespace MauticPlugin\HelloWorldBundle\EventListener;
use Mautic\CampaignBundle\CampaignEvents;
use Mautic\CampaignBundle\Event\CampaignBuilderEvent;
use Mautic\CampaignBundle\Event\ConditionEvent;
use MauticPlugin\HelloWorldBundle\HelloWorldEvents;
use MauticPlugin\HelloWorldBundle\Form\Type\TravelType;
use MauticPlugin\HelloWorldBundle\Helper\TravelService;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class CampaignConditionSubscriber implements EventSubscriberInterface
{
public const TYPE = 'helloworld.condition';
private TravelService $travelService;
public function __construct(TravelService $travelService): void
{
$this->travelService = $travelService;
}
public static function getSubscribedEvents(): array
{
return [
CampaignEvents::CAMPAIGN_ON_BUILD => ['onCampaignBuild', 0],
HelloWorldEvents::EVALUATE_CAMPAIGN_CONDITION => ['onEvaluateCampaignCondition', 0],
];
}
public function onCampaignBuild(CampaignBuilderEvent $event): void
{
$event->addCondition(
self::TYPE,
[
'label' => 'helloworld.campaign.event.condition',
'description' => 'helloworld.campaign.event.condition.descr',
'eventName' => HelloWorldEvents::EVALUATE_CAMPAIGN_CONDITION,
'formType' => TravelType::class,
]
);
}
public function onEvaluateCampaignCondition(ConditionEvent $event): void
{
$leadEventLog = $event->getLog();
$contact = $leadEventLog->getLead();
$world = $event->getEventConfig()->getProperty('world');
if ($this->travelService->hasTraveledTo($contact, $world)) {
$event->pass();
} else {
$event->fail();
}
}
}
- Mautic\CampaignBundle\Events\ConditionEvent
- public checkContext(string $eventType)
Checks if the given Event type matches the Event executed or evaluated. This is useful if listeners for different Campaign Events are listening to the same name defined as
eventName
in the Event’s definition.- Returns:
TRUE
if the context matches.- Return type:
bool
- public fail()
Evaluate this Condition as
FALSE
.- Return type:
void
- public getEventConfig()
Use the returned
AbstractEventAccessor
object to access properties configured for this Event.- Returns:
Object to fetch the configuration options for the Campaign Event.
- Return type:
\Mautic\CampaignBundle\EventCollector\Accessor\Event\AbstractEventAccessor
- public getLog()
- Returns:
The
LeadEventLog
object for the Condition.- Return type:
\Mautic\CampaignBundle\Entity\LeadEventLog
- public pass()
Evaluate this Condition as
TRUE
.- Return type:
void
- public setChannel(string $channel[, $channelId = null)
Set the Channel to attribute to the Event.
- Parameters:
$channel (
string
) – Name of the Channel this Event relates to. For example,email
,page
,form
, and so forth.$channelId (
mixed
) – ID of the Channel entity.
- Return type:
void
Evaluating a Campaign Decision
Decisions are when a Contact takes some kind of direct action - where they made a decision to act. The code that handles the logic of the decision also needs to tell the Campaign Engine to evaluate Campaign Decisions of the given type by calling Mautic\CampaignBundle\Executioner\RealTimeExecutioner::execute()
, registered as the the mautic.campaign.executioner.realtime
service.
The Campaign Engine then dispatches the Decision Event’s eventName
where listeners receive a \Mautic\CampaignBundle\Event\DecisionEvent
object. This object contains the single LeadEventLog object for the Contact to evaluate this decision. The listener must call DecisionEvent::setAsApplicable()
to instruct the Campaign Engine to execute or schedule Events attached to the “action” (left) path of the decision.
<?php
declare(strict_types=1);
namespace MauticPlugin\HelloWorldBundle\EventListener;
use Mautic\CampaignBundle\CampaignEvents;
use Mautic\CampaignBundle\Event\CampaignBuilderEvent;
use Mautic\CampaignBundle\Event\DecisionEvent;
use Mautic\CampaignBundle\Executioner\RealTimeExecutioner;
use MauticPlugin\HelloWorldBundle\HelloWorldEvents;
use MauticPlugin\HelloWorldBundle\Event\TravelDocumentEvent;
use MauticPlugin\HelloWorldBundle\Form\Type\TravelType;
use MauticPlugin\HelloWorldBundle\Helper\TravelService;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class CampaignDecisionSubscriber implements EventSubscriberInterface
{
public const TYPE = 'helloworld.decision';
private TravelService $travelService;
private RealTimeExecutioner $realTimeExecutioner;
public function __construct(TravelService $travelService, RealTimeExecutioner $realTimeExecutioner)
{
$this->travelService = $travelService;
$this->realTimeExecutioner = $realTimeExecutioner;
}
public static function getSubscribedEvents()
{
return [
CampaignEvents::CAMPAIGN_ON_BUILD => ['onCampaignBuild', 0],
HelloWorldEvents::EVALUATE_CAMPAIGN_DECISION => ['onEvaluateCampaignDecision', 0],
HelloWorldEvents::CONTACT_TRAVEL_DOCUMENTS_CREATED => ['onContactTravelDocumentsCreated', 0],
];
}
public function onCampaignBuild(CampaignBuilderEvent $event)
{
$event->addDecision(
self::TYPE,
[
'label' => 'helloworld.campaign.event.Decision',
'description' => 'helloworld.campaign.event.Decision.descr',
'eventName' => HelloWorldEvents::EVALUATE_CAMPAIGN_DECISION,
'formType' => TravelType::class,
]
);
}
public function onContactTravelDocumentsCreated(TravelDocumentEvent $event)
{
$this->realTimeExecutioner->execute(self::TYPE, $event, 'world', $event->getWorldId());
}
public function onEvaluateCampaignDecision(DecisionEvent $event)
{
$applicableWorld = $event->getEventConfig()->getProperty('world');
$travelDocumentEvent = $event->getPassthrough();
if ($applicableWorld !== $travelDocumentEvent->getWorldId()) {
return;
}
$event->setAsApplicable();
$event->setChannel('world', $travelDocumentEvent->getWorldId());
}
}
- Mautic\CampaignBundle\Events\DecisionEvent
- public checkContext(string $eventType)
Checks if the given Event type matches the Event executed or evaluated. This is useful if listeners for different Campaign Events are listening to the same name defined as
eventName
in the Event’s definition.- Returns:
TRUE
if the context matches.- Return type:
bool
- public getEventConfig()
Use the returned
AbstractEventAccessor
object to access properties configured for this Event.- Returns:
Object to fetch the configuration options for the Campaign Event.
- Return type:
\Mautic\CampaignBundle\EventCollector\Accessor\Event\AbstractEventAccessor
- public getLog()
- Returns:
The
LeadEventLog
object for the Condition.- Return type:
\Mautic\CampaignBundle\Entity\LeadEventLog
- public getPassthrough()
Access context data set by
RealTimeExecutioner::execute()
.- Returns:
Returns whatever was set as the second argument to
RealTimeExecutioner::execute()
.- Return type:
mixed
- public setAsApplicable()
Call this if the Decision is applicable to the action taken by the Contact which instructs the Campaign Engine to execute or schedule Events connected into this Decision’s “action” (left) path.
- Return type:
void
- public setChannel(string $channel[, $channelId = null)
Set the Channel to attribute to the Event.
- Parameters:
$channel (
string
) – Name of the Channel this Event relates to. For example,email
,page
,form
, and so forth.$channelId (
mixed
) – ID of the Channel entity.
- Return type:
void