Skip to content

Commit

Permalink
Merge pull request #6539 from mautic-inc/feature-ip-address-in-campai…
Browse files Browse the repository at this point in the history
…gn-webhook

Feature ip address in campaign webhook
  • Loading branch information
Woeler committed Nov 24, 2018
2 parents 9c211ee + c045c9c commit 6556987
Show file tree
Hide file tree
Showing 4 changed files with 322 additions and 73 deletions.
10 changes: 9 additions & 1 deletion app/bundles/WebhookBundle/Config/config.php
Expand Up @@ -87,7 +87,7 @@
'mautic.webhook.campaign.subscriber' => [
'class' => \Mautic\WebhookBundle\EventListener\CampaignSubscriber::class,
'arguments' => [
'mautic.http.connector',
'mautic.webhook.campaign.helper',
],
],
],
Expand All @@ -101,6 +101,14 @@
],
],
],
'others' => [
'mautic.webhook.campaign.helper' => [
'class' => \Mautic\WebhookBundle\Helper\CampaignHelper::class,
'arguments' => [
'mautic.http.connector',
],
],
],
],

'parameters' => [
Expand Down
84 changes: 12 additions & 72 deletions app/bundles/WebhookBundle/EventListener/CampaignSubscriber.php
Expand Up @@ -11,33 +11,26 @@

namespace Mautic\WebhookBundle\EventListener;

use Joomla\Http\Http;
use Mautic\CampaignBundle\CampaignEvents;
use Mautic\CampaignBundle\Event as Events;
use Mautic\CampaignBundle\Event\CampaignExecutionEvent;
use Mautic\CoreBundle\EventListener\CommonSubscriber;
use Mautic\CoreBundle\Helper\AbstractFormFieldHelper;
use Mautic\LeadBundle\Helper\TokenHelper;
use Mautic\WebhookBundle\Helper\CampaignHelper;
use Mautic\WebhookBundle\WebhookEvents;

/**
* Class CampaignSubscriber.
*/
class CampaignSubscriber extends CommonSubscriber
{
/**
* @var Http
* @var CampaignHelper
*/
protected $connector;
protected $campaignHelper;

/**
* CampaignSubscriber constructor.
*
* @param Http $connector
* @param CampaignHelper $campaignHelper
*/
public function __construct(Http $connector)
public function __construct(CampaignHelper $campaignHelper)
{
$this->connector = $connector;
$this->campaignHelper = $campaignHelper;
}

/**
Expand All @@ -58,66 +51,14 @@ public static function getSubscribedEvents()
*/
public function onCampaignTriggerAction(CampaignExecutionEvent $event)
{
if (!$event->checkContext('campaign.sendwebhook')) {
return;
}
$lead = $event->getLead();
$config = $event->getConfig();
try {
$url = $config['url'];
$method = $config['method'];
$data = !empty($config['additional_data']['list']) ? $config['additional_data']['list'] : '';
$data = array_flip(AbstractFormFieldHelper::parseList($data));
// replace contacts tokens
foreach ($data as $key => $value) {
$data[$key] = urldecode(TokenHelper::findLeadTokens($value, $lead->getProfileFields(), true));
}
$headers = !empty($config['headers']['list']) ? $config['headers']['list'] : '';
$headers = array_flip(AbstractFormFieldHelper::parseList($headers));
foreach ($headers as $key => $value) {
$headers[$key] = urldecode(TokenHelper::findLeadTokens($value, $lead->getProfileFields(), true));
}
$timeout = $config['timeout'];

switch ($method) {
case 'get':
$response = $this->connector->get(
$url.(parse_url($url, PHP_URL_QUERY) ? '&' : '?').http_build_query($data),
$headers,
$timeout
);
break;
case 'post':
case 'put':
case 'patch':
$response = $this->connector->$method(
$url,
$data,
$headers,
$timeout
);
break;

case 'delete':
$response = $this->connector->delete(
$url,
$headers,
$timeout,
$data
);
break;
default:
return;
if ($event->checkContext('campaign.sendwebhook')) {
try {
$this->campaignHelper->fireWebhook($event->getConfig(), $event->getLead());
$event->setResult(true);
} catch (\Exception $e) {
$event->setFailed($e->getMessage());
}

if (in_array($response->code, [200, 201])) {
return $event->setResult(true);
}
} catch (\Exception $e) {
return $event->setFailed($e->getMessage());
}

return $event->setFailed($this->translator->trans('Error code').': '.$response->code);
}

/**
Expand All @@ -127,7 +68,6 @@ public function onCampaignTriggerAction(CampaignExecutionEvent $event)
*/
public function onCampaignBuild(Events\CampaignBuilderEvent $event)
{
//Add action to remote url call
$sendWebhookAction = [
'label' => 'mautic.webhook.event.sendwebhook',
'description' => 'mautic.webhook.event.sendwebhook_desc',
Expand Down
173 changes: 173 additions & 0 deletions app/bundles/WebhookBundle/Helper/CampaignHelper.php
@@ -0,0 +1,173 @@
<?php

/*
* @copyright 2014 Mautic Contributors. All rights reserved
* @author Mautic
*
* @link http://mautic.org
*
* @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
*/

namespace Mautic\WebhookBundle\Helper;

use Doctrine\Common\Collections\Collection;
use Joomla\Http\Http;
use Mautic\CoreBundle\Helper\AbstractFormFieldHelper;
use Mautic\LeadBundle\Entity\Lead;
use Mautic\LeadBundle\Helper\TokenHelper;

class CampaignHelper
{
/**
* @var Http
*/
protected $connector;

/**
* Cached contact values in format [contact_id => [key1 => val1, key2 => val1]].
*
* @var array
*/
private $contactsValues = [];

/**
* @param Http $connector
*/
public function __construct(Http $connector)
{
$this->connector = $connector;
}

/**
* Prepares the neccessary data transformations and then makes the HTTP request.
*
* @param array $config
* @param Lead $contact
*/
public function fireWebhook(array $config, Lead $contact)
{
// dump($config);die;
$payload = $this->getPayload($config, $contact);
$headers = $this->getHeaders($config, $contact);
$this->makeRequest($config['url'], $config['method'], $config['timeout'], $headers, $payload);
}

/**
* Gets the payload fields from the config and if there are tokens it translates them to contact values.
*
* @param array $config
* @param Lead $contact
*
* @return array
*/
private function getPayload(array $config, Lead $contact)
{
$payload = !empty($config['additional_data']['list']) ? $config['additional_data']['list'] : '';
$payload = array_flip(AbstractFormFieldHelper::parseList($payload));

return $this->getTokenValues($payload, $contact);
}

/**
* Gets the payload fields from the config and if there are tokens it translates them to contact values.
*
* @param array $config
* @param Lead $contact
*
* @return array
*/
private function getHeaders(array $config, Lead $contact)
{
$headers = !empty($config['headers']['list']) ? $config['headers']['list'] : '';
$headers = array_flip(AbstractFormFieldHelper::parseList($headers));

return $this->getTokenValues($headers, $contact);
}

/**
* @param string $url
* @param string $method
* @param int $timeout
* @param array $headers
* @param array $payload
*
* @throws \InvalidArgumentException
* @throws \OutOfRangeException
*/
private function makeRequest($url, $method, $timeout, array $headers, array $payload)
{
switch ($method) {
case 'get':
$payload = $url.(parse_url($url, PHP_URL_QUERY) ? '&' : '?').http_build_query($payload);
$response = $this->connector->get($payload, $headers, $timeout);
break;
case 'post':
case 'put':
case 'patch':
$response = $this->connector->$method($url, $payload, $headers, $timeout);
break;
case 'delete':
$response = $this->connector->delete($url, $headers, $timeout, $payload);
break;
default:
throw new \InvalidArgumentException('HTTP method "'.$method.' is not supported."');
}

if (!in_array($response->code, [200, 201])) {
throw new \OutOfRangeException('Campaign webhook response returned error code: '.$response->code);
}
}

/**
* Translates tokens to values.
*
* @param array $rawTokens
* @param Lead $contact
*
* @return array
*/
private function getTokenValues(array $rawTokens, Lead $contact)
{
$values = [];
$contactValues = $this->getContactValues($contact);

foreach ($rawTokens as $key => $value) {
$values[$key] = urldecode(TokenHelper::findLeadTokens($value, $contactValues, true));
}

return $values;
}

/**
* Gets array of contact values.
*
* @param Lead $contact
*
* @return array
*/
private function getContactValues(Lead $contact)
{
if (empty($this->contactsValues[$contact->getId()])) {
$this->contactsValues[$contact->getId()] = $contact->getProfileFields();
$this->contactsValues[$contact->getId()]['ipAddress'] = $this->ipAddressesToCsv($contact->getIpAddresses());
}

return $this->contactsValues[$contact->getId()];
}

/**
* @param Collection $ipAddresses
*
* @return string
*/
private function ipAddressesToCsv(Collection $ipAddresses)
{
$addresses = [];
foreach ($ipAddresses as $ipAddress) {
$addresses[] = $ipAddress->getIpAddress();
}

return implode(',', $addresses);
}
}

0 comments on commit 6556987

Please sign in to comment.