Stream Elements PUT Request - php

Good Afternooon all,
Please can someone give me a example of a PUT request? i have seen a couple online but i can not seam to get any to work.... I am trying to create an app for my live streaming channel, below is what i am trying to use PUT for.
Here is the DEV link to the API: https://dev.streamelements.com
So the URL would be: https://api.streamelements.com/kappa/v2
the PUT i need is the following
/points/{channel}/{user}/{amount}
Media type: application/json
so i understand the url in full if it was a get:
(api.streamelements.com/kappa/v2/points/channe id removed/username removed)
That gives me my points on a selected channel but to add or remove points it has to be a PUT and i have no idea on how to use it, so if anyone could give me some example of the above i could learn from it and do all the other requests myself
Many Thanks for your time
Kev (TADS)

You may need to be familiar with HTTP clients such as Guzzle or other clients that implements Psr7 interface.
In your case your code should looks like:
$client = new GuzzleHttp\Client();
$client->put('https://api.streamelements.com/kappa/v2/REST_OF_URL', [
'headers' => ['X-Foo' => 'Bar'],
'body' => [
'field1' => 'value1',
// ...
],
'timeout' => 10
]);
Obviously I'm assuming that you know how to include the Guzzle library to your project using Composer or standalone include.

Related

Possibly recoverable warning exit code from extractor: -536870935 when translating Revit source file

I have been following along with the Translate a Revit File, Generating Room and Space Information tutorial. Right now I'm stuck on task 3 trying to translate a Revit source file to SVF2.
Using the provided Revit file and the following request POST https://developer.api.autodesk.com/modelderivative/v2/regions/eu/designdata/job:
// Headers
[
'Authorization' => ...,
'Content-Type' => 'application/json',
'x-ads-force' => true,
]
// Body
[
"input" => [
"urn" => "<some urn>",
"compressedUrn" => false
],
"output" => [
"destination" => [
"region" => "EMEA"
],
"formats" => [
[
"type" => "svf2",
"views" => [
"2d",
"3d"
],
"advanced" => [
"generateMasterViews" => true
]
]
]
]
]
I always get the following messages:
Revit-UnsupportedFileType
The file is not a Revit file or is not a supported version. TranslationWorker-RecoverableInternalFailure
Possibly recoverable warning exit code from extractor: -536870935
I hope someone can tell what is wrong with the POST request. I found a similar question but the answer doesn't seem apply to this issue.
I actually tried this same tutorial myself and it works perfectly on my end. As long as you follow every step, you are supposed to get the desired result.
If you're running into an error in the third task, it shows there might be something you didn't do correctly in Task 2.
There are a few steps you should check in Task 2 that Task 3 is dependent upon. Please check the following:
Make sure your file is fully uploaded. Look at "Upload the file" section in Task 2 of the tutorial.
You must inform OSS (Object Storage Service) that the upload operation is complete. Look at "Finalize Upload" section in Task 2.
These actions should ensure that your file is fully uploaded and ready to be translated to SVF2
NOTE: When doing all these processes, make sure your Access Token is valid as it only remains valid for one hour. If the token expires, you must obtain a fresh token by sending an authenticate request to Forge once again.
When asking the question I was using the following code to upload the file to Autodesk using Laravel's http client:
$response = Http::attach( 'file', $file->getContent(), $file->getClientOriginalName() )
->put( $signed_url );
This did upload the files and everything worked for zipped models. But as explained in the question plain source files like .ipt or .rvt did not translate.
I guess Laravel is adding something to that request that somehow corrupts files for Autodesk. Using the following request:
$response = Http::withHeaders( [
'Content-Disposition' => 'attachment; filename='.$file->getClientOriginalName(),
'Content-Length' => $file->getSize(),
] )
->send(
'PUT',
$signed_url,
[
'body' => $file->getContent(),
]
);
it does work. I guess using send, sends a "raw"/ binary request.
In Symfony it would look something like:
$response = HttpClient::create()->request(
'PUT',
$signed_url,
[
'body' => $file->getContent(),
'headers' => [
'Content-Disposition' => 'attachment; filename='.$file->getClientOriginalName(),
'Content-Length' => $file->getSize()
]
]
);
I'm not familiar with Lavarel so I might not offer much help on that part.
However, you could try and use another framework like Nodejs or even .NET to try and see if you can achieve your desired results.
You can follow this tutorial that will help you get started in creating your application on top of the Autodesk platform using either Nodejs or .NET framework: https://forge-tutorials.autodesk.io/
You will get to use the Model Derivative API and you can then try and convert the model as intended.

How to add tags when uploading an object to an S3 bucket

I've been working with some example code from Amazon to get a script to upload an object to a bucket in version 3 of the php sdk for aws. I can get the object to upload to a bucket, but I'm trying to add a tag to this new object during this PutObject method call. I've worked through a few examples that I found, but nothing has worked for me. Here is my php code so far:
$cmd = $s3Client->getCommand('PutObject', [
'Bucket' => $config['s3BucketName'],
'Key' => 'file_upload_direct.mp4',
'Tagging' => 'status=notProcessed',
]);
The Tagging property doesn't get applied and doesn't give any error when the form is sent. I've seen a few ways of adding tags to uploads, but none of those have worked for me. I'm trying to avoid using the PutObjectTagging method since that seems to be extra work if I'm able to define the tag in the PutObject method. I'm not sure if the issue is trying to use the PutObject method in the getCommand or not, but as far as I can tell you should be able to pass the normal parameters as an array like this. Has anyone been able to get this to work, or is there a different way I should be trying to accomplish this?
it is better later than never, right?
The problem here is that AWS Docs are poor on emphasising important details like:
Note: Not all operation parameters are supported when using pre-signed URLs. Certain parameters, such as SSECustomerKey, ACL, Expires, ContentLength, or Tagging must be provided as headers when sending a request.
You can find these in API Docs and easy to overlook.
This means you prepare data to create a signature with this:
$cmd = $s3Client->getCommand('PutObject', [
'Bucket' => $config['s3BucketName'],
'Key' => 'file_upload_direct.mp4',
'Tagging' => 'status=notProcessed',
]);
Then when you get the URL back from
$s3Client->createPresignedRequest($cmd, '+5 minutes');
And you PUT to that URL, you have to also send HTTP Header X-Amz-Tagging: status=notProcessed
Another important thing to keep in mind is that, if you are PUTting from the frontend, your bucket must have CORS policies properly set up and allow headers like x-amz-tagging.

Is it possible to insert a Horizontal Rule with Google Docs API?

I've been working on a project that needs to insert both text and other types of elements into a Google Docs Document, using PHP. I'm able to insert text using the following code:
$requests = [];
```
$requests[] = new \Google_Service_Docs_Request(
['insertText' => ['text' => 'Text to insert',
'location' => ['index' => $insertionIndex],
],
]);
```
$batchUpdateRequest = new \Google_Service_Docs_BatchUpdateDocumentRequest(['requests' => $requests]);
$docsService->documents->batchUpdate($documentID, $batchUpdateRequest);
I can also insert a page break with a similar call:
$requests = [];
```
$requests[] = new \Google_Service_Docs_Request(
['insertPageBreak' => ['location' => ['index' => $insertionIndex],
],
]);
```
$batchUpdateRequest = new \Google_Service_Docs_BatchUpdateDocumentRequest(['requests' => $requests]);
$docsService->documents->batchUpdate($documentID, $batchUpdateRequest);
Both of the above work fine (and as per Google's recommendations when I am carrying out multiple insertions I am working backwards). What I need to be able to do is add a horizontal rule to the document. I know Google Docs allows the manual insertion of them and Apps Script supports insertHorizontalRule but the Docs API doesn't seem to have an equivalent. I have searched here, Google, and the API documentation and can't find any reference to it. Could someone tell me if it is possible? If it is possible, what is the correct request type?
It's seems additionally strange that there isn't a documented way of inserting them, and yet you can query the contents of an existing document and any that are in the document are reported back to you as part of its structure.
For clarity of purpose, I am trying to append the contents of one Google Doc to the another. If anyone knows of a better way to do this than consuming the source document element by element and creating a request to add those elements to the destination document, that would bypass the need to handle inserting a horizontal rule.
You want to insert the horizontal rule to Google Document using Docs API.
You want to achieve this using php.
You have already been able to get and put the values for Google Document using Docs API.
I could understand like above. Unfortunately, in the current stage, it seems that there are no methods for adding the horizontal rule in Google Docs API yet, while "horizontalRule" can be retrieved by documents.get. Docs API is growing now. So this might be added in the future update.
So in the current stage, it is required to use the workaround for this.
Pattern 1:
In this pattern, the horizontal rule is added to Google Document using Web Apps created by Google Apps Script as an API.
Usage:
1. Set Web Apps Script:
Please copy and paste the following script to the script editor for Google Apps Script.
function doGet(e) {
DocumentApp.openById(e.parameter.id).getBody().insertHorizontalRule(Number(e.parameter.index) - 1);
return ContentService.createTextOutput("Done");
}
2. Deploy Web Apps:
On the script editor, Open a dialog box by "Publish" -> "Deploy as web app".
Select "Me" for "Execute the app as:".
Select "Anyone, even anonymous" for "Who has access to the app:".
This setting is for a test situation.
You can also access with the access token by setting "Only myself" instead of "Anyone, even anonymous".
Click "Deploy" button as new "Project version".
Automatically open a dialog box of "Authorization required".
Click "Review Permissions".
Select own account.
Click "Advanced" at "This app isn't verified".
Click "Go to ### project name ###(unsafe)"
Click "Allow" button.
Click "OK".
Copy the URL of Web Apps. It's like https://script.google.com/macros/s/###/exec.
When you modified the Google Apps Script, please redeploy as new version. By this, the modified script is reflected to Web Apps. Please be careful this.
3. Use Web Apps as an API:
The following script is for PHP. Please set the query parameter of id and index. id is the Google Document ID. When index=1 is set, the horizontal rule is inserted to the top of body in Document. In this case, index means each row in the Google Document.
$url = 'https://script.google.com/macros/s/###/exec?id=###&index=1';
$curl = curl_init();
$option = [
CURLOPT_URL => $url,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_FOLLOWLOCATION => true,
];
curl_setopt_array($curl, $option);
$response = curl_exec($curl);
$result = json_decode($response, true);
curl_close($curl);
Pattern 2:
I think that your proposal of I'm also going to look at possible inserting a thin table with a top border line as a replacement for a horizontal rule. can be also used as the workaround. For achieving this, the script is as follows.
When this script is run, new table that has the line of only top is created to the top of document. Before you run the script, please set $documentId. In this case, please set Google_Service_Docs::DOCUMENTS to the scopes.
Sample script:
$documentId = '###';
$index = 1;
$style = [
'width' => ['magnitude' => 0, 'unit' => 'PT'],
'dashStyle' => 'SOLID',
'color' => ['color' => ['rgbColor' => ['blue' => 1, 'green' => 1, 'red' => 1]]]
];
$requests = [
new Google_Service_Docs_Request([
'insertTable' => [
'location' => ['index' => $index],
'columns' => 1,
'rows' => 1
]
]),
new Google_Service_Docs_Request([
'updateTableCellStyle' => [
'tableCellStyle' => [
'borderBottom' => $style,
'borderLeft' => $style,
'borderRight' => $style,
],
'tableStartLocation' => ['index' => $index + 1],
'fields' => 'borderBottom,borderLeft,borderRight'
]
])
];
$batchUpdateRequest = new Google_Service_Docs_BatchUpdateDocumentRequest([
'requests' => $requests
]);
$result = $service->documents->batchUpdate($documentId, $batchUpdateRequest);
References:
Web Apps
insertHorizontalRule()
Method: documents.batchUpdate

How to download word document from API using Laravel

I am pretty new to using Guzzle with Laravel. I currently just use it for communication between my front-end and a seperate REST api.
I'm trying to download a file from my api but I'm not sure how to go about it. I could just specify the path to the file and directly download it but I also want to be able to stream or view it in my browser so a user can just view a word document instead of just downloading it.
Currently I'm sending a GET request from front end project (with backend to do api calls) to the api project:
$resp = $client->request('GET', env('API_BASE_URL').'/project/'.$id. '/download-report', [ 'headers' => [ 'Authorization' => 'Bearer '. session()->get('api_token') ] ]);
and in my api backend I return the file with the ->download() function.
return response()->download($report->getPath());
Can someone explain what would be the best way to approach this situation?
Solutions for both issues would be awesome, just downloading it, or actually viewing the contents of the word document.
Thanks in advance!
First of all, it's better to serve files with the web server (and leave PHP for "smarter" work). The idea behind it is to generate a "secure" link, that hides the real file and has an expiration timeout.
There are a few ways to do that (depends on your server: nginx, Apache or something else). A good example for nginx, with which you can just generate such link in your API, and send it to the end user through your frontend.
If you prefer to do in PHP for some reasons, just download the file to a temporary file and send it using response()->download() with corresponding headers (Content-Type) in your frontend.
$tmpFile = tempnam(sys_get_temp_dir(), 'reports_');
$resp = $client->request('GET', '...', [
// ... your options ...
'sink' => $tmpFile,
]);
response()->download(
$tmpFile,
null,
[
'Content-Type' => $resp->getHeader('Content-Type')[0]
]
)->deleteFileAfterSend(true);

allow client coder to post json and get a full view back from web service

I wrote a scheduling app in laravel 5 that basically builds some json from local storage and sends this to the controller and then the view. the view is mostly javascript that parses the json and builds the schedule. I would like to extend this to allow a client coder to generate their own json and post that to my app and have my app send them a full view / schedule back.
I'm using php 7 and the php -S options to bring up 2 servers - one hosting the main schedule that i have and one hosting the client test code that posts to the schedule.
require 'vendor/autoload.php';
use GuzzleHttp\Client;
$uri ='/api/clientJSON';
$uri_token ='eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjEsImlzcyI6Imh0dHA6XC9cL2xvY2FsaG9zdDo4MDAwXC9hcGlcL2F1dGhlbnRpY2F0ZSIsImlhdCI6MTQ1Njg0NDI1NiwiZXhwIjoxNDU2ODQ3ODU2LCJuYmYiOjE0NTY4NDQyNTYsImp0aSI6IjI2ODZjZWIwNjI2ZDVmZWE1YmVlZjMwNzM0ZDhkMzZmIn0.hWrIGNGLlIHOLP9FltefsN066WOHpGTm2SmsF6feAsI';
$calendarJson = '{"auth":"test"}';
$client = new Client([
'base_uri' => 'http://localhost:8000',
'timeout' => 2.0,
]);
$response = $client->request('POST', $uri, [
'query'=>['token' => $uri_token],
'form_params' => [
'calendarJson' => $calendarJson
]
]);
echo $response->getBody();
this issue seems to be that while the body does echo out, its only pulling in the html page and all the dependent js / css files are not loaded. I'm clearly missing something fundamental about building my web service. Can someone enlighten me please?
While Guzzle is a PHP HTTP Client, it is not a web browser. As such it will perform HTTP requests, but it will not parse the response to determine if or what other files need to be downloaded to view the content properly.
As observed, if a request is actioned, and the response contains references for externally stored javascript, or CSS files, they will not be requested.
For years the internet has been very good at blurring the lines between content and presentation. As a service provider, you are interested in the content obtained from external sources, not how those external sources present it.

Categories