Drupal + Mailchimp API : create campaign with an existing template - php

I'm trying to create a campaign with the Mailchimp PHP API in a custom Drupal module, but i fail to use an existing template.
I am sure of my template id in the request, but the id is always 0 in the response.
What is the correct request payload to reuse a template ?
I just want to reuse a very simple template. For now, there's no specific text for the campaign, i'll try to insert a text pattern when i'll be able to use the correct template.
Thanks in advance.
Here is my current code :
function mymodule_templates_list()
{
$mailchimpPath = realpath(__DIR__ . '/../../libraries/mailchimp');
require_once $mailchimpPath . '/src/Mailchimp.php';
require_once $mailchimpPath . '/src/Mailchimp/Templates.php';
$mailchimp = new Mailchimp('my-api-key');
$templatesService = new Mailchimp_Templates($mailchimp);
$list = $templatesService->getList(
array(
'user' => true,
'gallery' => false,
'base' => false,
),
array(
'include_drag_and_drop' => true,
)
);
dpm($list); // just to verify the template ID
$campaignService = new Mailchimp_Campaigns($mailchimp);
$response = $campaignService->getList();
dpm($response);
$options = array(
"list_id" => 'my-list-id', // this is OK, correct list used in the response
"subject" => "My subject", // OK
"from_email" => "mymail#dev.null", // OK
"from_name" => "Site name", // OK
"to_name" => '',
'template_id' => 123456, // KO : 0 in the response
);
$content = array(
"text" => "dunno what to use here",
"url" => 'dunno what to use here',
"archive" => "dunno what to use here",
);
$response = $campaignService->create('regular', $options, $content);
dpm($response);
return '';
}

Related

Amazon Pay SDK InvalidSignatureError

I'm integrating Amazon Pay php SDK from documentation, but getting this error.
Here's my php implementation code:
$amazonpay_config = array(
'public_key_id' => 'XXXXXXXX',
'private_key' => 'my_private_key_path',
'region' => 'US',
'sandbox' => true
);
$payload = array(
'webCheckoutDetails' => array(
'checkoutReviewReturnUrl' => 'https://www.example.com/review',
'checkoutResultReturnUrl' => 'https://www.example.com/result'
),
'storeId' => 'amzn1.application-oa2-client.XXXXXXXXX'
);
$headers = array('x-amz-pay-Idempotency-Key' => uniqid());
$requestResult = [
'error' => 1,
'msg' => 'Error. Can not create checkout session.',
'checkoutSession' => null,
'payloadSign' => null
];
$client = new Client($amazonpay_config);
$resultCheckOut = $client->createCheckoutSession($payload, $headers);
$resultSignPayload = $client->generateButtonSignature($payload);
if($resultCheckOut['status'] !== 201) {
return json_encode($requestResult, true);
}
else {
$requestResult = [
'error' => 0,
'msg' => null,
'checkoutSession' => json_decode($resultCheckOut['response']),
'payloadSign' => $resultSignPayload
];
return $requestResult;
}
Here's JS implementation code for generating Amazon Pay button.
amazon.Pay.renderButton('#amazon-pay-btn', {
// set checkout environment
merchantId: 'XXXXXXXX',
ledgerCurrency: 'USD',
sandbox: true,
checkoutLanguage: 'en_US',
productType: 'PayOnly',
placement: 'Cart',
buttonColor: 'Gold',
createCheckoutSessionConfig: {
payloadJSON: jsonResult['checkoutSession'],
signature: jsonResult['payloadSign'],
publicKeyId: 'XXXXXXXXXXX'
}
});
Couple of problems with the code, mainly that you aren't passing the payload and signature to the front-end correctly. For the payload, you're using jsonResult['checkoutSession'], while it should be jsonResult['payloadSign']. This doesn't contain the payload though but from the PHP code it's apparently the signature that you have put in there. The full code sample should more like this (not tested).
Back-end:
$headers = array('x-amz-pay-Idempotency-Key' => uniqid());
$requestResult = [
'error' => 1,
'msg' => 'Error. Can not create checkout session.',
'signature' => null,
'payload' => null
];
$client = new Client($amazonpay_config);
$resultCheckOut = $client->createCheckoutSession($payload, $headers);
$resultSignature = $client->generateButtonSignature($payload);
if($resultCheckOut['status'] !== 201) {
return json_encode($requestResult, true);
}
else {
$requestResult = [
'error' => 0,
'msg' => null,
'signature' => $resultSignature,
'payload' => $payload
];
return json_encode($requestResult);
}
Front-end:
amazon.Pay.renderButton('#amazon-pay-btn', {
// set checkout environment
merchantId: 'XXXXXXXX',
ledgerCurrency: 'USD',
sandbox: true,
checkoutLanguage: 'en_US',
productType: 'PayOnly',
placement: 'Cart',
buttonColor: 'Gold',
createCheckoutSessionConfig: {
payloadJSON: JSON.stringify(jsonResult['payload']),
signature: jsonResult['signature'],
publicKeyId: 'XXXXXXXXXXX'
}
});
I'm not sure how you're passing $requestResult back to the front-end, potentially there's some additional JSON encoding/decoding required to get the right string. To prevent a signature mismatch error, please make sure that the payload string used for the signature generation in the backend, and the payload string assigned to the 'payloadJSON' parameter match exactly (especially pay attention to whitespaces, escape characters, line breaks, etc.).
Two comments about this issue:
I have defined the payload as an string (that's the way current AmazonPay doc states - Link).
$payload = '{
"webCheckoutDetails": {
"checkoutReviewReturnUrl": "https://www.example.com/review",
"checkoutResultReturnUrl": "https://www.example.com/result"
},
"storeId": "amzn1.application-oa2-client.XXXXXXXXX"
}';
instead of array
$payload = array(
'webCheckoutDetails' => array(
'checkoutReviewReturnUrl' => 'https://www.example.com/review',
'checkoutResultReturnUrl' => 'https://www.example.com/result'
),
'storeId' => 'amzn1.application-oa2-client.XXXXXXXXX'
);
The signature was created, but when rendering the button and clicking on it I get the following error.
Error Message: Signature Dk4qznkoiTVqjcY8Yn1l0iLbsoIj2pEAHWVtgYrphLtFXR9BKhJJPD53It4qYOswS1T/STYMHRy5jtCHGqvLntDjuy0MrhkpoHTpYEtwdOqGHA2qk+QnSGV5LoYldQ/UkAxSG7m8s2iOr11q2sWxUjrk2M3fgzAIxDeZRjJYeAr97eGANYva3jtGDfM6cJdieInBM4dEWWxKqGIh6HxOrY5K/ga26494vAwZAGvXRhZG48FOVp/XCr0mbu6V5pkEOzRJSc+hN5WKAs/c49UsfKPx75Ce7QbaBCZZT1UiczfyYx/mBuZuysUlGmnXPhLOLTPw4+SIizH/pOQyClOQyw== does not match signedString AMZN-PAY-RSASSA-PSS dfff7a87b93cfa78685a233f2dd59e18ad0451b2e3a90af11e500fcc0ceee924 for merchant XXXXXXXX
I was some time till I realized that this was the reason of the error. Actually, while writing this, the new lines in the string were the reason. If string is only in one line, it works.
The button only needs the payload and the signed payload. The $client->createCheckoutSession is not needed. More over, the checkoutSessionId of the resultCheckOut is different from the one obtained when the checkoutReviewReturnUrl is called.

Cannot get derived property from ZF2 Twitter user search

I'm using ZF2 Twitter package to get user info by username and retrieve it's location, but the returned object doesn't give me the "derived" property, that should have the detailed data about location I want to use.
public function twitterAction()
{
$config = array(
'access_token' => array(
'token' => 'MY TOKEN',
'secret' => 'MY SECRET',
),
'oauth_options' => array(
'consumerKey' => 'MY CONSUMER KEY',
'consumerSecret' => 'MY COMSUMER SECRET',
),
'http_client_options' => array(
'adapter' => 'Zend\Http\Client\Adapter\Curl',
'curloptions' => array(
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_SSL_VERIFYPEER => false,
),
),
);
$twitter = new Twitter($config);
$response = $twitter->account->accountVerifyCredentials();
if (!$response->isSuccess()) {
die(var_dump($response->getErrors()));
}
$params = $this->params()->fromRoute();
$profile = $params['profile'];
$user = $twitter->users->show($profile);
$coordinates = $user->derived->geo->coordinates;
return new JsonModel(
[
'placeName' => $user->derived->locality . ' - ' $user->derived->region,
'link' => 'http://www.google.com/maps/place/'.$coordinates[0].','.$coordinates[1]
]
);
}
I'm using the twitter api page as reference
this is the response I get if I return the user
{
'placename: ': '-',
'link: ': 'http://www.google.com/maps/place/,',
}
How can I retrieve this data?
From that page:
Profile Geo data will be included in Twitter's PowerTrack, Replay, Volume Stream, Search, and Historical PowerTrack APIs.
I think that means the geo data is only available for paying customers of PowerTrack. If you're just a regular developer, you can't get it.

Php: Create web push notification

I want to create a web push notification in Php but I don't have the exact procedure for it. Following is the code I found, but it is not working.
<?php
require __DIR__ . '/../vendor/autoload.php';
use Minishlink\WebPush\WebPush;
$subscription = json_decode(file_get_contents('php://input'), true);
$auth = array(
'VAPID' => array(
'subject' => '`enter code here`',
'publicKey' => '**********',
'privateKey' => '***********',
),
);
$webPush = new WebPush($auth);
$res = $webPush->sendNotification(
$subscription['endpoint'],
"Hello!",
$subscription['key'],
$subscription['token'],
true
);
Please suggest the correct steps.
I spent some time my self figuring this out. I'm posting the code as it works for me. Generate the keys from here https://web-push-codelab.glitch.me/
<?php
require_once './vendor/autoload.php';
use Minishlink\WebPush\WebPush;
// array of notifications
$notifications = array(
array(
'endpoint' => 'https://fcm.googleapis.com/fcm/send/abcd........', // Chrome
'payload' => 'Hello',
'userPublicKey' => 'BFHh..........',
'userAuthToken' => 'DI............',
)
);
$auth = array(
'GCM' => 'AAAAKTK8bp4..............', // deprecated and optional, it's here only for compatibility reasons
'VAPID' => array(
'subject' => 'Some Text', // can be a mailto: or your website address
'publicKey' => 'BGsm2vrV2AMpT.............', // (recommended) uncompressed public key P-256 encoded in Base64-URL
'privateKey' => 'a89H............', // (recommended) in fact the secret multiplier of the private key encoded in Base64-URL
),
);
$defaultOptions = array(
'TTL' => 300, // defaults to 4 weeks
'urgency' => 'normal', // protocol defaults to "normal"
'topic' => 'push', // not defined by default - collapse_key
);
$webPush = new WebPush($auth, $defaultOptions);
$vr = $webPush->sendNotification(
$notifications[0]['endpoint'],
$notifications[0]['payload'], // optional (defaults null)
$notifications[0]['userPublicKey'], // optional (defaults null)
$notifications[0]['userAuthToken'], // optional (defaults null)
true // optional (defaults false)
);

Linkedin Invitation API Internal server error

Yo!
I'm trying to use the linkedin invitation api to allow users to conncect on linkedin from my application using email-addresses. I am able to find people, access the api and so on. I can't get the invites to work though. I am using php (Laravel).
I based myself on the example from the linkedin documentation ( Linkedin Invite API ). I send my data in a post using JSON (that contains the same info as their example).
I ask permission to use w_messages, the post works and my variables contain the correct information. I get a Internal Server error as a result.
$data = array(
"recipients" => array(
"values" => array(
"person" => array(
"_path" => "/people/email=".$email,
"first-name" => $firstname,
"last-name" => $lastname
)
)
),
"subject" => "Bla",
"body"=> "BlaBLa",
"item-content" => array(
"invitation-request" => array(
"connect-type" => "friend"
)
)
);
$dataString = json_encode($data);
$opts = array('http' =>
array(
'method' => 'POST',
'header' => "Content-type: application/json\r\n".
"Connection: close\r\n" .
"Content-length: " . strlen($dataString) . "\r\n",
'content' => $dataString
)
);
$params = array('oauth2_access_token' => Session::get('access_token'),
'format' => 'json'
);
$url = "https://api.linkedin.com/v1/people/~/mailbox".'?' . http_build_query($params);
$context = stream_context_create($opts);
$result = file_get_contents($url, false, $context);
Log::info($result);
return Response::json(array("invite" => "sent"));
I assume I'm doing something wrong but don't really know where to look.
Looks like you doing this manually, have you tried using a tried & tested third party library like simple-linkedinphp - A PHP-based wrapper for the LinkedIn API.
https://code.google.com/p/simple-linkedinphp/wiki/Reference
Usage:
// Connect
$API_CONFIG = array(
'appKey' => '<your application key here>',
'appSecret' => '<your application secret here>',
'callbackUrl' => NULL
);
$linkedin = new LinkedIn($API_CONFIG);
// Send Invite
$linkedin->invite($method, $recipient, $subject, $body, $type = 'friend');
Doc: https://code.google.com/p/simple-linkedinphp/wiki/Reference

NuSoap equivalent of SoapVar()

I don't know much about NuSoap, but unfortunately I have to use it.
I'm trying to follow example code for the dotmailer web service api Here. I need to be able to add custom fields for subscribers.
In the example code custom/additional fields are defined like so;
new SoapVar($FirstName,XSD_STRING,"string","http://www.w3.org/2001/XMLSchema");
Heres the code I have right now;
<?php
function subscribeUserEmail($email)
{
$username = "********";
$password = "********";
$postURL = "http://apiconnector.com/api.asmx?WSDL";
$contact = array (
"Email" => $email,
"AudienceType" => "B2C",
"OptInType" => "Single",
"EmailType" => "Html",
"ID" => -1,
"DataFields" => array(
"Keys" => array("TEST"),
"Values" => array("Name")
)
);
$params = array(
"username" => $username,
"password" => $password,
"contact" => $contact,
"addressbookId" => "******"
);
$client = new soapclient($postURL, true);
$error = $client->getError();
$result = $client->call('AddContactToAddressBook', $params);
echo "<h2>Request</h2>";
print("<pre>".$client->request."</pre>");
echo "<h2>Response</h2>";
print("<pre>".$client->response."</pre>");
echo "<h2>Debug</h2>";
print("<pre>".$client->debug_str."</pre>");
}
?>
If the $contact array is changed to this;
$contact = array (
"Email" => $email,
"AudienceType" => "B2C",
"OptInType" => "Single",
"EmailType" => "Html",
"ID" => -1,
"DataFields" => array(
"Keys" => array("TEST"),
"Values" => array(new SoapVar("Name",XSD_STRING,"string","http://www.w3.org/2001/XMLSchema") )
)
);
And used with a regular soap client, the code works. So I'm pretty sure there aren't any other problems with my function.
I've tried using the following;
new soapval("string", XSD_STRING, "Name","http://www.w3.org/2001/XMLSchema");
As an alternative to the SoapVar() method, but I get the same errors as if I entered the value as plain text.
How can I replicate the functionality of SoapVar() in NuSoap? This appears to be the only issue.

Categories