Skip to content

Commit

Permalink
Merge pull request #641 from art-institute-of-chicago/fix/sfmc-fuelsdk
Browse files Browse the repository at this point in the history
Refactor SFMC integration
  • Loading branch information
nikhiltri authored Dec 19, 2024
2 parents aa30a88 + deb3d1c commit 27cd67e
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 299 deletions.
201 changes: 61 additions & 140 deletions app/Libraries/ExactTargetService.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@

namespace App\Libraries;

use Illuminate\Support\Facades\Http;
use Illuminate\Support\Str;
use App\Models\ExactTargetList;
use FuelSdk\ET_Client;
use FuelSdk\ET_DataExtension_Row;
use FuelSdk\ET_Subscriber;

class ExactTargetService
{
Expand Down Expand Up @@ -42,14 +40,9 @@ public function __construct(
*/
public function subscribe($alsoRemove = true)
{
$client = $this->getEtClient();

// Add the user to a data extension
$deRow = new ET_DataExtension_Row();

$deRow->authStub = $client;
$deRow->props = [
'Email' => $this->email,
$accessToken = $this->getAccessToken();
$dataExtensionKey = config('exact-target.customer_key');
$props = [
'OptMuseum' => 'True',
];

Expand All @@ -62,65 +55,35 @@ public function subscribe($alsoRemove = true)

foreach ($allLists as $list) {
if (in_array($list, $this->list)) {
$deRow->props[$list] = 'True';
$props[$list] = 'True';
} elseif ($alsoRemove) {
$deRow->props[$list] = 'False';
$props[$list] = 'False';
}
}
}

if ($this->wasFormPrefilled || $this->firstName) {
$deRow->props['FirstName'] = $this->firstName;
$props['FirstName'] = $this->firstName;
}

if ($this->wasFormPrefilled || $this->lastName) {
$deRow->props['LastName'] = $this->lastName;
}

$deRow->CustomerKey = config('exact-target.customer_key');
$deRow->Name = config('exact-target.name');

$response = $deRow->post();

// If it fails, try patch
if (!$response->status) {
$response = $deRow->patch();

if (!$response->status) {
return $response;
}
}

// Add the subscriber
$subscriber = new ET_Subscriber();
$subscriber->authStub = $client;
$subscriber->props = [
'EmailAddress' => $this->email,
'SubscriberKey' => $this->email,
];
$response = $subscriber->post();

if (!$response->status) {
$error = $response->results[0]->ErrorMessage ?? '';
$status = $response->results[0]->StatusMessage ?? '';

if (
Str::startsWith($error, 'Violation of PRIMARY KEY constraint')
|| Str::startsWith($status, 'The subscriber is already on the list')
) {
// Email has been previously subscribed, so proceed
} else {
return $response;
}
$props['LastName'] = $this->lastName;
}

// Then patch it with some additional properties
$subscriber->props['Status'] = 'Active';
$subscriber->Name = 'Museum Business Unit';
$response = $subscriber->patch();
$response = Http::withToken($accessToken)->post(
config('exact-target.client.baseUrl') . "hub/v1/dataeventsasync/key:$dataExtensionKey/rowset",
[
[
'keys' => [
'Email' => $this->email
],
'values' => $props
]
]
);

if (!$response->status) {
return $response;
if ($response->failed()) {
return $response->json();
}

return true;
Expand All @@ -131,108 +94,66 @@ public function subscribe($alsoRemove = true)
*/
public function unsubscribe()
{
$client = $this->getEtClient();
$accessToken = $this->getAccessToken();
$dataExtensionKey = config('exact-target.customer_key');

// Delete the user from the data extension
$deRow = new ET_DataExtension_Row();

$deRow->authStub = $client;
$deRow->props = [
'Email' => $this->email,
];

$deRow->CustomerKey = config('exact-target.customer_key');
$deRow->Name = config('exact-target.name');

$response = $deRow->delete();

if (!$response->status) {
return $response;
}

// Set the subscriber to Unsubscribed
$subscriber = new ET_Subscriber();
$subscriber->authStub = $client;
$subscriber->props = [
'EmailAddress' => $this->email,
'SubscriberKey' => $this->email,
'Status' => 'Unsubscribed'
];
$subscriber->Name = 'Museum Business Unit';
$response = $subscriber->patch();
$response = Http::withToken($accessToken)->delete(
config('exact-target.client.baseUrl') . "hub/v1/dataevents/key:$dataExtensionKey/rowset",
[
'keys' => [
'Email' => $this->email
]
]
);

if (!$response->status) {
return $response;
if ($response->failed()) {
return $response->json();
}

return true;
}

public function get()
{
$client = new ET_Client(false, config('app.debug'), config('exact-target.client'));

$deRow = new ET_DataExtension_Row();
$deRow->authStub = $client;

// Select
$allLists = ExactTargetList::getList()->keys()->all();
$fields = array_merge(
$accessToken = $this->getAccessToken();
$dataExtensionKey = config('exact-target.customer_key');
$fields = array_merge([
'Email',
'FirstName',
'LastName',
], ExactTargetList::getList()->keys()->all());

$response = Http::withToken($accessToken)->get(
config('exact-target.client.baseUrl') . "data/v1/customobjectdata/key:$dataExtensionKey/rowset",
[
'Email',
'FirstName',
'LastName',
],
$allLists
'fields' => implode(',', $fields),
'filter' => [
'Property' => 'Email',
'SimpleOperator' => 'equals',
'Value' => $this->email
]
]
);

$deRow->props = $fields;

// From (e.g. "All Subscribers Master")
$deRow->Name = config('exact-target.customer_key');

// Where
$deRow->filter = [
'Property' => 'Email',
'SimpleOperator' => 'equals',
'Value' => $this->email,
];

return $deRow->get();
return $response->json();
}

protected function getEtClient()
protected function getAccessToken()
{
$auth_url = config('exact-target.client.baseAuthUrl');
$clientId = config('exact-target.client.clientid');
$clientSecret = config('exact-target.client.clientsecret');

$api = new \GuzzleHttp\Client();
$response = Http::asForm()->post($auth_url . "v2/token", [
'grant_type' => 'client_credentials',
'client_id' => config('exact-target.client.clientid'),
'client_secret' => config('exact-target.client.clientsecret'),
]);

$result = $api->request(
'POST',
$auth_url . '/v2/token',
[
'json' => [
'client_id' => $clientId,
'client_secret' => $clientSecret,
'grant_type' => 'client_credentials',
]
]
);

$tokenInfo = json_decode($result->getBody()->getContents(), true);
if ($response->failed()) {
throw new \Exception('Unable to retrieve access token');
}

return new ET_Client(
true,
config('app.debug'),
array_merge(
config('exact-target.client'),
[
'authorizationCode' => $tokenInfo['access_token'],
'scope' => $tokenInfo['scope'],
]
)
);
return $response->json()['access_token'];
}
}
5 changes: 0 additions & 5 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,6 @@
"type": "vcs",
"url": "/~https://github.com/art-institute-of-chicago/data-hub-foundation.git"
},
{
"type": "vcs",
"url": "/~https://github.com/axsweet/FuelSDK-PHP.git"
},
{
"type": "package",
"package": {
Expand Down Expand Up @@ -61,7 +57,6 @@
"michelf/php-smartypants": "^1.8",
"ramsey/uuid": "^4.0",
"rlanvin/php-rrule": "^2.0",
"salesforce-mc/fuel-sdk-php": "dev-master",
"sendgrid/sendgrid": "^8.1",
"sentry/sentry-laravel": "^4.9",
"spatie/calendar-links": "^1.0",
Expand Down
Loading

0 comments on commit 27cd67e

Please sign in to comment.