0

Ich versuche, eine Anfrage an die Youtube Analytics API zu stellen. und ich habe Probleme, die Anfragen so zu formulieren, dass sie akzeptiert werden. Ich bin mit dem Google-APIs Node.js-ClientYoutube Analytics - Erstellen von Anfragen

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

und mein Code wie folgt

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}); 

Ich halte die folgende Fehlermeldung erhalten

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

ich seine denken zu tun mit meiner Anfrage Objekt

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

aber alle Beispiele, die ich gefunden habe, sagen, dass dieses Anfrageobjekt funktionieren sollte. Ich habe es so weit wie möglich vereinfacht. Meine ursprüngliche Anfrage (die, die ich eigentlich möchte) war wie folgt.

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

danach brauche ich eine andere Anforderung zu tun, alle zugehörigen Informationen zu den Videos zu bekommen aufgelistet, die einen anderen api-Endpunkt verwendet.

//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; 
    } 
}); 

So In Zusammenfassung

Ich brauche eine Anfrage an verschiedene Google api zu tun und habe Schwierigkeiten mit der Anfrage bilden, so dass sie akzeptiert werden (ich habe nicht über die erste Anfrage von YouTube Analytics bekam) .

Kann mir jemand in die richtige Richtung zeigen?

Antwort

0

Ich habe es herausgefunden. Ich kann keine Service-Account-Anfrage für diese API durchführen. Ich Setup Kontoüberprüfung durch Konten-google

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

es auf dem Basiskonto verschmelzenden Konten

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

meld verwendet, die mir ein Zugriffstoken für den Benutzer angebracht gibt dann ein OAuth tat 2,0 ruf stattdessen an. Hat etwas Ähnliches auch für Facebook gemacht.

Ein Problem, das ich immer noch habe, ist, dass der Abschnitt "Retention für Videos holen" sehr ineffizient ist. es macht einen Anruf pro Video. Es gibt Batch-Anfragen für die Google API, aber ich kann kein richtiges Beispiel mit dem 'googleapis' Paket finden. Wenn jemand ein Beispiel hat, würde das sehr geschätzt werden.

Hier ist der neue Code.

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}); 
Verwandte Themen