MailChimp API v3 - Unable to PATCH/ Update? - php

I am trying to simply add/ remove (well subscribe/ unsubscribe rather than delete) email addresses upon sign up of my website to a MailChimp list using the API. When the user is approved on my site, the email address is added via API successfully if the correct checkbox is ticked. However I can not for the life of me get unsubscribe to work. I think I'm having issues with the PATCH method. The code doesn't error, however the user status in the list does not change to unsubscribed and if I echo out the API call I simply get the following:
{"id":"EMAIL_HASH","email_address":"EMAIL_UNHASHED","unique_email_id":"3dae8dd13a","email_type":"html","status":"subscribed","merge_fields":{"FNAME":"","LNAME":"","MMERGE3":"","MMERGE4":"","MMERGE5":"","MMERGE6":"","MMERGE7":"","MMERGE8":"","MMERGE9":"","MMERGE10":""},"interests":{"edf7fefb79":false},"stats":{"avg_open_rate":0,"avg_click_rate":0},"ip_signup":"","timestamp_signup":"","ip_opt":"77.68.14.17","timestamp_opt":"2018-11-23T14:02:27+00:00","member_rating":2,"last_changed":"2018-11-23T14:02:27+00:00","language":"","vip":false,"email_client":"","location":{"latitude":0,"longitude":0,"gmtoff":0,"dstoff":0,"country_code":"","timezone":""},"tags_count":0,"tags":[],"list_id":"LIST_ID","_links":[{"rel":"self","href":"https://us6.api.mailchimp.com/3.0/lists/LIST_ID/members/EMAIL_HASH","method":"GET","targetSchema":"https://us6.api.mailchimp.com/schema/3.0/Definitions/Lists/Members/Response.json"},{"rel":"parent","href":"https://us6.api.mailchimp.com/3.0/lists/LIST_ID/members","method":"GET","targetSchema":"https://us6.api.mailchimp.com/schema/3.0/Definitions/Lists/Members/CollectionResponse.json","schema":"https://us6.api.mailchimp.com/schema/3.0/CollectionLinks/Lists/Members.json"},{"rel":"update","href":"https://us6.api.mailchimp.com/3.0/lists/LIST_ID/members/EMAIL_HASH","method":"PATCH","targetSchema":"https://us6.api.mailchimp.com/schema/3.0/Definitions/Lists/Members/Response.json","schema":"https://us6.api.mailchimp.com/schema/3.0/Definitions/Lists/Members/PATCH.json"},{"rel":"upsert","href":"https://us6.api.mailchimp.com/3.0/lists/LIST_ID/members/EMAIL_HASH","method":"PUT","targetSchema":"https://us6.api.mailchimp.com/schema/3.0/Definitions/Lists/Members/Response.json","schema":"https://us6.api.mailchimp.com/schema/3.0/Definitions/Lists/Members/PUT.json"},{"rel":"delete","href":"https://us6.api.mailchimp.com/3.0/lists/LIST_ID/members/EMAIL_HASH","method":"DELETE"},{"rel":"activity","href":"https://us6.api.mailchimp.com/3.0/lists/LIST_ID/members/EMAIL_HASH/activity","method":"GET","targetSchema":"https://us6.api.mailchimp.com/schema/3.0/Definitions/Lists/Members/Activity/Response.json"},{"rel":"goals","href":"https://us6.api.mailchimp.com/3.0/lists/LIST_ID/members/EMAIL_HASH/goals","method":"GET","targetSchema":"https://us6.api.mailchimp.com/schema/3.0/Definitions/Lists/Members/Goals/Response.json"},{"rel":"notes","href":"https://us6.api.mailchimp.com/3.0/lists/LIST_ID/members/EMAIL_HASH/notes","method":"GET","targetSchema":"https://us6.api.mailchimp.com/schema/3.0/Definitions/Lists/Members/Notes/CollectionResponse.json"},{"rel":"delete_permanent","href":"https://us6.api.mailchimp.com/3.0/lists/LIST_ID/members/EMAIL_HASH/actions/delete-permanent","method":"POST"}]}
which seems more like a dump of possible actions, rather than a response to my call. Needless to say LIST_ID and EMAIL_HASH are accurate and not in the final code.
curl options are as follows, am I possibly missing something require to patch but not POST?
$curl = curl_init();
switch ($method)
{
case "POST":
curl_setopt($curl, CURLOPT_POST, 1);
if ($data)
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
break;
case "PUT":
curl_setopt($curl, CURLOPT_PUT, 1);
break;
case "PATCH":
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PATCH");
break;
default:
if ($data)
$url = sprintf("%s?%s", $url, http_build_query($data));
}
curl_setopt($curl, CURLOPT_USERPWD, "user:API_KEY");
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($curl);
Any help would be appreciated as extensive googling has not returned this problem, predominantly it's people trying to re-add deleted subscribers which this obviously isn't.
$url = 'https://us6.api.mailchimp.com/3.0/lists/LIST_ID/members/'.md5(strtolower($email));
$api_data = array(
'status' => 'unsubscribed'
);
$api_data = json_encode($api_data);
$test_call = CallAPI("PATCH","$url",$api_data);
The PHP using the custom function to call the API. I think I've included the relevant curl info from inside the function but if not please just let me know.

Your function doesn't set any data for a PATCH request. You need to set CURLOPT_POSTFIELDS same as with a POST request:
case "PATCH":
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PATCH");
if ($data){
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
}
break;
Incidentally, the same should be done for a PUT request or any other request type where you need to pass data parameters. You may also want to take a look at my answer here for a function that can both create and update list members.

Related

Get all the contacts from HubSpot list using API

I am using the contact API but it returns maximum 250 contacts only. I used 'vidOffset' parameter for next page but no luck.
Note: I want to export all the contacts from the Hubspot List to my local database using API
Here is my code with php curl:
function callAPI($method, $url, $data){
$curl = curl_init();
$url = $url.'&property=firstname&property=email&count=5&vidOffset=2';
switch ($method){
case "POST":
curl_setopt($curl, CURLOPT_POST, 1);
if ($data)
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
break;
case "PUT":
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PUT");
if ($data)
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
break;
default:
if ($data)
$url = sprintf("%s?%s", $url, http_build_query($data));
}
// OPTIONS:
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
));
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
// EXECUTE:
$result = curl_exec($curl);
if(!$result){die("Connection Failure");}
curl_close($curl);
return $result;
}
// call the function
callAPI('GET', 'https://api.hubapi.com/contacts/v1/lists/11/contacts/all?hapikey=[API key]', false);
Is there anything wrong I am doing? or if there is a better way to get all contact using php/wordpress then please share your experience.
There are a few things to look for here when you make your calls to this API.
Is there a "true" value in the "has-more" field. If so, there are more contacts that can be pulled.
The value of the "vid-offset" field that is returned in your calls.
For the "has-more", this boolean specifies whether or not there are more contacts that you can pull via pagination. For the "vid-offset", this is an integer generated by the API, it does not take a simple sequential integer.
Additionally, you're only grabbing 5 records at a time, you may as well just do the maximum, since it's only 100. This will limit the number of calls you need to make.
Lastly, you may just want to add these to a file, which you can then use for whatever you want, i.e. adding to database, download etc.
So, my suggestion is to amend your initial function to check for the "has-more" value of "true", if it is true send the "vid-offset" value to a new function that makes another call. In that function, you can continue to check for those values, and run your function as many times as it takes until that "has-more" value turns up false.
// the rest of your function is above
// Decode the result so you can traverse the data
$contacts = json_decode($result);
// Store 'has-more' value
$has_more = $contacts->has-more;
// Check if there are more records
if($has_more) {
// Get the offset number provided by API
$offset = $contacts->vid-offset;
// Get more records
getMore($offset);
} else {
// Complete calls and do something else...
}
}
function getMore($offset) {
// Make cURL call with your your offset value
$url = $url.'&property=firstname&property=email&count=100&vidOffset=' . $offset;
$contacts = json_decode($result);
$has_more = $contacts->has-more;
if($has_more) {
$offset = $contacts->vid-offset;
getMore($offset);
} else {
// Complete calls and do something else...
}
}
The documentation that they provide is actually quite clear, so I would read it over a bit as well.

Complete form with cURL using PHP (POST)

I'm trying to make a registration system where users that visit us and register to our website will have an account on a secondary website in order for them to be able to see some opportunities.
So here it goes: The website were I want to POST the Form and Register
My code so far
<?php
// set post fields
$post = [
// this i don't master fell free to approach the subject for future reffrance
'authenticity_token'=>'vhmPffEAIiIbjo36K8CI77+YDQfMPBWEG8ymplsGJ0w=',
'user[email]'=>'test#gmail.com',
'user[first_name]'=>'test',
'user[last_name]'=>'test',
'user[password]'=>'12345678',//smart password (had to be 8char long)
'user[country]'=>'Country(placeholder)',
'user[mc]'=>'1560', //id of the country
'user[lc_input]'=>'1475', //id of the dropdown
'user[lc]'=>'1475',//id of the dropdown
'commit'=>'REGISTER',//value of submit
];
$ch = curl_init('https://auth.aiesec.org/users/sign_in');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
// execute!
$response = curl_exec($ch);
// close the connection, release resources used
curl_close($ch);
// do anything you want with your response
var_dump($response);
?>
Story:
As a user I want to be able to complete a form on domain A and at the same time have an account on domain B using CURL or even JS and AJAX.
If you have any solution to achieve this please let me know :) You can also have a look on the website.
Thank you!
Late edit
I`ve made this in POSTMAN. So I think I should be able to make the for post that information. If you have other suggestions.
In this case server returns 500 as success and 200 as error (security)
Final Working Code
<?php
// set post fields
$post = [
// this i don`t master fell free to approach the subject for future reffrance
'authenticity_token'=>'NKWAg8mGA9gUueBaJ5Og+oEOC5O2rZarZzMK+GnjuCA=',
'user[email]'=>'',
'user[first_name]'=>'',
'user[last_name]'=>'',
'user[password]'=>'',//smart password (had to be 8char long)
'user[country]'=>'',
'user[mc]'=>'', //id of the country
'user[lc_input]'=>'', //id of the dropdown
'user[lc]'=>'',//id of the dropdown
'commit'=>'REGISTER',//value of submit
];
$ch = curl_init('https://auth.aiesec.org/users/');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
// execute!
$response = curl_exec($ch);
// close the connection, release resources used
curl_close($ch);
// do anything you want with your response
var_dump($response);
?>
You are connection via https. So you should add these lines:
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
I tested your code and the website responded "Wrong username / password". That means curl is connecting correctly.

Using the Maven Link V1 API with PHP

I wanted to share this and also seek testing by others to hone this code. If you use maven link, this may be helpful to you in making a project on there from an online form. We use the form submission to do several internal functions with our file sever and the like.
At any rate here is the code. Further testing needs done specifically around the PUT function:
///// CREATE THE MAVEN LINK PROJECT /////
function CallAPI($method, $url, $data = false)
{
$curl = curl_init();
switch ($method)
{
case "POST":
curl_setopt($curl, CURLOPT_POST, 1);
if ($data)
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
break;
case "PUT":
if ($data)
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
break;
default:
if ($data)
$url = sprintf("%s?%s", $url, http_build_query($data));
}
// MAKE SURE CURL DOES NOT OUTPUT TO PAGE
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
//SET HEADERS FOR AUTH
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
'Authorization: Bearer !---INSERT-0-AUTH-TOKEN---!', 'Expect:'
));
//PUT REQUIRES ADDITIONAL HEADERS
if ($method == "PUT")
curl_setopt($curl, CURLOPT_HTTPHEADER, array('X-HTTP-Method-Override: PUT',
'Authorization: Bearer !---INSERT-0-AUTH-TOKEN---!', 'Expect:'
));
curl_setopt($curl, CURLOPT_URL, $url);
$vars = curl_exec($curl);
return $vars;
}
// CREATE THE WORKSPACE: NOTE, I left my post variables in here - however should be noted that a script was used (not included) to ensure against injection.
// build the data according to the jason standards for mavenlink's API
$Data = array('workspace[title]' => $_POST['Description'], 'workspace[creator_role]'=> "maven", 'workspace[description]'=> strip_tags($_POST['Details']), 'workspace[price]'=>$_POST['CostBudget'], 'workspace[due_date]'=>date("Y-m-d",strtotime($_POST['ProjectDue'])), 'workspace[project_tracker_template_id]'=> "285045" );
$DecodeMe = CallAPI("POST","https://api.mavenlink.com/api/v1/workspaces.json",$Data);
$Decoded = json_decode($DecodeMe,true); // be sure to set the option to true so your array comes back as associative
// INVITE USERS:
//////// BASE USERS
$InviteUrl = "https://api.mavenlink.com/api/v1/workspaces/".$Decoded['results'][0]['id']."/invite.json";
$Data2 = array('invitation[full_name]' => "User Fullname", 'invitation[email_address]'=> "email#email.com", 'invitation[invitee_role]'=> "maven" );
$Decoded2 = json_decode(CallAPI("POST",$InviteUrl,$Data2),true);
// repeat the above or use a do while script to process more.
// THE END

How to create category in Disqus

I need to creating some categories in Disqus. I tried to do it by Javascript but it cannot do because require POST request but JSONP only work with GET request. After that, I tried to use CURL in server-side, there are my code
public function createDisqusCategory($title, $forum)
{
$access_token = ACCESS_TOKEN;
$secret_key = SECRET_KEY;
$public_key = PUBLIC_KEY;
$url = 'https://disqus.com/api/3.0/categories/create.json';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER,array('Content-Type: application/json'));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "access_token=$access_token&api_secret=$secret_key&api_key=$public_key&forum=$forum&title=$title");
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
and it response {"code": 22, "response": "You do not have admin privileges on forum '...'"}
How can I solve this problem?
Does your application have Default access set to "Read, write and manage forums"? If not, you'll either need to add a "scope" parameter to your POSTFIELDS, or set default access to manage forums in your application settings. Here's our documentation on scopes: http://disqus.com/api/docs/permissions/
On another note, categories in Disqus are limited to use with the API, so it's not useful in any way unless you're querying comments/threads using a custom script. If you are, I'd also advise keeping it to about 5 categories maximum, or else it can really slow down queries.

Adding events via places return 404 error:

Please excuse my terminology if I get anything wrong, I'm new to Google API
I'm trying to add events via the Places API, for a single venue (listed under the bar category). I've followed the instructions here:
https://developers.google.com/places/documentation/actions?utm_source=welovemapsdevelopers&utm_campaign=places-events-screencast#event_intro
and this is the URL I am posting to (via PHP)
https://maps.googleapis.com/maps/api/place/event/add/format?sensor=false&key=AIzaSyAFd-ivmfNRDanJ40pWsgP1 (key altered)
which returns a 404 error. If I have understood correctly, I have set the sensor to false as I am not mobile, and created an API key in Google apis, with the PLACES service turned on.
Have I missed a vital step here, or would a subsequent error in the POST submission cause a 404 error? I can paste my code in but I thought I'd start with the basics.
Many thanks for your help, advice and time. It's very much apprecciated.
I've added this line to my CurlCall function which I believe should specify a POST, and the result is still the same.
curl_setopt($ch, CURLOPT_POST, 1);
so the whole functions reads
function CurlCall($url,$topost)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADERS, array('Content-Type: application/json'));
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt($ch, CURLOPT_VERBOSE, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $topost);
$body = curl_exec($ch);
curl_close($ch);
echo $body;
echo '<br>';
echo 'URL ' . $url;
echo '<br>';
return $body;
}
Are you sure that you are using the POST method and not GET?
You need to specify the format of your request in the URL by changing the word format to either json or xml depending on how you are going to structure and POST your request.
XML:
https://maps.googleapis.com/maps/api/place/event/add/xml?sensor=false&key=your_api_key
JSON:
https://maps.googleapis.com/maps/api/place/event/add/json?sensor=false&key=your_api_key

Categories