Unable to upload file on Teamwork using API in PHP - php

I am uploading a file on teamworking using the following link
https://developer.teamwork.com/projects/questions/fileUpload-preferred
Here I am using PHP Codeigniter 4.x framework with CURL to send request and in response to the first step, I am getting Ref and URL both values. i.e. First step is working fine on my end.
Now for the second step as mentioned in the documentation as follows,
Send a PUT request to the link above, with the ‘file’ in the body of the request. Along with this, you need the following headers:
X-Amz-Acl: public-read,
Content-Length: file-size
Host:host-from-the-generate-link
I am passing file object
CodeIgniter\HTTP\Files\UploadedFile Object ( [path:protected] =>
/var/www/web116/tmp/phpDyYgjj [originalName:protected] =>
banner-01.png [name:protected] => banner-01.png
[originalMimeType:protected] => image/png [error:protected] => 0
[hasMoved:protected] => [size:protected] => 639542
[pathName:SplFileInfo:private] => /var/www/web116/tmp/phpDyYgjj
[fileName:SplFileInfo:private] => phpDyYgjj )
in request body.
Here is my code as follows:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url); // $url is value which I have gotten after first step
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'X-Amz-Acl: public-read',
'Content-Length:' . $fileSize, // size of file
'Host: tw-bucket.s3.amazonaws.com'
));
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(['file' => $file])); // $file is file object which I have printed above
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$json = curl_exec($ch);
$result = (array) json_decode($json);
$result['http_code'] = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
But in the HTTP code, I am getting 403 rather than 200.
Can anyone please help me out with this so that I can upload the file on teamwork? I am working to upload a file for a particular task on teamwork.
Thanks

You can find another API to bypass this issue until the Teamwork API Support Team can fix this issue, here is what I did to make this work:
Step 1: Use the API https://apidocs.teamwork.com/docs/teamwork/86ecebd6161af-file-uploading-via-the-api-classic
To do this, you make an API Call to POST /pendingFiles.json. The actual file contents are sent via a form field called “file.”
If this is successful, you will receive a Status Code of 201 (Created) and a structure containing a reference code.
{ “pendingFile”: { “ref” : “tf_xxxxxxxxxxxxxxxx” } }
The ref bit is the important part and is the Pending File Handle.
Step 2: Create an actual file object using the Pending File Handle
The next step is to create the actual file object in a project on your Teamwork account.
To do this, you make an API Call to POST /projects/{id}/files.json where {id} is the project you want to create the file.
{
“file”: {
“description”: “Optional string describing the file”,
“category-id”: “ID of the category you to create the file in. Pass 0 if no category”,
“category-name”: “String if you want to create a new category – Pass category-id=0 also”,
“pendingFileRef”: “tf_xxxxxxxxxxxxxxxx”
}
}
Please note the "fileId" instead of the "pendingFileRef" if you want to attach the file to a task.
This is not a pending file like the other API.

Related

php telegram sendPhoto not working (url & file location)

I need some help if possible with php sendPhoto api, I've been using the sendPhoto method in php on my apache server to auto send images into telegram, I've been using this same method for almost 6-7 months and from few days ago suddenly the api method stopped working. I tried passing photo= using the absolute path of file in url and in php using the files directory+filename but sends me an error msg from the api as shown below, first part is my php method which doesnt return any errors, just shows blank
# my php telegram code
$dir = "Attachments/2022/04/09/imagename.jpeg";
$chat_id = '(groupchatid)';
$bot_url = "https://api.telegram.org/bot(mybotapi)/";
$url = $bot_url . "sendPhoto?chat_id=" . $chat_id ;
$post_fields = array('chat_id' => $chat_id,
'photo' => new CURLFile(realpath($dir)),
'caption' =>'Test Image', );
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, array( "Content-Type:multipart/form-data" ));
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);
$output = curl_exec($ch);
When i execute this script as it used to work before recently this is the response i get from the API
{
"ok": false,
"error_code": 400,
"description": "Bad Request: invalid file HTTP URL specified: Unsupported URL protocol"
}
If I replace the image URL to another server it send the image successfully, but im unable to send anything only from my server, If I try access the file directly using the URL of my servers image file I can access it from any pc no issue, only problem is telegram fetching the image, please help, appreciate it
Excuse, I don't usually use curl, so I can give you another option:
function sendPhoto($id, $photo, $text = null){
GLOBAL $token;
$url = 'https://api.telegram.org/bot'.$token."/sendPhoto?
chat_id=$id&photo=$photo&parse_mode=HTML&caption=".urlencode($text);
file_get_contents($url);
}
Just declare the sendPhoto function in this way, put the variabile in which you stored the token instead of "$token" and use the parameters in this way:
$id = the id of the user (the one you declared like this: $id = $update['message']['from']['id'];)
$photo = absolute path of the image you want to send
$text = OPTIONAL caption for the image

How do I send info to this API using cURL and PUT?

I am working with an API that is documented here: https://cutt.ly/BygHsPV
The documentation is a bit thin, but I am trying to understand it the best I can. There will not be a developer from the creator of the API available before the middle of next week, and I was hoping to get stuff done before that.
Basically what I am trying to do is update the consent of the customer. As far as I can understand from the documentation under API -> Customer I need to send info through PUT to /customers/{customerId}. That object has an array called "communicationChoices".
Going into Objects -> CustomerUpdate I find "communicationChoices" which is specified as "Type: list of CommunicationChoiceRequest". That object looks like this:
{
"choice": true,
"typeCode": ""
}
Doing my best do understand this, I have made this function:
function update_customer_consent() {
global $userPhone, $username, $password;
// Use phone number to get correct user
$url = 'https://apiurlredacted.com/api/v1/customers/' . $userPhone .'?customeridtype=MOBILE';
// Initiate cURL.
$ch = curl_init( $url );
// Specify the username and password using the CURLOPT_USERPWD option.
curl_setopt( $ch, CURLOPT_USERPWD, $username . ":" . $password );
// Tell cURL to return the output as a string instead
// of dumping it to the browser.
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
// Data to send
$data = [
"communicationChoices" => [
"communicationChoiceRequest" => [
"choice" => true,
"typeCode" => "SMS"
]
]
];
$json_payload = json_encode($data);
print_r($json_payload);
// Set other options
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json','Content-Length: ' . strlen($json_payload)));
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($ch, CURLOPT_POSTFIELDS, $json_payload);
// Execute the cURL request
$response = curl_exec($ch);
// Check for errors.
if( curl_errno( $ch ) ) :
// If an error occured, throw an Exception.
throw new Exception( curl_error( $ch ) );
endif;
if (!$response)
{
return false;
} else {
// Decode JSON
$obj = json_decode( $response );
}
print_r($response);
}
I understand that this is very hard to debug without knowing what is going on within the API and with limited documentation, but I figured asking here was worth a shot anyway.
Basically, $json_payload seems to be a perfectly fine JSON object. The response from the API however, is an error code that means unknown error. So I must be doing something wrong. Maybe someone has more experience with APIs and such documentation and can see what I should really be sending and how.
Any help or guidance will be highly appreciated!
before you test your code, you can use the form provided on the API Documentation.
when you navigate to API > Customers > /customers/{customerId} (GET), you will see a form on the right side of the page (scroll up). you need to provide the required values on the form then hit Submit button. you will surely get a valid data for communicationChoices based on the result from the Response Text section below the Submit button.
now, follow the data structure of communicationChoices object that you get from the result and try the same on API > Customers > /customers/{customerId} (PUT) form.
using the API forms, you may be able to instantly see a success or error from your input (data structure), then translate it to your code.

How to decode Json data from php file into another php file?

I am new in Creating API`s and I have created 2 files.php
1- API_ReadAll.php ( Its an API code that after execution will return Json Result)
Example Execute the below link:
http://localhost:8080/To%20work%20on/API_FUNCTIONS/API_ReadAll.php
Output:
Status Data Records:
[
{
STATUS_ID: "14",
STATUS_CODE: "AP 2013",
STATUS_DESCRIPTION: "Amazing wheel"
}, {
STATUS_ID: "13",
STATUS_CODE: "AP55.0",
STATUS_DESCRIPTION: "A23 Powder"
}, {
STATUS_ID: "16",
STATUS_CODE: "AP525.0",
STATUS_DESCRIPTION: "Power Drink"
}
]
2- Index.php ( Its an php file consist of HTML elements and table to display the data retrieved from the the page above)
I have tried to do the below:
// path to your JSON file
$url = 'http://localhost:8080/To%20work%20on/API_FUNCTIONS/API_ReadAll.php';
$json = file_get_contents($url);
$data = json_decode($json,true);
echo $data->STATUS_ID;
foreach($data As $display){
echo $display->STATUS_ID."<br>";
echo $display->STATUS_CODE."<br>";
echo $display->STATUS_DESCRIPTION."<br>";
}
Output:
Warning: file_get_contents( http://localhost:8080/To%20work%20on/API_FUNCTIONS/API_ReadAll.php): failed to open stream: No such file or directory in C:\xampp\htdocs\To work on\Temp-Builder\SEED_STATUS.PHP on line 122
Notice: Trying to get property 'STATUS_ID' of non-object in C:\xampp\htdocs\To work on\Temp-Builder\SEED_STATUS.PHP on line 125
Warning: Invalid argument supplied for foreach() in C:\xampp\htdocs\To work on\Temp-Builder\SEED_STATUS.PHP on line 125
Question:
How can I get and fetch the above Json inside the Index.php.
I'd first of all recommend you to read through the following guide create simple rest api with php (or any other tutorial of your choice), to get into the field of REST Apis with php.
Rather than handling api endpoints as file, you can use curl to perform a request against them. The result of that request can then be decoded to json with php's build in json_decode function.
To get you a starting point, I applied your approach to the curl sample found on php.net:
// define api endpoint
$url = 'http://localhost:8080/To%20work%20on/API_FUNCTIONS/API_ReadAll.php';
// create curl resource
$ch = curl_init();
// set url
curl_setopt($ch, CURLOPT_URL, $url);
//return the transfer as a string
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// $output contains the output string
$output = curl_exec($ch);
// close curl resource to free up system resources
curl_close($ch);
$json_obj = json_decode($output)
I also noticed, that you're passing "true" as second parameter to json_decode(). That way you will receive an associative array rather than an object. But in your example you're treating it as an object.
Also be aware of the fact that localhost is only accessable within your local network. So the community here cannot acess your example if that was your intension.
Good luck
-------------------------------------------------------------------------
Thank you for your time:
Regarding the link you provided to me to learn more about how to build the API. I did learn and build my API`s from that link and I successfully achieved what I am looking for.
Second about the code the comment of the link yes sure it will only have access from local serve, and I just posted like that trying to figure if this was a right way or not.
Regarding the code, I just tried your`s and still not working showing the following error:
Notice: Trying to get property 'STATUS_CODE' of non-object in C:\xampp\htdocs\To work on\Temp-Builder\INDEX.PHP....
Code:
// define api endpoint
$url = 'http://localhost:8080/To%20work%20on/Temp-Builder/API_FUNCTIONS/API_ReadAllSeed_Status.php';
// create curl resource
$ch = curl_init();
// set url
curl_setopt($ch, CURLOPT_URL, $url);
//return the transfer as a string
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// $output contains the output string
$output = curl_exec($ch);
// close curl resource to free up system resources
curl_close($ch);
$json_obj = json_decode($output);
foreach ($json_obj as $display){
echo $display->STATUS_ID."<br>";
echo $display->STATUS_CODE."<br>";
echo $display->STATUS_DESCRIPTION."<br>";
}

Get order transaction ID from authorize.net Authorize AIM

I'm making a custom woocommerce reports plugin that will display certain information and spit it out as a .csv. I have it return stuff like name, company name, product, and amount. I do this the following way.
/**
* Check if we need customer phone.
*/
case 'wc_settings_tab_customer_phone':
array_push( $csv_values, self::customer_meta( get_the_ID(), '_billing_phone' ) );
break;
Now I'm using the Authorize.net AIM Payment Gateway for Woocommerce plugin so a Transaction ID is generated.
I want to include this in my .csv export. How would I go about doing this? I tried looking in the plugin files and noticed this is what the transaction id was $response_array[6] but can't figure out how to return it. If someone could show me how to tap into Authorize.net API and get the transaction ID that would be awesome! Thanks in advanced!
EDIT: Here is what I've got so far. I added the php code to connect but can't seem to pull the order transaction id. By the way, the "x_login" and "x_tran_key" have been taken out and replaced with "test123".
case 'wc_settings_tab_authorize_id':
$post_url = "https://secure.authorize.net/gateway/transact.dll";
$post_values = array(
// the API Login ID and Transaction Key must be replaced with valid values
"x_login" => "test123",
"x_tran_key" => "test123",
"x_version" => "3.1",
"x_delim_data" => "TRUE",
"x_delim_char" => "|",
"x_relay_response" => "FALSE",
// Additional fields can be added here as outlined in the AIM integration
// guide at: http://developer.authorize.net
);
// This sample code uses the CURL library for php to establish a connection,
// submit the post, and record the response.
// If you receive an error, you may want to ensure that you have the curl
// library enabled in your php configuration
$request = curl_init($post_url); // initiate curl object
curl_setopt($request, CURLOPT_HEADER, 0); // set to 0 to eliminate header info from response
curl_setopt($request, CURLOPT_RETURNTRANSFER, 1); // Returns response data instead of TRUE(1)
curl_setopt($request, CURLOPT_POSTFIELDS, $post_string); // use HTTP POST to send form data
curl_setopt($request, CURLOPT_SSL_VERIFYPEER, FALSE); // uncomment this line if you get no gateway response.
$post_response = curl_exec($request); // execute curl post and store results in $post_response
// additional options may be required depending upon your server configuration
// you can find documentation on curl options at http://www.php.net/curl_setopt
curl_close ($request); // close curl object
// This line takes the response and breaks it into an array using the specified delimiting character
$response_array = explode($post_values["x_delim_char"],$post_response);
array_push( $csv_values, TransactionID() );
break;
EDIT 2: Implementing John's code
case 'wc_settings_tab_authorize_id':
$post_url = "https://secure.authorize.net/gateway/transact.dll";
$post_values = array(
// the API Login ID and Transaction Key must be replaced with valid values
"x_login" => "test123",
"x_tran_key" => "test123",
"x_version" => "3.1",
"x_delim_data" => "TRUE",
"x_delim_char" => "|",
"x_relay_response" => "FALSE",
// Additional fields can be added here as outlined in the AIM integration
// guide at: http://developer.authorize.net
);
// This sample code uses the CURL library for php to establish a connection,
// submit the post, and record the response.
// If you receive an error, you may want to ensure that you have the curl
// library enabled in your php configuration
$request = curl_init($post_url); // initiate curl object
curl_setopt($request, CURLOPT_HEADER, 0); // set to 0 to eliminate header info from response
curl_setopt($request, CURLOPT_RETURNTRANSFER, 1); // Returns response data instead of TRUE(1)
curl_setopt($request, CURLOPT_POSTFIELDS, $post_string); // use HTTP POST to send form data
curl_setopt($request, CURLOPT_SSL_VERIFYPEER, FALSE); // uncomment this line if you get no gateway response.
$post_response = curl_exec($request); // execute curl post and store results in $post_response
// additional options may be required depending upon your server configuration
// you can find documentation on curl options at http://www.php.net/curl_setopt
curl_close ($request); // close curl object
$post_response = '1|1|1|This transaction has been approved.|4DHVNH|Y|2230582188|none|Test transaction for ValidateCustomerPaymentProfile.|0.00|CC|auth_only|none|John|Doe||123 Main St.|Bellevue|WA|98004|USA|800-555-1234|800-555-1234|email#example.com|||||||||0.00|0.00|0.00|FALSE|none|E440D094322A0D406E01EDF9CE871A4F||2|||||||||||XXXX1111|Visa||||||||||||||||';
$response_array = explode('|',$post_response);
$transaction_id = $response_array[6];
array_push( $csv_values, $transaction_id );
break;
EDIT 3: Okay, this is what I currently have (excluding the api and transaction key).
/**
* Check for authorize.net transaction id.
*/
case 'wc_settings_tab_authorize_id':
$post_url = "https://secure.authorize.net/gateway/transact.dll";
$post_values = array(
// the API Login ID and Transaction Key must be replaced with valid values
"x_login" => "TEST",
"x_tran_key" => "TEST",
"x_version" => "3.1",
"x_delim_data" => "TRUE",
"x_delim_char" => "|",
"x_relay_response" => "FALSE",
// Additional fields can be added here as outlined in the AIM integration
// guide at: http://developer.authorize.net
);
// This sample code uses the CURL library for php to establish a connection,
// submit the post, and record the response.
// If you receive an error, you may want to ensure that you have the curl
// library enabled in your php configuration
$request = curl_init($post_url); // initiate curl object
curl_setopt($request, CURLOPT_HEADER, 0); // set to 0 to eliminate header info from response
curl_setopt($request, CURLOPT_RETURNTRANSFER, 1); // Returns response data instead of TRUE(1)
curl_setopt($request, CURLOPT_POSTFIELDS, http_build_query($post_values)); // use HTTP POST to send form data
curl_setopt($request, CURLOPT_SSL_VERIFYPEER, FALSE); // uncomment this line if you get no gateway response.
$post_response = curl_exec($request); // execute curl post and store results in $post_response
// additional options may be required depending upon your server configuration
// you can find documentation on curl options at http://www.php.net/curl_setopt
curl_close ($request); // close curl object
// This line takes the response and breaks it into an array using the specified delimiting character
$response_array = explode($post_values["x_delim_char"],$post_response);
$transaction_id = $response_array[6];
array_push( $csv_values, $transaction_id );
break;
Still can't figure out why this won't work. When I try and return the $transaction_id I get the value 0. When I try $post_response to see what it returns I get this:
3|2|33|Credit card number is required.||P|0|||0.00|CC|auth_capture||||||||||||||||||||||||||THISISANALPHANUMERICNUMBER||||||||||||||||||||||||||||||
Before there was an alphanumberic string but I replaced it for security purposes. Do you think this may be happening because I'm not setting a cc number or billing address with it?
The response string returned by Authorize.Net is going to look something like this:
1|1|1|This transaction has been approved.|4DHVNH|Y|2230582188|none|Test transaction for ValidateCustomerPaymentProfile.|0.00|CC|auth_only|none|John|Doe||123 Main St.|Bellevue|WA|98004|USA|800-555-1234|800-555-1234|email#example.com|||||||||0.00|0.00|0.00|FALSE|none|E440D094322A0D406E01EDF9CE871A4F||2|||||||||||XXXX1111|Visa||||||||||||||||
This is the results separated by a | which is the delimiting character you set here:
"x_delim_char" => "|",
You correctly break apart the string using explode():
$response_array = explode($post_values["x_delim_char"],$post_response);
which gives us that data in an array called $response_array.
In Authorize.Net's response, the transaction ID is 2230582188. In our array that is the seventh element so we can get it using:
$transaction_id = $response_array[6];
Here is a demo showing you this works.

Callback from API not happening after posting parameters to API URL from server side

API integration description
The API needs a form to be posted to the API URL with some input fields and a customer token. The API processes and then posts response to a callback.php file on my server. I can access the posted vals using $_POST in that file. That's all about the existing method and it works fine.
Requirement
To hide the customer token value from being seen from client side. So I started with sending server side post request.
Problem
I tried with many options but the callback is not happening -
1) CURL method
$ch = curl_init(API_URL);
$encoded = '';
$_postArray['customer_token'] = API_CUSTOMER_TOKEN;
foreach($_postArray as $name => $value)
{
$encoded .= urlencode($name).'='.urlencode($value).'&';
}
// chop off last ampersand
$encoded = substr($encoded, 0, strlen($encoded)-1);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $encoded);
$resp = curl_exec($ch);
curl_close($ch);
echo $resp;
$resp echoes 1 if the line curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); is removed but the callback does not happen. I am setting a session variable in the callback script to verify.Is it needed that the API be synchronous in order to use curl method, so that curl_exec returns the response?
2) without CURL as given in Posting parameters to a url using the POST method without using a form
But the callback is not happening.
I tried with the following code too, but looks like my pecl is not installed properly because the HttpRequest() is not defined.
$req = new HttpRequest($apiUrl, HttpRequest::METH_POST);
$req->addQueryData($params);
try
{
$r->send();
if ($r->getResponseCode() == 200)
{
echo "success";
// success!
}
else
{
echo "failure";
// got to the API, the API returned perhaps a RESTful response code like 404
}
}
catch (HttpException $ex)
{
// couldn't get to the API (probably)
}
Please help me out! I just need to easily send a server side post request and get the response in the callback file.
Try to debug your request using the curl_get_info() function:
$header = curl_getinfo($ch);
print_r($header);
Your request might be OK but it my result in an error 404.
EDIT: If you want to perform a post request, add this to your code:
curl_setopt($ch, CURLOPT_POST, true);
EDIT: Something else I mentioned at your code: You used a '1' at the 'CURLOPT_RETURNTRANSFER' but is should be 'true':
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
At least this is how I usually do it, and you never know if the function will also understand a '1' as 'true';
EDIT: The real problem: I copy-pasted your source and used it on one of my pages getting this error:
Warning: urlencode() expects parameter 1 to be string, array given in C:\xampp\htdocs\phptests\test.php on line 8
The error is in this line:
foreach($_postArray as $name => $value)
$_postArray is an array with one value holding the other values and you need either another foreach or you simple use this:
foreach($_postArray['customer_token'] as $name => $value)
As discussed in the previous question, the callback is an entirely separate thing from your request. The callback also will not have your session variables, because the remote API is acting as the client to the callback script and has its own session.
You should really show some API documentation here. Maybe we're misunderstanding each other but as far as I can see, what you are trying to do (get the callback value in the initial CURL request) is futile, and doesn't become any less futile by asking twice.

Categories