如何避免请求 OAuth API 验证以使用 Google 脚本发送电子邮件
How to avoid requesting OAuth API verification to send emails using Google Scripts
这个问题来自于上一个几乎解决的问题:
简介
也许这是一个技术问题,我不是程序员,所以如果可能的话,我想要一个循序渐进的答案,这样我才能完全理解它。
此处解释代码的步骤和用途:Hacking it: Generate PDFs from Google Forms。
代码是 post 在 link 上编辑的,但我还是 post 在这里:
function onSubmit(e) {
const rg = e.range;
const sh = rg.getSheet();
//Get all the form submitted data
//Note: This data is dependent on the headers. If headers, are changed update these as well.
const cName = e.namedValues['Client Name'][0];
const cEmail = e.namedValues['Client Email'][0];
const cAddress = e.namedValues['Client Address'][0];
const cMobile = e.namedValues['Client Mobile'][0];
const sendCopy = e.namedValues['Send client a copy?'][0];
const paymentType = e.namedValues['What is your agreed upon payment schedule?'][0];
const fixedCost = e.namedValues['What was your agreed upon cost for the project?'][0];
const hourlyRate = e.namedValues['Hourly Rate'][0];
const manHours = e.namedValues['Total man hours'][0];
const services = e.namedValues['Select the services'][0];
//Consequential Data
const tax = 18.5
var subtotal = 0;
var taxAmt = 0;
var payableAmt = 0;
//if the user has selected hourly payment model
//Note: Be careful that the responses match the elements on the actual form
switch (paymentType ){
case 'Hourly Rate':
subtotal = hourlyRate*manHours;
taxAmt = subtotal * (tax/100);
payableAmt = +subtotal + +taxAmt;
break;
case 'Fixed Cost':
subtotal = fixedCost;
taxAmt = fixedCost * (tax/100)
payableAmt = +fixedCost + +taxAmt;
break;
}
const invoiceID = 'IN' + Math.random().toString().substr(2, 9);
var formattedDate = Utilities.formatDate(new Date(), "IST", "dd-MMM-yyyy");
//Set the consequential data in the columns of the spreadsheet for record keeping
//Note: These variable are dependent on the sheet's columns so if that changes, please update.
const row = rg.getRow();
const payableAmtCol = 2; //B
const invoiceIDCol = 3; //C
sh.getRange(row,payableAmtCol).setValue(payableAmt);
sh.getRange(row,invoiceIDCol).setValue(invoiceID);
//Build a new invoice from the file
//Folder and file IDs
const invoiceFolderID = '<invoice-folder-id>';
const invoiceFolder = DriveApp.getFolderById(invoiceFolderID);
const templateFileID = '<template-id>';
const newFilename = 'Invoice_' + invoiceID;
//Make a copy of the template file
const newInvoiceFileID = DriveApp.getFileById(templateFileID).makeCopy(newFilename, invoiceFolder).getId();;
//Get the invoice body into a variable
var document = DocumentApp.openById(newInvoiceFileID);
var body = document.getBody();
//Replace all the {{ }} text in the invoice body
body.replaceText('{{Invoice num}}', invoiceID);
body.replaceText('{{Date}}', formattedDate);
body.replaceText('{{Client Name}}', cName);
body.replaceText('{{Client Address}}', cAddress);
body.replaceText('{{Client Mobile}}', cMobile);
body.replaceText('{{Client Email}}', cEmail);
body.replaceText('{{Services}}', services.split(', ').join('\n'));
body.replaceText('{{Subtotal}}', subtotal);
body.replaceText('{{Tax Value}}', taxAmt);
body.replaceText('{{Total}}', payableAmt);
//In the case of hourly rate payment type, let's add an additional message giving the rate and the man hours.
if(paymentType.includes('Hourly Rate')){
//It should look something like this on the invoice
//Hourly Rate
//Rate of Rs.1200/hour
//Completed 50 man hours
const message = paymentType + '\nRate of Rs.' + hourlyRate + '/hour\nCompleted ' + manHours + ' man hours';
body.replaceText('{{Payment Type}}', message);
} else {
body.replaceText('{{Payment Type}}', paymentType);
}
document.saveAndClose();
/* This is not useful for me
//If you have selected to directly send it via email
if(sendCopy.includes('Yes')){
//send email with the file
var attachment = DriveApp.getFileById(newInvoiceFileID);
GmailApp.sendEmail(cEmail, '<subject>,
'<body>',
{attachments: [attachment.getAs(MimeType.PDF)],
from:'<your-email>@gmail.com'});
}
*/
}
在post中,作者展示了一种向客户端发送电子邮件的方法,这就是我想要的项目。
实际问题
但是,那部分代码已过时,或者作者在发布她的应用程序之前完成了验证过程,因为我必须根据 sendEmail
命令请求 OAuth API 验证。正如我所研究的那样,这需要我完全不知道的时间和工具(我不是程序员)。
因此,我问 是否有一种简单的方法(无需附加组件并避免请求验证过程)在客户按下“发送”时将生成的文档的副本发送给客户Google 表单的按钮基于我 posted.
的代码
该代码运行良好,它根据模板将文档副本创建到我的云端硬盘文件夹中,但我想自动发送电子邮件,以便客户获得我拥有的文档副本。我不想发送任何其他信息,例如垃圾邮件等
编辑 这是我里面的内容 appsscript.json
:
{
"timeZone": "America/New_York",
"dependencies": {
},
"exceptionLogging": "STACKDRIVER",
"runtimeVersion": "V8"
}
这是我的一个 oauthscope 的样子:
"oauthScopes": [
"https://mail.google.com/",
"https://www.google.com/m8/feeds",
"https://www.googleapis.com/auth/userinfo.email",
"https://www.googleapis.com/auth/script.external_request",
"https://www.googleapis.com/auth/spreadsheets",
"https://www.googleapis.com/auth/script.container.ui",
"https://www.googleapis.com/auth/calendar",
"https://www.googleapis.com/auth/gmail.send",
"https://www.googleapis.com/auth/script.send_mail",
"https://www.googleapis.com/auth/drive",
"https://www.googleapis.com/auth/presentations",
"https://www.googleapis.com/auth/cloud-platform",
"https://www.googleapis.com/auth/documents",
"https://www.googleapis.com/auth/script.projects.readonly",
"https://sites.google.com/feeds",
"https://www.googleapis.com/auth/drive.activity",
"https://www.googleapis.com/auth/forms",
"https://www.googleapis.com/auth/script.projects"
],
这个问题来自于上一个几乎解决的问题:
简介
也许这是一个技术问题,我不是程序员,所以如果可能的话,我想要一个循序渐进的答案,这样我才能完全理解它。
此处解释代码的步骤和用途:Hacking it: Generate PDFs from Google Forms。
代码是 post 在 link 上编辑的,但我还是 post 在这里:
function onSubmit(e) {
const rg = e.range;
const sh = rg.getSheet();
//Get all the form submitted data
//Note: This data is dependent on the headers. If headers, are changed update these as well.
const cName = e.namedValues['Client Name'][0];
const cEmail = e.namedValues['Client Email'][0];
const cAddress = e.namedValues['Client Address'][0];
const cMobile = e.namedValues['Client Mobile'][0];
const sendCopy = e.namedValues['Send client a copy?'][0];
const paymentType = e.namedValues['What is your agreed upon payment schedule?'][0];
const fixedCost = e.namedValues['What was your agreed upon cost for the project?'][0];
const hourlyRate = e.namedValues['Hourly Rate'][0];
const manHours = e.namedValues['Total man hours'][0];
const services = e.namedValues['Select the services'][0];
//Consequential Data
const tax = 18.5
var subtotal = 0;
var taxAmt = 0;
var payableAmt = 0;
//if the user has selected hourly payment model
//Note: Be careful that the responses match the elements on the actual form
switch (paymentType ){
case 'Hourly Rate':
subtotal = hourlyRate*manHours;
taxAmt = subtotal * (tax/100);
payableAmt = +subtotal + +taxAmt;
break;
case 'Fixed Cost':
subtotal = fixedCost;
taxAmt = fixedCost * (tax/100)
payableAmt = +fixedCost + +taxAmt;
break;
}
const invoiceID = 'IN' + Math.random().toString().substr(2, 9);
var formattedDate = Utilities.formatDate(new Date(), "IST", "dd-MMM-yyyy");
//Set the consequential data in the columns of the spreadsheet for record keeping
//Note: These variable are dependent on the sheet's columns so if that changes, please update.
const row = rg.getRow();
const payableAmtCol = 2; //B
const invoiceIDCol = 3; //C
sh.getRange(row,payableAmtCol).setValue(payableAmt);
sh.getRange(row,invoiceIDCol).setValue(invoiceID);
//Build a new invoice from the file
//Folder and file IDs
const invoiceFolderID = '<invoice-folder-id>';
const invoiceFolder = DriveApp.getFolderById(invoiceFolderID);
const templateFileID = '<template-id>';
const newFilename = 'Invoice_' + invoiceID;
//Make a copy of the template file
const newInvoiceFileID = DriveApp.getFileById(templateFileID).makeCopy(newFilename, invoiceFolder).getId();;
//Get the invoice body into a variable
var document = DocumentApp.openById(newInvoiceFileID);
var body = document.getBody();
//Replace all the {{ }} text in the invoice body
body.replaceText('{{Invoice num}}', invoiceID);
body.replaceText('{{Date}}', formattedDate);
body.replaceText('{{Client Name}}', cName);
body.replaceText('{{Client Address}}', cAddress);
body.replaceText('{{Client Mobile}}', cMobile);
body.replaceText('{{Client Email}}', cEmail);
body.replaceText('{{Services}}', services.split(', ').join('\n'));
body.replaceText('{{Subtotal}}', subtotal);
body.replaceText('{{Tax Value}}', taxAmt);
body.replaceText('{{Total}}', payableAmt);
//In the case of hourly rate payment type, let's add an additional message giving the rate and the man hours.
if(paymentType.includes('Hourly Rate')){
//It should look something like this on the invoice
//Hourly Rate
//Rate of Rs.1200/hour
//Completed 50 man hours
const message = paymentType + '\nRate of Rs.' + hourlyRate + '/hour\nCompleted ' + manHours + ' man hours';
body.replaceText('{{Payment Type}}', message);
} else {
body.replaceText('{{Payment Type}}', paymentType);
}
document.saveAndClose();
/* This is not useful for me
//If you have selected to directly send it via email
if(sendCopy.includes('Yes')){
//send email with the file
var attachment = DriveApp.getFileById(newInvoiceFileID);
GmailApp.sendEmail(cEmail, '<subject>,
'<body>',
{attachments: [attachment.getAs(MimeType.PDF)],
from:'<your-email>@gmail.com'});
}
*/
}
在post中,作者展示了一种向客户端发送电子邮件的方法,这就是我想要的项目。
实际问题
但是,那部分代码已过时,或者作者在发布她的应用程序之前完成了验证过程,因为我必须根据 sendEmail
命令请求 OAuth API 验证。正如我所研究的那样,这需要我完全不知道的时间和工具(我不是程序员)。
因此,我问 是否有一种简单的方法(无需附加组件并避免请求验证过程)在客户按下“发送”时将生成的文档的副本发送给客户Google 表单的按钮基于我 posted.
的代码该代码运行良好,它根据模板将文档副本创建到我的云端硬盘文件夹中,但我想自动发送电子邮件,以便客户获得我拥有的文档副本。我不想发送任何其他信息,例如垃圾邮件等
编辑 这是我里面的内容 appsscript.json
:
{
"timeZone": "America/New_York",
"dependencies": {
},
"exceptionLogging": "STACKDRIVER",
"runtimeVersion": "V8"
}
这是我的一个 oauthscope 的样子:
"oauthScopes": [
"https://mail.google.com/",
"https://www.google.com/m8/feeds",
"https://www.googleapis.com/auth/userinfo.email",
"https://www.googleapis.com/auth/script.external_request",
"https://www.googleapis.com/auth/spreadsheets",
"https://www.googleapis.com/auth/script.container.ui",
"https://www.googleapis.com/auth/calendar",
"https://www.googleapis.com/auth/gmail.send",
"https://www.googleapis.com/auth/script.send_mail",
"https://www.googleapis.com/auth/drive",
"https://www.googleapis.com/auth/presentations",
"https://www.googleapis.com/auth/cloud-platform",
"https://www.googleapis.com/auth/documents",
"https://www.googleapis.com/auth/script.projects.readonly",
"https://sites.google.com/feeds",
"https://www.googleapis.com/auth/drive.activity",
"https://www.googleapis.com/auth/forms",
"https://www.googleapis.com/auth/script.projects"
],