优酷分析 - 创建请求



我正在尝试向youtube分析api发出请求,并且在形成请求时遇到一些问题,因此它们被接受。我正在使用 Google API Node.js 客户端

https://github.com/google/google-api-nodejs-client

我的代码如下

import { Meteor } from 'meteor/meteor';
import google from 'googleapis';
import KEY_FILE from './keyFile.json';
import { CHANNEL_ID } from './channelId.js';
//api's
const analytics = google.youtubeAnalytics('v1');
//fetch youtube analytics
export function youtubeAnalytics(start, end){
//initalise request data
const startDate = `${start.getFullYear()}-${('0'+(start.getMonth()+1)).slice(-2)}-${('0'+(start.getDate())).slice(-2)}`;
const endDate = `${end.getFullYear()}-${('0'+(end.getMonth()+1)).slice(-2)}-${('0'+(end.getDate())).slice(-2)}`;
const scopes = [
'https://www.googleapis.com/auth/youtube',
'https://www.googleapis.com/auth/youtube.readonly',
'https://www.googleapis.com/auth/yt-analytics-monetary.readonly',
'https://www.googleapis.com/auth/yt-analytics-monetary.readonly'
];
//generate authorisation token
var AUTH = new google.auth.JWT(
KEY_FILE.client_email,
null,
KEY_FILE.private_key,
scopes,
null
);
//authorize request
AUTH.authorize(function (err, tokens) {
if (err) {
console.log(err);
return;
}
//create request
const analyticsRequest = {
auth: AUTH,
'start-date': startDate,
'end-date': endDate,
ids: `channel==${CHANNEL_ID}`,
metrics: 'views',
};
//make request
analytics.reports.query(analyticsRequest, function (err, data) {
if (err) {
console.error('Error: ' + err);
return false;
}
if (data) {
console.log(data);
return data;
}
});
});
return false;
}
Meteor.methods({youtubeAnalytics});

我不断收到以下错误

Error: Error: Invalid query. Query did not conform to the expectations.

我认为这与我的请求对象有关

const analyticsRequest = {
auth: AUTH,
'start-date': startDate,
'end-date': endDate,
ids: `channel==${CHANNEL_ID}`,
metrics: 'views',
};

但是我找到的所有示例都表明此请求对象应该有效。 我尽可能地简化了它。 我最初的要求(我真正想要的要求)如下。

const analyticsRequest = {
auth: AUTH,
'start-date': startDate,
'end-date': endDate,
ids: `channel==${CHANNEL_ID}`,
metrics: 'views',
dimensions: 'video',
sort: '-views',
'max-results': '200'
}

之后,我需要执行另一个请求来获取使用不同 API 端点的所列视频的所有相关信息。

//api's
const youtube = google.youtube('v3');
/*
do processing of analytics data to create batchRequest
which is a string of comma separated video ids
*/
videoRequest = {
auth: AUTH,
part: 'id,snippet',
id: batchRequest;
}
youtubeApiData.search.list(videosRequest, function (err, data) {
if (err) {
console.error('Error: ' + err);
return false;
}
if (data) {
console.log(data);
return data;
}
});

所以总结

我需要向各种谷歌 API 发出请求,并且在形成请求时遇到问题,以便它们被接受(我还没有通过 youtube 分析的第一个请求)。

有人可以指出我正确的方向吗?

想通了。 无法对此 API 执行服务帐户请求。 我通过帐户-谷歌设置帐户验证

https://guide.meteor.com/accounts.html

使用帐户合并到基本帐户上

合并https://atmospherejs.com/splendido/accounts-meld

这给了我一个附加到用户的访问令牌,然后进行了 OAuth 2.0 调用。 Facebook也做了类似的事情。

我仍然遇到的一个问题是"视频的获取保留"部分效率非常低。 它为每个视频拨打一个电话。 谷歌 api 有可用的批处理请求,但我似乎找不到使用"googleapis"包的适当示例。 如果有人有一个例子,将不胜感激。

这是新代码。

import { Meteor } from 'meteor/meteor';
import google from 'googleapis';
import { CHANNEL_ID, USER_ID, KEY_FILE, API_KEY, CLIENT_ID, CLIENT_SECRET } from './keys.js';
//api's
const fetchAnalytics = google.youtubeAnalytics('v1');
const fetchYoutube = google.youtube('v3');
const OAuth2 = google.auth.OAuth2;
export function youtubeAnalytics(start, end){
//requires login to generate authorisation
const user = Meteor.user();
if(user && user.services && user.services.google && user.services.google.accessToken){
//-------------------- general setup -------------------- //
//convert async functions to sync functions
const fetchYoutubeSync = Meteor.wrapAsync(fetchYoutube.search.list);
const fetchAnalyticsSync = Meteor.wrapAsync(fetchAnalytics.reports.query);
// set up default values
const analytics = {views: [], retention: []};
const videos = [];
const startDate = `${start.getFullYear()}-${('0'+(start.getMonth()+1)).slice(-2)}-${('0'+(start.getDate())).slice(-2)}`;
const endDate = `${end.getFullYear()}-${('0'+(end.getMonth()+1)).slice(-2)}-${('0'+(end.getDate())).slice(-2)}`;
const startDateLong = `${start.getFullYear()}-${('0'+(start.getMonth()+1)).slice(-2)}-${('0'+(start.getDate())).slice(-2)}T00:00:00.0+00:00`;
const endDateLong = `${end.getFullYear()}-${('0'+(end.getMonth()+1)).slice(-2)}-${('0'+(end.getDate())).slice(-2)}T00:00:00.0+00:00`;
// generate authorisation tokens
const oauth2Client = new OAuth2(CLIENT_ID, CLIENT_SECRET,'');
oauth2Client.setCredentials({access_token: user.services.google.accessToken});
google.options({
auth: oauth2Client
});
//-------------------- fetch videos between dates -------------------- //
let fetch = true;
let next = '';
while (fetch) {
//create video request
let videosRequest = {
auth: oauth2Client,
part: 'id,snippet',
type: 'video',
channelId: CHANNEL_ID,
publishedAfter: startDateLong,
publishedBefore: endDateLong,
maxResults: 50,
pageToken: next,
}
//make video request
let response = fetchYoutubeSync(videosRequest);
//store video request
videos.push.apply(videos, response.items);
//check if more data is available
if(response.nextPageToken){ next = response.nextPageToken; }
else{ fetch = false;}
}
//-------------------- create batch request objects -------------------- //
if(videos.length > 0){
//process videos
let batchRequestViews = '';
let batchRequestRetention = [];
let first = true;
for(let i = 0; i < videos.length; i += 1){
let id = false;
if(videos[i].id.kind === 'youtube#video'){ id = videos[i].id.videoId;}
if(id){
//views processing
if(first){ first = false; batchRequestViews = id;}
else{ batchRequestViews = `${batchRequestViews},${id}`}
//retention processing
let request = {
auth: oauth2Client,
'start-date': startDate,
'end-date': endDate,
ids: `channel==${CHANNEL_ID}`,
metrics: 'audienceWatchRatio',
dimensions: 'elapsedVideoTimeRatio',
filters: `video==${id}`
};
batchRequestRetention.push(request);
}
}
//-------------------- fetch views for videos  -------------------- //
// create views request
const analyticsRequestViews = {
auth: oauth2Client,
'start-date': startDate,
'end-date': endDate,
ids: `channel==${CHANNEL_ID}`,
metrics: 'views',
dimensions: 'video',
filters: `video==${batchRequestViews}`
};
// make and store views request
analytics.views = fetchAnalyticsSync(analyticsRequestViews).rows;
//-------------------- fetch retention for videos  -------------------- //
//make retention batch request
if(batchRequestRetention && batchRequestRetention.length > 0){
for(let i = 0; i < batchRequestRetention.length; i += 1){
//fetch retention request
let request = batchRequestRetention[i];
//make retention request
let response = fetchAnalyticsSync(request);
//store response
analytics.retention.push({id: request.filters.substring(7), response});
}
}
//-------------------- return results  -------------------- //
return {videos, analytics};
}
}
return false;
}
Meteor.methods({youtubeAnalytics});

相关内容

  • 没有找到相关文章

最新更新