Para desenvolvedores

Construa plugins. Não workarounds.

O AcelleMail é uma plataforma de email marketing em Laravel 11+ que vem com código-fonte PHP completo e não criptografado — e um sistema de Hooks tipado que permite que seus plugins adicionem drivers de envio, gateways de pagamento, IA, UI customizada e até REST APIs. Sem dar fork no core.

Hello World em 5 min ↓

Plugins reais sendo entregues hoje

acelle/ai athena/evs rencontru/postal acelle/console
myvendor/loyalty/ PLUGIN SOURCE composer.json 240 B routes.php 1.2 KB src/ ServiceProvider.php entry Controllers/ Models/ database/migrations/ resources/ views/ lang/ index.json auto $ php artisan plugin:init … HOOK SYSTEM no core touches ACELLEMAIL Laravel 11+ · PHP 8.3+ layout.head.assets layout.body.close admin.sidebar.groups register_sending_* page.{ctrl}.{slot} customer_added sidebar-menu-items dispatch_*_job + many more…

Por que desenvolvedores escolhem o AcelleMail

Construído no framework que você já conhece.
Estendido pelos padrões que você já usa.

PHP / Laravel com código-fonte completo

Código-fonte PHP completo e não criptografado vem com cada licença. Modifique qualquer classe, sobrescreva qualquer serviço, dê fork no seu próprio namespace — seu código, suas regras. Construído sobre Laravel 11+ para que o framework que você já conhece faça o trabalho pesado.

$ grep -r "protected function" vendor/acelle/

Arquitetura de plugins

Coloque uma pasta no formato Composer em storage/app/plugins/<vendor>/<name>/ e o app carrega automaticamente. O ServiceProvider injeta rotas, views, migrations, hooks — ative, desative, exclua de forma limpa.

$ php artisan plugin:init myvendor/loyalty

REST API autenticada por token

Endpoints CRUD para campanhas, listas, assinantes, modelos, automações. Eventos webhook para cada acontecimento de domínio. Drop-in para frontends SaaS, apps mobile ou outros serviços Laravel. A mesma API que os plugins usam é a mesma que clientes externos usam — sem endpoints de segunda classe.

GET /api/v1/campaigns · POST /api/v1/lists

Auto-hospedado na sua infra

Seu servidor, seu banco, seus dados de assinante. Sem vendor lock-in. Pague uma vez pela licença; pague só o custo SMTP subjacente (ex. Amazon SES a $0.10/1K). Deploy onde PHP rodar — bare metal, Kubernetes, Forge, Laravel Vapor. Escale como sua stack escala.

· PHP 8.3+ · MySQL / MariaDB · Redis (optional)

O que você pode construir com plugins

14 superfícies de extensão.
Cada uma com um exemplo real em produção hoje.

Um plugin é um pacote Laravel autocontido que vive em disco, tem seu próprio namespace, suas próprias tabelas de banco, rotas, views, controllers, models — e se integra com o core via um sistema de Hooks tipado em vez de hacks com include.

Drivers e integrações · 4

Servidores / drivers de envio REGISTRY
register_sending_server_driver
rencontru/postal — driver Postal MTA como plugin único drop-in
Verificação de email / entregabilidade REGISTRY
REGISTRY + FILTER
athena/evs — subsistema de verificação com UI admin
Gateways de pagamento REGISTRY
REGISTRY
Stripe / PayPal / Braintree / Paystack / Razorpay / Coinbase embutidos mostram o padrão
IA / chatbot / assistentes REGISTRY
REGISTRY + EVENT
acelle/ai — chatbox + sparkle + observabilidade

UI e páginas · 5

Injeção de UI personalizada REGISTRY
layout.head.assets / layout.body.before_close / admin.sidebar.groups
Chatbox + popover sparkle do acelle/ai
Slots de conteúdo em nível de página REGISTRY
page.{ctrl}.{action}.{slot}
page.maillist.show.body, page.campaign.index.sidebar
Páginas admin ROUTE
Laravel routes
/rui/admin/ai-usage, /rui/admin/ai-audit, /rui/admin/ai-conversations
Páginas voltadas ao cliente ROUTE
Laravel routes
/plugins/acelle/ai/dashboard
REST APIs ROUTE
Routes + api.access_token
/api/v1/ai/* em acelle/ai

Dados e ciclo de vida · 2

Models Eloquent customizados + tabelas de banco BEHAVIOR
Plugin-isolated migrations
acelle/ai entrega 8 models / 12 migrations, nomes de tabela com prefixo do vendor
Traduções (18 locales) REGISTRY
add_translation_file
acelle/ai entrega 162 arquivos de lang (18 × 9)

Comportamento e fluxo · 3

Listeners de webhook / eventos de domínio EVENT
Hook::on(…)
customer_added, plan_changed, subscription_terminated
Overrides de comportamento BEHAVIOR
Hook::set / setIfEmpty / perform
dispatch_list_import_job — substitui a lógica de import por completo
Filter chains FILTER
Hook::modify / filter
sidebar-menu-items, mutação de conteúdo pré-envio, URLs de redirecionamento

Um único plugin pode combinar qualquer uma dessas superfícies — o acelle/ai usa 7 das 14 em um único pacote.

O sistema de Hooks

Quatro padrões de extensão tipados. Sem overrides-surpresa. Sem conflitos silenciosos.

O core nunca importa código de plugin — só declara pontos de extensão. Os plugins escutam e reagem. Quatro padrões, cada um com um papel claro. Conflitos lançam exceção imediatamente.

1

REGISTRY add() + collect()

O plugin contribui itens para uma lista. O core pergunta "quem tem um driver de envio?" e seu plugin diz "eu tenho um."


Hook::add('register_sending_server_driver', fn () => [
    'type'   => 'myvendor-foo',
    'driver' => \MyVendor\Foo\Driver::class,
]);


$drivers = Hook::collect('register_sending_server_driver');
2

EVENT on() + fire()

O plugin reage a algo acontecendo. Valores de retorno são descartados.


Hook::on('customer_added', function ($customer) {
    LoyaltyPoints::award($customer, 100, 'welcome');
});


Hook::fire('customer_added', [$customer]);
3

BEHAVIOR set() + perform()

O plugin substitui um pedaço da lógica do core por completo. Apenas um plugin pode reivindicar um dado comportamento — conflitos lançam exceção imediatamente.


Hook::set('dispatch_list_import_job',
    fn ($list, $f) => new MyFasterImportJob($list, $f));


Hook::setIfEmpty('dispatch_list_import_job',
    fn ($list, $f) => new DefaultImportJob($list, $f));
$job = Hook::perform('dispatch_list_import_job', [$list, $f]);
dispatch($job);
4

FILTER modify() + filter()

O plugin transforma um valor através de uma cadeia de callbacks. Cada callback recebe o valor atual e retorna o valor modificado.


Hook::modify('sidebar-menu-items', function (array $items) {
    $items[] = [
        'label' => 'Loyalty',
        'url'   => route('lp.dashboard'),
    ];
    return $items;
});


$menu = Hook::filter('sidebar-menu-items', $defaultMenu);

Hello World em 5 minutos

Um plugin funcional do zero em oito comandos.

O scaffold cria tudo — metadata do Composer, ServiceProvider, model de exemplo, migration de exemplo, rota de exemplo, view de exemplo. A partir daí é seu para crescer.

  1. 1

    Faça o scaffold do plugin

    Cria o layout padrão de pastas + uma linha inativa no banco.

    bash
    $ php artisan plugin:init myvendor/loyalty
      ✓ Created storage/app/plugins/myvendor/loyalty/
      ✓ DB row inserted  (status: inactive)
      ✓ index.json + ServiceProvider autoloaded
  2. 2

    Edite o composer.json

    Avise o Composer sobre seu namespace e o ServiceProvider.

    json
    {
      "name": "myvendor/loyalty",
      "description": "Award points on signup",
      "version": "1.0.0",
      "autoload":  { "psr-4": { "MyVendor\\Loyalty\\": "src/" } },
      "extra":     { "laravel": { "providers": [
        "MyVendor\\Loyalty\\ServiceProvider"
      ] } }
    }
  3. 3

    Escreva uma migration

    Tabela isolada do plugin, nome com prefixo do vendor. Roda no activate, faz rollback no delete.

    php
    Schema::create('myvendor_loyalty_accounts', function (Blueprint $t) {
        $t->id();
        $t->foreignId('customer_id')->constrained()->cascadeOnDelete();
        $t->integer('points')->default(0);
        $t->timestamps();
    });
  4. 4

    Defina um model

    Model Eloquent padrão no seu próprio namespace.

    php
    namespace MyVendor\Loyalty\Models;
    
    use Illuminate\Database\Eloquent\Model;
    
    class Account extends Model
    {
        protected $table    = 'myvendor_loyalty_accounts';
        protected $fillable = ['customer_id', 'points'];
    }
  5. 5

    Adicione um controller e uma view

    Controller Laravel puro — o namespace da view é o nome do seu plugin.

    php
    namespace MyVendor\Loyalty\Controllers;
    
    use Acelle\Http\Controllers\Controller;
    
    class DashboardController extends Controller
    {
        public function index()
        {
            return view('loyalty::dashboard', [
                'accounts' => \MyVendor\Loyalty\Models\Account::orderByDesc('points')->take(10)->get(),
            ]);
        }
    }
  6. 6

    Declare as rotas

    Mesmo Route::group que você já usa. Carregado pelo ServiceProvider::boot().

    php
    Route::group([
        'middleware' => ['web', 'auth'],
        'namespace'  => '\MyVendor\Loyalty\Controllers',
        'prefix'     => 'plugins/myvendor/loyalty',
    ], function () {
        Route::get('/',          'DashboardController@index')->name('lp.dashboard');
        Route::get('/{account}', 'DashboardController@show');
    });
  7. 7

    Ligue tudo no ServiceProvider::boot()

    Carregue views + rotas; conecte ao activate_plugin_… para migrar no activate.

    php
    public function boot(): void
    {
        $this->loadViewsFrom (__DIR__.'/../resources/views', 'loyalty');
        $this->loadRoutesFrom(__DIR__.'/../routes.php');
    
        Hook::on('activate_plugin_myvendor/loyalty', fn () =>
            \Artisan::call('migrate', [
                '--path'  => 'storage/app/plugins/myvendor/loyalty/database/migrations',
                '--force' => true,
            ])
        );
    
        Hook::on('customer_added', fn ($customer) =>
            Models\Account::create(['customer_id' => $customer->id, 'points' => 100])
        );
    }
  8. 8

    Ative pelo admin

    Vá em /rui/admin/plugins. As migrations rodam automaticamente. O plugin vive no seu prefixo.

    bash
    ✓ activated  myvendor/loyalty  v1.0.0
      → migrations: 1 ran (myvendor_loyalty_accounts)
      → routes:     2 registered under /plugins/myvendor/loyalty
      → hooks:      2 listening (activate, customer_added)
      → status:     active
    
    → visit /plugins/myvendor/loyalty/  ← live

Agora você tem um plugin funcional. Adicione quantos models, controllers e hooks o seu recurso pedir. Os testes ficam em tests/; rode com php artisan test --testsuite='Plugin: myvendor/loyalty'. Veja o contrato canônico na base de conhecimento.

Ciclo de vida do plugin

Quatro estados. Transições previsíveis. Sem o mistério "isso rodou?".

Cada plugin vive em exatamente um de quatro estados. O estado em que você está dita quais hooks disparam, quais migrations rodaram e o que acontece na próxima transição. Ancorado no código-fonte contra docs/plugin/SOURCE_OF_TRUTH.md.

STATE 01 register (inativo) Pasta do plugin descoberta. index.json + linha no banco existem. Hooks NÃO disparando. STATE 02 active Todos os hooks vivos. Rotas montadas. Migrations rodaram. activate_plugin_… disparou uma vez. STATE 03 inactive (pausado) Pasta ainda em disco. Hooks pausados. Rotas desmontadas. Tabelas do banco intactas. STATE 04 deleted (sumiu) Pasta removida. Migrations sofrem rollback se $keepData = false. Linha do banco removida. activate migrations rodam deactivate dados mantidos remove $keepData? re-activate hook activate NÃO roda de novo
Register · inativo

Descoberto, não rodando

Pasta do plugin existe, index.json indexado, linha do banco diz inactive. O register() do ServiceProvider rodou, mas os hooks do boot() ficam fechados até você clicar em Ativar.

Active

Vivo, hooks disparando

A primeira ativação dispara activate_plugin_<name> uma vez — é onde as migrations rodam. Depois disso todos os hooks REGISTRY / EVENT / FILTER / BEHAVIOR ficam vivos até a desativação.

Inactive · pausado

Pausado, dados intactos

Rotas desmontam, hooks fecham, mas a pasta + tabelas do banco ficam. Re-ativar não roda migrations de novo nem o hook activate — seguro para alternar em produção.

Deleted

Removido limpo

Pasta removida, linha do banco sumiu. Se $keepData = false, as migrations do plugin sofrem rollback — tabelas com prefixo do vendor são dropadas. Tabelas do core nunca são tocadas.

Vitrine de plugin real

acelle/ai — um subsistema completo de IA em uma única pasta de plugin.

O plugin acelle/ai entrega uma camada completa de assistente de IA: chatbox agente em cada página, reescrita de texto ✨ sparkle em campos rich-text, personas coach ancoradas na KB (Entregabilidade, Segmentos, Campanhas, Formulários) e uma superfície de observabilidade do admin em 5 rotas. Monta via 3 hooks de layout. Zero mudanças no core.

plugin acelle/ai em ação — bolha de chatbox flutuante do AcelleMail AI com o popover ✨ sparkle para reescrita em um clique, além do grupo da barra lateral admin do plugin renderizado dentro da UI do AcelleMail

O que ele entrega

  • Chatbox flutuante — modo suporte puro + modo agente opt-in que chama ferramentas
  • Popover sparkle — reescrita / expansão / simplificação em um clique em cada campo rich-text
  • Personas coach — ajudantes LLM especializados em domínio, com escopo por tela
  • Observabilidade do admin — uso, auditoria, conversas, feedback, auto-melhoria
  • Flexibilidade de motor — BYO OpenAI, Anthropic ou Ollama local
  • Página landing do plugin em /plugins/acelle/ai/dashboard

Pelos números

8
Models Eloquent
12
Migrations
60+
Templates blade
100+
Testes Pest
18 × 9
Locales × arquivos de lang
~35
Arquivos CSS + JS

Como ele monta — 3 hooks

acelle/ai plugin → CSS / JS assets Hook::add( 'layout.head.assets', fn()=>...); → Chatbox bubble Hook::add( 'layout.body.before_close' ,fn()=>...); → AI sidebar group Hook::add( 'admin.sidebar.groups', fn()=>...); Self-contained. AcelleMail core <head> + acelle-ai-chatbox.css </body> (just before) + <div class="ai-chatbox"> Admin sidebar AI · Settings AI · Usage AI · Conversations

3 hooks REGISTRY de layout — só isso. Mais injeções por página, listeners de eventos do ciclo de vida e uma REST API customizada com namespace em /api/v1/ai/*. Zero mudanças no core; a pasta do plugin é drop-in para deploy.

REST API

Endpoints autenticados por token. A mesma API que os plugins usam.

Use a REST API para integrar o AcelleMail no seu próprio frontend SaaS, app mobile ou serviço Laravel. A mesma API que os plugins usam é a mesma que clientes externos usam — sem endpoints de segunda classe.

Recursos

  • ListasGET/POST/PATCH/DELETE /api/v1/lists[/:uid]
  • Assinantes/api/v1/subscribers · tags · sub/unsub
  • Campanhas/api/v1/campaigns[/:uid] · run/pause/resume · log CSVs
  • Automações/api/v1/automations[/:uid] · execute · api/call
  • Servidores de envio/api/v1/sending_servers[/:uid]
  • Customers (admin)/api/v1/customers[/:uid] · assign/change-plan · enable/disable
  • Assinaturas (admin)/api/v1/subscriptions[/:uid]

Eventos webhook

Ciclo de vida (configurado em Admin → Webhooks): new_customer, new_subscription, change_plan, cancel_subscription, terminate_subscription, automation_webhook.
Tracking por destinatário (por campanha): open, click, unsubscribe.

Referência completa da API →
# Create a list
$ curl -X POST \
    https://your-acelle.example.com/api/v1/lists \
    -H "Authorization: Bearer $ACELLE_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "name": "Newsletter",
      "from_email": "hi@example.com",
      "from_name": "Hi Team",
      "subject": "Weekly digest"
    }'

# Add a subscriber
$ curl -X POST \
    .../api/v1/lists/:uid/subscribers \
    -H "Authorization: Bearer $ACELLE_TOKEN" \
    -d '{"EMAIL":"alice@example.com"}'

# Send a campaign
$ curl -X POST \
    .../api/v1/campaigns/:uid/send \
    -H "Authorization: Bearer $ACELLE_TOKEN"

# Receive a webhook
POST /your-webhook-endpoint
{
  "event": "campaign.sent",
  "campaign_uid": "abc123",
  "list_uid": "xyz789",
  "sent_at": "2026-05-06T12:34:56Z"
}

Ethos open-source

Seu código, para sempre. Sem caixas-pretas, sem mensalidades, sem ocupação de namespace.

Código-fonte não criptografado

Cada linha de PHP que roda no seu servidor. Sem ionCube, sem SourceGuardian, sem ofuscação. Faça git diff das suas customizações. Use grep para achar qualquer coisa.

Atualizações vitalícias

Toda release do AcelleMail desde 2016 está no seu histórico de downloads do CodeCanyon. Pegue o que quiser quando quiser. Sem pressão de assinatura.

Seu namespace, para sempre

Plugins vivem em MyVendor\MyPlugin\ — completamente isolados do core Acelle\*. Distribuíveis via Composer para sua equipe ou marketplace.

Licença única

Pague $80 (Regular) ou $199 (Extended para SaaS). Sem assinaturas, sem cobrança por assinante, sem cobrança por email. A matemática não muda enquanto você cresce.

Recursos e comunidade

Documentação, plugins de exemplo e linha direta com o suporte.

Documentação completa para desenvolvedores

Onze deep-dives ancorados no código-fonte. Vá direto para a página que você precisa:

Navegar pelo hub →

Guia de desenvolvimento de plugin

Cinco arquivos do lado do host, o fluxo de boot-and-load, os quatro estados do ciclo de vida, as duas camadas de injeção — o modelo mental que o resto da documentação assume.

/developers/plugin-architecture →

Referência da REST API

Autenticação, catálogo de endpoints, payloads de webhook, formatos de erro — página landing nativa com exemplos.

/api →

O sistema de Hooks — quatro padrões

REGISTRY / EVENT / BEHAVIOR / FILTER — as quatro formas de extensão que os plugins usam, com call-sites reais extraídos do core via grep, semântica de conflito e seis anti-padrões.

/developers/hook-system →

Drivers de envio — padrão de plugin completo

Entregue um backend MTA totalmente novo sem dar fork no core. O contrato register_sending_server_driver, nove marcadores de capacidade e cinco armadilhas do plugin Postal.

/developers/sending-drivers →

Vitrine de plugin — acelle/ai

O plugin complexo canônico percorrido de ponta a ponta. Oito models, quatorze migrations, dezoito locales, cada superfície de hook, a UI do chatbox, mais uma receita de aprendizado em quatro passos.

/developers/showcase →

Suporte para desenvolvedores

Travou em um contrato de hook ou em uma pergunta de ciclo de vida do plugin? Mande email para a gente — resposta típica em até 24h.

support@acellemail.com →
Índice da documentação · CAT

Navegar pelos 11 deep-dives →

Fundamentos, Construção, Qualidade, Referência — cada página em um só lugar, ancorada no código-fonte contra storage/app/plugins/acelle/ai/ e a documentação canônica do plugin.

/developers →

FAQ para desenvolvedores

As perguntas que desenvolvedores realmente fazem antes de comprar.

Posso modificar o código-fonte do core sem perder atualizações? +

Sim, mas o padrão mais limpo é um plugin. Plugins vivem fora do namespace do core e sobrevivem a cada upgrade automaticamente. Edições diretas no core funcionam, mas exigem mesclar manualmente as mudanças upstream a cada release. O sistema de plugins existe exatamente para evitar esse trabalho repetitivo.

Os plugins sobrevivem aos upgrades do AcelleMail? +

Sim, por design. O core declara pontos de hook; os plugins reagem. Enquanto o nome e a assinatura do hook permanecerem estáveis (e nós marcamos com versão as mudanças quebradoras), seu plugin continua funcionando. Testamos o plugin de IA (acelle/ai) a cada release.

Posso vender plugins comercialmente? +

Sim. A licença Extended permite distribuir seus próprios plugins sob a sua própria licença. Plugins vivem em seu próprio namespace; você é dono desse código 100%. Vários times rodam marketplaces privados para seus ecossistemas internos de plugins.

Como o sistema de plugins lida com conflitos? +

Hooks REGISTRY mesclam (cada plugin contribui); hooks EVENT todos disparam (sem conflito possível); cadeias FILTER acumulam; BEHAVIOR é o único padrão "exclusivo" — se dois plugins tentam reivindicar o mesmo comportamento, uma exceção é lançada imediatamente. Sem surpresas silenciosas de override.

Os plugins conseguem conversar entre si? +

Sim, pelo mesmo sistema de Hooks. O Plugin A pode disparar eventos que o Plugin B escuta. Ou expor uma classe pública — MyVendor\PluginA\Service é uma classe PHP comum, importável como qualquer outra. O plugin acelle/ai expõe hooks para outros plugins registrarem ferramentas de IA customizadas.

Qual a diferença entre Regular e Extended para um desenvolvedor? +

Regular ($80) cobre seu próprio uso em um único domínio. Extended ($199) adiciona o direito de cobrar usuários finais (revender como SaaS), distribuir clones em marca branca e vender seus próprios plugins. Ambas entregam o mesmo código-fonte.

As migrations do plugin tocam o banco principal? +

Elas escrevem no mesmo banco, mas em tabelas com prefixo do nome do seu vendor (ex. myvendor_loyalty_accounts). Migrations rodam no activate, fazem rollback no delete do plugin com $keepData = false. Zero risco para as tabelas do core.

Posso escrever plugins em algo que não seja PHP? +

O runtime do plugin é PHP/Laravel. Mas seu plugin pode acionar qualquer coisa por shell — serviços Node, ML em Python, binários Go, APIs HTTP externas. Vários times entregam plugins que envelopam ferramentas externas. O plugin é a casca de integração; o trabalho pesado pode viver em qualquer lugar.

Como os plugins interagem com o subsistema de IA? +

O acelle/ai expõe hooks que outros plugins podem usar para registrar ferramentas de IA customizadas, trocar motores ou se conectar à camada de observabilidade. Leia o código-fonte do plugin de IA para o contrato. Seu plugin também pode disparar eventos que o agente de IA pega como contexto.

Existe um marketplace de plugins? +

Ainda não. Hoje os plugins se distribuem via venda direta, GitHub ou seu registry privado. Um marketplace da comunidade está no roadmap quando houver plugins de terceiros suficientes para que faça sentido.

Lance seu primeiro plugin nesta tarde.

Código-fonte PHP completo. Atualizações vitalícias. O sistema de Hooks. Exemplos reais de produção para copiar. Pagamento único de $199 pela licença Extended (redistribuição comercial de plugins + uso SaaS).

Testar demo ao vivo