How to get media URL from cloudinary - mysql

I want to upload an image to cloudinary and then get the URL of the image in and store it (the url) in a database but don't have a clue on how to get started. I can upload to cloudinary, but I don't know how to programmatically get the url. I'm working with React and NodeJS. I need help guys

Next time you post a question, please include more context and show examples of what you have tried!
That being said, I would use the cloudinary npm package. https://www.npmjs.com/package/cloudinary
Uploading will return an object like this:
{
"public_id": "4srvcynxrf5j87niqcx6w",
"version": 1340625837,
"signature": "01234567890abcdef01234567890abcdef012345",
"width": 200,
"height": 200,
"format": "jpg",
"resource_type": "image",
"url": "http://res.cloudinary.com/demo/image/upload/v1340625837/4srvcynxrf5j87niqcx6w.jpg",
"secure_url": "https://res.cloudinary.com/demo/image/upload/v1340625837/4srvcynxrf5j87niqcx6w.jpg"
}
So to get the url after uploading, do this:
var cloudinary = require('cloudinary').v2;
const url = await new Promise((resolve, reject) => {
cloudinary.uploader.upload("my_picture.jpg", function (error, result) {
if(result){
resolve(result.url);
} else if(error){
reject(error)
}
});
})

Related

EJS can't find image in static public folder

I'm trying render a html template as a PDF using EJS, however the images are not appearing.
My project structure:
- public
- images
image.jpg
- routes
documentsRoute.js
- services
documentsService.js
- views
document-template.ejs
server.js
I am setting the public folder as a static folder in my server.js like so:
...
const app = express()
app.use(express.static('public'))
...
In my template file I'm using this as my src for the image
<img src="images/image.jpg" alt="my_image">
I'm rendering the file from my document service like so:
ejs.renderFile('views/document-template.ejs', inputs, (err, data) => {
if (err){
throw err;
}
let options = {
"format": "A4",
"header": {
"height": "20mm"
},
"footer": {
"height": "20mm"
}
};
pdf.create(data, options).toFile('test.pdf', (err, res) => {
if(err){
throw err;
}
});
})
The rest of the template is rendered correctly, just not the image, instead it shows the alt text. Does anyone know how I could fix this?
You need to set the view directory correctly in your server file.
So instead of app.use(express.static('public'))
try
app.use(express.static( path.join(__dirname, './public')))
it's rather pdf having trouble with the path. try using absolute path
add full path in the base property of pdf options:
let options = {
"format": "A4",
//...
base: `${req.protocol}://${req.headers.host}`
};

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}'

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

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/

Return image from Node REST API and use in img.src on client-side

I am storing images in MongoDB as base64 string. I created Express route to get image by id:
router.get('/:userId/images/:imgId', (req, res) => {
Image.findOne(
{ _id: req.params.imgId },
(err, img) => {
if (err) {
res.status(500).send('someErr');
} else {
var resultImg = Buffer.from(img.data, 'base64');
res.writeHead(200, {
'Content-Type': 'image/png',
'Content-Length': resultImg.length
});
res.end(resultImg);
}
}
);
});
Client-side:
<img src={`api/users/${userId}/images/${imgId}`} />
What I am sure about:
path is correct, server receives request and returns 200 response
data is correctly fetched from MongoDB
base64 string is correct (when I copy paste to verifier like https://codebeautify.org/base64-to-image-converter, it is working)
Why images are not loaded?
make sure the output has this string at the beginning
<img src='data:image/png;base64,your base 64 goes here'/>
you can test by copying the output and put it in a static html and see does it work.
so may be something like this would help
<img src=`data:image/png;base64,{`api/users/${userId}/images/${imgId}`}`/>
Have you try hit your backend using AJAX or Fetch API ?
After that, you can load response from that API into your image element