Unified Email Service Library: A simple mailing list subscriber factory that includes a mailing list subscription feature and the ability to send transactional emails.
- Mailjet
- Mailchimp (use Mandrill for transactional emails)
- Brevo (ex SendInBlue)
- Brevo DOI (Double Opt-In) (ex SendInBlue)
- YMLP
composer require rezozero/subscribeme
use SubscribeMe\Factory;
/**
* This library uses PSR18 and PSR17 so you need to provide a client that implements PSR18 like Guzzle for example
* @param ClientInterface $client
* @param RequestFactoryInterface $requestFactory
* @param StreamFactoryInterface $streamFactory
*/
$factory = new Factory($client, $requestFactory, $streamFactory);
// ######## GUZZLE EXAMPLE ##########
$client = new \GuzzleHttp\Client();
$httpFactory = new GuzzleHttp\Psr7\HttpFactory();
$factory = new Factory($client, $httpFactory, $httpFactory);
// ##################################
// 'mailjet' | 'brevo' | 'mailchimp' | 'ymlp'
$subscriber = $factory->createFor('mailjet');
$subscriber->setApiKey('xxxx');
$subscriber->setApiSecret('xxxx');
$subscriber->setContactListId('xxxx');
$userConsent = new \SubscribeMe\GDPR\UserConsent();
$userConsent->setReferrerUrl('https://form.test');
$userConsent->setReferrerFieldName('gdpr_consent_referrer');
$userConsent->setConsentGiven(true);
$userConsent->setConsentFieldName('gdpr_consent');
$userConsent->setIpAddress('xx.xx.xx.xx');
$userConsent->setIpAddressFieldName('gdpr_consent_ip_address');
$userConsent->setConsentDate(new \DateTime());
$userConsent->setDateFieldName('gdpr_consent_date');
$userConsent->setUsage('E-mail marketing campaigns');
$userConsent->setUsageFieldName('gdpr_consent_usage');
$subscriber->subscribe('hello@super.test', ['Name' => 'John Doe'], [$userConsent]);
/**
* Method for sending transactional emails (YMLP does not support transactional emails).
*
* @param array<\SubscribeMe\ValueObject\EmailAddress> $emails (email required, name optional)
* @param int|string $emailTemplateId required
* @param array $variables optional
*/
$subscriber->sendTransactionalEmail($emails, $emailTemplateId, $variables)With Symfony, you don't have to use the Factory,
you can directly make your code generic by depending on SubscriberInterface,
which means that if you want to change platform later,
you will just have to change the registration.
final class YourClass
{
public function __construct(
// Make it generic, let Symfony provide the right service for you
private SubscriberInterface $subscriber
) {
}
public function sendTransactional()
{
$this->subscriber->sendTransactionalEmail(
[
new EmailAddress('user@example.com')
],
$templateId
)
}
}# services.yaml
services:
SubscribeMe\Subscriber\SubscriberInterface:
# Here register the platform class used in your project (example with Mailjet)
class: SubscribeMe\Subscriber\MailjetSubscriber
# Here comes the Symfony magic, PSR17 and PSR18 will be automatically provided
autowire: true
calls:
# Here call necessary methods according to your platform (Mailjet need apiKey and apiSecret)
- setApiKey: [ '%env(string:APP_MAILJET_API_KEY)%' ]
- setApiSecret: [ '%env(string:APP_MAILJET_API_SECRET_KEY)%' ]Prepare your audience list with additional fields in order to store your users consent (https://www.mailjet.com/gdpr/consent/) :
$userConsent = new \SubscribeMe\GDPR\UserConsent();
$userConsent->setReferrerUrl('https://form.test');
$userConsent->setReferrerFieldName('gdpr_consent_referrer');
$userConsent->setConsentGiven(true);
$userConsent->setConsentFieldName('gdpr_consent');
$userConsent->setIpAddress('xx.xx.xx.xx');
$userConsent->setIpAddressFieldName('gdpr_consent_ip_address');
$userConsent->setConsentDate(new \DateTime());
$userConsent->setDateFieldName('gdpr_consent_date');
$userConsent->setUsage('E-mail marketing campaigns');
$userConsent->setUsageFieldName('gdpr_consent_usage');Some platform already have special mechanism for GDPR consent such as Mailchimp :
$userConsent = new \SubscribeMe\GDPR\UserConsent();
$userConsent->setConsentGiven(true);
// Find your Mailchimp marketing permission ID
// with a single API call on some existing contacts
$userConsent->setConsentFieldName('e7443e1720');
$userConsent->setIpAddress('xx.xx.xx.xx');You can add multiple UserConsent objects when platform allows it.
$userConsentEmail = new \SubscribeMe\GDPR\UserConsent();
$userConsentEmail->setConsentGiven(true);
$userConsentEmail->setConsentFieldName('e7443e1720');
$userConsentEmail->setIpAddress('xx.xx.xx.xx');
$userConsentAds = new \SubscribeMe\GDPR\UserConsent();
$userConsentAds->setConsentGiven(false);
$userConsentAds->setConsentFieldName('other_marketing_id');
$userConsentAds->setIpAddress('xx.xx.xx.xx');
$subscriber = $factory->createFor('mailchimp');
$subscriber->subscribe(
'hello@super.test',
['FNAME'=>'Hello', 'LNAME'=>'Super'],
[$userConsentEmail, $userConsentAds]
);$subscriber = $factory->createFor('mailchimp');
$subscriber->setApiKey('your_api_key');
$subscriber->setContactListId('xxxx');
// Set you account datacenter
$subscriber->setDc('us19');
// Choose which status your new user will be given
$subscriber->setSubscribed();
// or
$subscriber->setPending();Mailchimp use Mandrill api for his transactional emails See https://mailchimp.com/developer/transactional/api/messages/send-using-message-template/
$subscriber = $factory->createFor('mailchimp');
// Mailchimp only requires an API Key
$subscriber->setApiKey('mailchimp_api_key');
// use an array of value object EmailAddress for recipients
$emails = [
new \SubscribeMe\ValueObject\EmailAddress('hello@super.test', 'John Doe')
];
// Mailchimp only use string for his $templateEmailId
$emailTemplateId = 'template_name';
/**
* MailChimp accepts an array of variables to inject into your transactional template.
*/
$variables = [
'FNAME' => 'John',
'LNAME' => 'Doe'
];
$subscriber->sendTransactionalEmail($emails, $emailTemplateId, $variables);Mailchimp does not support unsubscribing a user from a list with their email address, we throw an UnsupportedUnsubscribePlatformException.
See https://www.ymlp.com/app/api_command.php?command=Contacts.Add
$subscriber = $factory->createFor('ymlp');
$subscriber->setApiKey('your_username');
$subscriber->setApiSecret('your_api_key');
$subscriber->setContactListId('your_group_id');
// if true the email address will be added even if this person previously
// unsubscribed or if the email address previously was removed by bounce back handling
$subscriber->setOverruleUnsubscribedBounced(true);For getting your additional fields ID: see https://www.ymlp.com/api/Fields.GetList?Key=api_key&Username=username
YMLP does not support transactional email, we throw an UnsupportedTransactionalEmailPlatformException.
YMLP does not support unsubscribing a user from a list with their email address, we throw an UnsupportedUnsubscribePlatformException.
See https://developers.brevo.com/reference#createcontact
$subscriber = $factory->createFor('brevo');
// Brevo only requires an API Key
$subscriber->setApiKey('brevo_api_key');
// Brevo list identifiers are int. You can subscribe user to multiple lists with comma-separated list
$subscriber->setContactListId('3,5,3');
$subscriber->subscribe('hello@super.test', ["FNAME" => "Elly", "LNAME" => "Roger"], [$userConsent]);For getting your additional fields ID: see https://my.brevo.com/lists/add-attributes
See https://developers.brevo.com/reference/createdoicontact
$subscriber = $factory->createFor('brevo-doi');
// Brevo only requires an API Key
$subscriber->setApiKey('brevo_api_key');
// Brevo list identifiers are int. You can subscribe user to multiple lists with comma-separated list
$subscriber->setContactListId('3,5,3');
$subscriber->setTemplateId(1);
$subscriber->setRedirectionUrl('https://www.example.com/subscribed');
$subscriber->subscribe('hello@super.test', ["FNAME" => "Elly", "LNAME" => "Roger"], [$userConsent]);See https://developers.brevo.com/reference/sendtransacemail
$subscriber = $factory->createFor('brevo');
// Brevo only requires an API Key
$subscriber->setApiKey('brevo_api_key');
// use an array of value object EmailAddress for recipients
$emails = [
new EmailAddress('jimmy98@example.com', 'Jimmy');
]
// Brevo only use int for his $templateEmailId
$templateEmail = 1;
/**
* Brevo accepts an array of variables to inject into your transactional template.
*/
$variables = [
'FNAME' => 'Joe',
'LNAME' => 'Doe'
];
$subscriber->sendTransactionalEmail($emails, $templateEmail, $variables);See https://developers.brevo.com/reference/removecontactfromlist
$subscriber = $factory->createFor('brevo');
// Brevo only requires an API Key
$subscriber->setApiKey('brevo_api_key');
// Use Just One list Id in same time for remove contact from a list
$subscriber->setContactListId('3');
$subscriber->unsubscribe('jimmy98@example.com');$subscriber = $factory->createFor('mailjet');
// Mailjet requires an API Key and an API Secret
$subscriber->setApiKey('mailjet_api_key');
$subscriber->setApiSecret('mailjet_api_secret')
// Mailjet list identifiers are int. You can subscribe user to multiple lists with comma-separated list
$subscriber->setContactListId('3,5,3');
$subscriber->subscribe('hello@super.test', ["FNAME" => "Elly", "LNAME" => "Roger"], [$userConsent]);See https://dev.mailjet.com/email/guides/send-api-v31/#use-templating-language
$subscriber = $factory->createFor('mailjet');
// Mailjet requires an API Key and an API Secret
$subscriber->setApiKey('mailjet_api_key');
$subscriber->setApiSecret('mailjet_api_secret')
// use an array of value object EmailAddress for recipients
$emails[] = new EmailAddress('passenger1@mailjet.com', 'passenger 1');
// Mailjet only use int for his $templateEmailId
$templateEmail = 1;
/**
* Mailjet accepts an array of variables to inject into your transactional template.
*/
$variables = [
'day' => 'Tuesday',
'personalmessage' => 'Happy birthday!'
];
$subscriber->sendTransactionalEmail($emails, $templateEmail, $variables);MailJet does not support unsubscribing a user from a list with their email address, we throw an UnsupportedUnsubscribePlatformException.
$subscriber = $factory->createFor('oximailing');
// OxiMailing requires an API Key and an API Secret
$subscriber->setApiKey('oximailing_api_key');
$subscriber->setApiSecret('oximailing_api_secret')
// OxiMailing list identifiers are int. You can only subscribe user to one list
$subscriber->setContactListId('123');
// OxiMailing Accept 3 modes
//Allows you to explain what to do with new duplicates :
//- ignore : remove duplicates
//- insert : don't do anything (all contacts are imported even duplicates)
//- update : update existing contacts information rather than adding duplicates
// Defaults to mode: ignore
$subscriber->subscribe('hello@super.test');
// You can override subscription mode using options array
$subscriber->subscribe('hello@super.test', ['mode' => 'update']);OxiMailing does not support transactional email, we throw an UnsupportedTransactionalEmailPlatformException.
See https://api.oximailing.com/doc/#/contacts/delete_lists__ListId__contacts
$subscriber = $factory->createFor('oximailing');
// OxiMailing requires an API Key and an API Secret
$subscriber->setApiKey('oximailing_api_key');
$subscriber->setApiSecret('oximailing_api_secret')
// You can only unsubscribe one user to one list
$subscriber->setContactListId('123');
$subscriber->unsubscribe('jimmy98@example.com');