通过服务帐户在 APP 脚本上使用 BigQuery API

Posted

技术标签:

【中文标题】通过服务帐户在 APP 脚本上使用 BigQuery API【英文标题】:Using the BigQuery API on APP Scritps with a Service Account 【发布时间】:2021-07-19 17:20:26 【问题描述】:

我正在尝试使用应用脚本在 VPC 项目上的 BigQuery 上执行作业。

我的目标是将结果存储在一个数组中,以便使用社区连接器为 DataStudio 创建一个动态提示

使用以下代码:

function runQuery() 
  
  var sql =  "SELECT Distinct ss_cd FROM `vf-pt-ngbi-dev-gen-03.AEAD_DataSet_test.d_customer` WHERE end_dttm IS NOT NULL";
  var queryResults;
  var projectNumber = 'projectNumber'
  
    // Inserts a Query Job
  try 
    var queryRequest = BigQuery.newQueryRequest();
    queryRequest.setQuery(sql).setTimeoutMs(100000);
    queryResults = BigQuery.Jobs.query(queryRequest, projectNumber);
  
  catch (err) 
    Logger.log(err);
    return;
  

由于这是一个 VPC 项目,我需要使用服务帐户来执行此请求吗?

但是,我想知道如何添加此授权?

或者是否存在另一种在 VPC 项目上执行 BigQuery 作业并将结果存储在数组中的方法?

【问题讨论】:

您是否能够检查以下解决方案? 【参考方案1】:

您可以在应用程序脚本中获取服务帐户令牌(请参阅 reference),然后通过 UrlFetchApp. 将该令牌用于 REST API

示例:

function runQuery() 
  // ...
  var service = getService();
  if (service.hasAccess()) 
    sendQuery(service);
  
  // ...


function sendQuery(service)
  var projectId = 'projectID';
  var url = 'https://bigquery.googleapis.com/bigquery/v2/projects/' + projectId + '/queries';
 
  // see request body for reference
  // https://cloud.google.com/bigquery/docs/reference/rest/v2/jobs/query#QueryRequest
  var body = 
    // ...
  
      
  var options = 
   "method": "post",
   "headers": 
      "Authorization": "Bearer " + service.getAccessToken()
     ,
   "contentType": "application/json", 
   "payload": JSON.stringify(body)
   ;
   var response = UrlFetchApp.fetch(url, options);    

// direclty copied from https://github.com/googleworkspace/apps-script-oauth2/blob/master/samples/GoogleServiceAccount.gs
function getService() 
  return OAuth2.createService('BigQuery:' + USER_EMAIL)
      // Set the endpoint URL.
      .setTokenUrl('https://oauth2.googleapis.com/token')

      // Set the private key and issuer.
      .setPrivateKey(PRIVATE_KEY)
      .setIssuer(CLIENT_EMAIL)

      // Set the name of the user to impersonate. This will only work for
      // Google Apps for Work/EDU accounts whose admin has setup domain-wide
      // delegation:
      // https://developers.google.com/identity/protocols/OAuth2ServiceAccount#delegatingauthority
      .setSubject(USER_EMAIL)

      // Set the property store where authorized tokens should be persisted.
      .setPropertyStore(PropertiesService.getScriptProperties())

      // Set the scope. This must match one of the scopes configured during the
      // setup of domain-wide delegation.
      .setScope('https://www.googleapis.com/auth/bigquery');

参考:

BigQuery REST API Creation of Service Account Get Service Account Token

注意:

查看question,其中包含您的代码应该是什么样子。

【讨论】:

以上是关于通过服务帐户在 APP 脚本上使用 BigQuery API的主要内容,如果未能解决你的问题,请参考以下文章

通过 Powershell 脚本将权限角色分配给服务主体

如何为具有多个帐户的用户在Google App Scripts中选择帐户?

如何使用 Bash 脚本自动添加用户帐户和密码?

如何使用API Explorer作为服务帐户?

通过服务帐户设置 Gmail 委托时出现权限不足错误

在 App Engine 上使用 OAuth2 的 IMAP