How to get user's photo(profile) using Microsoft Graph API? - javascript

When a GET(https://graph.microsoft.com/v1.0/users/ {{user_id}} /photo/$value) request is made, the response data will be written with the same characters as image
.
After converting to base64, I tried blob format but the picture does not appear.
router.js
router.get('/photo/:id',function (req,res) {
auth.getAccessToken().then(function (token){
let userId = req.params.id;
graph.getUserPhotoData(token, userId).then(function (result) {
res.json(result);
}).catch(function (e) { console.log(e) })
});
});
graph.js
function getUserPhoto(token, userId){
return axios({
method : 'get',
url : 'https://graph.microsoft.com/v1.0/users/'+{{user_id}}+'/photo/$value',
headers: {
'Authorization':token,
// 'Content-Type': 'image/jpeg',
},
responseType : 'blob'
})
}
async function getUserPhotoData(token,userId) {
try{
let userPhoto = getUserPhoto(token,userId);
let p = userPhoto.data;
// let photo = new Buffer(userPhoto.data).toString('base64');
return p; //...013O✿\u0011�e����|��>�4+�y��\u0017�"Y...
}catch (e) { console.log(e);}
}
index.js
$.get('/photo/'+userId, function(response) {
let binaryData = [];
binaryData.push(response);
const blobUrl = window.URL.createObjectURL(new Blob(binaryData, {type: "image/jpeg"}));
document.getElementById('user-img').setAttribute("src", blobUrl );
});

UPDATE: new Buffer is deprected. Please use
<img src={'data:image/jpeg;base64,' + Buffer.from(response.data, 'binary').toString('base64')}
Original answer
it works for me
const graphEndpoint = "https://graph.microsoft.com/v1.0/me/photo/$value";
const response = await axios(graphEndpoint, { headers: { Authorization: `Bearer ${token}` }, responseType: 'arraybuffer' });
const avatar = new Buffer(response.data, 'binary').toString('base64');

Finally found a solution to this! The previous answers didn't quite work for me. What I found that worked was:
const { data: photoValue} = await axios.request({
method: 'GET',
{ headers: { Authorization: `Bearer ${token}` },
responseType: 'blob',
url: 'https://graph.microsoft.com/v1.0/me/photo/$value',
});
const blobUrl = window.URL.createObjectURL(photoValue);
and then displaying it with <img src={blobUrl} />. This is the shortest answer in my opinion, and relies on the responseType: 'blob' being given.

I solved this problem.
router.js
const request = require('request');
router.get('/photo/:id',function (req,res) {
auth.getAccessToken().then(function (token){
let userId = req.params.id;
// graph.getUserPhotoData(token, userId).then(function (result) {
// console.log(result);
// res.json(result);
// }).catch(function (e) { console.log(e) })
request({ uri: 'https://graph.microsoft.com/beta/users/'+userId+'/photo/$value', method: "GET", headers:{'Authorization' : 'Bearer' + token}, encoding: null},
function(error, response, body) {
let data = "data:" + response.headers["content-type"] + ";base64," + new Buffer(body).toString('base64');
res.send(data); //data:image/jpeg;base64,/9j/4AAQSkZJRg...
});
});
});
index.js
$.get('/photo/'+ userId, function(response) {
document.getElementById('user-img').setAttribute("src", response);
});
'graph.js' is not needed.
reference :
Node.js get image from web and encode with base64

Related

Converting application/json image to displayable image type

I am using the hugging face API and the response sends back an image of type
data:application/json;base64
How can I convert this data type into a more usable one such as a png or jpg file?
Example hugging face API response:
data:application/json;base64,eyJpZCI6IkxpbmFxcnVmL2FueXRoaW5...
Function which makes network call:
const { prompt } = req.body;
try {
const inputData = {
inputs: prompt,
options: {
wait_for_model: true,
},
};
const response = await axios({
url: "https://api-inference.huggingface.co/models/Linaqruf/anything-v3.0",
headers: {
Authorization: `Bearer ${process.env.HUGGING_FACE_API_KEY}`,
Accept: "application/json",
"Content-Type": "application/json",
},
data: JSON.stringify(inputData),
responseType: "arraybuffer",
});
const mimeType = response.headers["content-type"];
const result = response.data;
const base64data = Buffer.from(result).toString("base64");
const img = `data:${mimeType};base64,` + base64data;
res.status(200).json({ img });
} catch (err) {
console.log(err);
return res.status(400).json({ message: "Server Error" });
}
I need the image to be displayable by React Native's image component.

Upload file to s3 using presigned post url in the server

TDLR: Using s3 presigned post url to upload file to s3. Works fine on the browser but fails on the server.
I have a simple lambda function that generates presigned post url that can be consumed either in the browser or in the server.
During testing I noticed that the upload works fine one the browser but fails if I try to upload a file from a server even tho the code is identical.
The error i get is:
You must provide the Content-Length HTTP header
Detailed error:
<?xml version="1.0" encoding="UTF-8"?>
<Error>
<Code>MissingContentLength</Code>
<Message>You must provide the Content-Length HTTP header.</Message>
<RequestId>JP75YMFARK0G3X5Z</RequestId>
<HostId>toHsKmxmVYYAtac94cQoy8wXoregKG3PNBm97c3gQewEmKxLggcumTAP882T/pJNWx/lxRgH98A=</HostId>
</Error>
Request failed with status code 411
I checked online and found many threads about this issue but unfortunately not a single suggestion helped me.
Code I am running in the server
const axios = require('axios');
const { createReadStream, readFileSync } = require('fs');
const FormData = require('form-data');
const getPostPresignedUrl = async () => {
var config = {
method: 'post',
url: LAMBDA_GET_URL,
headers: {
'Content-Type': 'application/json',
},
data: JSON.stringify({
key: 'test-2.jpg',
fileType: 'image/jpeg',
}),
};
const {
data: { data },
} = await axios(config);
return data;
};
const uploadFileToS3 = async (fields, url) => {
const formData = new FormData();
Object.entries(fields).map(([key, value]) => {
formData.append(key, value);
});
const file = createReadStream('./test-1.jpg');
formData.append('file', file);
try {
const { data } = await axios({
url,
method: 'post',
headers: {
'Content-Type': 'multipart/form-data',
},
data: formData,
});
} catch (error) {
if (error instanceof axios.AxiosError) {
console.log(error.response.data);
}
console.log(error.message);
}
};
const init = async () => {
const { fields, url } = await getPostPresignedUrl();
await uploadFileToS3(fields, url);
};
init();
Code I am running in the browser:
const form = document.getElementById('form');
const input = document.getElementById('file');
const getPostPresignedUrl = async (name) => {
var config = {
method: 'post',
url: LAMBDA_GET_URL,
headers: {
'Content-Type': 'application/json',
},
data: JSON.stringify({
key: name,
fileType: 'image/jpeg',
}),
};
const {
data: { data },
} = await axios(config);
return data;
};
const uploadFileToS3 = async (fields, url, file) => {
const formData = new FormData();
Object.entries(fields).map(([key, value]) => {
formData.append(key, value);
});
formData.append('file', file);
try {
const { data } = await axios({
url,
method: 'post',
headers: {
'Content-Type': 'multipart/form-data',
},
data: formData,
});
} catch (error) {
if (error instanceof axios.AxiosError) {
console.log(error.response.data);
}
console.log(error.message);
}
};
const handleSubmit = async (e) => {
e.preventDefault();
const file = input.files[0];
const data = await getPostPresignedUrl(file.name);
await uploadFileToS3(data.fields, data.url, file);
};
form.onsubmit = handleSubmit;

Javascript error saying that I do not provide an API token

Can someone take a look at the code below.
I try to make a converter work, which makes a png from a jpg.
I keep getting this error:
{"message":"Please provide an API key or token."}
This is the code:
const {
file,
filename,
mimetype,
token,
size,
folderid,
} = inputs;
var myHeaders = new Headers();
myHeaders.append("x-oc-api-key", "API KEY");
myHeaders.append("Content-Type", "application/json");
var raw = {
type: 'remote',
source: file}
conversion: {
target: 'png'}
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: raw,
redirect: 'follow'
};
const {url} = inputs;
try {
const response = await fetch("www.apiwebsite.com/jobs", requestOptions);
const outputvariableurl = await response.json();
return { outputvariableurl }
} catch (err) {
const error = {
code: 'unknownError',
message: 'Something went wrong.',
rawError: err,
}
return [1, { error }]
}

Display image from API

I got problem how to display image send by API from backend it not display. And when I console.log, I got this error.
This is my code as your reference.
HTML
<img [src]="imageToShow" style="width:100%;margin-left: -14px;">
Component
ngOnInit() {
this.getBanner()
}
getBanner() {
this.bannerId = {
confId: 1,
type: "Banner",
};
this.httpService.getBanner(this.bannerId).subscribe(
(baseImage: any) => {
let objectURL = "data:image/jpeg;base64," + baseImage.image;
this.imageToShow = this.sanitizer.bypassSecurityTrustUrl(objectURL);
},
(error) => {
// this.isImageLoading = false;
console.log(error);
}
);
}
Service
public getBanner(data){
console.log(data)
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json',
responseType: 'blob',
Authorization: 'Bearer '+this.getToken()
})
};
return this.httpClient.post((this.serverUrl + this.basePath + '/landing/conferenceitem'),data,httpOptions);
}
edit
when I check up Network Response I got this image
Try this
Step #1
Remove Content-Type header and set responseType to blob in httpOptions, but not in the header part like you did. Now, you should get a blob as a response. Before, angular was trying to parse your response as JSON, hence the error
public getBanner(data){
console.log(data)
const httpOptions = {
headers: new HttpHeaders({
Authorization: 'Bearer '+this.getToken()
}),
responseType: 'blob'
};
return this.httpClient.post((this.serverUrl + this.basePath + '/landing/conferenceitem'),data,httpOptions);
}
Step #2 Use baseImage instead of baseImage.image (the response is a blob, it does not have an image property), and then use createObjectURL to get an image url from the blob. Sanitize that URL like your did
this.httpService.getBanner(this.bannerId).subscribe(
(baseImage: Blob) => {
let objectURL = URL.createObjectURL(baseImage);
this.imageToShow = this.sanitizer.bypassSecurityTrustUrl(objectURL);
},
(error) => {
// this.isImageLoading = false;
console.log(error);
}
);
One way to fix this is by Setting the response type to blob
const requestOptions: Object = {
/* other options here */
responseType: 'blob'
}
return this.httpClient.post((this.serverUrl + this.basePath + '/landing/conferenceitem'),data,requestOptions);
and you have to convert your image data to a dataURL:
this.httpService.getBanner(this.bannerId).subscribe(
(baseImage: any) => {
this.imageToShow = baseImage;
},
(error) => {
// this.isImageLoading = false;
console.log(error);
}
);
Change Your getBannerMethod as below :-
getBanner() {
this.bannerId = {
confId: 1,
type: "Banner",
};
this.httpService.getBanner(this.bannerId).subscribe(
(baseImage: any) => {
const reader = new FileReader();
const url = reader.readAsDataURL(baseImage.image);
reader.onloadend = () => this.imageToShow = reader.result;
},
(error) => {
// this.isImageLoading = false;
console.log(error);
}
);
}
Working Stackblitz :- https://stackblitz.com/edit/angular-yvicvq

Using JavaScript Fetch with Formidablejs, Expressjs

I'm using Reactjs saga to send a post request using fetch. Also I'm trying to use formidable instead of usual body-parser. I'm getting weird parsing issues. What am I doing wrong?
// saga simplified piece of code
const { loginEmail, loginPwd } = request.payload;
let postLoginSubmitOptions = {
method: "POST",
headers: {
'Accept': 'application/json, application/xml, text/plain, text/html, *.*',
'Content-Type' : 'application/x-www-form-urlencoded'
},
body: JSON.stringify({
loginEmail: loginEmail,
loginPwd: loginPwd
})
};
const response = yield call(fetch, `http://www.example.com/register`, postLoginSubmitOptions);
// expressjs side, simplified view
router.post('/register', function(req, res, next) {
console.log('registering user');
var form = new formidable.IncomingForm();
form.parse(req, function(err, fields, files) {
if(err){
console.log(err);
}
console.log(`incoming fields via form parse`);
console.log(fields); // { '{"loginEmail":"my-email#gmail.com","loginPwd":"my-password"}': '' }
console.log(fields.loginEmail); // undefined
});
}
pass content type as json
let postLoginSubmitOptions = {
method: "POST",
headers: new Headers({'content-type': 'application/json'}),
body: JSON.stringify({
loginEmail: loginEmail,
loginPwd: loginPwd
})
};
I don't know where exactly the problem was but tried encoding data differently and then it worked. Getting a nice parsed object now with formidable: { loginEmail: 'dan#dan.com', loginPwd: 'asjdfkjsadlf' }
function sendData(data) {
const { loginEmail, loginPwd } = request.payload;
const body = { loginEmail, loginPwd };
var urlEncodedData = "";
var urlEncodedDataPairs = [];
var name;
for(name in body) {
urlEncodedDataPairs.push(encodeURIComponent(name) + '=' + encodeURIComponent(body[name]));
}
urlEncodedData = urlEncodedDataPairs.join('&').replace(/%20/g, '+');
var httpHeaders = {
'Content-Type' : 'application/x-www-form-urlencoded',
'Accept' : 'application/json'
}
let postOptions = {
method: 'post',
headers: new Headers(httpHeaders),
/*mode: 'no-cors',*/
body: urlEncodedData
};
try {
const response = yield call(fetch, `http://www.example.com/register`, postOptions);
const data = yield call([response, response.json]);
console.log(`data returned by fetch`);
console.log(data);
yield put({type: 'LOGIN_SUBMIT_RESPONSE', payload: data.message})
} catch (e) {
console.log(`error fetch post object`);
}
}
Thanks everyone!

Categories

Resources