Workflow Engine Built For Developers

Deliver world-class business processes as if you were hundreds of developers.

Gain Superpowers

Whatever the size of your technical team, Zenaton empowers you to deliver world-class processes.

x5 your speed to deliver new workflows

Implement sophisticated business processes, long-running marketing scenarios or data pipelines in a fraction of the time it usually takes.

Improve your team's productivity

Simplify the process of implementing workflows. When using Zenaton, there is no need to store transient states, write database requests or run cron jobs.

Build a more agile company

Easily iterate or A/B test your business processes. Test if adding a moderation process will impact your KPIs or A/B test whether its more efficient to wait 2 vs 3 days for a valiation.

Ensure your processes documentation is up-to-date

The business logic is easy to read in the code - and it is always up to date and accurate. There is no need to maintain separate documentation.

Improve your code readability

Zenaton allows you to separate tasks and workflows. The code describing your processes is well defined and easy to read for everyone on the team.

Improve communication within your teams

Zenaton dashboards allow all of your teams including tech, product, support and marketing - to easily see how your processes are performing.

Workflow as code

Zenaton provides a new revolutionary way to orchestrate distributedexecutions to build business processes as easily as you describe them.Just define the sequence of tasks as simply as if everything were local. Zenaton abstracts all the complexity from you.

<?php

use Zenaton\Interfaces\WorkflowInterface;
use Zenaton\Traits\Zenatonable;

class SequentialWorkflow implements WorkflowInterface
{
    use Zenatonable;

    public function handle()
    {
        $a = (new TaskA)->execute();

        if (0 < $a) {
            (new TaskB)->execute();
        } else {
            (new TaskC)->execute();
        }

        (new TaskD)->execute();
    }
}
<?php

use Zenaton\Interfaces\WorkflowInterface;
use Zenaton\Traits\Zenatonable;
use Zenaton\Parallel\Parallel;

class ParallelWorkflow implements WorkflowInterface
{
    use Zenatonable;

    public function handle()
    {
        [$a, $b] = (new Parallel(
            new TaskA,
            new TaskB
        ))->execute();

        if ($a > $b) {
            (new TaskC)->execute();
        } else {
            (new TaskD)->execute();
        }
    }
}
<?php

use Zenaton\Interfaces\WorkflowInterface;
use Zenaton\Traits\Zenatonable;

class AsynchronousWorkflow implements WorkflowInterface
{
    use Zenatonable;

    public function handle()
    {
        (new TaskA)->dispatch();
        (new TaskB)->dispatch();
        (new TaskC)->execute();
        (new TaskD)->execute();
    }
}

Time-based and Event-based orchestration

Zenaton is especially powerful when used to orchestrate workflows with triggersbased on time and external events.

TIME
<?php

use Zenaton\Interfaces\WorkflowInterface;
use Zenaton\Traits\Zenatonable;

class SequentialWorkflow implements WorkflowInterface
{
    use Zenatonable;

    public function handle()
    {
        $a = (new TaskA)->execute();

        if (0 < $a) {
            (new TaskB)->execute();
        } else {
            (new TaskC)->execute();
        }

        (new TaskD)->execute();
    }
}
WAIT 5S
<?php

use Zenaton\Interfaces\WorkflowInterface;
use Zenaton\Tasks\Wait;
use Zenaton\Traits\Zenatonable;

class WaitWorkflow implements WorkflowInterface
{
    use Zenatonable;

    public function handle()
    {
        (new TaskA())->execute();

        (new Wait())->seconds(5)->execute();

        (new TaskB())->execute();
    }
}
TIME
<?php

use Zenaton\Interfaces\WorkflowInterface;
use Zenaton\Tasks\Wait;
use Zenaton\Traits\Zenatonable;

class WaitEventWorkflow implements WorkflowInterface
{
    use Zenatonable;

    protected $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

    public function handle()
    {
        $event = (new Wait(MyEvent::class))->seconds(4)->execute();

        if ($event) {
            (new TaskA)->execute();
        } else {
            (new TaskB)->execute();
        }
    }

    public function getId()
    {
        return $this->id;
    }
}

Using code versatility

Building workflows in code lets you use the native versatility of yourpreferred programming language. Use and combine controlstructure (if, else, for each, while, ...) as well as whatever data structureand functions (map, filter, array...).

Moderation Workflow

This is typical of a moderation workflow where an external moderator should moderate an item:

  • an article is sent to a moderator
  • then we wait for the moderator's response
  • after 24h without response, we send a 1st reminder
  • after 24h without response, we send a 2nd reminder
  • after 24h without response, we send a 3rd reminder
  • if we don't have an answer or if the response is negative, we send a rejection notification

<?php

use Zenaton\Interfaces\WorkflowInterface;
use Zenaton\Traits\Zenatonable;
use Zenaton\Tasks\Wait;

class ModerationWorkflow implements WorkflowInterface
{
    use Zenatonable;

    public function __construct($article)
    {
        $this->article = $article;
    }

    public function handle()
    {
        $count = 0;
        do {
            (new SendArticleToModerator($this->article, $count))->execute();

            $event = (new Wait('ModerationEvent'))->hours(24)->execute();

            $count++;
        } while (! $event && $count < 4)

        if (! $event || ! $event->validated) {
            (new SendRejectionNotification($this->article))->execute();
        }
    }

    public function getId()
    {
        return $this->article->id;
    }
}

Welcome Process

This workflow illustrates how easy is to send a sequence of emails for new users:

  • A 1st email is sent to the user
  • Then we wait for 24h
  • A 2nd email is sent to the user
  • Then we wait for 36h
  • A 3rd email is sent to the user
  • Then we wait for 48h
  • A 4th email is sent to the user

<?php

use Zenaton\Interfaces\WorkflowInterface;
use Zenaton\Traits\Zenatonable;
use Zenaton\Tasks\Wait;

class WelcomeWorkflow implements WorkflowInterface
{
    use Zenatonable;

    public function __construct($user)
    {
        $this->user = $user;
    }

    public function handle()
    {
        (new SendWelcomeEmail1($this->user))->execute();

        (new Wait())->hours(24)->execute();

        (new SendWelcomeEmail2($this->user))->execute();

        (new Wait())->hours(36)->execute();

        (new SendWelcomeEmail3($this->user))->execute();

        (new Wait())->hours(48)->execute();

        (new SendWelcomeEmail4($this->user))->execute();
    }

    public function getId()
    {
        return $this->user->id;
    }
}

Shopping Cart Abandonment Workflow

Reducing shopping cart abandonment is an easy way to improve your conversion rate in ecommerce.

With Zenaton, a few lines of code is all you need. Note: a 'ShoppingCartEvent' is sent to this workflow each time something is added to the shopping cart. If the shopping cart is not purchased, an email is sent after 20 minutes of inactivity.

<?php

use Zenaton\Interfaces\WorkflowInterface;
use Zenaton\Traits\Zenatonable;
use Zenaton\Tasks\Wait;

class AbandonedShoppingCartWorkflow implements WorkflowInterface
{
    use Zenatonable;

    public function __construct($shoppingCart)
    {
        $this->shoppingCart = $shoppingCart;
    }

    public function handle()
    {
        do {
            $event = (new Wait('ShoppingCartEvent'))->minutes(20)->execute();
        } while ($event && $event->type !== 'purchased')

        if (! $event) {
            (new SendAbandonedShoppingCartEmail($this->shoppingCart))->execute();
        }
    }

    public function getId()
    {
        return $this->shoppingCart->id;
    }
}

Want to give it a try?

Start delivering new features and new processes faster