diff --git a/README.md b/README.md index 7ce27a9..34b5546 100644 --- a/README.md +++ b/README.md @@ -206,6 +206,10 @@ $variables = [ $subscriber->sendTransactionalEmail($emails, $emailTemplateId, $variables); ``` +### Mailchimp options unsubscribing + +Mailchimp does not support unsubscribing a user from a list with their email address, we throw an `UnsupportedUnsubscribePlatformException`. + ## YMLP ### YMLP options subscriber @@ -228,6 +232,10 @@ For getting your additional fields ID: see https://www.ymlp.com/api/Fields.GetLi YMLP does not support transactional email, we throw an `UnsupportedTransactionalEmailPlatformException`. +### YMLP options unsubscribing + +YMLP does not support unsubscribing a user from a list with their email address, we throw an `UnsupportedUnsubscribePlatformException`. + ## Brevo ### Brevo subscriber options @@ -286,6 +294,19 @@ $variables = [ $subscriber->sendTransactionalEmail($emails, $templateEmail, $variables); ``` +### Brevo options unsubscribing + +See https://developers.brevo.com/reference/removecontactfromlist + +```php +$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'); +``` + ## Mailjet ### Mailjet subscriber options @@ -322,4 +343,49 @@ $variables = [ 'personalmessage' => 'Happy birthday!' ]; $subscriber->sendTransactionalEmail($emails, $templateEmail, $variables); +``` + +### MailJet options unsubscribing + +MailJet does not support unsubscribing a user from a list with their email address, we throw an `UnsupportedUnsubscribePlatformException`. + + +## OxiMailing + +### OxiMailing subscriber options + +```php +$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 sender transactional email options + +OxiMailing does not support transactional email, we throw an `UnsupportedTransactionalEmailPlatformException`. + +### OxiMailing options unsubscribing + +See https://api.oximailing.com/doc/#/contacts/delete_lists__ListId__contacts + +```php +$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'); ``` \ No newline at end of file diff --git a/bruno/subscribeme/Brevo/Add existing contacts to a list.bru b/bruno/subscribeme/Brevo/Add existing contacts to a list.bru new file mode 100644 index 0000000..7c79cce --- /dev/null +++ b/bruno/subscribeme/Brevo/Add existing contacts to a list.bru @@ -0,0 +1,23 @@ +meta { + name: Add existing contacts to a list + type: http + seq: 2 +} + +post { + url: {{brevo_base_url}}/v3/contacts/lists/:listId/contacts/add + body: json + auth: none +} + +params:path { + listId: +} + +body:json { + { + "emails": [ + "john.smith@contact.com" + ] + } +} diff --git a/bruno/subscribeme/Brevo/Get all the lists.bru b/bruno/subscribeme/Brevo/Get all the lists.bru new file mode 100644 index 0000000..731e384 --- /dev/null +++ b/bruno/subscribeme/Brevo/Get all the lists.bru @@ -0,0 +1,16 @@ +meta { + name: Get all the lists + type: http + seq: 1 +} + +get { + url: {{brevo_base_url}}/v3/contacts/lists + body: none + auth: basic +} + +auth:basic { + username: {{brevo_login}} + password: {{brevo_password}} +} diff --git a/bruno/subscribeme/Brevo/Get contacts in a list.bru b/bruno/subscribeme/Brevo/Get contacts in a list.bru new file mode 100644 index 0000000..d3fad4d --- /dev/null +++ b/bruno/subscribeme/Brevo/Get contacts in a list.bru @@ -0,0 +1,15 @@ +meta { + name: Get contacts in a list + type: http + seq: 3 +} + +get { + url: {{brevo_base_url}}/v3/contacts/lists/:listId/contacts + body: none + auth: none +} + +params:path { + listId: +} diff --git a/bruno/subscribeme/Brevo/Remove a contacts from a list.bru b/bruno/subscribeme/Brevo/Remove a contacts from a list.bru new file mode 100644 index 0000000..715fe19 --- /dev/null +++ b/bruno/subscribeme/Brevo/Remove a contacts from a list.bru @@ -0,0 +1,25 @@ +meta { + name: Remove a contacts from a list + type: http + seq: 4 +} + +post { + url: {{brevo_base_url}}/v3/contacts/lists/:listId/contacts/remove + body: json + auth: none +} + +params:path { + listId: +} + +headers { + content-type: application/json +} + +body:json { + { + "emails": "john.smith@contact.com" + } +} diff --git a/bruno/subscribeme/MailChimp/Add member to list.bru b/bruno/subscribeme/MailChimp/Add member to list.bru new file mode 100644 index 0000000..769e494 --- /dev/null +++ b/bruno/subscribeme/MailChimp/Add member to list.bru @@ -0,0 +1,26 @@ +meta { + name: Add member to list + type: http + seq: 2 +} + +post { + url: {{mailchimp_base_url}}/lists/:listId/members + body: json + auth: basic +} + +params:path { + listId: 123 +} + +auth:basic { + username: {{mailchimp_login}} + password: {{mailchimp_password}} +} + +body:json { + { + "email_address": "john.smith@contact.com" + } +} \ No newline at end of file diff --git a/bruno/subscribeme/MailChimp/Get all lists.bru b/bruno/subscribeme/MailChimp/Get all lists.bru new file mode 100644 index 0000000..ab360a9 --- /dev/null +++ b/bruno/subscribeme/MailChimp/Get all lists.bru @@ -0,0 +1,16 @@ +meta { + name: Get all lists + type: http + seq: 3 +} + +get { + url: {{mailchimp_base_url}}/lists/ + body: none + auth: basic +} + +auth:basic { + username: {{mailchimp_login}} + password: {{mailchimp_password}} +} \ No newline at end of file diff --git a/bruno/subscribeme/MailChimp/List members info.bru b/bruno/subscribeme/MailChimp/List members info.bru new file mode 100644 index 0000000..436f97d --- /dev/null +++ b/bruno/subscribeme/MailChimp/List members info.bru @@ -0,0 +1,16 @@ +meta { + name: List members info + type: http + seq: 1 +} + +get { + url: {{mailchimp_base_url}}/lists/:listId/members + body: none + auth: basic +} + +auth:basic { + username: {{mailchimp_login}} + password: {{mailchimp_password}} +} diff --git a/bruno/subscribeme/MailJet/Add contact in a list.bru b/bruno/subscribeme/MailJet/Add contact in a list.bru new file mode 100644 index 0000000..f1b4187 --- /dev/null +++ b/bruno/subscribeme/MailJet/Add contact in a list.bru @@ -0,0 +1,11 @@ +meta { + name: Add contact in a list + type: http + seq: 2 +} + +post { + url: {{mailjet_base_url}} + body: none + auth: none +} diff --git a/bruno/subscribeme/MailJet/Get contacts in a list.bru b/bruno/subscribeme/MailJet/Get contacts in a list.bru new file mode 100644 index 0000000..e8c7056 --- /dev/null +++ b/bruno/subscribeme/MailJet/Get contacts in a list.bru @@ -0,0 +1,15 @@ +meta { + name: Get contacts in a list + type: http + seq: 3 +} + +get { + url: {{mailjet_base_url}}/v3/REST/contactslist/:listId + body: none + auth: none +} + +params:path { + listId: +} diff --git a/bruno/subscribeme/MailJet/Get contactsList.bru b/bruno/subscribeme/MailJet/Get contactsList.bru new file mode 100644 index 0000000..f0d5a0f --- /dev/null +++ b/bruno/subscribeme/MailJet/Get contactsList.bru @@ -0,0 +1,16 @@ +meta { + name: Get contactsList + type: http + seq: 1 +} + +get { + url: {{mailjet_base_url}}/v3/REST/contactslist/ + body: none + auth: basic +} + +auth:basic { + username: {{mailjet_login}} + password: {{mailjet_password}} +} diff --git a/bruno/subscribeme/OxiMailing/Add new contacts into the specified list..bru b/bruno/subscribeme/OxiMailing/Add new contacts into the specified list..bru new file mode 100644 index 0000000..2bd6141 --- /dev/null +++ b/bruno/subscribeme/OxiMailing/Add new contacts into the specified list..bru @@ -0,0 +1,42 @@ +meta { + name: Add new contacts into the specified list. + type: http + seq: 1 +} + +post { + url: {{oximailing_base_url}}/lists/:listId/contacts?contacts={"email1@example.com":{"customerName":"Dupont","customerId":123}} &method=ignore + body: none + auth: basic +} + +params:query { + contacts: {"email1@example.com":{"customerName":"Dupont","customerId":123}} + method: ignore +} + +params:path { + listId: 841 +} + +auth:basic { + username: {{oximailing_login}} + password: {{oximailing_password}} +} + +body:json { + { + "contacts" : { + "email@rezo-zero.com": { + "firstName": "firstName", + "lastName": "lastName" + } + }, + "mode" : "ignore" + } +} + +body:multipart-form { + ~contacts: {"email1@example.com":{"customerName":"Dupont","customerId":123}} + ~mode: ignore +} diff --git a/bruno/subscribeme/OxiMailing/Delete the specified contacts..bru b/bruno/subscribeme/OxiMailing/Delete the specified contacts..bru new file mode 100644 index 0000000..143cbec --- /dev/null +++ b/bruno/subscribeme/OxiMailing/Delete the specified contacts..bru @@ -0,0 +1,28 @@ +meta { + name: Delete the specified contacts. + type: http + seq: 3 +} + +delete { + url: {{oximailing_base_url}}/lists/:listId/contacts?emails=email1@example.com + body: none + auth: basic +} + +params:query { + emails: email1@example.com +} + +params:path { + listId: 841 +} + +auth:basic { + username: {{oximailing_login}} + password: {{oximailing_password}} +} + +body:multipart-form { + emails: email1@example.com +} diff --git a/bruno/subscribeme/OxiMailing/Get your contact lists..bru b/bruno/subscribeme/OxiMailing/Get your contact lists..bru new file mode 100644 index 0000000..bd7ea0a --- /dev/null +++ b/bruno/subscribeme/OxiMailing/Get your contact lists..bru @@ -0,0 +1,16 @@ +meta { + name: Get your contact lists. + type: http + seq: 4 +} + +get { + url: {{oximailing_base_url}}/lists + body: none + auth: basic +} + +auth:basic { + username: {{oximailing_login}} + password: {{oximailing_password}} +} diff --git a/bruno/subscribeme/OxiMailing/Get your contacts in the specified list..bru b/bruno/subscribeme/OxiMailing/Get your contacts in the specified list..bru new file mode 100644 index 0000000..eb78a2e --- /dev/null +++ b/bruno/subscribeme/OxiMailing/Get your contacts in the specified list..bru @@ -0,0 +1,20 @@ +meta { + name: Get your contacts in the specified list. + type: http + seq: 2 +} + +get { + url: {{oximailing_base_url}}/lists/:listId/contacts + body: none + auth: basic +} + +params:path { + listId: 841 +} + +auth:basic { + username: {{oximailing_login}} + password: {{oximailing_password}} +} diff --git a/bruno/subscribeme/bruno.json b/bruno/subscribeme/bruno.json new file mode 100644 index 0000000..af16c3f --- /dev/null +++ b/bruno/subscribeme/bruno.json @@ -0,0 +1,9 @@ +{ + "version": "1", + "name": "subscribeme", + "type": "collection", + "ignore": [ + "node_modules", + ".git" + ] +} \ No newline at end of file diff --git a/bruno/subscribeme/environments/PROD.bru b/bruno/subscribeme/environments/PROD.bru new file mode 100644 index 0000000..0ea83ee --- /dev/null +++ b/bruno/subscribeme/environments/PROD.bru @@ -0,0 +1,16 @@ +vars { + oximailing_base_url: https://api.oximailing.com + mailjet_base_url: https://api.mailjet.com + brevo_base_url: https://api.brevo.com + mailchimp_base_url: https://us16.api.mailchimp.com/3.0 +} +vars:secret [ + oximailing_login, + oximailing_password, + mailjet_login, + mailjet_password, + brevo_login, + brevo_password, + mailchimp_login, + mailchimp_password +] diff --git a/src/SubscribeMe/Exception/UnsupportedUnsubscribePlatformException.php b/src/SubscribeMe/Exception/UnsupportedUnsubscribePlatformException.php new file mode 100644 index 0000000..d6a5981 --- /dev/null +++ b/src/SubscribeMe/Exception/UnsupportedUnsubscribePlatformException.php @@ -0,0 +1,13 @@ +client, $this->requestFactory, $this->streamFactory); case 'ymlp': return new YmlpSubscriber($this->client, $this->requestFactory, $this->streamFactory); + case 'oximailing': + return new OxiMailingSubscriber($this->client, $this->requestFactory, $this->streamFactory); } throw new \InvalidArgumentException('No subscriber class found for ' . $platform); } diff --git a/src/SubscribeMe/Subscriber/BrevoDoubleOptInSubscriber.php b/src/SubscribeMe/Subscriber/BrevoDoubleOptInSubscriber.php index 4f41ae5..c36a043 100644 --- a/src/SubscribeMe/Subscriber/BrevoDoubleOptInSubscriber.php +++ b/src/SubscribeMe/Subscriber/BrevoDoubleOptInSubscriber.php @@ -5,6 +5,7 @@ namespace SubscribeMe\Subscriber; use SubscribeMe\Exception\CannotSubscribeException; +use SubscribeMe\Exception\UnsupportedUnsubscribePlatformException; final class BrevoDoubleOptInSubscriber extends BrevoSubscriber { diff --git a/src/SubscribeMe/Subscriber/BrevoSubscriber.php b/src/SubscribeMe/Subscriber/BrevoSubscriber.php index c234808..4cb5c59 100644 --- a/src/SubscribeMe/Subscriber/BrevoSubscriber.php +++ b/src/SubscribeMe/Subscriber/BrevoSubscriber.php @@ -10,6 +10,7 @@ use SubscribeMe\Exception\CannotSendTransactionalEmailException; use SubscribeMe\Exception\CannotSubscribeException; use SubscribeMe\Exception\ApiCredentialsException; +use SubscribeMe\Exception\UnsupportedUnsubscribePlatformException; use SubscribeMe\GDPR\UserConsent; use SubscribeMe\ValueObject\EmailAddress; @@ -195,4 +196,51 @@ public function sendTransactionalEmail(array $emails, string|int $emailTemplateI throw new CannotsendTransactionalEmailException($exception->getResponseBody()['message']); } } + + /** + * @inheritdoc + */ + public function unsubscribe(string $email): bool + { + try { + if (!is_string($this->getApiKey())) { + throw new ApiCredentialsException(); + } + + if (!is_string($this->getContactListId())) { + throw new CannotSubscribeException('Contact list id is required for subscribe'); + } + + $body = [ + 'emails' => [$email], + ]; + + $bodyStreamed = $this->getStreamFactory()->createStream(json_encode($body, JSON_THROW_ON_ERROR)); + + $uri = 'https://api.brevo.com/v3/contacts/lists/'.$this->getContactListId().'/contacts/remove'; + + $request = $this->getRequestFactory() + ->createRequest('POST', $uri) + ->withBody($bodyStreamed) + ->withAddedHeader('Content-Type', 'application/json') + ->withAddedHeader('api-key', $this->getApiKey()) + ->withAddedHeader('User-Agent', 'rezozero/subscribeme') + ; + + $res = $this->getClient()->sendRequest($request); + + // https://developers.sendinblue.com/reference/createcontact + if ($res->getStatusCode() === 200 || $res->getStatusCode() === 201) { + /** @var array $body */ + $body = json_decode($res->getBody()->getContents(), true); + if (isset($body['success'])) { + return true; + } + } + } catch (ClientExceptionInterface $exception) { + throw new CannotSubscribeException($exception->getMessage(), $exception); + } + + return false; + } } diff --git a/src/SubscribeMe/Subscriber/MailchimpSubscriber.php b/src/SubscribeMe/Subscriber/MailchimpSubscriber.php index 08f3a95..626c64b 100644 --- a/src/SubscribeMe/Subscriber/MailchimpSubscriber.php +++ b/src/SubscribeMe/Subscriber/MailchimpSubscriber.php @@ -9,6 +9,7 @@ use SubscribeMe\Exception\ApiResponseException; use SubscribeMe\Exception\CannotSendTransactionalEmailException; use SubscribeMe\Exception\CannotSubscribeException; +use SubscribeMe\Exception\UnsupportedUnsubscribePlatformException; use SubscribeMe\GDPR\UserConsent; use SubscribeMe\ValueObject\EmailAddress; @@ -64,6 +65,10 @@ public function subscribe(string $email, array $options, array $userConsents = [ throw new ApiCredentialsException(); } + if (!is_string($this->getContactListId())) { + throw new CannotSubscribeException('Contact list id is required for subscribe'); + } + $uri = 'https://' . $this->getDc() . '.api.mailchimp.com/3.0/lists/' . $this->getContactListId() . '/members'; $body = [ 'status' => $this->statusWhenSubscribed, @@ -213,4 +218,12 @@ private function transformVariables(array $variables): array } return $variables; } + + /** + * @inheritdoc + */ + public function unsubscribe(string $email): bool + { + throw new UnsupportedUnsubscribePlatformException(); + } } diff --git a/src/SubscribeMe/Subscriber/MailjetSubscriber.php b/src/SubscribeMe/Subscriber/MailjetSubscriber.php index 2e8ad45..01259c8 100644 --- a/src/SubscribeMe/Subscriber/MailjetSubscriber.php +++ b/src/SubscribeMe/Subscriber/MailjetSubscriber.php @@ -9,6 +9,7 @@ use SubscribeMe\Exception\ApiResponseException; use SubscribeMe\Exception\CannotSendTransactionalEmailException; use SubscribeMe\Exception\CannotSubscribeException; +use SubscribeMe\Exception\UnsupportedUnsubscribePlatformException; use SubscribeMe\GDPR\UserConsent; use SubscribeMe\ValueObject\EmailAddress; @@ -34,6 +35,10 @@ public function subscribe(string $email, array $options, array $userConsents = [ throw new ApiCredentialsException(); } + if (!is_string($this->getContactListId())) { + throw new CannotSubscribeException('Contact list id is required for subscribe'); + } + $name = null; if (isset($options['Name'])) { $name = $options['Name']; @@ -148,4 +153,12 @@ public function sendTransactionalEmail(array $emails, string|int $emailTemplateI throw new CannotsendTransactionalEmailException($exception->getResponseBody()['ErrorMessage']); } } + + /** + * @inheritdoc + */ + public function unsubscribe(string $email): bool + { + throw new UnsupportedUnsubscribePlatformException(); + } } diff --git a/src/SubscribeMe/Subscriber/OxiMailingSubscriber.php b/src/SubscribeMe/Subscriber/OxiMailingSubscriber.php new file mode 100644 index 0000000..1623e15 --- /dev/null +++ b/src/SubscribeMe/Subscriber/OxiMailingSubscriber.php @@ -0,0 +1,124 @@ +getApiKey())) { + throw new ApiCredentialsException(); + } + + if (!is_string($this->getApiSecret())) { + throw new ApiCredentialsException(); + } + + if (!is_string($this->getContactListId())) { + throw new CannotSubscribeException('Contact list id is required for subscribe'); + } + + $mode = $options['mode'] ?? 'ignore'; + if (isset($options['mode'])) { + unset($options['mode']); + } + + $contacts[$email] = $options; + + $body = [ + 'mode' => $mode, + 'contacts' => json_encode($contacts, JSON_THROW_ON_ERROR), + ]; + $queryParams = http_build_query($body); + + $uri = 'https://api.oximailing.com/lists/' . $this->getContactListId() . '/contacts?' . $queryParams; + try { + $request = $this->getRequestFactory() + ->createRequest('POST', $uri) + ->withAddedHeader('User-Agent', 'rezozero/subscribeme') + ->withAddedHeader('Authorization', 'Basic '.base64_encode(sprintf('%s:%s', $this->getApiKey(), $this->getApiSecret()))); + + $res = $this->getClient()->sendRequest($request); + + + if ($res->getStatusCode() === 200 || $res->getStatusCode() === 201) { + /** @var array $body */ + $body = json_decode($res->getBody()->getContents(), true); + if ($body['added'] == 1 || $body['ignored'] == 1 || $body['updated'] == 1) { + return true; + } + } + } catch (ClientExceptionInterface $exception) { + throw new CannotSubscribeException($exception->getMessage(), $exception); + } + + return false; + } + + /** + * @inheritdoc + */ + public function sendTransactionalEmail(array $emails, string|int $emailTemplateId, array $variables = []): string + { + throw new UnsupportedTransactionalEmailPlatformException(); + } + + /** + * @inheritdoc + */ + public function unsubscribe(string $email): bool + { + if (!is_string($this->getApiKey())) { + throw new ApiCredentialsException(); + } + + if (!is_string($this->getApiSecret())) { + throw new ApiCredentialsException(); + } + + if (!is_string($this->getContactListId())) { + throw new CannotSubscribeException('Contact list id is required for subscribe'); + } + + $queryParams = http_build_query(['emails' => $email]); + + $uri = 'https://api.oximailing.com/lists/' . $this->getContactListId() . '/contacts?' . $queryParams; + try { + $request = $this->getRequestFactory() + ->createRequest('DELETE', $uri) + ->withAddedHeader('User-Agent', 'rezozero/subscribeme') + ->withAddedHeader('Authorization', 'Basic '.base64_encode(sprintf('%s:%s', $this->getApiKey(), $this->getApiSecret()))); + + $res = $this->getClient()->sendRequest($request); + + + if ($res->getStatusCode() === 200 || $res->getStatusCode() === 201) { + /** @var array $body */ + $body = json_decode($res->getBody()->getContents(), true); + if ($body['deleted'] == 1 || $body['not_found'] == 1) { + return true; + } + } + } catch (ClientExceptionInterface $exception) { + throw new CannotSubscribeException($exception->getMessage(), $exception); + } + return false; + } +} diff --git a/src/SubscribeMe/Subscriber/SubscriberInterface.php b/src/SubscribeMe/Subscriber/SubscriberInterface.php index 1ab0918..cfcb5a2 100644 --- a/src/SubscribeMe/Subscriber/SubscriberInterface.php +++ b/src/SubscribeMe/Subscriber/SubscriberInterface.php @@ -5,6 +5,8 @@ namespace SubscribeMe\Subscriber; use JsonException; +use SubscribeMe\Exception\UnsupportedTransactionalEmailPlatformException; +use SubscribeMe\Exception\UnsupportedUnsubscribePlatformException; use SubscribeMe\GDPR\UserConsent; use SubscribeMe\ValueObject\EmailAddress; @@ -27,12 +29,19 @@ public function setContactListId(?string $contactListId): SubscriberInterface; */ public function subscribe(string $email, array $options, array $userConsents = []): bool|int; + /** + * @param string $email + * @return bool true on succeeded or false + * @throws JsonException|UnsupportedUnsubscribePlatformException + */ + public function unsubscribe(string $email): bool; + /** * @param array $emails * @param string|int $emailTemplateId * @param array> $variables * @return string Platform Response body after sending - * @throws JsonException + * @throws JsonException|UnsupportedTransactionalEmailPlatformException */ public function sendTransactionalEmail(array $emails, string|int $emailTemplateId, array $variables = []): string; } diff --git a/src/SubscribeMe/Subscriber/YmlpSubscriber.php b/src/SubscribeMe/Subscriber/YmlpSubscriber.php index ae61941..d5f9fac 100644 --- a/src/SubscribeMe/Subscriber/YmlpSubscriber.php +++ b/src/SubscribeMe/Subscriber/YmlpSubscriber.php @@ -8,6 +8,7 @@ use SubscribeMe\Exception\ApiCredentialsException; use SubscribeMe\Exception\CannotSubscribeException; use SubscribeMe\Exception\UnsupportedTransactionalEmailPlatformException; +use SubscribeMe\Exception\UnsupportedUnsubscribePlatformException; use SubscribeMe\GDPR\UserConsent; class YmlpSubscriber extends AbstractSubscriber @@ -47,6 +48,10 @@ public function subscribe(string $email, array $options, array $userConsents = [ throw new ApiCredentialsException(); } + if (!is_string($this->getContactListId())) { + throw new CannotSubscribeException('Contact list id is required for subscribe'); + } + $params = [ 'Key' => $this->getApiSecret(), 'Username' => $this->getApiKey(), @@ -124,6 +129,14 @@ public function subscribe(string $email, array $options, array $userConsents = [ return false; } + /** + * @inheritdoc + */ + public function unsubscribe(string $email): bool + { + throw new UnsupportedUnsubscribePlatformException(); + } + /** * @inheritdoc */ diff --git a/tests/MailjetMailerTest.php b/tests/MailjetMailerTest.php index 20b7f38..6e33ade 100644 --- a/tests/MailjetMailerTest.php +++ b/tests/MailjetMailerTest.php @@ -34,6 +34,7 @@ public function testSubscribe(): void $mailjetSubscriber->setApiKey('3f62c1f4-efb7-4bc7-b76d-0c2217d307b0'); $mailjetSubscriber->setApiSecret('df30148e-6cda-43ae-8665-9904f5f4f12a'); + $mailjetSubscriber->setContactListId('123'); $returnCode = $mailjetSubscriber->subscribe("passenger@mailjet.com", $options); $requests = $client->getRequests(); @@ -75,6 +76,7 @@ public function testSubscribeWithCodeError(): void $mailjetSubscriber->setApiKey('3f62c1f4-efb7-4bc7-b76d-0c2217d307b0'); $mailjetSubscriber->setApiSecret('df30148e-6cda-43ae-8665-9904f5f4f12a'); + $mailjetSubscriber->setContactListId('123'); $returnCode = $mailjetSubscriber->subscribe("passenger@mailjet.com", $options); $requests = $client->getRequests(); diff --git a/tests/OxiMailingMailerTest.php b/tests/OxiMailingMailerTest.php new file mode 100644 index 0000000..97b4b8c --- /dev/null +++ b/tests/OxiMailingMailerTest.php @@ -0,0 +1,144 @@ +setDefaultResponse(new Response(200, [], json_encode(['invalid' => 0, 'added' => 1, 'ignored' => 0, 'updated' => 0], JSON_THROW_ON_ERROR))); + + $oxiMailingSubscriber = new OxiMailingSubscriber($client, $factory, $factory); + + $oxiMailingSubscriber->setApiKey('3f62c1f4-efb7-4bc7-b76d-0c2217d307b0'); + $oxiMailingSubscriber->setApiSecret('df30148e-6cda-43ae-8665-9904f5f4f12a'); + $oxiMailingSubscriber->setContactListId('123'); + $returnCode = $oxiMailingSubscriber->subscribe("tester@oximailing.com", ['mode' => 'ignored', 'firstName' => 'John', 'lastName' => 'Doe']); + + $requests = $client->getRequests(); + + $this->assertTrue($returnCode); + $this->assertCount(1, $requests); + $this->assertEquals('Basic ' . base64_encode(sprintf('%s:%s', '3f62c1f4-efb7-4bc7-b76d-0c2217d307b0', 'df30148e-6cda-43ae-8665-9904f5f4f12a')), $requests[0]->getHeaders()['Authorization'][0]); + $this->assertEquals('rezozero/subscribeme', $requests[0]->getHeaders()['User-Agent'][0]); + $this->assertEquals('POST', $requests[0]->getMethod()); + $this->assertStringContainsString('api.oximailing.com', $requests[0]->getUri()->getHost()); + $this->assertStringContainsString('/lists/123/contacts', $requests[0]->getUri()->getPath()); + } + + /** + * @throws JsonException + */ + public function testSubscribeWithCodeError(): void + { + $client = new Client(); + $factory = new Psr17Factory(); + + $client->setDefaultResponse(new Response(400)); + + $oxiMailingSubscriber = new OxiMailingSubscriber($client, $factory, $factory); + + $oxiMailingSubscriber->setApiKey('3f62c1f4-efb7-4bc7-b76d-0c2217d307b0'); + $oxiMailingSubscriber->setApiSecret('df30148e-6cda-43ae-8665-9904f5f4f12a'); + $oxiMailingSubscriber->setContactListId('123'); + $returnCode = $oxiMailingSubscriber->subscribe("tester@oximailing.com", ['mode' => 'ignored', 'firstName' => 'John', 'lastName' => 'Doe']); + + $requests = $client->getRequests(); + + $this->assertFalse($returnCode); + $this->assertCount(1, $requests); + $this->assertEquals('Basic ' . base64_encode(sprintf('%s:%s', '3f62c1f4-efb7-4bc7-b76d-0c2217d307b0', 'df30148e-6cda-43ae-8665-9904f5f4f12a')), $requests[0]->getHeaders()['Authorization'][0]); + $this->assertEquals('rezozero/subscribeme', $requests[0]->getHeaders()['User-Agent'][0]); + $this->assertEquals('POST', $requests[0]->getMethod()); + $this->assertStringContainsString('api.oximailing.com', $requests[0]->getUri()->getHost()); + $this->assertStringContainsString('/lists/123/contacts', $requests[0]->getUri()->getPath()); + } + + /** + * @throws JsonException + */ + public function testExceptionListId(): void + { + $this->expectException(CannotSubscribeException::class); + $client = new Client(); + $factory = new Psr17Factory(); + $oxiMailingSubscriber = new OxiMailingSubscriber($client, $factory, $factory); + $oxiMailingSubscriber->setApiKey('3f62c1f4-efb7-4bc7-b76d-0c2217d307b0'); + $oxiMailingSubscriber->setApiSecret('df30148e-6cda-43ae-8665-9904f5f4f12a'); + $email = 'passenger1@mailjet.com'; + $oxiMailingSubscriber->unsubscribe($email); + } + + /** + * @throws JsonException + */ + public function testSendTransactionalEmail(): void + { + $this->expectException(UnsupportedTransactionalEmailPlatformException::class); + $client = new Client(); + $factory = new Psr17Factory(); + $oxiMailingSubscriber = new OxiMailingSubscriber($client, $factory, $factory); + $emails = [ + new EmailAddress('jdoe@example.com') + ]; + $oxiMailingSubscriber->sendTransactionalEmail($emails, '1'); + } + + /** + * @throws JsonException + */ + public function testExceptionApiKey(): void + { + $this->expectException(ApiCredentialsException::class); + $client = new Client(); + $factory = new Psr17Factory(); + $oxiMailingSubscriber = new OxiMailingSubscriber($client, $factory, $factory); + $emails = 'passenger1@mailjet.com'; + $oxiMailingSubscriber->subscribe($emails, ['mode' => 'update']); + } + + /** @throws JsonException */ + public function testUnsubscribe(): void + { + $client = new Client(); + $factory = new Psr17Factory(); + + $client->setDefaultResponse(new Response(200, [], json_encode(['deleted' => 1, 'not_found' => 0], JSON_THROW_ON_ERROR))); + + $oxiMailingSubscriber = new OxiMailingSubscriber($client, $factory, $factory); + + $oxiMailingSubscriber->setApiKey('3f62c1f4-efb7-4bc7-b76d-0c2217d307b0'); + $oxiMailingSubscriber->setApiSecret('df30148e-6cda-43ae-8665-9904f5f4f12a'); + $oxiMailingSubscriber->setContactListId('123'); + $returnCode = $oxiMailingSubscriber->unsubscribe("tester@oximailing.com"); + + $requests = $client->getRequests(); + + $this->assertTrue($returnCode); + $this->assertCount(1, $requests); + $this->assertEquals('Basic ' . base64_encode(sprintf('%s:%s', '3f62c1f4-efb7-4bc7-b76d-0c2217d307b0', 'df30148e-6cda-43ae-8665-9904f5f4f12a')), $requests[0]->getHeaders()['Authorization'][0]); + $this->assertEquals('rezozero/subscribeme', $requests[0]->getHeaders()['User-Agent'][0]); + $this->assertEquals('DELETE', $requests[0]->getMethod()); + $this->assertStringContainsString('api.oximailing.com', $requests[0]->getUri()->getHost()); + $this->assertStringContainsString('/lists/123/contacts', $requests[0]->getUri()->getPath()); + } +} diff --git a/tests/YmlpMailerTest.php b/tests/YmlpMailerTest.php index b7ab713..1e431a6 100644 --- a/tests/YmlpMailerTest.php +++ b/tests/YmlpMailerTest.php @@ -30,6 +30,7 @@ public function testSubscribe(): void $ymlpSubscriber->setApiKey('3f62c1f4-efb7-4bc7-b76d-0c2217d307b0'); $ymlpSubscriber->setApiSecret('df30148e-6cda-43ae-8665-9904f5f4f12a'); + $ymlpSubscriber->setContactListId('123'); $returnCode = $ymlpSubscriber->subscribe("jdoe@example.com", []); $requests = $client->getRequests(); @@ -39,7 +40,7 @@ public function testSubscribe(): void 'Username' => $ymlpSubscriber->getApiKey(), 'OverruleUnsubscribedBounced' => 0, 'Email' => 'jdoe@example.com', - 'GroupID' => 0, + 'GroupID' => 123, 'Output' => 'JSON' ]; $body = http_build_query($body, '', '&'); @@ -73,11 +74,12 @@ public function testSubscribeWithoutCode(): void $ymlpSubscriber->setApiKey('3f62c1f4-efb7-4bc7-b76d-0c2217d307b0'); $ymlpSubscriber->setApiSecret('df30148e-6cda-43ae-8665-9904f5f4f12a'); + $ymlpSubscriber->setContactListId('123'); $returnCode = $ymlpSubscriber->subscribe("jdoe@example.com", []); $requests = $client->getRequests(); - $body = "Key=df30148e-6cda-43ae-8665-9904f5f4f12a&Username=3f62c1f4-efb7-4bc7-b76d-0c2217d307b0&OverruleUnsubscribedBounced=0&Email=jdoe%40example.com&GroupID=0&Output=JSON"; + $body = "Key=df30148e-6cda-43ae-8665-9904f5f4f12a&Username=3f62c1f4-efb7-4bc7-b76d-0c2217d307b0&OverruleUnsubscribedBounced=0&Email=jdoe%40example.com&GroupID=123&Output=JSON"; $this->assertTrue($returnCode); $this->assertCount(1, $requests);