lindemannrock/craft-campaign-manager

Campaign management with SMS, email, and WhatsApp invitations

Installs: 7

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 0

Forks: 0

Open Issues: 0

Type:craft-plugin

pkg:composer/lindemannrock/craft-campaign-manager

5.3.0 2026-01-29 05:27 UTC

This package is auto-updated.

Last update: 2026-01-29 05:27:50 UTC


README

Latest Version Craft CMS PHP Formie License

Campaign management for surveys with SMS and email invitations for Craft CMS 5.x.

Beta Notice

This plugin is currently in active development and provided under the MIT License for testing purposes.

Licensing is subject to change. We are finalizing our licensing structure and some or all features may require a paid license when officially released on the Craft Plugin Store.

Features

  • Campaign Management: Create and manage survey campaigns linked to Formie forms
    • Multi-site support with site-specific recipients
    • Campaign types for organization
    • Configurable invitation delay and expiry periods
  • Recipient Management:
    • Import recipients from CSV files
    • Add individual recipients manually
    • Track invitation status (sent, opened, submitted)
    • Unique invitation codes per recipient
    • Export recipients to CSV/JSON/Excel
  • Multi-Channel Invitations:
    • SMS invitations via SMS Manager
    • Email invitations with customizable templates
    • Bitly URL shortening for SMS links
  • Queue-Based Processing:
    • Batch processing for large recipient lists
    • Background job execution
    • Progress tracking
  • Analytics Dashboard:
    • Overview stats (recipients, invitations, opens, submissions)
    • Daily activity charts
    • Channel distribution (Email/SMS/Both)
    • Engagement tracking over time
    • Conversion funnel visualization
    • Campaign performance comparison
    • Export analytics to CSV/JSON/Excel
    • Filter by campaign, site, and date range
  • Survey Response Tracking:
    • Link Formie submissions to recipients
    • Track survey completion rates
    • Invitation expiry handling
    • View responses directly in campaign edit page
  • User Permissions: Granular access control for campaigns, recipients, analytics, and settings
  • Logging: Structured logging via Logging Library with configurable levels

Requirements

  • Craft CMS 5.0 or greater
  • PHP 8.2 or greater
  • Formie 3.0 or greater
  • SMS Manager 5.0 or greater (for SMS invitations)
  • Logging Library 5.0 or greater (installed automatically)
  • Plugin Base 5.0 or greater (installed automatically)

Installation

Via Composer (Development)

Until published on Packagist, install directly from the repository:

cd /path/to/project
composer config repositories.campaign-manager vcs https://github.com/LindemannRock/craft-campaign-manager
composer require lindemannrock/craft-campaign-manager:dev-main
./craft plugin/install campaign-manager

Via Composer (Production - Coming Soon)

Once published on Packagist:

cd /path/to/project
composer require lindemannrock/craft-campaign-manager
./craft plugin/install campaign-manager

Via Plugin Store (Future)

  1. Go to the Plugin Store in your Craft control panel
  2. Search for "Campaign Manager"
  3. Click "Install"

Configuration

Settings

Navigate to Campaign Manager → Settings in the control panel to configure:

General Settings:

  • Plugin Name: Customize the display name in the control panel
  • Campaign Section Handle: The section handle where campaigns are stored

Bitly Settings:

  • Bitly API Key: API key for URL shortening (environment variable recommended)

Logging Settings:

  • Log Level: debug, info, warning, error

Environment Variables

# .env
BITLY_API_KEY=your-bitly-api-key

Config File

Create a config/campaign-manager.php file to override default settings:

<?php
return [
    // Plugin Settings
    'pluginName' => 'Campaign Manager',
    'campaignSectionHandle' => 'campaigns',

    // Logging Settings
    'logLevel' => 'error',

    // Multi-environment support
    'dev' => [
        'logLevel' => 'debug',
    ],
    'production' => [
        'logLevel' => 'error',
    ],
];

Setup

1. Create Campaign Section

Create a Craft section for campaigns with the following fields:

  • Campaign Type (Dropdown): Type categorization
  • Form (Formie Form): The survey form
  • Invitation Delay Period (Text): ISO 8601 duration (e.g., P1D for 1 day)
  • Invitation Expiry Period (Text): ISO 8601 duration (e.g., P30D for 30 days)
  • SMS Invitation Message (Plain Text): SMS template with {invitationUrl} and {customer_name} tokens
  • Email Invitation Subject (Plain Text): Email subject line
  • Email Invitation Message (Rich Text): Email template with tokens
  • Sender ID (Text): SMS sender ID handle
  • Surveys Welcome (Rich Text): Message shown before survey
  • Surveys Already Responded (Rich Text): Message for completed surveys
  • Surveys Invitation Expired (Rich Text): Message for expired invitations

2. Configure Plugin Settings

  1. Navigate to Campaign Manager → Settings
  2. Set the Campaign Section Handle to match your section
  3. Configure Bitly API key if using SMS invitations

3. Create Survey Template

Create a template for the survey page (e.g., templates/survey.twig):

{% extends '_layouts/surveys.twig' %}

{% block content %}
    {% set invitationCode = craft.app.request.getQueryParam('code') %}

    {% if invitationCode %}
        {% set recipient = campaignManager.recipients.getRecipientByInvitationCode(invitationCode) %}
        {% set campaign = recipient.getCampaign() %}

        {% if recipient.hasSubmission() %}
            {{ campaign.surveysAlreadyResponded|raw }}
        {% elseif recipient.invitationIsExpired() %}
            {{ campaign.surveysInvitationExpired|raw }}
        {% else %}
            {{ campaign.surveysWelcome|raw }}
            {{ craft.formie.renderForm(campaign.getForm()) }}
        {% endif %}
    {% else %}
        <p>Invalid invitation code.</p>
    {% endif %}
{% endblock %}

Usage

Managing Campaigns

  1. Navigate to Campaign Manager in the control panel
  2. Click New Campaign to create a campaign entry
  3. Configure the campaign settings and associated form
  4. Save the campaign

Adding Recipients

Single Recipient

  1. Navigate to the campaign's recipient list
  2. Click Add → New Recipient
  3. Enter recipient details (name, email, phone, site)
  4. Save

Import from CSV

  1. Navigate to the campaign's recipient list
  2. Click Add → Import from CSV
  3. Upload a CSV file with columns:
    • Name (required)
    • Email (optional)
    • Phone (optional)
    • Site (optional: site handle like en, ar or site ID like 1, 2)
  4. Choose whether to send invitations after import
  5. Click Import

CSV Format Example:

Name,Email,Phone,Site
John Doe,john@example.com,96512345678,en
Ahmed Ali,ahmed@example.com,96598765432,ar

Running Campaigns

Single Campaign

  1. Navigate to the campaign's recipient list
  2. Click Run Campaign
  3. Invitations will be queued and sent in batches

All Campaigns

  1. Navigate to Campaign Manager → Campaigns
  2. Click Run All
  3. All campaigns will be processed

Viewing Analytics

  1. Navigate to Campaign Manager → Analytics
  2. Use filters to select campaign, site, and date range
  3. View metrics across four tabs:
    • Overview: Key stats and campaign performance table
    • Delivery: Daily activity and channel distribution
    • Engagement: Open rates over time
    • Conversion: Funnel visualization and breakdown
  4. Export data using the Export button

Viewing Responses

  1. Navigate to a campaign and click Edit
  2. Click the Responses tab
  3. View all recipients who submitted the form
  4. Click "View" to see full submission details in Formie

Exporting Recipients

  1. Navigate to the campaign's recipient list
  2. Click Export
  3. Choose format (CSV, JSON, or Excel)
  4. Download includes all recipient data and status

Template Variables

campaignManager.campaigns

{# Get all campaigns #}
{% set campaigns = campaignManager.campaigns.find().all() %}

{# Get campaign by ID #}
{% set campaign = campaignManager.campaigns.find().id(123).one() %}

{# Get campaigns for a site #}
{% set campaigns = campaignManager.campaigns.find().site('en').all() %}

campaignManager.recipients

{# Get recipient by invitation code #}
{% set recipient = campaignManager.recipients.getRecipientByInvitationCode(code) %}

{# Mark recipient as opened #}
{% do campaignManager.recipients.markAsOpened(recipient) %}

{# Check recipient status #}
{% if recipient.hasSubmission() %}
    {# Already submitted #}
{% elseif recipient.invitationIsExpired() %}
    {# Invitation expired #}
{% endif %}

{# Get recipients with submissions for a campaign #}
{% set respondents = campaignManager.recipients.getWithSubmissions(campaignId, siteId) %}

Console Commands

# Run all campaigns
./craft campaign-manager/campaigns/run-all

# Run specific campaign
./craft campaign-manager/campaigns/run --campaign=123

Permissions

Campaign Permissions

  • Manage campaigns
    • View campaigns
    • Create campaigns
    • Edit campaigns
    • Delete campaigns

Recipient Permissions

  • Manage recipients
    • View recipients
    • Import recipients
    • Delete recipients

Analytics Permissions

  • View analytics: Access the analytics dashboard
  • Export analytics: Export analytics data

Settings Permissions

  • Manage settings

Events

use lindemannrock\campaignmanager\services\RecipientsService;
use lindemannrock\campaignmanager\events\RecipientEvent;
use yii\base\Event;

// Before sending invitation
Event::on(
    RecipientsService::class,
    RecipientsService::EVENT_BEFORE_SEND_INVITATION,
    function(RecipientEvent $event) {
        // Access: $event->recipient, $event->campaign
        // Set $event->isValid = false to cancel
    }
);

// After sending invitation
Event::on(
    RecipientsService::class,
    RecipientsService::EVENT_AFTER_SEND_INVITATION,
    function(RecipientEvent $event) {
        // Access: $event->recipient, $event->success
    }
);

Troubleshooting

Invitations Not Sending

  1. Check SMS Manager is configured: Ensure providers and sender IDs are set up
  2. Check Bitly API key: Required for SMS URL shortening
  3. Check queue is running: ./craft queue/run
  4. Check logs: Campaign Manager → Logs

Survey Page Not Loading

  1. Verify invitation code: Check the URL has a valid code parameter
  2. Check recipient exists: The invitation code must match a recipient record
  3. Check campaign has form: The campaign must have a Formie form assigned

CSV Import Failing

  1. Check CSV format: Must have Name column at minimum
  2. Check encoding: Use UTF-8 encoding for special characters
  3. Check file size: Large files are processed in batches

Bitly URLs Not Working

  1. Verify API key: Check BITLY_API_KEY environment variable
  2. Check API limits: Bitly has rate limits on free plans
  3. Fallback: If Bitly fails, original URLs are used

Logging

Campaign Manager uses the LindemannRock Logging Library for system logging.

Log Levels

  • Error: Critical errors only (default)
  • Warning: Errors and warnings
  • Info: General information
  • Debug: Detailed debugging (requires devMode)

Log Files

  • Location: storage/logs/campaign-manager-YYYY-MM-DD.log
  • Retention: 30 days (automatic cleanup)
  • Web Interface: View logs at Campaign Manager → Logs

Support

License

This plugin is licensed under the MIT License. See LICENSE for details.

Developed by LindemannRock