Google Sheets AddOn - 通过服务帐户集成 AppScript 和 BigQuery
Posted
技术标签:
【中文标题】Google Sheets AddOn - 通过服务帐户集成 AppScript 和 BigQuery【英文标题】:Google Sheets AddOn - AppScript & BigQuery Integration via Service Account 【发布时间】:2021-04-10 16:36:55 【问题描述】:我有一个 Google 表格工作区插件,最近做了一些工作来集成 BigQuery。本质上,BigQuery 保存着每本书的记录,每本书都有作者、标题等,我的插件允许人们将他们读过的书拉到他们的工作表中。工作表中的第一列允许人们从数据库中的所有作者中进行选择,根据该选择,第二列填充来自 BigQuery 的数据以及该作者的所有书籍等。我的插件无需访问用户的 BigQuery,他们只能访问“我的”BgQuery。
这一切都很好,但是当我提交我的插件以供批准时,我被告知
Unfortunately, we cannot approve your request for the use of the following scopes
https://www.googleapis.com/auth/bigquery
We recommend using service accounts for this type of information exchange.
这似乎很公平,阅读服务帐户似乎更适合我的用例。我已经完成了创建服务帐户的过程并下载了我的安全详细信息 json 文件,但是我只是不知道如何从 AppScript 实际查询 BigQuery。
在我的非服务帐户方法中,我在 AppScript 中安装了 BigQuery 库并基本上运行
var queryResults = BigQuery.Jobs.query(request, projectId);
我一直在尝试从https://developers.google.com/datastudio/solution/blocks/using-service-accounts 的示例开始工作
function getOauthService()
var serviceAccountKey = getServiceAccountCreds('SERVICE_ACCOUNT_KEY');// from private_key not private_key_id of JSON file
var serviceAccountEmail = getServiceAccountCreds('SERVICE_ACCOUNT_EMAIL');
return OAuth2.createService('RowLevelSecurity')
.setAuthorizationBaseUrl('https://accounts.google.com/o/oauth2/auth')
.setTokenUrl('https://accounts.google.com/o/oauth2/token')
.setPrivateKey(serviceAccountKey)
.setIssuer(serviceAccountEmail)
.setPropertyStore(scriptProperties)
.setCache(CacheService.getScriptCache())
.setScope(['https://www.googleapis.com/auth/bigquery.readonly']);
function getData(request)
var accessToken = getOauthService().getAccessToken();
var billingProjectId = getServiceAccountCreds('BILLING_PROJECT_ID');
// var email = Session.getEffectiveUser().getEmail();
// return cc
// .newBigQueryConfig()
// .setAccessToken(accessToken)
// .setBillingProjectId(billingProjectId)
// .setUseStandardSql(true)
// .setQuery(BASE_SQL)
// .addQueryParameter('email', bqTypes.STRING, email)
// .build();
上面的代码我已经注释掉了
var cc = DataStudioApp.createCommunityConnector();
在上面的教程中,因为我没有使用 DataStudio,但我真的不确定用什么替换它,所以我可以通过服务帐户使用 AppScript 查询 BigQuery。谁能给点建议?
【问题讨论】:
您应该可以使用您注释掉的代码。服务帐户有自己的电子邮件,因此请尝试使用它。您可以在为您的服务帐号密钥下载的 json 文件中的“client_email”属性下找到您的服务帐号电子邮件。 感谢您的回复。我在 getOauthService 函数var serviceAccountEmail = getServiceAccountCreds('SERVICE_ACCOUNT_EMAIL');
中提取客户电子邮件。但是我注释掉的代码与从 var cc = DataStudioApp.createCommunityConnector();
返回的对象有关 - 我没有使用 DataStudioApp
所以我应该使用其他东西吗?
哦。由于您使用的是服务帐户,因此您似乎需要使用 UrlFetchApp 直接利用 BigQuery REST API。
非常感谢,会看看。您有任何指南/示例的链接吗?
【参考方案1】:
根据上面 cmets 中 @TheAddonDepot 的建议,我修改后的代码现在看起来像:
function getBigQueryService()
return (
OAuth2.createService('BigQuery')
// Set the endpoint URL.
.setTokenUrl('https://accounts.google.com/o/oauth2/token')
// Set the private key and issuer.
.setPrivateKey(JSON_CREDS.private_key) // from the json file downloaded when you create service account
.setIssuer(JSON_CREDS.client_email). // from the json file downloaded when you create service account
// Set the property store where authorized tokens should be persisted.
.setPropertyStore(PropertiesService.getScriptProperties())
// Caching
.setCache(CacheService.getUserCache())
// Locking
.setLock(LockService.getUserLock())
// Set the scopes.
.setScope(['https://www.googleapis.com/auth/bigquery.readonly'])
// .setScope('https://www.googleapis.com/auth/bigquery')
)
function queryData()
const bigQueryService = getBigQueryService()
if (!bigQueryService.hasAccess())
Logger.log("BQ ERROR IS "+ bigQueryService.getLastError())
//const projectId = bigqueryCredentials.project_id
var projectId = "<yourprojectid>"
let url = 'https://bigquery.googleapis.com/bigquery/v2/projects/<yourprojectid>/queries'; //projectID is taken from the security json file for the service account, although it doesn't seem to matter if you use the project code
const headers =
Authorization: `Bearer $bigQueryService.getAccessToken()`,
'Content-Type': 'application/json',
var data = query:"<your query>",useLegacySql:false;
const options =
method: 'post',
headers,
//contentType: 'application/json',
payload: JSON.stringify(data),
muteHttpExceptions: true // on for debugging
try
const response = UrlFetchApp.fetch(url, options)
const result = JSON.parse(response.getContentText())
Logger.log("here is result "+ JSON.stringify(result))
catch (err)
console.error(err)
【讨论】:
以上是关于Google Sheets AddOn - 通过服务帐户集成 AppScript 和 BigQuery的主要内容,如果未能解决你的问题,请参考以下文章
“未安装以下 SDK 组件:sys-img-x86-addon-google_apis-google-22 和 addon-google_apis-google-22”
使用 Google Sheets API 将图像插入 Google Sheets 单元格