I'm trying to add a job to the Workflow Max API. I seem to be hitting the API but I keep getting the error message:
Message not in expected format. The following required element was missing - Job/ClientID
I'm sure that the client ID is added but something seems to be wrong. This is the code:
function post_job_to_workflow_max($job_data) {
// configure our connection to the api
$api_token = 'API_KEY';
$acc_key = 'ACC_TOKEN';
$url = 'https://api.workflowmax.com/job.api/add?apiKey=' . $api_token . '&accountKey=' . $acc_key;
// Job data must match the format required by WorkflowMax
// currently accepts XML data
// see: https://www.workflowmax.com/api/job-methods#POST%20add
$xml = new SimpleXMLElement("<Job></Job>");
$xml->addChild('Name', $job_data[0]);
$xml->addChild('Description', $job_data[1]);
$xml->addChild('ClientID', 18754031);
// $clientID = $xml->addChild('Client');
// $clientID->addChild('ID', 18754031);
// $clientID->addChild('Name', "TEST CLIENT");
$xml->addChild('State', 'Planned');
$xml->addChild('StartDate', $job_data[2]);
$xml->addChild('DueDate', $job_data[3]);
// print_r($xml);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml->asXML());
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: text/xml',
'Content-Length: ' . strlen($xml->asXML()))
);
$output = curl_exec($ch);
curl_close($ch);
$result = simplexml_load_string($output);
print_r($result);
}
If there's anyone with experience of using WFM, would be good to hear how you approached it.
Thanks
So in answer to my own question, I did finally work this out.
The way I did this was to return the ID of the client from the function I used to post a client to WorkFlow Max. See code:
1) post the client
function post_client_to_workflowmax($client_data) {
// configure our connection to the api
$api_token = 'YOUR_TOKEN';
$acc_key = 'YOUR_KEY';
$url = 'https://api.workflowmax.com/client.api/add?apiKey=' . $api_token . '&accountKey=' . $acc_key;
// Client data must match the format required by WorkflowMax
// currently accepts XML data
// These indexes match up with how the data has been stored
// see: https://www.workflowmax.com/api/client-methods#POST%20add
$xml = new SimpleXMLElement("<Client></Client>");
$xml->addChild('Name', htmlspecialchars($client_data[2]));
$xml->addChild('Email', htmlspecialchars($client_data[9]));
$xml->addChild('Phone', htmlspecialchars($client_data[10]));
$xml->addChild('Address', htmlspecialchars($client_data[3]) . ' ' . htmlspecialchars($client_data[4]));
$xml->addChild('City', htmlspecialchars($client_data[5]));
$xml->addChild('Postcode', htmlspecialchars($client_data[7]));
$xml->addChild('Country', htmlspecialchars($client_data[8]));
$xml->addChild('IsProspect', 'No');
$contacts = $xml->addChild('Contacts');
$contact = $contacts->addChild('Contact');
$name = $contact->addChild('Name', htmlspecialchars($client_data[0]) . ' ' . htmlspecialchars($client_data[1]));
// POST request
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml->asXML());
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: text/xml',
'Content-Length: ' . strlen($xml->asXML()))
);
$output = curl_exec($ch);
curl_close($ch);
// Create an array from the data that is sent back from the API
$result = simplexml_load_string($output);
$clientID = NULL;
// here we get the ID created for this client and pass it into the variable $clientID
foreach($result->Client as $k => $v) {
$clientID = $v->ID;
}
return $clientID;
}
We then get that ID passed into our job posting function like so:
2) post a job to WFM
function post_job_to_workflow_max($job_data, $clientID) {
// configure our connection to the api
$api_token = 'YOUR_TOKEN';
$acc_key = 'YOUR_KEY';
$url = 'https://api.workflowmax.com/job.api/add?apiKey=' . $api_token . '&accountKey=' . $acc_key;
// Job data must match the format required by WorkflowMax
// currently accepts XML data
// see: https://www.workflowmax.com/api/job-methods#POST%20add
$xml = new SimpleXMLElement("<Job></Job>");
$xml->addChild('ClientID', $clientID);
$xml->addChild('Name', htmlspecialchars($job_data[0]));
$xml->addChild('Description', htmlspecialchars($job_data[1]));
$xml->addChild('State', 'Planned');
$xml->addChild('StartDate', htmlspecialchars($job_data[2]));
$xml->addChild('DueDate', htmlspecialchars($job_data[3]));
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml->asXML());
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: text/xml',
'Content-Length: ' . strlen($xml->asXML()))
);
$output = curl_exec($ch);
curl_close($ch);
$result = simplexml_load_string($output);
}
And then calling these functions looks something like this:
$id = post_client_to_workflowmax($client);
post_job_to_workflow_max($job, $id);
Where $client must be an array of data. This worked for my case but might not work for your particular case so you may need to edit the fields etc.
Hopefully this helps someone who is stuck with the same problem. Not the most elegant code but it gets the job done.
Related
Im trying to connect to the API services of 2ba. Somehow I just can't connect. I get the error: error: "invalid_client"
I dont know what to try, it feels like I need to hash my cliend_secret or complete url but I dont see that in the documentation.
This is my code (PHP):
<?php
// ---- GET TOKEN ----
// Base url for all api calls.
$baseURL = 'https://authorize.2ba.nl';
// Specified url endpoint. This comes after the baseUrl.
$endPoint = '/OAuth/Token';
// Parameters that are required or/and optianal for the endPoint its request.
$parameters = 'grant_type=password&username=abc#abc.com&password=123abc&client_id=myClientID&client_secret=myClientSecret';
// All parts together.
$url = $baseURL . $endPoint . '?' . $parameters;
//Init session for CURL.
$ch = curl_init();
// Options
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
// Init headers for access to the binance API signed data.
$headers = array();
$headers[] = 'Content-type: application/x-www-form-urlencoded';
$headers[] = 'Content-Length: 0';
// Setting headers
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
// Execute request.
$data = curl_exec($ch);
// If there is an error. Show whats wrong.
if (curl_errno($ch)) {
echo 'Error:' . curl_error($ch);
}
// Ends the CURL session, frees all resources and deletes the curl (ch).
curl_close($ch);
$result = json_encode($data);
echo($data);
exit();
?>
The authentication is oauth2 and I want to use the "Password Grant" flow since I can login automaticly this way. Also I see in the example code in C# that they encode the url, something im not doing yet but did try. It did not work.
// Using $encodedUrl like this: curl_setopt($ch, CURLOPT_URL, $encodedUrl); but does not work.
$encodedUrl = urlencode($url);
Alright so I fixed it. I now got my access token and am able to recieve data from the API. This is what I did:
// ---- GET TOKEN - FLOW: USER PSW ----
// No changes
$baseURL = 'https://authorize.2ba.nl';
// No changes
$endPoint = '/OAuth/Token';
// $parameters is now an array.
$parameters = array(
'grant_type' => 'password',
'username' => 'myUsername',
'password' => 'myPassword',
'client_id' => 'myClientID',
'client_secret' => 'myClientSecret'
);
// Removed the $parameter part
$url = $baseURL . $endPoint;
//Init session for CURL.
$ch = curl_init();
// Init headers for access to the binance API signed data.
$headers = array();
$headers['Content-Type'] = "application/x-www-form-urlencoded";
// NOTE: http_build_query fixed it.
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($parameters)); // Automaticly encodes parameters like client_secret and id.
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
// Execute request.
$data = curl_exec($ch);
// If there is an error. Show whats wrong.
if (curl_errno($ch)) {
echo 'Error:' . curl_error($ch);
}
// Ends the CURL session, frees all resources and deletes the curl (ch).
curl_close($ch);
$result = json_encode($data);
echo($data);
exit();
I get JSON from the Soundcloud API by using code in section【A】.
But I want to get it without using $type, like in code【B】.
In other words, I want to get that information by only giving $target.
What should I do?
$r = soundcloud_responce();
var_dump( $r );
function soundcloud_responce(){
$client_id = 'xxx';
$type = 'tracks';
$q = 'words';
// code【A】
// If I have $type, So this process ok.
$url = "https://api.soundcloud.com/";
$url .= $type;
$url .= "?client_id=$client_id";
$url .= "&q=$q";
// code【B】
// I want to do same process with $target but without $type
$target = "https://soundcloud.com/accountname/trackname";
$target = str_replace('https://soundcloud.com/', '', $target);
$url = "https://api.soundcloud.com/";
$url .= $target;
$url .= "?client_id=$client_id";
// curl
$ch = curl_init();
$headers = [
'Accept: application/json',
'Content-Type: application/json',
];
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$res = curl_exec($ch);
$json = json_decode($res);
curl_close($ch);
return $json;
}
(Add 2020-02-21-09:38 #Tokyo)
I tried this code【C】but this also failed.
// code【C】
// I tried with oembed but this also failed.
$target = "https://soundcloud.com/accountname/trackname";
$url = 'http://soundcloud.com/oembed?format=json&url='.$target;
(Add 2020-02-21-10:12 #Tokyo)
I tried this code【D】but this also failed.
// code【D】
// I tried with resolve but this also failed.
$target = "https://soundcloud.com/accountname/trackname";
$url = "https://api.soundcloud.com/resolve?url=$target&client_id=$client_id";
I tried this code【E】this is successful!
Thank you for giving me good advice, #showdev.
// code【E】
// this is successful!
$target = "https://soundcloud.com/accountname/trackname";
$target = urlencode($target);
$url = "https://api.soundcloud.com/resolve.json?url=$target&client_id=$client_id";
I have this code in python that do a request to the API of suap passing the values of dados_usuario, that I tested and is working, but I wanna write the same code in php and I dont getting it, all I got was the token with the follow code, so, anyone could help me with the second part using curl in php?
python code - https://imgur.com/a/LpZ7j4S
import requests
# Obtaining the user's token
url = 'https://suap.ifrn.edu.br/api/v2/autenticacao/token/'
#username and password are your data used to access SUAP
dados_usuario = {
'username': '',
'password': ''
}
requisicao = requests.post(url, data=dados_usuario)
if requisicao.status_code == requests.codes.ok:
token_autenticacao = requisicao.json().get('token')
print ('\n--- Token de Autenticação:\n {}\n\n'.format(token_autenticacao))
# Obtaining User Data.
url = 'https://suap.ifrn.edu.br/api/v2/minhas-informacoes/meus-dados/'
headers = {
'Authorization':'JWT {}'.format(token_autenticacao)
}
requisicao = requests.get(url, headers=headers)
if requisicao.status_code == requests.codes.ok:
retorno_json = requisicao.json()
print ('--- Dados do Usuário Logado:\n{}\n\n'.format(retorno_json))
php code - https://imgur.com/a/tkxb9Gm
<?php
$url = 'https://suap.ifrn.edu.br/api/v2/autenticacao/token/';
$user_data = [
'username' => '',
'password' => ''
];
$ch = curl_init();
//Getting the user token
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $user_data);
$result = curl_exec($ch);
//Token variable
$token = json_decode($result, true);
curl_close($ch);
echo $token["token"]."\n\n";
I need get the user date with php, until now I just have the token, and I need get it with curl.
I got the resolver with this code
$token = "token hide";
$ch = curl_init('https://suap.ifrn.edu.br/api/v2/minhas-informacoes/meus-dados/');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Authorization: JWT ' . $token
));
$data = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);
I'm having a lot of trouble integrating Sagepay InFrame Server with PHP, as there are no integration kits available for the new protocol (v3). I have the old kits for v2.23 but much of the code therein is deprecated.
At the moment the only way i have been successful in retrieving an OK status from the Sagepay Server servers is to have a form with the collection of hidden values required by Sagepay, including the cryptography field, and using the server URL as the form action. This gives me a status of 'OK' and the SecurityKey etc in the browser tab, but its not much use in the browser tab as i need that POST response back on my server, not on theirs.
For this i opted for curl. I hold the return values for curl_exec in a variable called $rawresponse, and dump the response after each attempt, and as it stands $rawresponse is returning as a false boolean:
$curlSession = curl_init();
curl_setopt ($curlSession, CURLOPT_URL, $url);
curl_setopt ($curlSession, CURLOPT_HEADER, 0);
curl_setopt ($curlSession, CURLOPT_POST, 1);
$data['Crypt'] = new CurlFile('filename.png', 'image/png', 'filename.png');
curl_setopt ($curlSession, CURLOPT_POSTFIELDS, $data);
curl_setopt($curlSession, CURLOPT_RETURNTRANSFER,1);
curl_setopt($curlSession, CURLOPT_TIMEOUT,30);
curl_setopt($curlSession, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curlSession, CURLOPT_SSL_VERIFYHOST, 0);
$rawresponse = curl_exec($curlSession);
Now as you can see here I am having to force the Crypt value to be of type CurlFile, which is what i think is breaking the request, however if i dont do that i get the following error:
"The usage of the #filename API for file uploading is deprecated. Please use the CURLFile class instead"
I can only ascertain from this that the cryptography is being mistaken for a file (possibly because the string starts with #), and to counter this im trying to force it to be an image.
So my question is this - is there a particular way to use CurlFile so cryptography strings can be understood? Is there a better way of integrating this functionality with Sagepay that anyone knows about? It really is a very confusing system, and the good documentation is let down by a complete lack of example.
Apologies for this, I was building the string the wrong way. Just in case anyone has a similar problem in the future i'll paste the code that works for me:
public function registerTransaction()
{
$VPSProtocol = urlencode($_POST['VPSProtocol']);
$TxType = urlencode($_POST['TxType']);
$Vendor = urlencode($_POST['Vendor']);
$VendorTxCode = urlencode($_POST['VendorTxCode']);
$Currency = urlencode($_POST['Currency']);
$Amount = urlencode($_POST['Amount']);
$NotificationURL = urlencode($_POST['NotificationURL']);
$Description = urlencode($_POST['Description']);
$BillingSurname = urlencode($_POST['BillingSurname']);
$BillingFirstnames = urlencode($_POST['BillingFirstnames']);
$BillingAddress1 = urlencode($_POST['BillingAddress1']);
$BillingCity = urlencode($_POST['BillingCity']);
$BillingPostCode = urlencode($_POST['BillingPostCode']);
$BillingCountry = urlencode($_POST['BillingCountry']);
$DeliverySurname = urlencode($_POST['DeliverySurname']);
$DeliveryFirstnames = urlencode($_POST['DeliveryFirstnames']);
$DeliveryAddress1 = urlencode($_POST['DeliveryAddress1']);
$DeliveryCity = urlencode($_POST['DeliveryCity']);
$DeliveryPostCode = urlencode($_POST['DeliveryPostCode']);
$DeliveryCountry = urlencode($_POST['DeliveryCountry']);
$url = "?VPSProtocol=" . $VPSProtocol;
$url .= "&TxType=" . $TxType;
$url .= "&Vendor=" . $Vendor;
$url .= "&VendorTxCode=" . $VendorTxCode;
$url .= "&Currency=" . $Currency;
$url .= "&Amount=" . $Amount;
$url .= "&NotificationURL=" . $NotificationURL;
$url .= "&Description=" . $Description;
$url .= "&BillingSurname=" . $BillingSurname;
$url .= "&BillingFirstnames=" . $BillingFirstnames;
$url .= "&BillingAddress1=" . $BillingAddress1;
$url .= "&BillingCity=" . $BillingCity;
$url .= "&BillingPostCode=" . $BillingPostCode;
$url .= "&BillingCountry=" . $BillingCountry;
$url .= "&DeliverySurname=" . $DeliverySurname;
$url .= "&DeliveryFirstnames=" . $DeliveryFirstnames;
$url .= "&DeliveryAddress1=" . $DeliveryAddress1;
$url .= "&DeliveryCity=" . $DeliveryCity;
$url .= "&DeliveryPostCode=" . $DeliveryPostCode;
$url .= "&DeliveryCountry=" . $DeliveryCountry;
$strPurchaseURL = "https://test.sagepay.com/gateway/service/vspserver-register.vsp";
$arrResponse = $this->requestPost($strPurchaseURL, $url);
dd($arrResponse);
}
public function requestPost($url, $data){
// Set a one-minute timeout for this script
set_time_limit(60);
// Initialise output variable
$output = array();
// Open the cURL session
$curlSession = curl_init();
curl_setopt ($curlSession, CURLOPT_URL, $url);
curl_setopt ($curlSession, CURLOPT_HEADER, 0);
curl_setopt ($curlSession, CURLOPT_POST, 1);
curl_setopt ($curlSession, CURLOPT_POSTFIELDS, $data);
curl_setopt($curlSession, CURLOPT_RETURNTRANSFER,1);
curl_setopt($curlSession, CURLOPT_TIMEOUT,30);
curl_setopt($curlSession, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curlSession, CURLOPT_SSL_VERIFYHOST, 2);
$rawresponse = curl_exec($curlSession);
dd($rawresponse);
//Store the raw response for later as it's useful to see for integration and understanding
$_SESSION["rawresponse"]=$rawresponse;
//Split response into name=value pairs
$response = preg_split(chr(10), $rawresponse);
// Check that a connection was made
if (curl_error($curlSession)){
// If it wasn't...
$output['Status'] = "FAIL";
$output['StatusDetail'] = curl_error($curlSession);
}
// Close the cURL session
curl_close ($curlSession);
// Tokenise the response
for ($i=0; $i<count($response); $i++){
// Find position of first "=" character
$splitAt = strpos($response[$i], "=");
// Create an associative (hash) array with key/value pairs ('trim' strips excess whitespace)
$output[trim(substr($response[$i], 0, $splitAt))] = trim(substr($response[$i], ($splitAt+1)));
} // END for ($i=0; $i<count($response); $i++)
// Return the output
return $output;
} // END function requestPost()
I'm just stuck with the curl thing...
It doesn't give me any problem before in my code but here, it appears when I do a var_dump, that the $EAACCOUNT is always empty... Nevertheless, I'm pretty sure that the url request is right because it works in other parts of my coding...
Do you guys have any idea how I could solve this?
$account= "http://www.ea.com/p/fut/a/" . $machine . "/l/". $ulocal ."/s/p/ut/game/fifa13/user/accountinfo?timestamp=". $time;
$auth = "http://www.ea.com/p/fut/a/" . $machine . "/l/". $ulocal ."/s/p/ut/auth";
$quest = "http://www.ea.com/p/fut/a/" . $machine . "/l/". $ulocal ."/s/p/ut/game/fifa13/phishing/validate";
//Cookie Data includes the two keys from above
$cookie_string = $EASW_KEY."; ".$EASF_SESS;
//Setup cURL HTTP request
$ch = curl_init($account);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_COOKIE, $cookie_string);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/x-www-form-urlencoded')
);
$EAACCOUNT = curl_exec($ch);
curl_close($ch);
//Get personaID and Platform
$d = json_decode($EAACCOUNT, true);
$personaID = $d->userAccountInfo->personas[0]->personaId;
$platform = $d->userAccountInfo->personas[0]->userClubList[0]->platform;