Javascript Google Seach控制台API授权问题与服务帐户

Javascript Google Seach控制台API授权问题与服务帐户,javascript,api,oauth-2.0,google-app-maker,Javascript,Api,Oauth 2.0,Google App Maker,我正试图通过http请求从Google搜索控制台(GSC)获取数据 我正在使用带有javascript的google app Maker 就我而言,我正在使用一个服务帐户,该帐户的所有作用域都已设置 我复制了@Morfinismo提供的代码 /*********** SERVICE ACCOUNT CONFIGURATION USING THE OAUTH LIBRARY *********** ** All of the values are obtained from the .json f

我正试图通过http请求从Google搜索控制台(GSC)获取数据

我正在使用带有javascript的google app Maker

就我而言,我正在使用一个服务帐户,该帐户的所有作用域都已设置

我复制了@Morfinismo提供的代码

/*********** SERVICE ACCOUNT CONFIGURATION USING THE OAUTH LIBRARY ***********
** All of the values are obtained from the .json file that is downloaded at
** the time of the service account creation
** Ref: https://developers.google.com/identity/protocols/OAuth2ServiceAccount
** Ref: https://github.com/googlesamples/apps-script-oauth2
*/


var accessData = {
  "private_key" : "-----BEGIN PRIVATE KEY-----THE KEY-----END PRIVATE KEY-----\n",
  "client_email" : "searchconsolebot@project-id-xxxxxxxxxxxxxxx.iam.gserviceaccount.com",
  "user_email" : "user@domain.com" // Why do we need a user mail ?
};


var scopes = ["https://www.googleapis.com/auth/webmasters", "https://www.googleapis.com/auth/webmasters.readonly"]; //GSC api scope
scopes = scopes.join(" "); //join all scopes into a space separated string

function getOAuthService(user) {
  console.log("je passe par getOAuthService");
  user = user || accessData.user_email;
  console.log("user: " + user);
  return OAuth2.createService("GSC_Service_Account")
    .setTokenUrl('https://accounts.google.com/o/oauth2/token')
    .setPrivateKey(accessData.private_key)
    .setIssuer(accessData.client_email)
    .setSubject(user)
    .setPropertyStore(PropertiesService.getScriptProperties())
    .setCache(CacheService.getUserCache())
    .setParam('access_type', 'offline')
    .setScope(scopes);
}


function reset(user) {
  var service = getOAuthService(user);
  console.log("service: " + service);
  service.reset();
  return service;
}


function getToken(userEmail){
  var totoken = reset(userEmail).getAccessToken();
  console.log(totoken);
  return reset(userEmail).getAccessToken();
}


function getGCSUrlData(urlGiven){
  var token = getToken();
  if(token){
    var reqBody = {
      startDate: "2019-01-01",
      endDate: "2020-01-23"
    };
    var options = {
      method : 'POST',           
      headers : {
        Authorization : 'Bearer ' + token,
      },
      contentType: 'application/json',
      payload: JSON.stringify(reqBody),
      muteHttpExceptions: true,
    };
    var url = "https://www.googleapis.com/webmasters/v3/sites/" + encodeURIComponent(urlGiven) + "/searchAnalytics/query";
    var response = UrlFetchApp.fetch(url, options);
    console.log(response);
  }
}
使用OAuth库似乎非常好,但它确实返回了一个错误

Error: Access not granted or expired. at getToken (Service_Account_Config:46)
我还注意到,
getToken()
方法需要一个参数,但是当调用它时,我们没有给出任何参数,这正常吗? 既然我们使用的是服务帐户,为什么我们需要一封用户电子邮件? 那么我应该为用户输入哪封电子邮件

我真的很感激在这个问题上能得到一些帮助,以及任何能理解这类问题的建议

非常感谢,
使用时,Jacky与服务帐户的集成非常容易。以下是步骤:

1.)在服务器端脚本中添加以下内容:

/*********** SERVICE ACCOUNT CONFIGURATION USING THE OAUTH LIBRARY ***********
** All of the values are obtained from the .json file that is downloaded at
** the time of the service account creation
** Ref: https://developers.google.com/identity/protocols/OAuth2ServiceAccount
** Ref: https://github.com/googlesamples/apps-script-oauth2
*/

var accessData= {
  "private_key": "-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----\n",
  "client_email": "service-account825@08012018.iam.gserviceaccount.com",
  "user_email": "user@domain.com"
};

var scopes = ["https://www.googleapis.com/auth/webmasters", "https://www.googleapis.com/auth/webmasters.readonly"]; //drive api scope
scopes = scopes.join(" "); //join all scopes into a space separated string

function getOAuthService(user) {
  user = user || accessData.user_email;
  return OAuth2.createService("Service Account")
    .setTokenUrl('https://accounts.google.com/o/oauth2/token')
    .setPrivateKey(accessData.private_key)
    .setIssuer(accessData.client_email)
    .setSubject(user)
    .setPropertyStore(PropertiesService.getScriptProperties())
    .setCache(CacheService.getUserCache())
    .setParam('access_type', 'offline')
    .setScope(scopes);
}


function reset(user) {
  var service = getOAuthService(user);
  service.reset();
  return service;
}


function getToken(userEmail){
  return reset(userEmail).getAccessToken();
}
function getGCSUrlData(urlGiven){
  var token = getToken();
  if(token){
    var reqBody = {
      startDate: "2020-01-01",
      endDate: "2020-01-23"
    };
    var options = {
      method : 'POST',           
      headers : {
        Authorization : 'Bearer ' + token,
      },
      contentType: 'application/json',
      payload: JSON.stringify(reqBody),
      muteHttpExceptions: true,
    };
    var url = "https://www.googleapis.com/webmasters/v3/sites/" + encodeURIComponent(urlGiven) + "/searchAnalytics/query";
    var response = UrlFetchApp.fetch(url, options);
    console.log(response);
  }
}
然后,您可以通过执行以下操作调用所需的服务:

/*********** SERVICE ACCOUNT CONFIGURATION USING THE OAUTH LIBRARY ***********
** All of the values are obtained from the .json file that is downloaded at
** the time of the service account creation
** Ref: https://developers.google.com/identity/protocols/OAuth2ServiceAccount
** Ref: https://github.com/googlesamples/apps-script-oauth2
*/

var accessData= {
  "private_key": "-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----\n",
  "client_email": "service-account825@08012018.iam.gserviceaccount.com",
  "user_email": "user@domain.com"
};

var scopes = ["https://www.googleapis.com/auth/webmasters", "https://www.googleapis.com/auth/webmasters.readonly"]; //drive api scope
scopes = scopes.join(" "); //join all scopes into a space separated string

function getOAuthService(user) {
  user = user || accessData.user_email;
  return OAuth2.createService("Service Account")
    .setTokenUrl('https://accounts.google.com/o/oauth2/token')
    .setPrivateKey(accessData.private_key)
    .setIssuer(accessData.client_email)
    .setSubject(user)
    .setPropertyStore(PropertiesService.getScriptProperties())
    .setCache(CacheService.getUserCache())
    .setParam('access_type', 'offline')
    .setScope(scopes);
}


function reset(user) {
  var service = getOAuthService(user);
  service.reset();
  return service;
}


function getToken(userEmail){
  return reset(userEmail).getAccessToken();
}
function getGCSUrlData(urlGiven){
  var token = getToken();
  if(token){
    var reqBody = {
      startDate: "2020-01-01",
      endDate: "2020-01-23"
    };
    var options = {
      method : 'POST',           
      headers : {
        Authorization : 'Bearer ' + token,
      },
      contentType: 'application/json',
      payload: JSON.stringify(reqBody),
      muteHttpExceptions: true,
    };
    var url = "https://www.googleapis.com/webmasters/v3/sites/" + encodeURIComponent(urlGiven) + "/searchAnalytics/query";
    var response = UrlFetchApp.fetch(url, options);
    console.log(response);
  }
}

刚刚在firefox上试用过,效果非常好。。。为什么它不能在chrome上工作?谢谢。我试着检查谷歌提供的链接,但它似乎不存在。这可能是问题吗?在再次配置我的服务帐户后,它终于起作用了!谢谢你的回答。我设法让它工作,但你的例子真的很好,我的理解方式做它现在真的好多了。实际上,我正试图更新此内容以使用服务帐户(出于我的目的),我想我需要打开一个新的线程,因为这不是同一个问题。@LIMJacky使用服务帐户更好,只需编辑您的问题,我就会发布解决方案。@LIMJacky更新了答案。希望有帮助!谢谢你的回答@Morfinismo,我现在就试试!!我尝试了代码,但它确实返回了一个错误,说访问权限未授予或令牌已过期。我同时更新了这个帖子,谢谢你的帮助@Morfinismo。