I'm trying to use the MailChimp API to add subscribers to a list once they've checked a box on a form. I can do this with cURL, and it works fine, but the server that this will be on does not have it enabled. I'm trying to use file_get_contents(), but that gives me a 401 error. I've checked the API key and the list id, and they're both correct. I'm guessing that my syntax is messed up or that I've put something in the wrong place, but I'm not seeing the problem. What I've tried is below. Anyone have any ideas?
if (isset($_POST['mailtest']) == 'value1'){
$email = $_POST['email'];
$fname = $_POST['firstname'];
$lname = $_POST['lastname'];
$mailchimp_api_key = 'apikey';
$mailchimp_list_id = 'listid';
$data = array(
'apikey' => $mailchimp_api_key,
'id' => $mailchimp_list_id,
'email' => $email
'status'=>'subscribed'
);
$memberId = md5(strtolower($email));
$dataCenter = substr($mailchimp_api_key ,strpos($mailchimp_api_key, '-')+1);
$endpoint = 'https://' . $dataCenter . '.api.mailchimp.com/3.0/lists/' . $mailchimp_list_id . '/members/' . $memberId;
if ($fname && $lname) $data['merge_vars '] = array('FNAME' => $fname, 'LNAME' => $lname);
$json_data = json_encode($data);
$options = array(
'http' => array(
'method' => 'POST',
'header' => "Content-type: application/json",
"Connection: close\r\n" .
"Content-length: " . strlen($json_data) . "\r\n",
'data' => $json_data,
),);
$context = stream_context_create($options);
$result = file_get_contents($endpoint, false, $context);
}
You need to set the Basic authentication header. As well it seems you're including your dataCentre in with your api key, so the below code might need some tweaking since I don't actually know what $mailchimp_api_key is set to.
// this is improper usage of isset. isset returns a boolean
// since you're not doing a strict match it'll always work,
// unless mailtest is null or isn't set.
if (isset($_POST['mailtest']) == 'value1') {
$email = $_POST['email'];
$fname = $_POST['firstname'];
$lname = $_POST['lastname'];
$mailchimp_api_key = 'apikey';
$mailchimp_list_id = 'listid';
$data = array(
'apikey' => $mailchimp_api_key,
'id' => $mailchimp_list_id,
'email' => $email
'status'=>'subscribed'
);
$memberId = md5(strtolower($email));
$dataCenter = substr($mailchimp_api_key ,strpos($mailchimp_api_key, '-')+1);
$endpoint = 'https://' . $dataCenter . '.api.mailchimp.com/3.0/lists/' . $mailchimp_list_id . '/members/' . $memberId;
if ($fname && $lname) {
$data['merge_vars '] = array('FNAME' => $fname, 'LNAME' => $lname);
}
$json_data = json_encode($data);
$options = array(
'http' => array(
'method' => 'POST',
'header' => implode(
"\r\n",
[
"Content-type: application/json",
"Content-length: " . strlen($json_data),
"Authorization: Basic " . base64_encode("anystring:$mailchimp_api_key") // see note above
]
),
'content' => $json_data,
)
);
$context = stream_context_create($options);
$result = file_get_contents($endpoint, false, $context);
}
Related
I am trying to submit a new subscriber via a form on a WordPress website. I am concentrating on sending the subscriber information to a list in MailChimp. I am getting the following error:
string(75) "cURL error 6: Could not resolve host: us19.api.mailchimp.com; Unknown error"
My question is whether there is an issue with the arguments being passed to the wp_remote_post() function?
This is my code:
<?php
$api_key = '[HIDDEN]';
$list_id = '[HIDDEN]';
$email = "[HIDDEN]";
$firstname = "[HIDDEN]";
$lastname = "[HIDDEN]";
$status = 'subscribed'; // subscribed, cleaned, pending
$args = array(
'method' => 'PUT',
'headers' => array(
'Authorization' => 'Basic ' . base64_encode( 'user:'. $api_key )
),
'body' => json_encode(array(
'email_address' => $email,
'status' => $status
))
);
$response = wp_remote_post( 'https://' . substr($api_key,strpos($api_key,'-')+1) . '.api.mailchimp.com/3.0/lists/' . $list_id . '/members/' . md5(strtolower($email)), $args );
var_dump($response);
?>
I'm trying to follow the Using OAuth 2.0 for Server to Server Applications guide to get an access token so that I can use the Youtube Reporting API.
But no matter what I do, I always this result:
Warning: file_get_contents(https://www.googleapis.com/oauth2/v4/token): failed to open stream: HTTP request failed! HTTP/1.0 400 Bad Request
Here's my code
$contents = file_get_contents('BCGA-557d334b8526.json');
$account = json_decode($contents, TRUE);
$privateKeyString = $account['private_key'];
$time = time();
$expiration = $time + 3600;
$header = '{"alg":"RS256","typ":"JWT"}';
$claim_set = '{"iss":"youtube-reporting#ataproject-850089.iam.gserviceaccount.com","scope":"https://www.googleapis.com/auth/yt-analytics.readonly","aud":"https://www.googleapis.com/oauth2/v4/token","exp":"' . $expiration . '","iat":"' . $time . '"}';
$unsignedToken = base64_encode($header) . '.' . base64_encode($claim_set);
$signature = hash_hmac('sha256', $unsignedToken, $privateKeyString, true);
$jwt = base64_encode($header) . '.' . base64_encode($claim_set) . '.' . base64_encode($signature);
$url = "https://www.googleapis.com/oauth2/v4/token";
$data = array('grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', 'assertion' => $jwt);
// use key 'http' even if you send the request to https://...
$options = array(
'http' => array(
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
'method' => 'POST',
'content' => http_build_query($data)
)
);
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
if ($result === FALSE) { /* Handle error */ }
var_dump($result);
Any suggestions?
You forgot
'grant_type' => 'refresh_token'
I am trying to use file_get_contents to "post" to a url and get auth token. The problem I am having is that it returns a error.
Message: file_get_contents(something): failed to open stream: HTTP request failed! HTTP/1.1 411 Length Required.
I am not sure what is causing this but need help. Here is the function.
public function ForToken(){
$username = 'gettoken';
$password = 'something';
$url = 'https://something.com';
$context = stream_context_create(array (
'http' => array (
'header' => 'Authorization: Basic ' . base64_encode("$username:$password"),
'method' => 'POST'
)
));
$token = file_get_contents($url, false, $context);
if(token){
var_dump($token);
}else{
return $resultArray['result'] = 'getting token failed';
}
}
I tried it with POSTMAN, and it works, so only problem I am having is that why isnt it working with file_get_contents.
Cannot command so i will do it this way. If you use Postman why don't you let Postman generate the code for you. In postman you can click code at a request and you can even select in what coding language you wanne have it. Like PHP with cURL:
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "http://somthing.com/",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => array(
"password: somthing",
"username: gettoken"
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
Hope this will help!
I can not comment because of my reputation;
In some servers file_get_content is not available...
You may try with CURL like this
Your request havent any data and content length is missing.
You can try this:
public function ForToken(){
$username = 'gettoken';
$password = 'something';
$url = 'https://something.com';
$data = array('foo' => 'some data');
$data = http_build_query($data);
$context_options = array (
'http' => array (
'method' => 'POST',
'header'=> "Content-type: application/x-www-form-urlencoded\r\n"
. "Authorization: Basic " . base64_encode("$username:$password") . "\r\n"
. "Content-Length: " . strlen($data) . "\r\n",
'content' => $data
)
);
$context = context_create_stream($context_options);
$token = file_get_contents($url, false, $context);
if(token){
var_dump($token);
}else{
return $resultArray['result'] = 'getting token failed';
}
}
Here is similar problem:
How to fix 411 Length Required error with file_get_contents and the expedia XML API?
RFC2616 10.4.12
https://www.rfc-editor.org/rfc/rfc2616#section-10.4.12
Code: (Doesn't work, see below)
public function ForToken(){
$username = 'gettoken';
$password = 'something';
$url = 'https://something.com';
$context = stream_context_create(array (
'http' => array (
'header' => 'Authorization: Basic ' . base64_encode("$username:$password") . 'Content-Length: ' . strlen($url) . '\r\n',
'method' => 'POST'
)
));
$token = file_get_contents($url, false, $context);
if(token){
var_dump($token);
}else{
return $resultArray['result'] = 'getting token failed';
}
}
2nd Try:
public function ForToken(){
$username = 'gettoken';
$password = 'something';
$url = 'https://something.com';
$context_options = array (
'http' => array (
'method' => 'POST',
'header'=> "Content-type: application/x-www-form-urlencoded\r\n" . "Authorization: Basic " . base64_encode("$username:$password") . "Content-Length: " . strlen($url) . "\r\n",
'content' => $url
)
);
$context = stream_context_create($context_options);
$token = file_get_contents($url, false, $context);
if(token){
var_dump($token);
}else{
return $resultArray['result'] = 'getting token failed';
}
}
This is from patryk-uszynski's answer formatted with the OP's code.
I'm very new to programming and using API. I am currently working on a project to take data from BLS.GOV using their API to port the data to my website! so far, BLS has given me this code:
$url = 'http://api.bls.gov/publicAPI/v2/timeseries/data/';
$method = 'POST';
$query = array(
'seriesid' => array('LEU0254555900', 'APU0000701111'),
'startyear' => '2002',
'endyear' => '2012'
);
$pd = json_encode($query);
$contentType = 'Content-Type: application/json';
$contentLength = 'Content-Length: ' . strlen($pd);
$result = file_get_contents(
$url, null, stream_context_create(
array(
'http' => array(
'method' => $method,
'header' => $contentType . "\r\n" . $contentLength . "\r\n",
'content' => $pd
),
)
)
);
var_dump($http_response_header);
var_dump($result);
How would I be able to grab graph data with PHP from this link.
One site requires login for three variables: username, password and token. This data is sent via POST.
token is also sent through a section.
I have all three variables, and I want to log in via file_get_contents.
How can that data be sent and the authentication is successful?
function file_post_contents()
{
$url = 'http://site.com/auth.php?' . session_name() . '=' . session_id();
$login = 'jhon';
$senha = 'doe';
$token = '123456';
$_SESSION["token"] = $token;
$postdata = http_build_query(
array(
'login' => $login,
'senha' => $senha,
'token' => $token,
$_SESSION["token"] => $token
)
);
$opts = array('http' =>
array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => $postdata
)
);
if($login && $senha)
{
$opts['http']['header'] = ("Authorization: Basic " . base64_encode("$login:$senha"));
}
$context = stream_context_create($opts);
return file_get_contents($url, false, $context);
}
Modified code. It does not work.
function file_post_contents()
{
$url = 'http://site.com/auth.php?' . session_name() . '=' . session_id();
$login = 'jhon';
$senha = 'doe';
$token = '123456';
$_SESSION["token"] = $token;
$postdata = http_build_query(
array(
'login' => $login,
'senha' => $senha,
'token' => $token
//, $_SESSION["token"] => $token
)
);
$opts = array('http' =>
array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded'
. "\r\n" . "Authorization: Basic " . base64_encode("$login:$senha"). "\r\n",
'content' => $postdata
)
);
$context = stream_context_create($opts);
return file_get_contents($url, false, $context);
}
Your headers might be set wrong, try adding \r\n like so
$opts = array('http' =>
array(
'method' => 'POST',
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
'content' => $postdata
)
);
and later down the code
$opts['http']['header'] = $opts['http']['header'] . "Authorization: Basic " . base64_encode("$login:$senha") . "\r\n";
You're overriding $opts['http']['header'] with the Basic auth. You're not adding it to the Content-type, you're replacing Content-type with it.