So I've hit a wall in the last 24 hours on the Constant Contact implementation. I'm using the Oauth flow and I have obtained an access token and refresh token and am now trying to Post a contact. The issue is in I'm hitting the Unauthorized/Unauthorized message when doing so. Going off what I have read in other posts, I then created an automatic refresh mechanic so that if a request comes back with an httpCode of 401, we do a quick refresh of the access tokens and try the request over with that new access token. No matter what I do, it's always coming back as Unauthorized/Unauthorized. Since every single thing I've seen in this forum states that "Unauthorized/Unauthorized" messages mean that the access token has expired, how is that occurring if I'm refreshing the access token (and seeing that new access token update and within the request) and then making the same request again (w/ newly updated access token) only to get the same error message? I've tried every solution I can come up within in the last 6 hours and at this point I need a little help. Here is the class I'm working off of, follow the logic of the createContact() function. <?php
class Constant_Contact extends Email
{
private $clientKey;
private $clientSecret;
private $connection;
private $refreshAttempts = 0;
const BASIC = 1;
const BEARER = 2;
function __construct()
{
$this->clientKey = $GLOBALS['fw']['config']['constantContact']['clientKey'];
$this->clientSecret = $GLOBALS['fw']['config']['constantContact']['clientSecret'];
}
function storeInit(Store $store)
{
$connection = StoreManager::singleton()->WHERE(array('store_id' => $store->id, 'type_id' => Connection_To_Store::ConstantContact))->getObject('Connection_To_Store');
if (isset($connection->id) && $connection->id) {
$this->connection = $connection;
}
return false;
}
// creates a URL that the browser will redirect to obtain a code for authorization
public function getAuthorizationURL()
{
$baseUrl = 'https://authz.constantcontact.com/oauth2/default/v1/authorize';
$scope = '+contact_data+offline_access';
$responseType = 'code';
$state = 'asdf08a8dfljsfs1';
$redirectUri = 'http://devadmin.xxxx.com/admin/connections/ConstantContactGetCode';
return $baseUrl . '?client_id=' . $this->clientKey . '&scope=' . $scope . '&response_type=' . $responseType . '&state=' . $state . '&redirect_uri=' . urlencode($redirectUri);
}
// Using the ?code from authorization, we will grab the tokens for using Constant Contact
public function getTokens($code)
{
if (!$code)
return;
$redirectUri = 'http://devadmin.xxxx.com/admin/connections/ConstantContactGetCode';
$baseUrl = 'https://authz.constantcontact.com/oauth2/default/v1/token?code=' . $code . '&redirect_uri=' . $redirectUri . '&grant_type=authorization_code';
return $this->request(Constant_Contact::BASIC, FWHTTPRequest::POST, $baseUrl, $data);
}
public function createContact(User $user)
{
if (!$user->id)
return;
if (!$this->connection->id)
return;
$data['api_key'] = $this->clientKey;
$data['first_name'] = $user->first_name;
$data['last_name'] = $user->last_name;
$data['email_address']['address'] = $user->email;
$data['email_address']['permission_to_send'] = 'implicit';
return $this->request(Constant_Contact::BEARER, FWHTTPRequest::POST, 'https://api.cc.email/v3/contacts', $data);
}
private function refreshToken()
{
$baseUrl = 'https://authz.constantcontact.com/oauth2/default/v1/token?refresh_token=' . $this->connection->key_3 . '&grant_type=refresh_token';
$data = $this->request(Constant_Contact::BASIC, FWHTTPRequest::POST, $baseUrl);
$connection = new Connection_To_Store($this->connection->id);
$connection->access_token = $data->access_token;
$connection->account_index = $data->expires_in;
$connection->key_3 = $data->refresh_token;
$connection->save();
$this->connection = $connection;
}
private function request($type, $mode = FWHTTPRequest::POST, $endpoint, $data = array(), $refresh = false)
{
if (!$type)
return;
if (!$this->clientKey)
return;
if ($refresh && $this->refreshAttempts == 1)
$this->refreshToken();
$fwoptions = new FWHTTPRequestOptions();
$fwoptions->action = $mode;
$fwoptions->contentType = 'json';
$fwoptions->returnResult = true;
$fwoptions->timeout = 300;
$fwoptions->connectionTimeout = 30;
$fwoptions->maxRedirects = -1;
if ($type == Constant_Contact::BEARER) {
$authorization = 'Authorization: Bearer ' . $this->connection->access_token;
$fwoptions->headers = array($authorization, 'Content-Type: application/json');
} else if ($type == Constant_Contact::BASIC) {
$credentials = base64_encode($this->clientKey . ':' . $this->clientSecret);
$authorization = 'Authorization: Basic ' . $credentials;
$fwoptions->headers = array($authorization, 'Content-Type: application/x-www-form-urlencoded');
}
if (is_array($data) && count($data)) {
foreach($data as $key => $value) {
$fwoptions->postFields[$key] = $value;
}
}
try {
LogManager::info(__METHOD__ . ' making call to ' . $endpoint);
if ($request = new FWHTTPRequest($endpoint, $fwoptions, true)) {
// if we got here, the access token needs to be renewed
if ($request->httpCode == '401') {
$this->refreshAttempts++;
$this->request($type, $mode, $endpoint, $data, true);
} else if ($request->httpCode != '404') {
if ($request->responseBody == 'false') {
exit;
}
$content = $request->responseBody;
$content = json_decode($content);
if (isset($content->error_key) && $content->error_key)
Log_Error::create($_SESSION['store']->id, Log_Error::Connections, $content->error_message, $content->error_key, $endpoint);
if (isset($content->error) && $content->error)
Log_Error::create($_SESSION['store']->id, Log_Error::Connections, $content->error_description, $content->error, $endpoint);
return $content;
}
print_r($request);
}
} catch(exception $e) {
LogManager::error(__METHOD__ . ' endpoint: ' . $endpoint . ', exception: ' . $e);
throw $e;
}
}
}
?>
... View more