I have to implement form on a webpage, that sends data to Microsoft Dynamics CRM when submited. The data needs to be saved to a certain lead.
I have created simple PHP script that uses curl to communicate with CRM server but I always get 401 status code that indicates authorization has failed.
define('MS_CRM_URL', 'https://______.crm.dynamics.com/');
define('MS_CRM_USER', 'user#domain.com');
define('MS_CRM_PASS', 'password');
$method = '/api/data/v8.0/accounts?$select=name&$top=3';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, MS_CRM_URL . $method);
curl_setopt($ch, CURLOPT_USERPWD, MS_CRM_USER .':'. MS_CRM_PASS);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, array(
));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Accept' => 'application/json',
'OData-MaxVersion' => '4.0',
'OData-Version' => '4.0',
'Content-Type' => 'application/json',
));
$server_output = curl_exec($ch);
$status_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$json = array();
if ((int)$status_code === 200) {
$json = json_decode($server_output);
}
echo '<pre>';
var_dump($status_code);
var_dump($json);
echo '</pre>';
The $method var contents are taken from an example that I've found somewhere on Microsoft documentation site. The documentation was not very helpful to me.
Have you seen this yet? http://jlattimer.blogspot.com/2015/02/soap-only-authentication-using-php.html
Also, it looks like there's an ADAL library for PHP. https://github.com/jamesmcq/azure-activedirectory-library-for-php You should be able to authenticate using that.
You can do it using SOAP Authentication. I have same requirement where we need to send data to Dynamics 365 online from PHP website. I have achieved it using source code from below link :
https://bitbucket.org/nigelheap/msdynamicsphp-master
Related
I'm trying to send a message to a Telegram Bot using CURL in this PHP code ...
<?php
$botToken="<MY_DESTINATION_BOT_TOKEN_HERE>";
$website="https://api.telegram.org/bot".$botToken;
$chatId=1234567; //Receiver Chat Id
$params=[
'chat_id'=>$chatId,
'text'=>'This is my message !!!',
];
$ch = curl_init($website . '/sendMessage');
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, ($params));
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$result = curl_exec($ch);
curl_close($ch);
?>
The code runs with no error but no message is shown in my destination Telegram bot.
The token is what the BotFather give me when I created my destination Telegram bot (Use this token to access the HTTP API: <MY_DESTINATION_BOT_TOKEN>)
Any suggestion will be appreciated ...
I've solved .... In my original code there were two errors, one in the code and one due on a Telegram feature that I didn't know: actually, telegram bot to bot communication is not possible as explained here Simulate sending a message to a bot from url
So my code revised is the follow
<?php
$botToken="<MY_DESTINATION_BOT_TOKEN_HERE>";
$website="https://api.telegram.org/bot".$botToken;
$chatId=1234567; //** ===>>>NOTE: this chatId MUST be the chat_id of a person, NOT another bot chatId !!!**
$params=[
'chat_id'=>$chatId,
'text'=>'This is my message !!!',
];
$ch = curl_init($website . '/sendMessage');
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, ($params));
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$result = curl_exec($ch);
curl_close($ch);
?>
In this way all works fine!
You can obtain chat ID from #RawDataBot, it will be .message.chat.id.
For instance, in this response will be 109780439.
if you want to send telegram using CURL, you need to download file cacert.pem and copy to your web server and then call them from your PHP script.
You can download file cacert.pem from
https://drive.google.com/open?id=1FCLH88MpKNLDXZg3pJUSAZ0BbUbNmBR2
I have tutorial video that can give you the clearly answer, include how to create bot, get token, get user chat_id, troubleshooting SSL and Proxy in CURL, etc:
Here is the link of my tutorial video https://youtu.be/UNERvcCz-Hw
Here is the complete script:
<?php
// using GET URL Parameter -> message
$pesan = urlencode($_GET["message"]);
$token = "bot"."<token>";
$chat_id = "<chat_id>";
$proxy = "<ip_proxy>:<port>";
$url = "https://api.telegram.org/$token/sendMessage?parse_mode=markdown&chat_id=$chat_id&text=$pesan";
$ch = curl_init();
if($proxy==""){
$optArray = array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CAINFO => "C:\cacert.pem"
);
}
else{
$optArray = array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_PROXY => "$proxy",
CURLOPT_CAINFO => "C:\cacert.pem"
);
}
curl_setopt_array($ch, $optArray);
$result = curl_exec($ch);
$err = curl_error($ch);
curl_close($ch);
if($err<>"") echo "Error: $err";
else echo "Message SENT";
?>
use this will work
$TOKEN="your bot token";
$url="https://api.telegram.org/bot{$TOKEN}/sendMessage";
$request=curl_init($url);
$query=http_build_query([
'chat_id'=>"your id",
'text'=>$msg,
'parse_mode'=>'MarkDown'
]);
curl_setopt_array($request,[
CURLOPT_POST=>1,
CURLOPT_POSTFIELDS=>$query,
]);
curl_exec($request);
I've tested it and its worked.
you only need to us chatId like below:
$chatId='1234567';
I've written a basic API script in PHP using cURL - and successfully used a version of it on another API, this one is specifically to handle domain DNS management on DigitalOcean - and I can't send data?
Prelude...
I understand there is a PHP library available, I'm not after something that full featured or bloated with dependencies - just something small to use locally and primarily to help me understand how RESTful API's work a little better in practice - an educational exercise
The offending Code...
function basic_api_handle($key, $method, $URI, $data) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Authorization: Bearer '.$key,
'Content-Type: application/json')
);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
curl_setopt($ch, CURLOPT_URL, $URI);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
$result = curl_exec($ch);
if($result === false) error_log("API ERROR: Connection failure: $URI", 0);
curl_close($ch);
return json_decode($result, true);
}
var_dump(basic_api_handle($api_key, 'POST', 'https://api.digitalocean.com/v2/domains', array('name' => 'my-domain.tld', 'ip_address' => '1.2.3.4')));
This works with a GET request, such as listing the domains on the account but seems to fail at posting/sending data... this results in "unprocessable_entity" and "Name can't be blank" - as the name is not blank and is correctly formatted (as far as I can tell) it suggests to me the data is not being sent correctly?
Solution Attempts so far...
I've tried json encoding the data (seen in code), not json encoding, url encoding with and without json encoding and various other options with no luck.
I've seen a few posts online about this exact same issue specifically with DigitalOcean's API (and a another) but no one had an explanation (other than give up and use the library or something to that affect).
Using cURL directly from a terminal does work etc so there is nothing wrong with the API for creating a domain.
As far as I understand, the authentication is working, and the general setup works as I can list domains within the account, I just cant POST or PUT new data. I've been though the API's documentation and can't see what I'm doing wrong, maybe some sort of wrong encoding?
Any help would be much appreciated! :)
Edit:
After much work and research even other simple API handlers do not work with Digital Ocean (such as https://github.com/ledfusion/php-rest-curl) - is there something this API in particular needs or am I missing something fundamental about API's in general?
Technically this is not an fix but a work around. Thank you everyone for your comments and ideas, unfortunately nothing worked/fixed the code and the bounty expired :(
Although I have no idea why the PHP cURL option didn't work (the HTTP works, just Digital Ocean spitting errors for unknown reason linked to validation of the post data)...
I do have a new method that DOES WORK finally... (thanks to jtittle post on the Digital Ocean Community forum)
Just incase that link dies in the future... he's the working function using streams and file_get_contents and not curl...
<?php
function doapi( $key, $method, $uri, array $data = [] )
{
/**
* DigitalOcean API URI
*/
$api = 'https://api.digitalocean.com/v2';
/**
* Merge DigitalOcean API URI and Endpoint URI
*
* i.e if $uri is set to 'domains', then $api ends up as
* $api = 'https://api.digitalocean.com/v2/domains'
*/
$uri = $api . DIRECTORY_SEPARATOR . $uri;
/**
* Define Authorization and Content-Type Header.
*/
$headers = "Authorization: Bearer $key \r\n" .
"Content-Type: application/json";
/**
* If $data array is not empty, assume we're passing data, so we'll encode
* it and pass it to 'content'. If $data is empty, assume we're not passing
* data, so we won't sent 'content'.
*/
if ( ! empty( $data ) )
{
$data = [
'http' => [
'method' => strtoupper( $method ),
'header' => $headers,
'content' => json_encode( $data )
]
];
}
else
{
$data = [
'http' => [
'method' => strtoupper( $method ),
'header' => $headers
]
];
}
/**
* Create Stream Context
* http://php.net/manual/en/function.stream-context-create.php
*/
$context = stream_context_create( $data );
/**
* Send Request and Store to $response.
*/
$response = file_get_contents( $uri, false, $context );
/**
* Return as decoded JSON (i.e. an array)
*/
return json_decode( $response, true );
}
/**
* Example Usage
*/
var_dump(doapi(
'do-api-key',
'get',
'domains'
));
I used this to actually post the data successfully...
var_dump(doapi(
$api_key,
'post',
'domains',
array("name" => (string) $newDomain, "ip_address" => "1.2.3.4")
));
Add the Content-Length header and use CURLOPT_POST option for POST requests
function basic_api_handle($key, $method, $URI, $data) {
$json = json_encode($data)
$headers = array(
'Authorization: Bearer '.$key,
'Content-Type: application/json'
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_URL, $URI);
if ( $method === 'POST' ) {
curl_setopt($curl, CURLOPT_POST, 1);
} else {
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
array_push($headers, 'Content-Length: ' . strlen($json) );
}
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers)
curl_setopt($ch, CURLOPT_POSTFIELDS, $json );
$result = curl_exec($ch);
if($result === false) error_log("API ERROR: Connection failure: $URI", 0);
curl_close($ch);
return json_decode($result, true);
}
Maybe this will work for you:
function basic_api_handle($key, $method, $URI, $data) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method); // <-- Should be set to "GET" or "POST"
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // <-- Maybe the SSL is the problem
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36"); // <-- I am not familiar with this API, but maybe it needs a user agent?
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Authorization: Bearer '.$key,
'Content-Type: application/json')
);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
curl_setopt($ch, CURLOPT_URL, $URI);
curl_setopt($ch, CURLOPT_POST, count($data)); // <-- Add this line which counts the inputs you send
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
$result = curl_exec($ch);
if($result === false) error_log("API ERROR: Connection failure: $URI", 0);
curl_close($ch);
return json_decode($result, true);
}
It can also be a problem of a header you should sent and your missing it.
It could be a 307 or 308 http redirect.
Maybe "https://api.digitalocean.com/v2/domains" redirects to another url.
If this is the case, try adding:
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
to make curl follow the redirection and keep the parameters.
It is suggested that you also use:
curl_setopt($curl, CURLOPT_POSTREDIR, 3);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST");
to keep the request body.
Hope it helps.
You can also try use CURLOPT_POST
I have an API in postman. I want to create a CURL Request and get proper response with it. This is my POSTMAN API.
I am successfully getting this response with it.
"{\"Request\":{\"state\":\"Manama\",\"address\":\"406 Falcon Tower\",\"address2\":\"Diplomatic Area\",\"city\":\"Manama\",\"country\":\"BH\",\"fullname\":\"Dawar Khan\",\"postal\":\"317\"},\"Response\":{\"status\":\"Success\",\"code\":100,\"message\":\"Address is verified\"}}"
Now I want to use this API Call inside my PHP Code. I used this code.
$data = array(
'Request' => 'ValidateAddress',
'address' => test_input($form_data->address),
'secondAddress' => test_input($form_data->secondAddress),
'city' => test_input($form_data->city),
'country' => test_input($form_data->country),
'name' => test_input($form_data->name),
'zipCode' => test_input($form_data->zipCode),
'merchant_id' => 'shipm8',
'hash' => '09335f393d4155d9334ed61385712999'
);
$data_string = json_encode($data);
$url = 'myurl.com/';
$ch = curl_init($url);
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);
curl_close($ch);
$json_result = json_decode($result, true);
echo '<pre>';print_r($json_result);echo '</pre>';
But I can't see my $json_result. It just echoes <pre></pre> in the view. Can anyone guide me? Thanks in advance. I want to get my Response.
UPDATE
I used curl_error and it gives me the following error.
Curl error: SSL certificate problem: self signed certificate in certificate chain
It is Very Simple Just Click on Code you will get the code in php.
you will get the code in many language like php,java,ruby,javascript,nodejs,shell,swift,pythom,C# etc.
Answer updated as per updated question.
There are two ways to solve this issue
Lengthy, time-consuming yet clean
Visit URL in web browser.
Open Security details.
Export certificate.
Change cURL options accordingly.
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_CAINFO, getcwd() . "/CAcerts/BuiltinObjectToken-EquifaxSecureCA.crt");
Quick but dirty
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
We are configuring cURL to accept any server(peer) certificate. This isn’t optimal from a security point of view.
Excerpt from very detailed and precise article with screenshots for better understanding. Kindly refer the same before actually implementing it in production site.
I've just read the following on the MailChimp website:
MailChimp API v3.0 is now live!
Prior versions will no longer be supported after 2016, so all API users should begin transitioning to v3.0.
As a result, I would like to move to v3.0 of the API. Please could I have a function, in PHP, that returns a boolean, that will check whether an email address is subscribed to a specific MailChimp list. I do not want to subscribe that user, but merely check whether they are subscribed or not.
If you use the mailchimp-api it looks like that
include 'Mailchimp.php';
use \DrewM\MailChimp\MailChimp;
$MailChimp = new MailChimp('your**api***key');
function emailExistsMc($subscriberMail, $list_id){
global $MailChimp;
$subscriber_hash = $MailChimp->subscriberHash($subscriberMail);
$result = $MailChimp->get("lists/$list_id/members/$subscriber_hash");
if($result['status'] == '404') return false;
return true;
}
If $result['status'] is 404 then the resource was not found. Other possible values for $result['status'] are stated in the docs:
subscribed
unsubscribed
cleaned
pending
transactional
UPDATE: I answered another question with a more elaborate tutorial of how to do this with jQuery .ajax(): Adding subscribers to a list using Mailchimp's API v3
Looking at the Mailchimp documentation and assuming you have a given list in mind, it looks like you would call this endpoint with a GET:
/lists/{list_id}/members/{subscriber_hash}
To do this in PHP, I found a nice script sitting on github. Their last function would probably do the trick for you:
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'};
}
If that function doesn't work, the only wrapper I could find for the v3 library works in conjunction with Laravel - Mailchimp v3 API PHP wrapper.
I use the DrewM library
function isSubscribed($emailAddress, $listId) {
$chimp = new \DrewM\MailChimp\MailChimp($apiKeyHere);
$subscriberHash = $chimp->subscriberHash($emailAddress);
$result = $chimp->get('lists/' . $listId . '/members/' . $subscriberHash);
return ($chimp->success() && isset($result['id']));
}
We're updating our Mailchimp implementation from 1.3 to 3.0. We succesfully updated our code to subscribe someone to a list. Now we're trying to add an ecommerce order. In API v1.3 we did this with the function campaignEcommOrderAdd. I found the function to this with in v3.0: /ecommerce/stores/{store_id}/orders(website link).
But I can't get it to work. When posting to Mailchimp I get an 404 error, but I don't know what I'm doing wrong. Below is my code.
$apiKey = "xxx"; //xxx for privacy reasons
$json = json_encode(array(
'id' => $mailchimp_order['id'],
'customer' => array(
'id' => $mailchimp_order['email_id'],
),
'campaign_id' => $mailchimp_order['campaign_id'],
'currency_code' => "EUR",
'order_total' => $mailchimp_order['total'],
'tax_total' => $mailchimp_order['tax'],
'lines' => $mailchimp_order['items'],
));
$dataCenter = substr($apiKey,strpos($apiKey,'-')+1);
$url = 'https://'.$dataCenter.'.api.mailchimp.com/3.0/ecommerce/stores/'.$mailchimp_order['store_id'].'/orders';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_USERPWD, 'user:' . $apiKey);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
$result = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
This is the output of my $json var:
{
"id":"10000003",
"customer":{
"id":"a90f52f710"
},
"campaign_id":"641657",
"currency_code":"EUR",
"order_total":"56.90",
"tax_total":"47.02",
"lines":[
{
"id":"224",
"product_id":"4427",
"product_title":"Product name",
"product_variant_id":0,
"quantity":"1",
"price":"49.95"
}
]
}
And this is the error I get:
object(stdClass) {
type => 'http://developer.mailchimp.com/documentation/mailchimp/guides/error-glossary/'
title => 'Resource Not Found'
status => (int) 404
detail => 'The requested resource could not be found.'
instance => ''
}
Without knowing more I would try a few things here. One (you may have already tried this, but check the output of $url) to make sure that all that is getting set correctly. Secondly I would make sure that the store instance you are posting this order to is reachable/exists by making a GET request to, what would be:
$url = 'https://'.$dataCenter.'.api.mailchimp.com/3.0/ecommerce/stores/'.$mailchimp_order['store_id']'
Lastly I would verify that both the campaign and product instances associated with the order are reachable using:
GET https://{dc}.api.mailchimp.com/3.0/campaigns/641657
GET https://{dc}.api.mailchimp.com/3.0/ecommerce/stores/{store_id}/products/4427
Also if you are doing a lot of updating to 3.0 for your app it might be useful to implement a library that abstracts out a lot of this code I use this one:
https://github.com/Jhut89/Mailchimp-API-3.0-PHP
My reputation score wont let me post more links to those endpoints but they should be easily found in the MailChimp documentation. Hope that helps out.