gpt4 book ai didi

google-apps-script - 检查用户是否运行过

转载 作者:行者123 更新时间:2023-12-02 00:30:55 25 4
gpt4 key购买 nike

我运行一个 Google Apps 脚本,将文件上传到用户的 Google 云端硬盘文件:

function doGet(e) {
var blob = UrlFetchApp.fetch(e.parameters.url).getBlob();
DriveApp.createFile(blob);
return HtmlService.createHtmlOutput("DONE!");
}

我的网站加载一个弹出窗口,该窗口使用该代码运行 Google Apps 脚本。工作正常。

现在,如何向我的网站反馈用户已成功上传文件的信息? 例如,我如何向我的服务器反馈用户已成功上传文件的信息?已运行 doGet()?`

必须存在某种类型的响应处理?

完整的工作代码(在 JSBin 上进行测试):

<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.js"></script>
</head>
<body>
<div class="google-upload" data-url="https://calibre-ebook.com/downloads/demos/demo.docx">
<span style="background-color: #ddd">Upload</span>
</div>
<script>
$(function() {
$(".google-upload").click(function() {
var url = "https://script.google.com/macros/s/AKfycbwsuIcO5R86Xgv4E1k1ZtgtfKaENaKq2ZfsLGWZ4aqR0d9WBYc/exec"; // Please input the URL here.
var withQuery = url + "?url=";
window.open(withQuery + $('.google-upload').attr("data-url"), "_blank", "width=600,height=600,scrollbars=1");
});
});
</script>
</body>
</html>

所以为了澄清,我想要一种方法来查明用户是否已成功上传文件。像这样的东西:

request.execute(function(response) {
if (response.code == 'uploaded') {
// uploaded, do stuff
} else {
// you get the idea...
}
});

添加赏金以获得完整的解决方案。

最佳答案

而不是返回 HtmlService对象,您可以使用 jQuery 的 $.getJSON 传递数据方法并从 doGet 检索数据函数 ContentService 。 Google Apps 脚本不接受 CORS,因此使用 JSONP 是从脚本获取数据或从脚本获取数据的最佳方式。 See this post了解更多。

<强> Working CodePen Example

为了清楚起见,我将您的 HTML 和脚本分开。与原始示例相比,HTML 没有任何变化。

代码.gs

function doGet(e) { 
var returnValue;

// Set the callback param. See https://stackoverflow.com/questions/29525860/
var callback = e.parameter.callback;

// Get the file and create it in Drive
try {
var blob = UrlFetchApp.fetch(e.parameters.url).getBlob();
DriveApp.createFile(blob);

// If successful, return okay
// Structure this JSON however you want. Parsing happens on the client side.
returnValue = {status: 'okay'};
} catch(e) {
Logger.log(e);
// If a failure, return error message to the client
returnValue = {status: e.message}
}

// Returning as JSONP allows for crossorigin requests
return ContentService.createTextOutput(callback +'(' + JSON.stringify(returnValue) + ')').setMimeType(ContentService.MimeType.JAVASCRIPT);
}

客户端JS

$(function() {
$(".google-upload").click(function() {
var appUrl = "https://script.google.com/macros/s/AKfycbyUvgKdhubzlpYmO3Marv7iFOZwJNJZaZrFTXCksxtl2kqW7vg/exec";
var query = appUrl + "?url=";
var popupUrl = query + $('.google-upload').attr("data-url") + "&callback=?";

console.log(popupUrl)

// Open this to start authentication.
// If already authenticated, the window will close on its own.
var popup = window.open(popupUrl, "_blank", "width=600,height=600,scrollbars=1");

$.getJSON(popupUrl, function(returnValue) {
// Log the value from the script
console.log(returnValue.status);
if(returnValue.status == "okay") {
// Do stuff, like notify the user, close the window
popup.close();
$("#result").html("Document successfully uploaded");
} else {
$("#result").html(returnValue);
}
})
});
});

您可以通过在 data-url 中传递空字符串来测试错误消息。参数。该消息将在控制台以及用户页面中返回。

编辑 3.7.18

上述解决方案在控制授权流程方面存在问题。经过研究并与 Drive 工程师 ( see thread here ) 交谈后,我将其重新设计为基于 Apps Script API 的自托管示例。并将项目作为 API 可执行文件而不是 Apps 脚本 Web 应用程序运行。这将允许您访问[run](https://developers.google.com/apps-script/api/reference/rest/v1/scripts/run) Apps 脚本 Web 应用程序外部的方法。

设置

关注Google Apps Script API instructions for JavaScript 。 Apps 脚本项目应该是独立的(不链接到文档)并作为 API 可执行文件发布。您需要打开 Cloud Console 并创建 OAuth 凭据和 API key 。

这些说明要求您在计算机上使用 Python 服务器。我使用 Node JS 服务器,http-server ,但您也可以将其上线并从那里进行测试。您需要在 Cloud Console 中将您的来源列入白名单。

客户端

由于这是自托管的,因此您需要一个纯 HTML 页面,通过 OAuth2 向用户授权。通过 JavaScript 的 API。这是更可取的,因为它可以让用户保持登录状态,从而允许对脚本进行多个 API 调用而无需重新授权。下面的代码适用于此应用程序,并使用 Google 快速入门指南中的授权流程。

index.html

  <body>

<!--Add buttons to initiate auth sequence and sign out-->
<button id="authorize-button" style="display: none;">Authorize</button>
<button id="signout-button" style="display: none;">Sign Out</button>

<button onclick="uploadDoc()" style="margin: 10px;" id="google-upload" data-url="https://calibre-ebook.com/downloads/demos/demo.docx">Upload doc</button>

<pre id="content"></pre>
</body>

index.js

// Client ID and API key from the Developer Console
var CLIENT_ID = 'YOUR_CLIENT_ID';
var API_KEY = 'YOUR_API_KEY';
var SCRIPT_ID = 'YOUR_SCRIPT_ID';

// Array of API discovery doc URLs for APIs used by the quickstart
var DISCOVERY_DOCS = ["https://script.googleapis.com/$discovery/rest?version=v1"];

// Authorization scopes required by the API; multiple scopes can be
// included, separated by spaces.
var SCOPES = 'https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/script.external_request';

var authorizeButton = document.getElementById('authorize-button');
var signoutButton = document.getElementById('signout-button');
var uploadButton = document.getElementById('google-upload');
var docUrl = uploadButton.getAttribute('data-url').value;

// Set the global variable for user authentication
var isAuth = false;

/**
* On load, called to load the auth2 library and API client library.
*/
function handleClientLoad() {
gapi.load('client:auth2', initClient);
}

/**
* Initializes the API client library and sets up sign-in state
* listeners.
*/
function initClient() {
gapi.client.init({
apiKey: API_KEY,
clientId: CLIENT_ID,
discoveryDocs: DISCOVERY_DOCS,
scope: SCOPES
}).then(function () {
// Listen for sign-in state changes.
gapi.auth2.getAuthInstance().isSignedIn.listen(updateSigninStatus);

// Handle the initial sign-in state.
updateSigninStatus(gapi.auth2.getAuthInstance().isSignedIn.get());
authorizeButton.onclick = handleAuthClick;
signoutButton.onclick = handleSignoutClick;
// uploadButton.onclick = uploadDoc;
});
}

/**
* Called when the Upload button is clicked. Reset the
* global variable to `true` and upload the document.
* Thanks to @JackBrown for the logic.
*/
function updateSigninStatus(isSignedIn) {
if (isSignedIn && !isAuth) {
authorizeButton.style.display = 'none';
signoutButton.style.display = 'block';
uploadButton.style.display = 'block'
uploadButton.onclick = uploadDoc;
} else if (isSignedIn && isAuth) {
authorizeButton.style.display = 'none';
signoutButton.style.display = 'block';
uploadButton.style.display = 'block';
uploadDoc();
} else {
authorizeButton.style.display = 'block';
signoutButton.style.display = 'none';
uploadButton.style.display = 'none';
isAuth = false;
}
}

/**
* Sign in the user upon button click.
*/
function handleAuthClick(event) {
gapi.auth2.getAuthInstance().signIn();
isAuth = true; // Update the global variable
}


/**
* Sign out the user upon button click.
*/
function handleSignoutClick(event) {
gapi.auth2.getAuthInstance().signOut();
isAuth = false; // update the global variable
}

/**
* Append a pre element to the body containing the given message
* as its text node. Used to display the results of the API call.
*
* @param {string} message Text to be placed in pre element.
*/
function appendPre(message) {
var pre = document.getElementById('content');
var textContent = document.createTextNode(message + '\n');
pre.appendChild(textContent);
}

/**
* Handle the login if signed out, return a Promise
* to call the upload Docs function after signin.
**/
function uploadDoc() {

console.log("clicked!")
var docUrl = document.getElementById('google-upload').getAttribute('data-url');

gapi.client.script.scripts.run({
'scriptId':SCRIPT_ID,
'function':'uploadDoc',
'parameters': [ docUrl ]
}).then(function(resp) {
var result = resp.result;
if(result.error && result.error.status) {
// Error before the script was Called
appendPre('Error calling API');
appendPre(JSON.parse(result, null, 2));
} else if(result.error) {
// The API executed, but the script returned an error.

// Extract the first (and only) set of error details.
// The values of this object are the script's 'errorMessage' and
// 'errorType', and an array of stack trace elements.
var error = result.error.details[0];
appendPre('Script error message: ' + error.errorMessage);

if (error.scriptStackTraceElements) {
// There may not be a stacktrace if the script didn't start
// executing.
appendPre('Script error stacktrace:');
for (var i = 0; i < error.scriptStackTraceElements.length; i++) {
var trace = error.scriptStackTraceElements[i];
appendPre('\t' + trace.function + ':' + trace.lineNumber);
}
}
} else {
// The structure of the result will depend upon what the Apps
// Script function returns. Here, the function returns an Apps
// Script Object with String keys and values, and so the result
// is treated as a JavaScript object (folderSet).
console.log(resp.result)
var msg = resp.result.response.result;
appendPre(msg);

// do more stuff with the response code
}
})
}

应用程序脚本

Apps Script 代码不需要做太多修改。而不是使用 ContentService 返回,我们可以返回纯 JSON 对象以供客户端使用。

function uploadDoc(e) {
Logger.log(e);
var returnValue = {};

// Set the callback URL. See https://stackoverflow.com/questions/29525860/

Logger.log("Uploading the document...");

try {
// Get the file and create it in Drive
var blob = UrlFetchApp.fetch(e).getBlob();
DriveApp.createFile(blob);

// If successful, return okay
var msg = "The document was successfully uploaded!";
return msg;
} catch(e) {
Logger.log(e);
// If a failure, return error message to the client
return e.message
}
}

我很难将 CodePen 列入白名单,所以 I have an example hosted securely on my own site使用上面的代码。请随意检查源代码并查看 live Apps Script project .

请注意,当您在 Apps 脚本项目中添加或更改范围时,用户需要重新授权。

关于google-apps-script - 检查用户是否运行过,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49069853/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com