You are viewing beta documentation for Formie 4.x.
Custom Integration

Email Marketing Integration

Email marketing integrations extend EmailMarketing. They usually fetch lists from a provider, expose a list selector in the form builder, then map Formie fields to subscriber fields for the selected list.

Form Settings Data

Return an IntegrationFormSettings object containing provider lists. Each list is usually an IntegrationCollection with its own fields.

use verbb\formie\models\IntegrationCollection;
use verbb\formie\models\IntegrationField;
use verbb\formie\models\IntegrationFormSettings;

public function fetchFormSettings(): IntegrationFormSettings
{
    $settings = [];
    $lists = $this->request('GET', 'lists');

    foreach ($lists as $list) {
        $settings['lists'][] = new IntegrationCollection([
            'id' => (string)$list['id'],
            'name' => $list['name'],
            'fields' => [
                new IntegrationField([
                    'handle' => 'email',
                    'name' => Craft::t('formie', 'Email'),
                    'required' => true,
                ]),
                new IntegrationField([
                    'handle' => 'first_name',
                    'name' => Craft::t('formie', 'First Name'),
                ]),
            ],
        ]);
    }

    return new IntegrationFormSettings($settings);
}

Form Settings Schema

EmailMarketing already defines a common form settings schema for list selection and field mapping. It includes the opt-in field, a refreshable list selector and the field-mapping UI for the selected list.

Override defineFormSettingsSchema() when your provider needs extra per-form settings.

use verbb\formie\base\FormInterface;
use verbb\formie\helpers\SchemaHelper;

protected function defineFormSettingsSchema(FormInterface $form): array
{
    $schema = parent::defineFormSettingsSchema($form);

    $schema[] = SchemaHelper::lightswitchField([
        'label' => Craft::t('formie', 'Resubscribe'),
        'instructions' => Craft::t('formie', 'Whether existing unsubscribed contacts should be resubscribed.'),
        'name' => 'resubscribe',
    ]);

    return $schema;
}

Sending Payloads

Use getFieldMappingValues() with $this->fieldMapping. The EmailMarketing base class resolves the selected list and passes the correct list fields to Formie’s mapping conversion.

use verbb\formie\base\Integration;
use verbb\formie\elements\Submission;
use Throwable;

public function sendPayload(Submission $submission): bool
{
    try {
        $fieldValues = $this->getFieldMappingValues($submission, $this->fieldMapping);
        $email = $fieldValues['email'] ?? null;

        $response = $this->deliverPayload($submission, "lists/{$this->listId}/subscribers", [
            'email' => $email,
            'fields' => $fieldValues,
        ]);

        return $response !== false;
    } catch (Throwable $e) {
        Integration::apiError($this, $e);

        return false;
    }
}

Email marketing providers differ in how they represent custom fields, groups and resubscribe behavior. Keep provider-specific API decisions in fetchFormSettings() and sendPayload(), and let the base class handle the common Formie mapping flow.