merge_fields error 400 - Mailchimp api v3 - ajax

I have a list with these fields: email, FNAME and LNAME. When I try to send merge_fields via Ajax, the Ajax return an error:
string(400) "{"type":"http://developer.mailchimp.com/documentation/mailchimp/guides/error-glossary/","title":"Invalid Resource","status":400,"detail":"The resource submitted could not be validated. For field-specific details, see the 'errors' array.","instance":"f311cff1-ec28-4003-8dde-007bc0001688","errors":[{"field":"merge_fields.FNAME","message":"Data did not match any of the schemas described in anyOf."}]}"
JS:
app.subscribe = function() {
$(document).on('submit', '.form-course', function(e) {
var fullName = $('#name').val(),
arrName = fullName.split(' '),
fname = arrName.slice(0, 1).join(' '),
lname = arrName.slice(1, arrName.length).join(' ');
var data = {
'email' : $('#email').val(),
"merge_fields": {
"FNAME": fname,
"LNAME": lname
}
};
console.log(data);
$.ajax({
url: url+'/wp-admin/admin-ajax.php?action=ux_subscribe',
method: 'POST',
data: data,
success: function(response) {
gtag('send', 'event', 'Modal', 'subscribed', 'Subscription');
fbq('track', 'CompleteRegistration');
$('#modal').fadeOut(function() {
// window.location.replace("./sucesso");
});
}, error: function(data) {
alert('ERRO! Tente novamente mais tarde!');
}
});
return false;
});
};
PHP:
function ux_subscribe() {
//GET via front-end form
$apiKey = 'XXX'; //Generate an API key via: Account > Extras > Api Keys
$listId = 'XXX'; //Find this via: Lists > List > Settings > List name and defaults
$email = $_POST['email']; //GET via front-end form
$fname = $_POST['fname']; //GET via front-end form
$lname = $_POST['lname']; //GET via front-end form
$auth = base64_encode( 'user:' . $apiKey );
echo $fname;
$json = json_encode([
'email_address' => $email,
'status' => "subscribed", // Choices include: "subscribed", "unsubscribed", "cleaned", "pending"
'merge_fields' => array(
'FNAME' => $fname,
'LNAME' => $lname
)
]);
$memberId = md5(strtolower( $email ));
$dataCenter = substr($apiKey,strpos($apiKey,'-')+1);
$url = 'https://' . $dataCenter . '.api.mailchimp.com/3.0/lists/' . $listId . '/members/';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['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_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
$result = curl_exec($ch);
var_dump($result);
wp_die();
}
If I remove the variables and put a string, it works:
$json = json_encode([
'email_address' => $email,
'status' => "subscribed", // Choices include: "subscribed", "unsubscribed", "cleaned", "pending"
'merge_fields' => array(
'FNAME' => 'hello',
'LNAME' => 'bye'
)
]);
Someone knows why???

You can not send "empty" values to the API.
For example, this will work:
$fname = "joe";
$lname = "smith"
'merge_fields' => array(
'FNAME' => $fname,
'LNAME' => $lname
)
But this would fail, notice how the lname is not defined.
$fname = "joe";
'merge_fields' => array(
'FNAME' => $fname,
'LNAME' => $lname
)
Therefore you need some simple shorthand to supply "empty" values.
$fname = empty($fname) ? " " : $fname;
$lname = empty($lname ) ? " " : $lname ;
'merge_fields' => array(
'FNAME' => $fname,
'LNAME' => $lname
)
I had a large array with 20 segments in it, and got the same error over and over, once I tossed in some proper empty() checking all was well...

This is old but wanted to point out that your javascript ajax call sends this data:
var data = {
'email' : $('#email').val(),
"merge_fields": {
"FNAME": fname,
"LNAME": lname
}
};
...But your PHP script is trying to find the post variables in:
$fname = $_POST['fname'];
$lname = $_POST['lname'];
Just update your ajax data to this:
var data = {
'email' : $('#email').val(),
'fname': fname,
'lname' : lname
};

Related

How to change the parameter name ? Sending file using Http Client

I am trying to change the parameter name from "filename" to "File1". This is the response.
"url" => "https://dev.abc.com?userName=1234&password=1234&cn=3517546&filename="
This my Laravel code. How should I mention it?
public function get_csv(){
$headers = array(
'Content-Type' => 'text/csv'
);
if (!File::exists(public_path()."/files")) {
File::makeDirectory(public_path() . "/files");
}
$newFileName = "alp-test-".rand(3,5).".csv";
$filename = public_path("files"."\\".$newFileName);
// dd($filename);
$handle = fopen($filename, 'w');
$user_CSV[0] = array('3517546', 'AMZ-test'.rand(3,5), 'UPS-Blue', '766369214006', '5170', '06', '', '3', '1', 'Hanes', '', '3931 Stone Lane', '', 'West Chester', 'PA', '19382');
foreach ($user_CSV as $line) {
fputcsv($handle, $line, ',');
}
fclose($handle);
$getFile = response()->file($filename, $headers);
$response = Http::withBasicAuth('webdev', 'alpdev')
->attach('File1', $getFile)
->post('https://dev.abc.com',
[
'userName' => '1234',
'password' => '1234',
'cn' => '3517546'
]);
return $response;
}

Update existing contact in Mailchimp

Hello guys I am trying to update a contact in my list with CRUL. I think everything looks great, only one think that I don't understand is {subscriber_hash}. How can i get this? Or maybe thats not a problem
I get this response
Exists","status":400,"detail":"example#example.com is already a list member. Use PUT to insert or update list members.","instance":"a5de431b-3b5a-3149-1fe3-bc1f6d08ec24"}
But my code looks good i think
$list_id = '[LISTID]';
$authToken = '[APIKEY]';
$postData = array(
"email_address" => "example#example.com",
"status" => "subscribed"
);
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://us12.api.mailchimp.com/3.0/lists/'.$list_id.'/members/{subscriber_hash}',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode($postData),
CURLOPT_HTTPHEADER => array(
'Authorization: apikey '.$authToken,
"cache-control: no-cache",
"content-type: application/json"
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
This is the working code finally
$list_id = 'LISTID';
$authToken = 'APIKEY';
// The data to send to the API
$postData = array(
"email_address" => "example#example.com",
"status" => "subscribed",
"firstname" => "asd",
"lastname" => "asda"
);
$data = $postData;
function syncMailchimp($data) {
$apiKey = 'APIKEY';
$listId = '0LISTID';
$memberId = md5(strtolower($data['email_address']));
$dataCenter = substr($apiKey,strpos($apiKey,'-')+1);
$url = 'https://' . $dataCenter . '.api.mailchimp.com/3.0/lists/' . $listId . '/members/' . $memberId;
$json = json_encode([
'email_address' => $data['email_address'],
'status' => $data['status'], // "subscribed","unsubscribed","cleaned","pending"
'merge_fields' => [
'FNAME' => 'asd',
'LNAME' => 'asd'
]
]);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_USERPWD, 'user:' . $apiKey);
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, 'PATCH');
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 $result;
}
$res = syncMailchimp($data);
print_r($res);

Send Transactional Mail using mailchimp

I am developing web application using Laravel. In this application I have to send email to the user. Now I want to send those emails using MailChimp. Can anyone guide me how can I send one to one email using MailChimp in Laravel.
I am using below code to send email please check and let me know what to do to send email
$apikey = '<key>-us12';
$to_emails = array('test#gmail.com');
$to_names = array('test');
$message = array(
'html' => 'Yo, this is the <b>html</b> portion',
'text' => 'Yo, this is the *text* portion',
'subject' => 'This is the subject',
'from_name' => 'OMO CRM',
'from_email' => 'customerservice#test.com',
'to_email' => $to_emails,
'to_name' => $to_names
);
$tags = array('WelcomeEmail');
$params = array(
'apikey' => $apikey,
'message' => $message,
'track_opens' => true,
'track_clicks' => false,
'tags' => $tags
);
$url = "https://us12.api.mailchimp.com/3.0/";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url . '?' . http_build_query($params));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
echo $result;
curl_close($ch);
$data = json_decode($result);
echo "Status = " . $data->status . "\n";
I am not able to send email using above code.

setting for saving data in the list in mailchimp campaign?

** I am building a emailing techniques with mailchimp i want to store
data in the lists how can i insert data in the list of mailchimp
campaign ?**
is there any kind of api or something else i am new to it.
I am using laravel to do this. data store in mysql but how to start saving it in the mailchimp list ?
This will help you
class MailChimpController extends Controller
{
public function add( Request $request ) {
$apikey="api key-us17";
$server = "us17.";
$listid = 'list id';
if ( $request->isMethod( 'post' ) ) {
//try {
$request_data = $request->all();
$email =$request_data['email'];
$request_data['earlyprice'] = isset($request_data['earlyprice']) ? floatval($request_data['earlyprice']) : 0.0 ;
$request->merge(['earlyprice' => $request_data['earlyprice']]);
$request_data['gaprice'] = isset($request_data['gaprice']) ? floatval($request_data['gaprice']) : 0.0 ;
$request->merge(['gaprice' => $request_data['gaprice']]);
$this->validate( $request, [
'title' => 'required|max:255',
'location' => 'required|max:255',
'starttime' => 'required',
'category' => 'required',
'type' => 'required',
'image' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048|dimensions:min_width=360,min_height=261',
'description' => 'required|max:1000',
'fullname' => 'required|max:255',
'phone' => 'required|max:255',
'email' => 'required|max:255',
'website' => 'required',
'socialmedia' => 'required'
] );
$event = new \App\CustomerEvent();
$imageName = "";
if ( $request->hasFile( 'image' ) ) {
$imageName = md5( time() ) . '.' . $request->image->getClientOriginalExtension();
$request->image->move( public_path( 'events_images' ), $imageName );
}
$requestData = $request->all();
$requestData['image'] = $imageName;
$requestData['status'] = "D";
$requestData['eventkey'] = $this->generate_key();
$event->fill( $requestData );
$x = $event->save();
$auth = base64_encode( 'user:'.$apikey );
$data = array(
'apikey' => $apikey,
'email_address' => $email,
'status' => 'subscribed',
);
$json_data = json_encode($data);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'Pathto ur trigger');
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_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, $json_data);
//return redirect()->back()->with( 'status', 'Event created' );
} else {
return view( 'events.host.index' );
}
}

To check favicon using Google API

How can we check favicon provided by Google API is the default globe?
https://www.google.com/s2/u/0/favicons?domain=facebook.com returns the favicon of the facebook, where as https://www.google.com/s2/u/0/favicons?domain=test.com returns the globe as the favicon.
How can we check if the favicon is default globe or not?
I made a function a while back which checks if the default globe icon is returned.
function getFavicon($domain) {
$data = file_get_contents('https://plus.google.com/_/favicon?domain=' . $domain);
$base64 = base64_encode($data);
return ($data && hash('md5', $base64) !== '99fd8ddc4311471625e5756986002b6b' ? 'data:image/png;base64,' . $base64 : false);
}
$favicon = getFavicon('facebook.com');
if ( $favicon ) {
echo '<img src="' . $favicon . '" />';
}
When I came across this same issue I performed an md5 checksum of the returned image, made a note of what the default globe image md5 hash was and used that to confirm the presence of a favicon (or not).
See example php code below
<?php
class favicon {
/*
Example Return
Array
(
[md5] => 598900b91902a2de1e8be0a888a3f7bb
[png_string] => // image as a string for saving to file later
[image] => // Embedded Image <img alt="Embedded Image" src="data:image/png;base64,iVBORw0K..." />
[error] => // true or flase
[error_text] => // description of the error
[domain] => // http://www.orange.co.uk/
[endpoint] => https://plus.google.com/_/favicon?domain=http://www.orange.co.uk/
[endpoint_id] => 1
[headers] => Array
(
[Content-Type] => image/png
[X-UA-Compatible] => IE=edge, chrome=1
[Expires] => Mon, 07 Oct 2013 10:39:34 GMT
[Date] => Sun, 06 Oct 2013 10:39:34 GMT
[X-Content-Type-Options] => nosniff
[X-Frame-Options] => SAMEORIGIN
[X-XSS-Protection] => 1; mode=block
[Server] => GSE
[Cache-Control] => public, max-age=86400
[Content-Length] => 232
[Age] => 23
)
)
*/
public static function stream($domain, $endpoint = 1) {
if ($endpoint == 1) {
// endpoint 1
$url = 'https://plus.google.com/_/favicon?domain=' . $domain;
$error = 'b8a0bf372c762e966cc99ede8682bc71'; // md5 of blank image
}
elseif ($endpoint == 2) {
// endpoint 2 etc
$url = 'https://plus.google.com/_/favicon?domain=' . $domain;
$error = 'b8a0bf372c762e966cc99ede8682bc71'; // md5 of blank image
}
else {
return array(
'md5' => null,
'png_string' => '',
'error' => true,
'error_text' => '$endpoint argument should have the value 1 or 2',
'headers' => null,
'domain' => $domain,
'endpoint' => $url,
'endpoint_id' => (int) $endpoint
);
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); // The number of seconds to wait while trying to connect. Use 0 to wait indefinitely.
curl_setopt($ch, CURLOPT_TIMEOUT, 10); // The maximum number of seconds to allow cURL functions to execute.
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); // don’t try and do any clever ssl
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 1);
$part = explode("\r\n\r\n", curl_exec($ch));
curl_close($ch);
$headers = self::http_parse_headers($part[0]);
$md5 = md5($part[1]);
if ($md5 == $error) {
return array(
'md5' => $md5,
'png_string' => '',
'image' => '',
'error' => true,
'error_text' => 'no favicon could be found for this domain',
'domain' => $domain,
'endpoint' => $url,
'endpoint_id' => (int) $endpoint,
'headers' => $headers
);
}
return array(
'md5' => $md5,
'png_string' => $part[1],
'image' => '<img alt="Embedded Image" src="data:image/png;base64,' . base64_encode($part[1]) . '" />',
'error' => false,
'error_text' => null,
'domain' => $domain,
'endpoint' => $url,
'endpoint_id' => (int) $endpoint,
'headers' => $headers
);
}
private static function http_parse_headers($raw_headers) {
if (! empty($raw_headers)) {
$headers = array();
foreach (explode("\n", $raw_headers) as $i => $h) {
$h = explode(':', $h, 2);
if (isset($h[1])) {
$headers[$h[0]] = trim($h[1]);
}
}
return $headers;
}
return false;
}
}
?>

Resources