Mailchimp API status 200 for members who are already subscribed - mailchimp

The following code is working and subscribing new members successfully. However, the status returns 200 even if the email address is already subscribed. I have checked that $member_id is hashing correctly, and despite identical values it still returns 200.
$result = array(
'status' => sync_mailchimp($data)
);
var_dump($result) // 200
function sync_mailchimp($data) {
// Setup our Mailchimp info
$api_key = 'xxxxx';
$list_id = 'ab8abde5bb';
$member_id = md5(strtolower($data['email'])); // lowercase hash of the email
$datacenter = 'us16';
$url = 'https://' . $datacenter . '.api.mailchimp.com/3.0/lists/' . $list_id . '/members/' . $member_id;
$json = json_encode([
'email_address' => $data['email'],
'status' => $data['status']
]);
// Send via curl
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_USERPWD, 'user:' . $api_key);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
$result = curl_exec($ch);
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return $httpcode;
}

I was also having the same issue while using a similar snippet.
Reading the MailChimp API 3.0 docs relating to managing subscribers (specifically the section Subscribe an Address), it was clear that this method was not the correct way to add a new subscriber.
The request type needs to be a POST
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
and must be sent to the endpoint
https://<data_center>.api.mailchimp.com/3.0/lists/<list_id>/members/
The request body containing the JSON is identical.
The response code will be 200 when an email address is added to the list successfully, and 400 when the email address already exists on the list.
Note that this method will not work for updating an existing subscriber – to do that, the request type must be PATCH, and you must use the original endpoint ending with the hashed email address.

Related

how do i send notification to all mobile devices when i post a new content in Drupal? also Laravel is my Authentication back-end

I am using Laravel for authentication and druapl for content management, and now using firebase for notification to mobile devices... how do i send notification to all mobile devices when i post a new content in druapl?
this is my send function in Laravel
public function sendNotification($device_token, $message)
{
$SERVER_API_KEY = 'myKey';
$data = [
"to" => $device_token, // for single device id
"notification" => $message
];
$dataString = json_encode($data);
$headers = [
'Authorization: key=' . $SERVER_API_KEY,
'Content-Type: application/json',
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://fcm.googleapis.com/fcm/send');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $dataString);
$response = curl_exec($ch);
curl_close($ch);
return $response;
}
You should get token id from each user device and send notification via their device token as an array.
Add a new table named devices has user_id and device_token as columns then each new user open your application his device token will be sent to your server then you should save received token as new record to devices table.

How to update a Deal custom field in Pipedrive API?

I have a list of custom fields for a Deals in Pipedrive. (Located here https://your-instance.pipedrive.com/settings/fields?type=DEAL)
Each custom field has a custom API Key which looks like this a56aff894af47285d3bbcd67fe06ee5143fb1123
I try to update these fields in a Deal in bulk.
According to the Update a deal documentation https://developers.pipedrive.com/docs/api/v1/#!/Deals/put_deals_id there is no information about these custom fields.
The question is how to update custom field value in a certain Deal?
To achieve this you can send custom field key - value pairs just in the request body.
According to this example:
// Pipedrive API token
$api_token = '659c9fddb16335e48cc67114694b52074e812';
// Custom field key value pairs
$data = array(
'dcf558aac1ae4e8c4f849ba5e668430d8df9be12' => 'Custom field value'
);
// Deal ID
$deal_id = 260;
// URL for updating a Deal
$url = 'https://your-instance.pipedrive.com/api/v1/deals/' . $deal_id . '?api_token=' . $api_token;
// Prepare CURL Request
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
$output = curl_exec($ch);
curl_close($ch);

Mock Curl response for testing in laravel

I am trying to unit test a function(updateMeeting) in laravel which uses a curl request inside it. I tried many google links but nothing worked. can you guys give me suggestions on this matter.
following are relevant methods. $this->meeting is a MeetingModel
public function updateMeeting($meetingId){
$meeting = $this->meeting->find($meetingId);
$endpoint = \Config::get('api_backend_endpoint');
$response = $this->curlPut($endpoint);
if ($response->http_status_code != 200) {
if(Input::get('source') == 'ajax') {
$apiResponse = app(ApiResponse::class);
$message = 'ERROR Updating Meeting ' . $meeting->name;
return $apiResponse->failed($message);
}
return Redirect::route('meetings.show', $meetingId)
->withInput()
->with('message', 'An error occurred hiding meeting with message: ' . $response->errors);
}
$meeting->save();
}
following is curlPut method
private function curlPut($url, $payload = array())
{
$data_string = json_encode($payload);
$ch = curl_init();
//send through our payload as post fields
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_USERPWD, $this->username . ":" . $this->password);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($data_string))
);
$buffer = json_decode(curl_exec($ch));
curl_close($ch);
return $buffer;
}
Use a webservice like https://www.mocky.io/. Instead of requesting the real API, you send your requests to their API. You can create mock endpoints which return a response you can define.

POST requests require a Content-length header in laravel

$output = Curl::httpGet("https://bhleh.com/emailstorage", "POST", $params);
return $output;
this is in my laravel but when ever i try to run this i get an error saying
411. That’s an error.
POST requests require a Content-length header. That’s all we know.
i tried adding header files in my middle ware folder but nothing seems to work.
i figured out that the Content-length header isn't included in laravel (i think so not so sure) so how would i add it
please note i am very new to laravel
this fix to this is that this i replaced the whole code with this
$data_string = json_encode($params);
$ch = curl_init('https://bhleh.com/emailstorage');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($data_string))
);
$result = curl_exec($ch);
return $result;
I was facing the same issue but I was not sending CURLOPT_POSTFIELDS as per the API endpoint. I don't need to send any variable but when I send CURLOPT_POSTFIELDS with a blank array it started working.
$data_string = array();
$ch = curl_init('https://bhleh.com/emailstorage');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data_string));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json'
);
$result = curl_exec($ch);
return $result;

Quick q. Mailchimp API 3.0

Can i use the first script or i need to use the curl option for mailchimp 3.0? I read some posts that the first one may be depreciated.. is that correct? Note that i'm not running on WordPress. Thank you for your fast answers.
<?php
require("vendor/autoload.php");
use \DrewM\MailChimp\MailChimp;
$mc = new MailChimp('apikey');
$email = $_POST['email'];
$subscriber_hash = $mc->subscriberHash($email);
$response = [];
$list_id = 'listid';
$resp = $mc->get("/lists/$list_id/members/$subscriber_hash";
if ($mc->success()) {
$response['message'] = 'Thank you for subscribing to the mailing list';
// User successfully subscribed - set HTTP status code to 200
http_response_code(200);
} else {
$response['message'] = $mc->getLastError();
// User not subscribed - set HTTP status code to 400
http_response_code(400);
}
// Return json-formatted response
echo json_encode($response);
?>
Or should i use this one?
function mc_checklist($email, $debug, $apikey, $listid, $server) {
$userid = md5($email);
$auth = base64_encode( 'user:'. $apikey );
$data = array(
'apikey' => $apikey,
'email_address' => $email
);
$json_data = json_encode($data);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://'.$server.'.api.mailchimp.com/3.0/lists/'.$listid.'/members/' . $userid);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json',
'Authorization: Basic '. $auth));
curl_setopt($ch, CURLOPT_USERAGENT, 'PHP-MCAPI/2.0');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, $json_data);
$result = curl_exec($ch);
if ($debug) {
var_dump($result);
}
$json = json_decode($result);
echo $json->{'status'};
}
This row is only for stackoverflow not alowing me to post that much code without including more details.
The first is not deprecated. It uses this wrapper to make API calls using the same API version that the second block of code uses. It's just simpler to work with so you don't have to write separate CURL requests for every call. You can also take a look at some of its source code and notice that it uses CURL anyway to make its calls.
So either way will use CURL, and whichever option you choose is simply a matter of preference.
Hopefully that clears it up for you!

Resources