![](/img/trans.png)
[英]Firebase | Google Sheet | App Script | How do I save the data in column instead of row from Firebase to Google Sheet?
[英]POST data to Google Sheet web app from AWS Lambda
目前
我有一个 Google 表格应用脚本“网络应用”
Goolge 表格中的脚本
function doPost(e) {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName("Sheet1");
sheet.getRange("A1").setValue("Hello!")
return "Success!"
}
Google Apps 脚本 Web 应用配置:
Execute as: Me // or as User. I've tried both.
Who has access: Anyone within MyOrganisation
我想从 AWS Lambda 向上述 Web 应用程序发出 POST 请求。
AWS Lambda.js:
const { GoogleSpreadsheet } = require("google-spreadsheet");
const doc = new GoogleSpreadsheet(
{spreadsheetId}
);
await doc.useServiceAccountAuth({
client_email: process.env.GOOGLE_SERVICE_ACCOUNT_EMAIL,
private_key: process.env.GOOGLE_PRIVATE_KEY.replace(/\\n/g, "\n"),
});
let token = doc["jwtClient"]["credentials"]["access_token"];
await new Promise((resolve, reject) => {
const options = {
host: 'script.google.com',
path: "/macros/s/{myscriptid}/exec", //<-- my web app path!
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': "Bearer "+ token
}
};
//create the request object with the callback with the result
const req = HTTPS.request(options, (res) => {
resolve(JSON.stringify(res.statusCode));
});
// handle the possible errors
req.on('error', (e) => {
reject(e.message);
});
//do the request
req.write(JSON.stringify(data));
//finish the request
req.end();
});
console.log("response:"+JSON.stringify(response))
GCP 服务帐号
doPost(e)
脚本对 Google 工作表的EDIT
访问权限。令牌 Output:
"jwtClient": {
"_events": {},
"_eventsCount": 0,
"transporter": {},
"credentials": {
"access_token": "somelongvalue...............", //<-- what I use
"token_type": "Bearer",
"expiry_date": 1661662492000,
"refresh_token": "jwt-placeholder"
},
"certificateCache": {},
"certificateExpiry": null,
"certificateCacheFormat": "PEM",
"refreshTokenPromises": {},
"eagerRefreshThresholdMillis": 300000,
"forceRefreshOnFailure": false,
"email": "serviceaccount@appspot.gserviceaccount.com",
"key": "-----BEGIN PRIVATE KEY-----\nsomelongvalue=\n-----END PRIVATE KEY-----\n",
"scopes": [
"https://www.googleapis.com/auth/spreadsheets"
],
"subject": null,
"gtoken": {
"key": "-----BEGIN PRIVATE KEY-----\nsomelongvalue=\n-----END PRIVATE KEY-----\n",
"rawToken": {
"access_token": "somelongvalue...............",
"expires_in": 3599,
"token_type": "Bearer"
},
"iss": "serviceaccount@appspot.gserviceaccount.com",
"sub": null,
"scope": "https://www.googleapis.com/auth/spreadsheets",
"expiresAt": 1661662492000
}
}
问题
目前的回应:
response:"401"
MyOrganisation
,我就很难找到一种方法来验证我的 POST 请求。帮助!
如何设置对我的 Google 表格 web 应用程序的 POST 请求,以便可以通过身份验证对其进行保护? 现在,我很高兴找到任何方法来验证这个请求(不一定是服务帐户),而不是让它完成对公众开放。
我应该使用这个黑客吗?
我的一个想法是将“秘密”放入我的 lambda function 中,然后公开 web 应用程序。 web 应用程序将检查密钥,如果匹配,将执行 function。
为了使用带有脚本的访问令牌访问 Web 应用程序,需要包含 Drive API 的范围。 这些是https://www.googleapis.com/auth/drive.readonly
、 https://www.googleapis.com/auth/drive
等等。 参考
当我看到您的显示脚本时,似乎使用google-spreadsheet
检索了访问令牌。 当我看到google-spreadsheet
的脚本时,似乎这只使用了https://www.googleapis.com/auth/spreadsheets
的 scope 。 参考
从这种情况来看,我认为您当前问题的原因可能是由于此。 如果我的理解是正确的,那么下面的修改呢? 在此修改中,访问令牌由 googleapis 从服务帐户中检索到 Node.js。 参考
function doPost(e) {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName("Sheet1");
sheet.getRange("A1").setValue("Hello!")
return ContentService.createTextOutput("Success!"); // Modified
}
const { google } = require("googleapis");
const HTTPS = require("https");
const auth = new google.auth.JWT(
"###", // Please set client_email here.
null,
"###", // Please set private_key here. When you set private_key of service account, please include \n.
["https://www.googleapis.com/auth/drive.readonly"],
null
);
function req(token) {
return new Promise((resolve, reject) => {
const data = { key1: "value1" }; // Please set your value.
const options = {
host: "script.google.com",
path: "/macros/s/{myscriptid}/exec", //<-- my web app path!
method: "POST",
headers: {Authorization: "Bearer " + token},
};
const req = HTTPS.request(options, (res) => {
if (res.statusCode == 302) {
HTTPS.get(res.headers.location, (res) => {
if (res.statusCode == 200) {
res.setEncoding("utf8");
res.on("data", (r) => resolve(r));
}
});
} else {
res.setEncoding("utf8");
res.on("data", (r) => resolve(r));
}
});
req.on("error", (e) => reject(e.message));
req.write(JSON.stringify(data));
req.end();
});
}
auth.getAccessToken().then(({ token }) => {
req(token).then((e) => console.log(e)).catch((e) => console.log(e));
});
Success!
被退回。如果此修改后的脚本对您的 Web 应用程序设置没有用,请进行如下测试。
当您设置服务帐户的private_key
时,请包含\n
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.