Autodesk Forge: Translation Failed - File to bucket data: fileContent - autodesk-forge

I've been following this viewer walkthrough tutorial (node.js), for uploading and showing a file in the forge viewer.
I've been using angular to recreate the example, except instead of a user uploading a file, the file is hardcoded into the app from my assets folder for testing purposes.
The issue comes to when i try and translate the revit file into svf.
I know there isn't an issue with the revit file as i have used models.autodesk.io to check if all is good.
I can successfully create a bucket and post a job, but when calling the translation status to check if translation is completed, i receive this:
{
"type": "manifest",
"hasThumbnail": "false",
"status": "failed",
"progress": "complete",
"region": "US",
"urn": "dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6OTA0ZmZmYmMtODI1Ni00OWY2LWI3YzYtNDI3MmM1ZDlmNDljL2RyYXBlLnJ2dA",
"version": "1.0",
"derivatives": [
{
"name": "drape.rvt",
"hasThumbnail": "false",
"status": "failed",
"progress": "complete",
"messages": [
{
"type": "error",
"code": "Revit-UnsupportedFileType",
"message": "<message>The file is not a Revit file or is not a supported version.</message>"
},
{
"type": "error",
"message": "Possibly recoverable warning exit code from extractor: -536870935",
"code": "TranslationWorker-RecoverableInternalFailure"
}
],
"outputType": "svf"
}
]
}
I'm pretty sure my code for translating a project is correct, i think the issue is coming from uploading the file to my bucket.
The body structure for the PUT request must contain the contents of the file.
Here is my code for loading and reading a file using XMLHttpRequest and FileReader
loadFile(bucketKey, accessToken) {
const reader: XMLHttpRequest = new XMLHttpRequest();
reader.open('GET', './assets/drape.rvt', true);
reader.responseType = 'blob';
reader.onloadend = (request) => {
const blob: Blob = reader.response;
console.log(blob); //returns BlobĀ {size: 372736, type: "text/xml"}
// Create file from blob
const modelFile: File = new File([blob], 'drape.rvt');
this.readFile(bucketKey, accessToken, modelFile);
};
reader.send();
}
readFile(bucketKey, accessToken, modelFile) {
const myReader: FileReader = new FileReader();
myReader.readAsArrayBuffer(modelFile);
myReader.onloadend = (e) => {
const arrayBuffer: ArrayBuffer = myReader.result as ArrayBuffer;
this.fileToBucket(bucketKey, accessToken, arrayBuffer);
};
}
And the put request:
fileToBucket(bucketKey, accessToken, fileContent) {
const encodedBucketKey = encodeURIComponent(bucketKey);
const encodedFileName = encodeURIComponent('drape.rvt');
const uploadURI = `https://developer.api.autodesk.com/oss/v2/buckets/${encodedBucketKey}/objects/${encodedFileName}`;
const options = {
headers: new HttpHeaders({
'Content-Type': 'application/octet-stream',
Authorization: 'Bearer ' + accessToken
})
};
const body = {
data: fileContent
};
this.http.put(uploadURI, body, options)
.subscribe(
success => {
// URL safe base64 encoding
const urn = btoa(success.objectId);
this.translateObject(accessToken, urn);
}, error => {
console.log('fileToBucket');
console.log(error);
});
}
I'm assuming that the file content is the issue, here is the equivalent using node.js for the tutorial: PUT request read file.

You can use a utility web app like https://oss-manager.autodesk.io/ to check if the file you previously uploaded is correct (by downloading it or trying to translate it to SVF through the app's UI) and upload the file using this utility and then try to translate it with your app. It can also be used to delete all the derivatives for a given file in your bucket.
That could help narrow down the issue.
It's also possible that the file was not correctly uploaded the first time (at a certain point when you were still testing things) and so the translation failed back then and now it won't try to translate the file again. You can force the translation to take place by adding x-ads-force to the POST Job request with value "true" - see https://forge.autodesk.com/en/docs/model-derivative/v2/reference/http/job-POST/

Related

how to check if bucket object is already translated

I've uploaded file to oss and have object id, if bucket object is not yet translated then how to check derivatives info. with object id?
It's straightforward, just base64 encode your objectId, then call GET {urn}/manifest. If it returns a 404 http status code, then it means this URN hasn't got translated.
If your file is stored on BIM360/ACC, you will need to get derivative URN from the file's version tip. Please follow this tutorial, but find relationships.data.derivatives.data.id instead for the URN like the below for example.
https://forge.autodesk.com/en/docs/bim360/v1/tutorials/document-management/download-document/#step-4-find-the-storage-object-id-for-the-file
"derivatives": {
"data": {
"type": "derivatives",
"id": "dXJuOmFkc2sud2lwcHJvZDpmcy5maWxlOnZmLkVueWtrU3FjU0lPVTVYMGhRdy1mQUM_dmVyc2lvbj0x"
},
// ...
},
Node.js code sample tested with yiskang/forge-viewmodels-nodejs-svf2
const {
DerivativesApi
} = require('forge-apis');
const { getClient, getPublicToken } = require('./routes/common/oauth');
const derivativeApi = new DerivativesApi();
const urn = 'dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6bXlidWNrZXQvdGVzdC5ydnQ';
getPublicToken().then(accessToken => {
derivativeApi.getManifest(urn, {}, null, accessToken).then(function (res) {
console.log(res.statusCode, res.statusMessage);
},
function (err) {
// When the urn hasn't got translated, it goes here
console.error('error', err.statusCode, err.statusMessage);
// if you want to redire page to some where, write your codes here
});
}, function (err) {
console.error(err);
});
ref: https://stackoverflow.com/a/70664111/7745569

How to download media files in WhatsApp API which send users?

I am currently writing a chatbot for WhatsApp.
I use the 360dialog platform, which makes it possible to work with the WhatsApp Business API.
When the client sends a message, I see the following JSON object in the logs of my application:
{
"messages": [
{
"from": "77773336633",
"id": "ABGGd3c1cGY_Ago61ytHsZknvtLv",
"image": {
"id": "ffd23134-2dae-4fed-b5f8-0ce7867b6ddd",
"mime_type": "image/jpeg",
"sha256": "bd02100d961b5a1dbaae1dd645485ebbfeda77b44e82c015f1cf29b05654ccb9"
},
"timestamp": "1605703542",
"type": "image"
}
],
"contacts": [
{
"profile": {
"name": "Nurzhan Nogerbek"
},
"wa_id": "77773336633"
}
]
}
I can't find any information in the documentation about how to download this file.
In my case, I want to upload this image file that the client sends to my file storage.
Please tell me which URL method from the WhatsApp API is responsible for this mechanism?
P.S. At the same time, I can send files to clients. This information is available on the official documentation.
May be it will help, just try, take a look:-
const URL = `https://lookaside.fbsbx.com/whatsapp_business/attachments/?mid=1104480873777230&ext=1662705250&hash=ATuMx352sLrhKUegbQZSC8oLl3J5Vy3Z49lO4HwTUKWRYQ`;
const FROM = `video`;
const config = {
method: 'get',
url: URL, //PASS THE URL HERE, WHICH YOU RECEIVED WITH THE HELP OF MEDIA ID
headers: {
'Authorization': `Bearer ${token}`
},
responseType: 'arraybuffer'
};
axios(config)
.then(function (response) {
const ext = response.headers['content-type'].split("/")[1];
fs.writeFileSync(`${FROM}.${ext}`, response.data);
})
.catch(function (error) {
console.log(error);
});
It was very tricky because postman worked, but c# didn't work for me, and I spent two days trying to find the solution and finally did the following code, which works in C#:
using HttpClient _httpClient = new HttpClient();
Uri uri = new Uri(mediaUrl);
var fileName = $"{DateTime.Now.ToString("yyyyMMddhhmmss")}.jpeg";
string filePath = $"Files\\{fileName}";
// NOTE: to save bandwidth, request compressed content
_httpClient.DefaultRequestHeaders.AcceptEncoding.Clear();
_httpClient.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip"));
_httpClient.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("deflate"));
_httpClient.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("br"));
// NOTE: accept all languages
_httpClient.DefaultRequestHeaders.AcceptLanguage.Clear();
_httpClient.DefaultRequestHeaders.AcceptLanguage.Add(new StringWithQualityHeaderValue("*"));
// NOTE: accept all media types
_httpClient.DefaultRequestHeaders.Accept.Clear();
_httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("*/*"));
_httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("image/jpeg"));
var productValue = new ProductInfoHeaderValue("ScraperBot", "1.0");
var commentValue = new ProductInfoHeaderValue("(+http://www.API.com/ScraperBot.html)");
_httpClient.DefaultRequestHeaders.UserAgent.Add(productValue);
_httpClient.DefaultRequestHeaders.UserAgent.Add(commentValue);
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", {WhatsApp_Access_Token});
HttpResponseMessage response = await _httpClient.GetAsync(uri);
response.EnsureSuccessStatusCode();
var mediaType = response?.Content?.Headers?.ContentType?.MediaType ?? string.Empty;
var imageBytes = await response.Content.ReadAsByteArrayAsync();
using (var fs = new FileStream(filePath, FileMode.Create, FileAccess.Write))
{
fs.Write(imageBytes, 0, imageBytes.Length);
}
Here, {WhatsApp_Access_Token} is your Whatsapp API permanent token.
Ping me in a comment, please, if you have any issues or questions.
The official documentation has a session for this in https://developers.facebook.com/docs/whatsapp/api/media.
Basically you must make a GET request to download the media.
curl --request GET \
--url https://waba.360dialog.io/v1/media/{media id} \
--header 'D360-API-KEY: {your api token}'

uploading image using file_picker flutter to a nodejs server

I have an api which gives the following data as response:
{
"status": 200,
"msg": "Data Found",
"data": {
"id": 104,
"firstName": "aaa",
"lastName": "aaa",
"surname": "aaa",
"email": "email#email.care",
"phone": "090909090",
"age": "23",
"gender": "M",
"height": "163",
"bloodGroup": null,
"weight": "72",
"status": null,
"fileId": 228,
"password": "pass",
"file": {
"id": 228,
"filename": "images.jpg",
"path": "user/images1613558976577.jpg",
"alt": "shafa care"
}
},
"success": true,
"token": "some token",
"userAccess": "some data"
}
The "file" parameter in the response is used to hold the image that the user uploads. For my update method, the user needs to pass their token as header for the update api. For updating the file parameter i have tried many different ways just to update the user image. The below code is using multipart form data to update the existing file image.
Future<AuthModel> updateImage(File imageFile, AuthModel authModel) async{
final String _accessToken = '${authModel.token}';
final String url =
'${GlobalConfiguration().getString('api_base_url')}auth/user/update';
var stream = new http.ByteStream(imageFile.openRead());
var length = await imageFile.length();
var uri = Uri.parse(url);
var request = new http.MultipartRequest("POST", uri);
request.headers['Authorization'] = _accessToken;
// request.headers['Content-Type'] = 'multipart/form-data';
var multipartFile = new http.MultipartFile('file', stream, length, filename: basename(imageFile.path));
request.files.add(multipartFile);
var response = await request.send();
print("updating: " + response.statusCode.toString());
response.stream.transform(utf8.decoder).listen((event) {
currentUser = authModelFromJson(event);
print("updating img: " + event);
});
return currentUser;
}
The above function does not update my file parameter even when the data is found. I just get the same old response. filepicker is also sending the correct image path that the user chooses from the gallery. I have also tried using http.client.post method using a token as the header and 'file' parameter as the body but then data is not found as the api only accepts form-data when an image is being uploaded.
It works in postman using form-data post method.
I am new to flutter and still learning. I have been stuck here for days without any solution. How can i update the file parameter from my flutter application? Any help is appreciated.
This is sample code. I hope this may help you !
static Future<bool> uploadFileAsFormData(
String url, File file) async {
try {
var uri = Uri.parse(_buildUrl(url));
var request = http.MultipartRequest('POST', uri);
request.files.add(await http.MultipartFile.fromPath('file', file.path));
var res = await request.send();
if (res.statusCode == 200) {
return true;
} else {
return false;
}
} catch (err) {
return false;
}
}
You can use this Dio to upload the image as shown by the following code:
Dio dio = Dio();
var formData = FormData();
for (var file in filePath) {
formData.files.addAll([MapEntry("files", await MultipartFile.fromFile(file)),]);
print(formData.length);
}
var response = await dio.post(url
data: formData,
options: Options(headers: {
'Authorization': _accessToken
}));
if(response.statusCode == 200){
print(response.data.toString();
}

Google App Script: UrlFetchApp.fetch Address unavailable error

I wrote following code in google app script. When I run this code, it gives "Address unavailable: https://gsd.jira.com/jira/rest/api/2/issue/ (line 30, file "Code")"
function myFunction() {
var header =
{
"Cookie":"JSESSIONID=82AEF41778F3036829323019EB7437C4",
"Content-Type": "application/json"
};
var data =
{
"fields": {
"project":
{
"key": "TEST"
},
"summary": "REST ye merry gentlemen.",
"description": "Creating of an issue using project keys and issue type names using the REST API",
"issuetype": {
"name": "Story"
}
}
};
var options =
{
"headers" : header,
"method" : "post",
"payload" : data
};
var response = UrlFetchApp.fetch("https://gsd.jira.com/jira/rest/api/2/issue/", options);
Logger.log(response.getContentText());
}
However, when same HTTP request was created using "REST Console" chrome extension, it worked successfully and created a jira issue.
What is wrong with this code?
Host gsd.jira.com doesn't exist (try http://www.dnswatch.info/dns/dnslookup?la=en&host=gsd.jira.com&type=A&submit=Resolve).
It seems "gsd.jira.com" is address on your computer or local network specified e.g. via hosts file or local DNS server. When you use apps script, you are accessing the target API endpoint from Google servers.
If your API interface is not public, you can not access it froom apps script.

Google Drive API Upload to Parent Folder

I have a JavaScript based Google Apps script that iterates through all files in Drive and converts MS files to Google format. I am using Drive API to upload and convert. Everything seems to work fine, except when I have a file in a Drive sub folder. When the file is uploaded back to Drive, I cannot define a parent folder, so it goes directly to the root.
I have a handle on the parent folder ID, but when I add "parents : folderID" to the JSON String, I do not see any change in the upload path.
This is my upload and convert function, is there any way to modify this to define a parent folder? I'm totally lost with the API... Can anyone assist?
var uploadFile = JSON.parse(
UrlFetchApp.fetch("https://www.googleapis.com/upload/drive/v2/files?uploadType=media&convert=true",
{
method: "POST",
contentType: officeFile.getMimeType(),
payload: officeFile.getBlob().getBytes(),
parents: ['id' : folderID], <<<<<<<<<<<<<<<<< this line
headers: {
"Authorization" : "Bearer " + ScriptApp.getOAuthToken()
},
muteHttpExceptions: true
}).getContentText());
With V3 of the API the format of the parents parameter has changed (didn't seem to be listed in the documentation which always makes things fun). Parents are no longer added as {id:} objects.
var folderId = '0BwwA4oUTeiV1TGRPeTVjaWRDY1E';
var fileMetadata = {
'name': 'photo.jpg',
'parents': [ folderId ]
};
var media = {
mimeType: 'image/jpeg',
body: fs.createReadStream('files/photo.jpg')
};
drive.files.create({
resource: fileMetadata,
media: media,
fields: 'id'
}, function(err, file) {
if(err) {
// Handle error
console.log(err);
} else {
console.log('File Id: ', file.id);
}
});
Full documentation
I use v2 API with curl and succeeded to upload file in parent folder by writing meta json file with below format.
{
"title": "35_20190702.csv",
"mimeType": "text/csv",
"description": "Uploaded From Curl",
"parents": [
{
"kind": "drive#parentReference",
"id": ${FOLDER_ID}
}
]
}