Api Youtube Upload with Service Account - javascript

I want to upload a video from server to youtube.
I create a service account to auth,
var path = "720_final.mov"
// var key = readJson(`${__dirname}/secret.json`);
var google = require('googleapis');
var youTube = google.youtube('v3');
var authClient = new google.auth.JWT(
"xxxx#yyyyyyy.gserviceaccount.com",
"secret.p12",
null,
['https://www.googleapis.com/auth/youtube','https://www.googleapis.com/auth/youtube.upload'],
null
);
authClient.authorize(function(err, tokens) {
if (err) {
console.log(err);
return;
}
authClient.setCredentials(tokens);
var req = Youtube.videos.insert({
auth: authClient,
resource: {
// Video title and description
snippet: {
title: "Testing YoutTube API NodeJS module"
, description: "Test video upload via YouTube API"
}
// I don't want to spam my subscribers
, status: {
privacyStatus: "public"
}
}
// This is for the callback function
, part: "snippet,status"
// Create the readable stream to upload the video
, media: {
body: fs.createReadStream(path)
}
}, (err, data) => {
console.log(err)
console.log(data)
process.exit();
});
My file 720_final.mov has size 33Mb.
When upload to 34.6Mb seem like Upload cannot find channel of user to upload ??
However, when is use tokens generator from Oauth2, upload success, example use oath 2 https://github.com/IonicaBizau/youtube-api/blob/master/example/index.js
Anyone can give me a resolve or a keyword to fix this?

Related

Upload file to google drive after http get request

I have two functions in separate files to split up the workflow.
const download = function(url){
const file = fs.createWriteStream("./test.png");
const request = https.get(url, function(response) {
response.pipe(file);
});
}
This function in my fileHelper.js is supposed to take a URL with an image in it and then save it locally to test.png
function uploadFile(filePath) {
fs.readFile('credentials.json', (err, content) => {
if (err) return console.log('Error loading client secret file:', err);
// Authorize a client with credentials, then call the Google Drive API.
authorize(JSON.parse(content), function (auth) {
const drive = google.drive({version: 'v3', auth});
const fileMetadata = {
'name': 'testphoto.png'
};
const media = {
mimeType: 'image/png',
body: fs.createReadStream(filePath)
};
drive.files.create({
resource: fileMetadata,
media: media,
fields: 'id'
}, (err, file) => {
if (err) {
// Handle error
console.error(err);
} else {
console.log('File Id: ', file.id);
}
});
});
});
}
This function in my googleDriveHelper.js is supposed to take the filePath of call and then upload that stream into my google drive. These two functions work on their own but it seems that the https.get works asynchronously and if I try to call the googleDriveHelper.uploadFile(filePath) function after the download, it doesn't have time to get the full file to upload so instead a blank file will be uploaded to my drive.
I want to find a way so that when the fileHelper.download(url) is called, it automatically uploads into my drive.
I also don't know if there is a way to create a readStream directly from the download function to the upload function, so I can avoid having to save the file locally to upload it.
I believe your goal as follows.
You want to upload a file retrieving from an URL to Google Drive.
When you download the file from the URL, you want to upload it to Google Drive without creating the file.
You want to achieve this using googleapis with Node.js.
You have already been able to upload a file using Drive API.
For this, how about this answer?
Modification points:
At download function, the retrieved buffer is converted to the stream type, and the stream data is returned.
At uploadFile function, the retrieved stream data is used for uploading.
When the file ID is retrieved from the response value of Drive API, please use file.data.id instead of file.id.
By above modification, the file downloaded from the URL can be uploaded to Google Drive without creating a file.
Modified script:
When your script is modified, please modify as follows.
download()
const download = function (url) {
return new Promise(function (resolve, reject) {
request(
{
method: "GET",
url: url,
encoding: null,
},
(err, res, body) => {
if (err && res.statusCode != 200) {
reject(err);
return;
}
const stream = require("stream");
const bs = new stream.PassThrough();
bs.end(body);
resolve(bs);
}
);
});
};
uploadFile()
function uploadFile(data) { // <--- Modified
fs.readFile("drive_credentials.json", (err, content) => {
if (err) return console.log("Error loading client secret file:", err);
authorize(JSON.parse(content), function (auth) {
const drive = google.drive({ version: "v3", auth });
const fileMetadata = {
name: "testphoto.png",
};
const media = {
mimeType: "image/png",
body: data, // <--- Modified
};
drive.files.create(
{
resource: fileMetadata,
media: media,
fields: "id",
},
(err, file) => {
if (err) {
console.error(err);
} else {
console.log("File Id: ", file.data.id); // <--- Modified
}
}
);
});
});
}
For testing
For example, when above scripts are tested, how about the following script?
async function run() {
const url = "###";
const data = await fileHelper.download(url);
googleDriveHelper.uploadFile(data);
}
References:
Class: stream.PassThrough
google-api-nodejs-client

Shared files can't access(get list of shared file) using drive.file scope Google Drive API

The file is shared success and the shared user gets an email notification, file display in the user google drive but when we try using API to get shared files, it is not working.
var SCOPES = ["https://www.googleapis.com/auth/drive.file", "profile"];
function createPermissions(fileId, body) {
gapi.client.load("drive", "v3", function() {
gapi.client.drive.permissions
.create({
fileId: fileId,
resource: body
})
.then(function(res) {
//console.log(res);
Swal.fire("Success!", "File has been success shared!", "success");
// do something
})
.catch(function(err) {
//console.log(err);
Swal.fire({
icon: "error",
title: "Oops...",
text: "Something went wrong! Plese try agian later!!",
footer: ""
});
// do something
});
});
}
The above code is working fine, the file is successfully shared but when shared user login in-app user can't access shared files.
Anyone please suggest/help to fix the above issue?
Thanks
I would suggest you call the Drive API in this way:
// This is a good scope for testing
const SCOPES = ["https://www.googleapis.com/auth/drive"];
// This code takes into consideration that you already did all the OAuth2.0 proccess
// correctly to connect to the Drive API
module.exports.init = async function (){
// Create the Drive service
const drive = google.drive({version: 'v3', oauth2Client});
// Create permissions for an user
await createPermissions(drive, null, null);
}
// This function will create the permissions to share a file using Promises
function createPermissions(drive, fileId, body){
// These parameters are for test, past the values you want as arguments
fileId = fileId || "your-file-id";
body = body || {
"role": "writer",
"type": "user",
"emailAddress": "user#domain"
};
// Create the promise and return the value from the promise if you want to
return new Promise((resolve, reject) => {
try {
// Call the endpoint, if there are no errors you will pass the results to resolve
// to return them as the value from your promise
return drive.permissions.create({
fileId: fileId,
resource: body
},
(err, results) => {
if(err) reject(`Drive error: ${err.message}`);
resolve(results);
});
} catch (error) {
console.log(`There was a problem in the promise: ${error}`);
}
});
}
I tried it and the files are shared successfully to the user I wanted. Keep in mind to build your body as:
{
"role": "writer",
"type": "user",
"emailAddress": "user#domain"
};
Docs
Here are some links to know more about the Drive API Permissions:
Permissions.
Permissions: create.

How to read json file from storage blob container with azure function using javascript?

I'm totally new in azure and I would like to create azure function, which will read the content from azure storage container file.json.
Folder structure :
Storage account name: storageaccounttest
Container name: test
File name: file.json
File.json:
[
{
"name":"Kate",
"age":"28"
},
{
"name":"John",
"age":"30"
}
]
Cors on storage account: get enabled.
Environemnts variable added: process.env.AZURE_STORAGE_NAME and process.env.AZURE_STORAGE_KEY and process.env.AZURE_CONNECTION_STRING
I'm using VisualStudioCode to deploy the function.
I installed locally the dependencies:
"dependencies": {
"azure-storage": "^2.10.3",
"dotenv": "^8.1.0"
}
I choose the javascript -> HttpTrigger fn-> anonymus options
I'm using getBlobToText fn.
My index.js:
var storage = require('azure-storage');
var blobService = storage.createBlobService();
var containerName = 'test';
var blobName = 'file.json';
module.exports = blobService.getBlobToText(
containerName,
blobName,
function(err, blobContent) {
if (err) {
console.error("Couldn't download blob");
console.error(err);
} else {
console.log("Sucessfully downloaded blob");
console.log(blobContent);
}
});
Fn is deployed successfully, but I'm not able to see results.
After start, fn is finished with status 500, Internal Server Errror, Console: No new trace in the past 1 min(s).
What I made wrong?
Just summarized for helping others who get the same issue.
I think you were using context.binding.response to pass the blobContent value to the output response as the offical document Azure Functions JavaScript developer guide said.
Here is my sample code with Promise feature to solve it.
var azure = require('azure-storage');
var blobService = azure.createBlobService();
var containerName = 'test';
var blobName = 'file.json';
async function getBlobContent(containerName, blobName) {
return new Promise((resolve, reject) => {
blobService.getBlobToText(containerName, blobName, function(err, blobContent) {
if (err) {
reject(err);
} else {
resolve(blobContent);
}
});
});
}
module.exports = async function (context, req) {
await getBlobContent(containerName, blobName).then(
function(content) {
context.res = {
headers: {"Content-Type": "application/json"},
body: content
}
}, function(error) {
context.res = {
status: 400,
body: error
}
}
);
};
It works as the figure below.

Getting error when sending a file stream through a POST request

I have created a web service to connect with google drive API. Also there is an another system which is frontend developed using react js. I need to send a file from react system to google drive through the web service which I developed. For that I used file stream. When I send it, I got an error which says "part.body.pipe is not a function". This comes from the google drive api.
Below code is sample code for POST request which I sent.
const axios = require('axios');
const fs = require('fs');
const stream = fs.createReadStream('./download.jpg');
axios.post('http://localhost:3008/google-drive/upload-file', {
stream,
name: 'add.jpg',
mimeType: 'image/jpeg',
}
)
.then((res) => {
console.log(`statusCode: ${res.statusCode}`)
console.log(res)
})
.catch((error) => {
console.error(error)
})
Below is the google drive integration for file upload.
function uploadFiles(auth, mainRequest, mainResponse) {
const drive = google.drive({version: 'v3', auth});
const {
stream,
name,
mimeType,
} = mainRequest.body;
let fileMetaData = {
name,
};
let media = {
mimeType,
body: stream,
};
drive.files.create({
media,
resource: fileMetaData,
fields: 'id',
}, (error, file) => {
if (error) {
console.log(error);
return mainResponse.status(200).json({
message: 'The API returned an error: ' + error
});
}
return mainResponse.status(200).json({
fileId: file.id
});
});
}
I think the problem is in createReadStream. I'm not sure I used it correctly or not.
Thanks in advance. :)
You made a mistake in the fs
Rather try using this synchronous func
fs.readFileSync('filename.jpg','utf8')

Problems with File plugin in Ionic2

I'm integrating Quickblox in my Ionic2 app, for now I was able to do all the things except uploading a file.
In Quickblox you have to upload a file using a function made by them that according to js documentation looks like this:
var inputFile = $("input[type=file]")[0].files[0];
var params = {name: inputFile.name,
file: inputFile,
type: inputFile.type,
size: inputFile.size,
public: false};
QB.content.createAndUpload(params, function(err, response){
if (err) {
console.log(err);
} else {
console.log(response);
var uploadedFile = response;
var uploadedFileId = response.id;
}
});
So I translated above code to typescript and I have something like this:
uploadFile(filename) {
File.resolveDirectoryUrl(cordova.file.dataDirectory).then(
(dirEntry) => {
File.getFile(dirEntry, filename, { create: false }).then(
(fileEntry) => {
console.log(fileEntry);
fileEntry.file((file) => {
console.log(file);
var params = {
name: file['name'],
file: file,
type: file['type'],
size: file['size'],
'public': false
};
quickblox.content.createAndUpload(params,
(err, response) => {
if (err) {
console.log(err);
} else {
console.log(response);
var uploadedFileId = response.id;
var msg = {
type: 'groupchat',
body: "[attachment]",
extension: {
save_to_history: 1,
}
};
msg["extension"]["attachments"] = [{ id: uploadedFileId, type: 'photo' }];
quickblox.chat.send(this.xmpp_room_jid, msg);
}
});
})
}).catch(
(err) => {
console.log(err);
}
);
}
);
}
This work in the terms of "I get ok responses from quickblox server", but when I go to the admin console of quickblox to check the uploaded content I find out that the image I uploaded has 0 bytes.
So after checking the code for a while I compared side by side all my function calls with the example app of quickblox and the only difference I could find was in the File object.
This is the File object I get in my Ionic 2 app:
And this is the one I get in the quickblox js example:
All the others things looks identically except this File object.
I'm almost sure that this is the problem I'm having, and because I'm very newbie in this field, I couldn't find a way to cast from my File object in Ionic to something like the File object in the js example.
Thanks in advance at all for your time and help.
EDIT:
I attach the requests/responses logs from my Ionic app:
Could you please post the code you used to connect to chat, create a session, open a video call?
The documentation on quickblox is very bad and i got stuck at connecting to chat.

Categories

Resources