Skip to content

Commit

Permalink
add webhook controller for contact unsubscribe
Browse files Browse the repository at this point in the history
  • Loading branch information
Andreas Penz committed Jul 18, 2019
1 parent 47b153f commit f845d1a
Show file tree
Hide file tree
Showing 5 changed files with 223 additions and 1 deletion.
77 changes: 77 additions & 0 deletions Controller/AbstractWebhook.php
@@ -0,0 +1,77 @@
<?php
declare(strict_types=1);
/**
*/

namespace CommerceLeague\ActiveCampaign\Controller;

use CommerceLeague\ActiveCampaign\Helper\Config as ConfigHelper;
use Magento\Framework\App\Action\Action;
use Magento\Framework\App\Action\Context;
use Magento\Framework\App\Action\HttpPostActionInterface;
use Magento\Framework\App\CsrfAwareActionInterface;
use Magento\Framework\App\Request\InvalidRequestException;
use Magento\Framework\App\RequestInterface;
use Magento\Framework\Controller\Result\RawFactory as RawResultFactory;
use Magento\Framework\Controller\Result\Raw as RawResult;
use Magento\Framework\Phrase;

/**
* Class AbstractWebhook
*/
abstract class AbstractWebhook extends Action implements HttpPostActionInterface, CsrfAwareActionInterface
{
private const PARAM_TOKEN = 'token';

/**
* @var ConfigHelper
*/
private $configHelper;

/**
* @var RawResultFactory
*/
private $rawResultFactory;

/**
* @param Context $context
* @param ConfigHelper $configHelper
* @param RawResultFactory $rawResultFactory
*/
public function __construct(
Context $context,
ConfigHelper $configHelper,
RawResultFactory $rawResultFactory
) {
parent::__construct($context);
$this->configHelper = $configHelper;
$this->rawResultFactory = $rawResultFactory;
}

/**
* @inheritDoc
*/
public function createCsrfValidationException(RequestInterface $request): ?InvalidRequestException
{
/** @var RawResult $response */
$response = $this->rawResultFactory->create();
$response->setHttpResponseCode(401);
$response->setContents('');

return new InvalidRequestException($response, [new Phrase('Invalid Token.')]);
}

/**
* @inheritDoc
*/
public function validateForCsrf(RequestInterface $request): ?bool
{
$token = $request->getParam(self::PARAM_TOKEN);

if (!$token || $this->configHelper->getWebhookToken() !== $token) {
return false;
}

return true;
}
}
81 changes: 81 additions & 0 deletions Controller/Webhook/Contact/Unsubscribe.php
@@ -0,0 +1,81 @@
<?php
declare(strict_types=1);
/**
*/

namespace CommerceLeague\ActiveCampaign\Controller\Webhook\Contact;

use CommerceLeague\ActiveCampaign\Controller\AbstractWebhook;
use CommerceLeague\ActiveCampaign\Helper\Config as ConfigHelper;
use CommerceLeague\ActiveCampaign\Logger\Logger;
use Magento\Framework\App\Action\Context;
use Magento\Framework\Controller\Result\RawFactory as RawResultFactory;
use Magento\Framework\Exception\LocalizedException;
use Magento\Newsletter\Model\SubscriberFactory;
use Magento\Newsletter\Model\Subscriber;

/**
* Class Unsubscribe
*/
class Unsubscribe extends AbstractWebhook
{
/**
* @var SubscriberFactory
*/
private $subscriberFactory;

/**
* @var Logger
*/
private $logger;

/**
* @param Context $context
* @param ConfigHelper $configHelper
* @param RawResultFactory $rawResultFactory
* @param SubscriberFactory $subscriberFactory
* @param Logger $logger
*/
public function __construct(
Context $context,
ConfigHelper $configHelper,
RawResultFactory $rawResultFactory,
SubscriberFactory $subscriberFactory,
Logger $logger
) {
parent::__construct($context, $configHelper, $rawResultFactory);
$this->subscriberFactory = $subscriberFactory;
$this->logger = $logger;
}

/**
* @inheritDoc
*/
public function execute()
{
$params = $this->getRequest()->getParams();

if (!isset($params['contact']) || !(isset($params['contact']['email']))) {
$this->logger->error(__('Invalid webhook params received'));
return;
}

$email = $params['contact']['email'];

/** @var Subscriber $subscriber */
$subscriber = $this->subscriberFactory->create();
$subscriber->loadByEmail($email);

if (!$subscriber->getId()) {
$this->logger->error(__('Unable to find subscriber with email "%s"', $email));
return;
}

try {
$subscriber->unsubscribe();
} catch (LocalizedException $e) {
$this->logger->error($e->getMessage());
return;
}
}
}
19 changes: 19 additions & 0 deletions Helper/Config.php
Expand Up @@ -21,6 +21,9 @@ class Config extends AbstractHelper
private const XML_PATH_EXPORT_ORDER_ENABLED = 'activecampaign/export/order_enabled';
private const XML_PATH_EXPORT_ABANDONED_CART_ENABLED = 'activecampaign/export/abandoned_cart_enabled';

private const XML_PATH_WEBHOOK_ENABLED = 'activecampaign/webhook/enabled';
private const XML_PATH_WEBHOOK_TOKEN = 'activecampaign/webhook/token';

/**
* @return bool
*/
Expand Down Expand Up @@ -84,4 +87,20 @@ public function isAbandonedCartExportEnabled(): bool
{
return (bool)$this->scopeConfig->isSetFlag(self::XML_PATH_EXPORT_ABANDONED_CART_ENABLED);
}

/**
* @return bool
*/
public function isWebhookEnabled(): bool
{
return (bool)$this->scopeConfig->isSetFlag(self::XML_PATH_WEBHOOK_ENABLED);
}

/**
* @return string|null
*/
public function getWebhookToken(): ?string
{
return $this->scopeConfig->getValue(self::XML_PATH_WEBHOOK_TOKEN);
}
}
32 changes: 32 additions & 0 deletions Test/Unit/Helper/ConfigTest.php
Expand Up @@ -174,4 +174,36 @@ public function testIsAbandonedCartExportEnabledTrue()

$this->assertTrue($this->config->isAbandonedCartExportEnabled());
}

public function testIsWebhookEnabledTrue()
{
$this->scopeConfig->expects($this->once())
->method('isSetFlag')
->with('activecampaign/webhook/enabled')
->willReturn(false);

$this->assertFalse($this->config->isWebhookEnabled());
}

public function testIsWebhookEnabledFalse()
{
$this->scopeConfig->expects($this->once())
->method('isSetFlag')
->with('activecampaign/webhook/enabled')
->willReturn(true);

$this->assertTrue($this->config->isWebhookEnabled());
}

public function testGetWebhookToken()
{
$token = 'THE_TOKEN';

$this->scopeConfig->expects($this->once())
->method('getValue')
->with('activecampaign/webhook/token')
->willReturn($token);

$this->assertEquals($token, $this->config->getWebhookToken());
}
}
15 changes: 14 additions & 1 deletion etc/adminhtml/system.xml
Expand Up @@ -30,7 +30,7 @@
</depends>
</field>
</group>
<group id="export" translate="label" type="select" sortOrder="20" showInDefault="1" showInWebsite="0" showInStore="0">
<group id="export" translate="label" type="text" sortOrder="20" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Export Settings</label>
<depends>
<field id="activecampaign/general/enabled">1</field>
Expand Down Expand Up @@ -58,6 +58,19 @@
</depends>
</field>
</group>
<group id="webhook" translate="label" type="text" sortOrder="30" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Webhook Settings</label>
<field id="enabled" translate="label" type="select" sortOrder="10" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Enabled</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
<field id="token" translate="label" sortOrder="20" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Webhook Token</label>
<depends>
<field id="enabled">1</field>
</depends>
</field>
</group>
</section>
</system>
</config>

0 comments on commit f845d1a

Please sign in to comment.