Workers创建并分享谷歌团队盘

网站所有资源都有,可联系VX:bjlyxy1688

简介

自动在线创建Google Drive谷歌团队无限储存网盘,独享管理员身份!

操作

获取授权

Rclone获取

<span style="font-weight: bold;">我个人觉得不如第三方操作简单</span>,点此可查看<br>安装依赖<br><br>#CentOS系统<br>yum install p7zip unzip -y<br>#Debian/Ubuntu系统<br>apt install -y p7zip-full<br>安装Rclone<br><br>curl https://rclone.org/install.sh | bash<br>配置Rclone<br><br>rclone config<br>参照下面内容选择输入命令<br><br>n) New remote<br>s) Set configuration password<br>q) Quit config<br>n/s/q> n<br>name> Rats #配置名称,随便填<br>Type of storage to configure.<br>Enter a string value. Press Enter for the default ("").<br>Choose a number from below, or type in your own value<br> 1 / 1Fichier<br> \ "fichier"<br> 2 / Alias for an existing remote<br> \ "alias"<br> 3 / Amazon Drive<br> \ "amazon cloud drive"<br> 4 / Amazon S3 Compliant Storage Provider (AWS, Alibaba, Ceph, Digital Ocean, Dreamhost, IBM COS, Minio, etc)<br> \ "s3"<br> 5 / Backblaze B2<br> \ "b2"<br> 6 / Box<br> \ "box"<br> 7 / Cache a remote<br> \ "cache"<br> 8 / Dropbox<br> \ "dropbox"<br> 9 / Encrypt/Decrypt a remote<br> \ "crypt"<br>10 / FTP Connection<br> \ "ftp"<br>11 / Google Cloud Storage (this is not Google Drive)<br> \ "google cloud storage"<br>12 / Google Drive<br> \ "drive"<br>13 / Google Photos<br> \ "google photos"<br>14 / Hubic<br> \ "hubic"<br>15 / JottaCloud<br> \ "jottacloud"<br>16 / Koofr<br> \ "koofr"<br>17 / Local Disk<br> \ "local"<br>18 / Mega<br> \ "mega"<br>19 / Microsoft Azure Blob Storage<br> \ "azureblob"<br>20 / Microsoft OneDrive<br> \ "onedrive"<br>21 / OpenDrive<br> \ "opendrive"<br>22 / Openstack Swift (Rackspace Cloud Files, Memset Memstore, OVH)<br> \ "swift"<br>23 / Pcloud<br> \ "pcloud"<br>24 / Put.io<br> \ "putio"<br>25 / QingCloud Object Storage<br> \ "qingstor"<br>26 / SSH/SFTP Connection<br> \ "sftp"<br>27 / Union merges the contents of several remotes<br> \ "union"<br>28 / Webdav<br> \ "webdav"<br>29 / Yandex Disk<br> \ "yandex"<br>30 / http Connection<br> \ "http"<br>31 / premiumize.me<br> \ "premiumizeme"<br>Storage> 12 #选择12,Google Drive<br>client_id> 850428 #填上你的Google Drive客户端ID<br>client_secret> D72gPc #填上你的Google Drive客户端密匙<br>Choose a number from below, or type in your own value<br> 1 / Full access all files, excluding Application Data Folder.<br> \ "drive"<br> 2 / Read-only access to file metadata and file contents.<br> \ "drive.readonly"<br> / Access to files created by rclone only.<br> 3 | These are visible in the drive website.<br> | File authorization is revoked when the user deauthorizes the app.<br> \ "drive.file"<br> / Allows read and write access to the Application Data folder.<br> 4 | This is not visible in the drive website.<br> \ "drive.appfolder"<br> / Allows read-only access to file metadata but<br> 5 | does not allow any access to read or download file content.<br> \ "drive.metadata.readonly"<br>scope> 1 <br>ID of the root folder<br>Leave blank normally.<br>Fill in to access "Computers" folders. (see docs).<br>Enter a string value. Press Enter for the default ("").<br>root_folder_id> <br>Service Account Credentials JSON file path <br>Leave blank normally.<br>Needed only if you want use SA instead of interactive login.<br>Enter a string value. Press Enter for the default ("").<br>service_account_file> <br>Edit advanced config? (y/n)<br>y) Yes<br>n) No<br>y/n> n #输入n<br>Remote config<br>Use auto config?<br> * Say Y if not sure<br> * Say N if you are working on a remote or headless machine<br>y) Yes<br>n) No<br>y/n> n #输入n<br>If your browser doesn't open automatically go to the following link: https://accounts.google.com/o/ #打开该地址获取code<br>Log in and authorize rclone for access<br>Enter verification code>hjdd #输入你获取到的code<br>Configure this as a team drive?<br>y) Yes<br>n) No<br>y/n> n #输入n<br>--------------------<br>[Rats]<br>type = drive<br>client_id = 85042871<br>client_secret = D72gPc<br>scope = drive<br>token = {"access_token":"y902Z"} #记住里面的refresh_token参数<br>--------------------<br>y) Yes this is OK<br>e) Edit this remote<br>d) Delete this remote<br>y/e/d> y #输入y<br>Current remotes:<br><br>Name Type<br>==== ====<br>Rats drive<br><br>e) Edit existing remote<br>n) New remote<br>d) Delete remote<br>r) Rename remote<br>c) Copy remote<br>s) Set configuration password<br>q) Quit config<br>e/n/d/r/c/s/q> q #输入q保存退出<br>执行 rclone config file 查看 rclone.conf 路径。找到 root_folder_id 和 refresh_token 记录下来。
<span style="font-weight: bold;">我个人觉得不如第三方操作简单</span>,点此可查看<br>安装依赖<br><br>#CentOS系统<br>yum install p7zip unzip -y<br>#Debian/Ubuntu系统<br>apt install -y p7zip-full<br>安装Rclone<br><br>curl https://rclone.org/install.sh | bash<br>配置Rclone<br><br>rclone config<br>参照下面内容选择输入命令<br><br>n) New remote<br>s) Set configuration password<br>q) Quit config<br>n/s/q> n<br>name> Rats  #配置名称,随便填<br>Type of storage to configure.<br>Enter a string value. Press Enter for the default ("").<br>Choose a number from below, or type in your own value<br> 1 / 1Fichier<br>   \ "fichier"<br> 2 / Alias for an existing remote<br>   \ "alias"<br> 3 / Amazon Drive<br>   \ "amazon cloud drive"<br> 4 / Amazon S3 Compliant Storage Provider (AWS, Alibaba, Ceph, Digital Ocean, Dreamhost, IBM COS, Minio, etc)<br>   \ "s3"<br> 5 / Backblaze B2<br>   \ "b2"<br> 6 / Box<br>   \ "box"<br> 7 / Cache a remote<br>   \ "cache"<br> 8 / Dropbox<br>   \ "dropbox"<br> 9 / Encrypt/Decrypt a remote<br>   \ "crypt"<br>10 / FTP Connection<br>   \ "ftp"<br>11 / Google Cloud Storage (this is not Google Drive)<br>   \ "google cloud storage"<br>12 / Google Drive<br>   \ "drive"<br>13 / Google Photos<br>   \ "google photos"<br>14 / Hubic<br>   \ "hubic"<br>15 / JottaCloud<br>   \ "jottacloud"<br>16 / Koofr<br>   \ "koofr"<br>17 / Local Disk<br>   \ "local"<br>18 / Mega<br>   \ "mega"<br>19 / Microsoft Azure Blob Storage<br>   \ "azureblob"<br>20 / Microsoft OneDrive<br>   \ "onedrive"<br>21 / OpenDrive<br>   \ "opendrive"<br>22 / Openstack Swift (Rackspace Cloud Files, Memset Memstore, OVH)<br>   \ "swift"<br>23 / Pcloud<br>   \ "pcloud"<br>24 / Put.io<br>   \ "putio"<br>25 / QingCloud Object Storage<br>   \ "qingstor"<br>26 / SSH/SFTP Connection<br>   \ "sftp"<br>27 / Union merges the contents of several remotes<br>   \ "union"<br>28 / Webdav<br>   \ "webdav"<br>29 / Yandex Disk<br>   \ "yandex"<br>30 / http Connection<br>   \ "http"<br>31 / premiumize.me<br>   \ "premiumizeme"<br>Storage> 12  #选择12,Google Drive<br>client_id> 850428  #填上你的Google Drive客户端ID<br>client_secret> D72gPc  #填上你的Google Drive客户端密匙<br>Choose a number from below, or type in your own value<br> 1 / Full access all files, excluding Application Data Folder.<br>   \ "drive"<br> 2 / Read-only access to file metadata and file contents.<br>   \ "drive.readonly"<br>   / Access to files created by rclone only.<br> 3 | These are visible in the drive website.<br>   | File authorization is revoked when the user deauthorizes the app.<br>   \ "drive.file"<br>   / Allows read and write access to the Application Data folder.<br> 4 | This is not visible in the drive website.<br>   \ "drive.appfolder"<br>   / Allows read-only access to file metadata but<br> 5 | does not allow any access to read or download file content.<br>   \ "drive.metadata.readonly"<br>scope> 1 <br>ID of the root folder<br>Leave blank normally.<br>Fill in to access "Computers" folders. (see docs).<br>Enter a string value. Press Enter for the default ("").<br>root_folder_id> <br>Service Account Credentials JSON file path <br>Leave blank normally.<br>Needed only if you want use SA instead of interactive login.<br>Enter a string value. Press Enter for the default ("").<br>service_account_file> <br>Edit advanced config? (y/n)<br>y) Yes<br>n) No<br>y/n> n  #输入n<br>Remote config<br>Use auto config?<br> * Say Y if not sure<br> * Say N if you are working on a remote or headless machine<br>y) Yes<br>n) No<br>y/n> n  #输入n<br>If your browser doesn't open automatically go to the following link: https://accounts.google.com/o/  #打开该地址获取code<br>Log in and authorize rclone for access<br>Enter verification code>hjdd   #输入你获取到的code<br>Configure this as a team drive?<br>y) Yes<br>n) No<br>y/n> n  #输入n<br>--------------------<br>[Rats]<br>type = drive<br>client_id = 85042871<br>client_secret = D72gPc<br>scope = drive<br>token = {"access_token":"y902Z"}  #记住里面的refresh_token参数<br>--------------------<br>y) Yes this is OK<br>e) Edit this remote<br>d) Delete this remote<br>y/e/d> y  #输入y<br>Current remotes:<br><br>Name                 Type<br>====                 ====<br>Rats                 drive<br><br>e) Edit existing remote<br>n) New remote<br>d) Delete remote<br>r) Rename remote<br>c) Copy remote<br>s) Set configuration password<br>q) Quit config<br>e/n/d/r/c/s/q> q  #输入q保存退出<br>执行 rclone config file 查看 rclone.conf 路径。找到 root_folder_id 和 refresh_token 记录下来。
我个人觉得不如第三方操作简单,点此可查看
安装依赖

#CentOS系统
yum install p7zip unzip -y
#Debian/Ubuntu系统
apt install -y p7zip-full
安装Rclone

curl https://rclone.org/install.sh | bash
配置Rclone

rclone config
参照下面内容选择输入命令

n) New remote
s) Set configuration password
q) Quit config
n/s/q> n
name> Rats #配置名称,随便填
Type of storage to configure.
Enter a string value. Press Enter for the default ("").
Choose a number from below, or type in your own value
1 / 1Fichier
\ "fichier"
2 / Alias for an existing remote
\ "alias"
3 / Amazon Drive
\ "amazon cloud drive"
4 / Amazon S3 Compliant Storage Provider (AWS, Alibaba, Ceph, Digital Ocean, Dreamhost, IBM COS, Minio, etc)
\ "s3"
5 / Backblaze B2
\ "b2"
6 / Box
\ "box"
7 / Cache a remote
\ "cache"
8 / Dropbox
\ "dropbox"
9 / Encrypt/Decrypt a remote
\ "crypt"
10 / FTP Connection
\ "ftp"
11 / Google Cloud Storage (this is not Google Drive)
\ "google cloud storage"
12 / Google Drive
\ "drive"
13 / Google Photos
\ "google photos"
14 / Hubic
\ "hubic"
15 / JottaCloud
\ "jottacloud"
16 / Koofr
\ "koofr"
17 / Local Disk
\ "local"
18 / Mega
\ "mega"
19 / Microsoft Azure Blob Storage
\ "azureblob"
20 / Microsoft OneDrive
\ "onedrive"
21 / OpenDrive
\ "opendrive"
22 / Openstack Swift (Rackspace Cloud Files, Memset Memstore, OVH)
\ "swift"
23 / Pcloud
\ "pcloud"
24 / Put.io
\ "putio"
25 / QingCloud Object Storage
\ "qingstor"
26 / SSH/SFTP Connection
\ "sftp"
27 / Union merges the contents of several remotes
\ "union"
28 / Webdav
\ "webdav"
29 / Yandex Disk
\ "yandex"
30 / http Connection
\ "http"
31 / premiumize.me
\ "premiumizeme"
Storage> 12 #选择12,Google Drive
client_id> 850428 #填上你的Google Drive客户端ID
client_secret> D72gPc #填上你的Google Drive客户端密匙
Choose a number from below, or type in your own value
1 / Full access all files, excluding Application Data Folder.
\ "drive"
2 / Read-only access to file metadata and file contents.
\ "drive.readonly"
/ Access to files created by rclone only.
3 | These are visible in the drive website.
| File authorization is revoked when the user deauthorizes the app.
\ "drive.file"
/ Allows read and write access to the Application Data folder.
4 | This is not visible in the drive website.
\ "drive.appfolder"
/ Allows read-only access to file metadata but
5 | does not allow any access to read or download file content.
\ "drive.metadata.readonly"
scope> 1
ID of the root folder
Leave blank normally.
Fill in to access "Computers" folders. (see docs).
Enter a string value. Press Enter for the default ("").
root_folder_id>
Service Account Credentials JSON file path
Leave blank normally.
Needed only if you want use SA instead of interactive login.
Enter a string value. Press Enter for the default ("").
service_account_file>
Edit advanced config? (y/n)
y) Yes
n) No
y/n> n #输入n
Remote config
Use auto config?
* Say Y if not sure
* Say N if you are working on a remote or headless machine
y) Yes
n) No
y/n> n #输入n
If your browser doesn't open automatically go to the following link: https://accounts.google.com/o/ #打开该地址获取code
Log in and authorize rclone for access
Enter verification code>hjdd #输入你获取到的code
Configure this as a team drive?
y) Yes
n) No
y/n> n #输入n
--------------------
[Rats]
type = drive
client_id = 85042871
client_secret = D72gPc
scope = drive
token = {"access_token":"y902Z"} #记住里面的refresh_token参数
--------------------
y) Yes this is OK
e) Edit this remote
d) Delete this remote
y/e/d> y #输入y
Current remotes:

Name Type
==== ====
Rats drive

e) Edit existing remote
n) New remote
d) Delete remote
r) Rename remote
c) Copy remote
s) Set configuration password
q) Quit config
e/n/d/r/c/s/q> q #输入q保存退出
执行 rclone config file 查看 rclone.conf 路径。找到 root_folder_id 和 refresh_token 记录下来。

第三方获取

[rihide]  

  1. 访问 https://install.gd.workers.dev/

  2. 点击“获取认证码”,授权 Google 账户 (推荐无限盘)

  3. 将新窗口获取到的代码,复制粘贴到“Auth认证码(通过认证连接获取认证码)”处

  4. 点击“生成代码”,稍等

  5. 下拉页面,查看生成后的代码,记录 client_id 、 client_secret 和 refresh_token 。

关于Google Drive目录ID
打开团队盘(或文件夹或别人共享的文件夹),看地址栏。
https://drive.google.com/drive/folders/{这后面就是目录id}
留空是根目录。

配置

  1. 注册 CloudFlare Workers

  2. 复制 Workers代码 ,并将 client_id 、 client_secret 和 refresh_token 修改为自己的

  3. var authConfig = {<br> version: "1.0.1-fix1",<br> dailyLimit: true, // 是否限制每一个邮箱每天只能提交一次请求<br> client_id: "",<br> client_secret: "",<br> refresh_token: "", // 授权 token<br> domain: "", // 面页中显示本站团队盘域, 可不填<br> // 黑名单, 免费版没有数据库, 一个可行思路是从自己服务器上获取, 可自行实现<br> black_list: ["example@gmail.com"]<br>};<br><br>var gd;<br><br>var today;<br><br>var html = `<br><!DOCTYPE html><br><html><br> <head><br> <meta charset="utf-8" /><br> <meta<br> name="viewport"<br> content="width=device-width, initial-scale=1.0,maximum-scale=1.0, user-scalable=no"<br> /><br> <title>创建Google TeamDrive</title><br> <link<br> rel="stylesheet"<br> href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"<br> /><br> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script><br> <script<br> src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"<br> integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1"<br> crossorigin="anonymous"<br> ></script><br> <script<br> src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"<br> integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM"<br> crossorigin="anonymous"<br> ></script><br> <!--源码地址: https://github.com/yyuueexxiinngg/some-scripts/blob/master/workers/google/drive/create-share-teamdrive.js--><br> </head><br> <body><br> <div id="app"><br> <div id="container" class="container"><br> <div class="row"><br> <div class="col-sm-8 offset-sm-2 col-md-6 offset-md-3 text-center"><br> <h1>创建Google TeamDrive</h1><br> <p>${authConfig.version}</p><br> ${<br> authConfig.domain<br> ? ` <h5>本站团队盘域为: ${authConfig.domain}</h5>`<br> : ""<br> }<br> <p><br> 后端多个API请求, 过程耗时较长, 请耐心等待,<br> <span style="color: red"><b>切勿重复提交</b></span><br> </p><br> <br /><br> <div class="info-form text-left"><br> <form id="teamDriveForm"><br> <div class="form-group"><br> <label for="teamDriveName" class="sr-only"><br> TeamDrive 名称<br> </label><br> <input<br> type="text"<br> class="form-control"<br> id="teamDriveName"<br> placeholder="TeamDrive 名称"<br> /><br> </div><br> <div class="form-group"><br> <label for="emailAddress" class="sr-only"><br> 您的GMail邮箱地址<br> </label><br> <input<br> type="email"<br> class="form-control"<br> id="emailAddress"<br> placeholder="您的GMail邮箱地址"<br> /><br> </div><br> <div class="form-check"><br> <input<br> type="checkbox"<br> class="form-check-input"<br> id="customTheme"<br> value=""<br> /><br> <label class="form-check-label" for="customTheme"><br> 自定TeamDrive主题头图<br> </label><br> </div><br> <div id="customThemeSection" class="d-none"><br> <div id="teamDriveThemePreview"></div><br> <div id="teamDriveThemeOptions"><br> <div class="form-check"><br> <input<br> class="form-check-input"<br> type="radio"<br> name="teamDriveTheme"<br> id="teamDriveThemeOptionRandom"<br> value="random"<br> checked<br> /><br> <label<br> class="form-check-label"<br> for="teamDriveThemeOptionRandom"<br> ><br> 随机<br> </label><br> </div><br> </div><br> </div><br> <button type="submit" class="btn btn-primary">Submit</button><br> </form><br> </div><br> </div><br> </div><br> </div><br> </div><br> <div<br> class="modal fade"<br> id="loadMe"<br> tabindex="-1"<br> role="dialog"<br> aria-labelledby="loadMeLabel"<br> ><br> <div class="modal-dialog modal-sm" role="document"><br> <div class="modal-content"><br> <div class="modal-body text-center"><br> <div class="d-flex justify-content-center"><br> <div class="spinner-border" role="status"><br> <span class="sr-only">正在创建中...</span><br> </div><br> </div><br> <div clas="loader-txt"><br> <p>正在创建中...</p><br> </div><br> </div><br> </div><br> </div><br> </div><br> <footer class="page-footer font-small blue"><br> <div class="footer-copyright text-center py-3"><br> © 2020 源码:<br> <a<br> href="https://www.24s.net/?golink=aHR0cHM6Ly9lbnN1LmNjL2dvL2FIUjBjSE02THk5bmFYUm9kV0l1WTI5dEwzbDVkWFZsWlhoNGFXbHVibWRuTDNOdmJXVXRjMk55YVhCMGN5OWliRzlpTDIxaGMzUmxjaTkzYjNKclpYSnpMMmR2YjJkc1pTOWtjbWwyWlM5amNtVmhkR1V0YzJoaGNtVXRkR1ZoYldSeWFYWmxMbXB6" target="_blank" <br> ><br> yyuueexxiinngg<br> </a><br> <br /><br> Special Thanks:<br> <a href="https://github.com/donwa/goindex"><br> donwa<br> </a><br> </div><br> </footer><br> </body><br> <script><br> var teamDriveThemes;<br> $("input[id=customTheme]").change(function() {<br> if ($(this).is(":checked")) {<br> $("#customThemeSection").removeClass("d-none");<br> } else {<br> $("#customThemeSection").addClass("d-none");<br> $("input[name=teamDriveTheme]")[0].click();<br> }<br> });<br> $.get("/teamDriveThemes", function(json) {<br> teamDriveThemes = json.teamDriveThemes;<br> $.each(json.teamDriveThemes, function(i, item) {<br> $("#teamDriveThemeOptions").append(\`<br> <div class="form-check"><br> <input<br> class="form-check-input"<br> type="radio"<br> name="teamDriveTheme"<br> id="teamDriveThemeOption-\${item.id}"<br> value="\${item.id}"<br> /><br> <label class="form-check-label" for="teamDriveThemeOption-\${item.id}"><br> \${item.id}<br> </label><br> </div><br> \`);<br> });<br> $("input[name=teamDriveTheme]").change(function() {<br> var themeId = this.value;<br> if (themeId === "random") {<br> $("#teamDriveThemePreview").html("");<br> } else {<br> var theme = teamDriveThemes.find(function(t) {<br> return t.id == themeId;<br> });<br> $("#teamDriveThemePreview").html(<br> \`<br> <div class="card" style="background-color: \${theme.colorRgb}"><br> <img src="\${theme.backgroundImageLink}" class="card-img-top" alt="\${theme.id}" /><br> <div class="card-body"><br> <h5 class="card-text" style="color: white"><br> \${theme.id}<br> </h5><br> </div><br> </div><br> \`<br> );<br> }<br> });<br> $("#teamDriveForm").on("submit", function(event) {<br> event.preventDefault();<br> $("#loadMe").modal({<br> backdrop: "static", //remove ability to close modal with click<br> keyboard: false, //remove option to close with keyboard<br> show: true //Display loader!<br> });<br> $.ajax({<br> type: "POST",<br> url: "/drive",<br> data: JSON.stringify({<br> teamDriveName: $("input[id=teamDriveName]").val(),<br> teamDriveThemeId: $("input[name=teamDriveTheme]:checked").val(),<br> emailAddress: $("input[id=emailAddress]").val()<br> }),<br> success: function(data) {<br> $("#loadMe").modal("hide");<br> alert("成功!");<br> },<br> error: function(request, status, error) {<br> $("#loadMe").modal("hide");<br> alert("失败!" + request.responseText);<br> },<br> contentType: "application/json"<br> });<br> });<br> });<br> </script><br> <style type="text/css"><br> .card-img-top {<br> width: 100%;<br> object-fit: cover;<br> }<br> </style><br></html><br>`;<br><br>addEventListener("fetch", event => {<br> event.respondWith(handleRequest(event.request));<br>});<br><br>var dailyLimit = [];<br><br>/**<br> * Fetch and log a request<br> * @param {Request} request<br> */<br>async function handleRequest(request) {<br> if (authConfig.dailyLimit) {<br> if (!today) today = new Date().getDate();<br><br> // Remove email rate limit every day<br> if (new Date().getDate() != today) {<br> today = new Date().getDate();<br> dailyLimit.length = 0;<br> }<br> }<br><br> if (gd == undefined) {<br> gd = new googleDrive(authConfig);<br> }<br> let url = new URL(request.url);<br> let path = url.pathname;<br><br> switch (path) {<br> case "/teamDriveThemes":<br> let teamDriveThemes = await gd.getTeamDriveThemes();<br> return new Response(JSON.stringify(teamDriveThemes), {<br> status: 200,<br> headers: {<br> "Content-Type": "application/json",<br> "Access-Control-Allow-Origin": "*"<br> }<br> });<br> case "/drive":<br> if (request.method === "POST") {<br> const requestBody = await request.json();<br><br> if (authConfig.dailyLimit) {<br> if (dailyLimit.includes(requestBody.emailAddress)) {<br> return new Response("每天只允许提交一次", {<br> status: 429<br> });<br> } else {<br> dailyLimit.push(requestBody.emailAddress);<br> }<br> }<br><br> if (authConfig.black_list.includes(requestBody.emailAddress)) {<br> return new Response("Failed", {<br> status: 429<br> });<br> }<br><br> try {<br> let result = await gd.createAndShareTeamDrive(requestBody);<br> return new Response("OK", {<br> status: 200<br> });<br> } catch (err) {<br> return new Response(err.toString(), {<br> status: 500<br> });<br> }<br> } else if (request.method === "OPTIONS") {<br> return new Response("", {<br> status: 200,<br> headers: {<br> "Access-Control-Allow-Origin": "*"<br> }<br> });<br> } else {<br> return new Response("Bad Request", {<br> status: 400<br> });<br> }<br> default:<br> return new Response(html, {<br> status: 200,<br> headers: {<br> "Content-Type": "text/html; charset=utf-8",<br> "Access-Control-Allow-Origin": "*"<br> }<br> });<br> }<br>}<br>// https://stackoverflow.com/a/2117523<br>function uuidv4() {<br> return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, c => {<br> // tslint:disable-next-line:one-variable-per-declaration<br> const r = (Math.random() * 16) | 0,<br> // tslint:disable-next-line:triple-equals<br> v = c == "x" ? r : (r & 0x3) | 0x8;<br> return v.toString(16);<br> });<br>}<br><br>class googleDrive {<br> constructor(authConfig) {<br> this.authConfig = authConfig;<br> this.accessToken();<br> }<br><br> async getTeamDriveThemes() {<br> let url = "https://www.googleapis.com/drive/v3/about";<br> let requestOption = await this.requestOption();<br> let params = { fields: "teamDriveThemes" };<br> url += "?" + this.enQuery(params);<br> let response = await fetch(url, requestOption);<br> return await response.json();<br> }<br><br> async createAndShareTeamDrive(requestBody) {<br> // Create team drive<br> console.log("Creating TeamDrive");<br> let url = "https://www.googleapis.com/drive/v3/drives";<br> let requestOption = await this.requestOption(<br> { "Content-Type": "application/json" },<br> "POST"<br> );<br> let params = { requestId: uuidv4() };<br> url += "?" + this.enQuery(params);<br> let post_data = {<br> name: requestBody.teamDriveName<br> };<br> if (<br> requestBody.teamDriveThemeId &&<br> requestBody.teamDriveThemeId !== "random"<br> ) {<br> post_data.themeId = requestBody.teamDriveThemeId;<br> }<br> requestOption.body = JSON.stringify(post_data);<br> let response = await fetch(url, requestOption);<br> let result = await response.json();<br> const teamDriveId = result.id;<br> console.log("Created TeamDrive ID", teamDriveId);<br><br> // Get created drive user permission ID<br> console.log(`Getting creator permission ID`);<br> url = `https://www.googleapis.com/drive/v3/files/${teamDriveId}/permissions`;<br> params = { supportsAllDrives: true };<br> params.fields = "permissions(id,emailAddress)";<br> url += "?" + this.enQuery(params);<br> requestOption = await this.requestOption();<br> response = await fetch(url, requestOption);<br> result = await response.json();<br> const currentUserPermissionID = result.permissions[0].id;<br> console.log(currentUserPermissionID);<br><br> // Share team drive with email address<br> console.log(`Sharing the team drive to ${requestBody.emailAddress}`);<br> url = `https://www.googleapis.com/drive/v3/files/${teamDriveId}/permissions`;<br> params = { supportsAllDrives: true };<br> url += "?" + this.enQuery(params);<br> requestOption = await this.requestOption(<br> { "Content-Type": "application/json" },<br> "POST"<br> );<br> post_data = {<br> role: "organizer",<br> type: "user",<br> emailAddress: requestBody.emailAddress<br> };<br> requestOption.body = JSON.stringify(post_data);<br> response = await fetch(url, requestOption);<br> await response.json();<br><br> // Delete creator from the team drive<br> console.log("Deleting creator from the team drive");<br> url = `https://www.googleapis.com/drive/v3/files/${teamDriveId}/permissions/${currentUserPermissionID}`;<br> params = { supportsAllDrives: true };<br> url += "?" + this.enQuery(params);<br> requestOption = await this.requestOption({}, "DELETE");<br> response = await fetch(url, requestOption);<br> return await response.text();<br> }<br><br> async accessToken() {<br> console.log("accessToken");<br> if (<br> this.authConfig.expires == undefined ||<br> this.authConfig.expires < Date.now()<br> ) {<br> const obj = await this.fetchAccessToken();<br> if (obj.access_token != undefined) {<br> this.authConfig.accessToken = obj.access_token;<br> this.authConfig.expires = Date.now() + 3500 * 1000;<br> }<br> }<br> return this.authConfig.accessToken;<br> }<br><br> async fetchAccessToken() {<br> console.log("fetchAccessToken");<br> const url = "https://www.googleapis.com/oauth2/v4/token";<br> const headers = {<br> "Content-Type": "application/x-www-form-urlencoded"<br> };<br> const post_data = {<br> client_id: this.authConfig.client_id,<br> client_secret: this.authConfig.client_secret,<br> refresh_token: this.authConfig.refresh_token,<br> grant_type: "refresh_token"<br> };<br><br> let requestOption = {<br> method: "POST",<br> headers: headers,<br> body: this.enQuery(post_data)<br> };<br><br> const response = await fetch(url, requestOption);<br> return await response.json();<br> }<br><br> async requestOption(headers = {}, method = "GET") {<br> const accessToken = await this.accessToken();<br> headers["authorization"] = "Bearer " + accessToken;<br> return { method: method, headers: headers };<br> }<br><br> enQuery(data) {<br> const ret = [];<br> for (let d in data) {<br> ret.push(encodeURIComponent(d) + "=" + encodeURIComponent(data[d]));<br> }<br> return ret.join("&");<br> }<br>}
    var authConfig = {<br>  version: "1.0.1-fix1",<br>  dailyLimit: true, // 是否限制每一个邮箱每天只能提交一次请求<br>  client_id: "",<br>  client_secret: "",<br>  refresh_token: "", // 授权 token<br>  domain: "", // 面页中显示本站团队盘域, 可不填<br>  // 黑名单, 免费版没有数据库, 一个可行思路是从自己服务器上获取, 可自行实现<br>  black_list: ["example@gmail.com"]<br>};<br><br>var gd;<br><br>var today;<br><br>var html = `<br><!DOCTYPE html><br><html><br>  <head><br>    <meta charset="utf-8" /><br>    <meta<br>      name="viewport"<br>      content="width=device-width, initial-scale=1.0,maximum-scale=1.0, user-scalable=no"<br>    /><br>    <title>创建Google TeamDrive</title><br>    <link<br>      rel="stylesheet"<br>      href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"<br>    /><br>    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script><br>    <script<br>      src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"<br>      integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1"<br>      crossorigin="anonymous"<br>    ></script><br>    <script<br>      src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"<br>      integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM"<br>      crossorigin="anonymous"<br>    ></script><br>  <!--源码地址: https://github.com/yyuueexxiinngg/some-scripts/blob/master/workers/google/drive/create-share-teamdrive.js--><br>  </head><br>  <body><br>    <div id="app"><br>      <div id="container" class="container"><br>        <div class="row"><br>          <div class="col-sm-8 offset-sm-2 col-md-6 offset-md-3 text-center"><br>            <h1>创建Google TeamDrive</h1><br>             <p>${authConfig.version}</p><br>         ${<br>           authConfig.domain<br>             ? ` <h5>本站团队盘域为:  ${authConfig.domain}</h5>`<br>             : ""<br>         }<br>            <p><br>              后端多个API请求, 过程耗时较长, 请耐心等待,<br>              <span style="color: red"><b>切勿重复提交</b></span><br>            </p><br>            <br /><br>            <div class="info-form text-left"><br>              <form id="teamDriveForm"><br>                <div class="form-group"><br>                  <label for="teamDriveName" class="sr-only"><br>                    TeamDrive 名称<br>                  </label><br>                  <input<br>                    type="text"<br>                    class="form-control"<br>                    id="teamDriveName"<br>                    placeholder="TeamDrive 名称"<br>                  /><br>                </div><br>                <div class="form-group"><br>                  <label for="emailAddress" class="sr-only"><br>                    您的GMail邮箱地址<br>                  </label><br>                  <input<br>                    type="email"<br>                    class="form-control"<br>                    id="emailAddress"<br>                    placeholder="您的GMail邮箱地址"<br>                  /><br>                </div><br>                <div class="form-check"><br>                  <input<br>                    type="checkbox"<br>                    class="form-check-input"<br>                    id="customTheme"<br>                    value=""<br>                  /><br>                  <label class="form-check-label" for="customTheme"><br>                    自定TeamDrive主题头图<br>                  </label><br>                </div><br>                <div id="customThemeSection" class="d-none"><br>                  <div id="teamDriveThemePreview"></div><br>                  <div id="teamDriveThemeOptions"><br>                    <div class="form-check"><br>                      <input<br>                        class="form-check-input"<br>                        type="radio"<br>                        name="teamDriveTheme"<br>                        id="teamDriveThemeOptionRandom"<br>                        value="random"<br>                        checked<br>                      /><br>                      <label<br>                        class="form-check-label"<br>                        for="teamDriveThemeOptionRandom"<br>                      ><br>                        随机<br>                      </label><br>                    </div><br>                  </div><br>                </div><br>                <button type="submit" class="btn btn-primary">Submit</button><br>              </form><br>            </div><br>          </div><br>        </div><br>      </div><br>    </div><br>    <div<br>      class="modal fade"<br>      id="loadMe"<br>      tabindex="-1"<br>      role="dialog"<br>      aria-labelledby="loadMeLabel"<br>    ><br>      <div class="modal-dialog modal-sm" role="document"><br>        <div class="modal-content"><br>          <div class="modal-body text-center"><br>            <div class="d-flex justify-content-center"><br>              <div class="spinner-border" role="status"><br>                <span class="sr-only">正在创建中...</span><br>              </div><br>            </div><br>            <div clas="loader-txt"><br>              <p>正在创建中...</p><br>            </div><br>          </div><br>        </div><br>      </div><br>    </div><br>    <footer class="page-footer font-small blue"><br>      <div class="footer-copyright text-center py-3"><br>        © 2020 源码:<br>        <a<br>          href="https://www.24s.net/?golink=aHR0cHM6Ly9lbnN1LmNjL2dvL2FIUjBjSE02THk5bmFYUm9kV0l1WTI5dEwzbDVkWFZsWlhoNGFXbHVibWRuTDNOdmJXVXRjMk55YVhCMGN5OWliRzlpTDIxaGMzUmxjaTkzYjNKclpYSnpMMmR2YjJkc1pTOWtjbWwyWlM5amNtVmhkR1V0YzJoaGNtVXRkR1ZoYldSeWFYWmxMbXB6"  target="_blank" <br>        ><br>          yyuueexxiinngg<br>        </a><br>        <br /><br>        Special Thanks:<br>        <a href="https://github.com/donwa/goindex"><br>          donwa<br>        </a><br>      </div><br>    </footer><br>  </body><br>  <script><br>    var teamDriveThemes;<br>    $("input[id=customTheme]").change(function() {<br>      if ($(this).is(":checked")) {<br>        $("#customThemeSection").removeClass("d-none");<br>      } else {<br>        $("#customThemeSection").addClass("d-none");<br>        $("input[name=teamDriveTheme]")[0].click();<br>      }<br>    });<br>    $.get("/teamDriveThemes", function(json) {<br>      teamDriveThemes = json.teamDriveThemes;<br>      $.each(json.teamDriveThemes, function(i, item) {<br>        $("#teamDriveThemeOptions").append(\`<br>        <div class="form-check"><br>           <input<br>            class="form-check-input"<br>            type="radio"<br>            name="teamDriveTheme"<br>            id="teamDriveThemeOption-\${item.id}"<br>            value="\${item.id}"<br>          /><br>          <label class="form-check-label" for="teamDriveThemeOption-\${item.id}"><br>           \${item.id}<br>          </label><br>        </div><br>        \`);<br>      });<br>      $("input[name=teamDriveTheme]").change(function() {<br>        var themeId = this.value;<br>        if (themeId === "random") {<br>          $("#teamDriveThemePreview").html("");<br>        } else {<br>          var theme = teamDriveThemes.find(function(t) {<br>            return t.id == themeId;<br>          });<br>          $("#teamDriveThemePreview").html(<br>            \`<br>          <div class="card" style="background-color: \${theme.colorRgb}"><br>            <img src="\${theme.backgroundImageLink}" class="card-img-top" alt="\${theme.id}" /><br>            <div class="card-body"><br>              <h5 class="card-text" style="color: white"><br>                \${theme.id}<br>              </h5><br>            </div><br>          </div><br>      \`<br>          );<br>        }<br>      });<br>      $("#teamDriveForm").on("submit", function(event) {<br>        event.preventDefault();<br>        $("#loadMe").modal({<br>          backdrop: "static", //remove ability to close modal with click<br>          keyboard: false, //remove option to close with keyboard<br>          show: true //Display loader!<br>        });<br>        $.ajax({<br>          type: "POST",<br>          url: "/drive",<br>          data: JSON.stringify({<br>            teamDriveName: $("input[id=teamDriveName]").val(),<br>            teamDriveThemeId: $("input[name=teamDriveTheme]:checked").val(),<br>            emailAddress: $("input[id=emailAddress]").val()<br>          }),<br>          success: function(data) {<br>            $("#loadMe").modal("hide");<br>            alert("成功!");<br>          },<br>          error: function(request, status, error) {<br>            $("#loadMe").modal("hide");<br>            alert("失败!" + request.responseText);<br>          },<br>          contentType: "application/json"<br>        });<br>      });<br>    });<br>  </script><br>  <style type="text/css"><br>    .card-img-top {<br>      width: 100%;<br>      object-fit: cover;<br>    }<br>  </style><br></html><br>`;<br><br>addEventListener("fetch", event => {<br>  event.respondWith(handleRequest(event.request));<br>});<br><br>var dailyLimit = [];<br><br>/**<br> * Fetch and log a request<br> * @param {Request} request<br> */<br>async function handleRequest(request) {<br>  if (authConfig.dailyLimit) {<br>    if (!today) today = new Date().getDate();<br><br>    // Remove email rate limit every day<br>    if (new Date().getDate() != today) {<br>      today = new Date().getDate();<br>      dailyLimit.length = 0;<br>    }<br>  }<br><br>  if (gd == undefined) {<br>    gd = new googleDrive(authConfig);<br>  }<br>  let url = new URL(request.url);<br>  let path = url.pathname;<br><br>  switch (path) {<br>    case "/teamDriveThemes":<br>      let teamDriveThemes = await gd.getTeamDriveThemes();<br>      return new Response(JSON.stringify(teamDriveThemes), {<br>        status: 200,<br>        headers: {<br>          "Content-Type": "application/json",<br>          "Access-Control-Allow-Origin": "*"<br>        }<br>      });<br>    case "/drive":<br>      if (request.method === "POST") {<br>        const requestBody = await request.json();<br><br>        if (authConfig.dailyLimit) {<br>          if (dailyLimit.includes(requestBody.emailAddress)) {<br>            return new Response("每天只允许提交一次", {<br>              status: 429<br>            });<br>          } else {<br>            dailyLimit.push(requestBody.emailAddress);<br>          }<br>        }<br><br>        if (authConfig.black_list.includes(requestBody.emailAddress)) {<br>          return new Response("Failed", {<br>            status: 429<br>          });<br>        }<br><br>        try {<br>          let result = await gd.createAndShareTeamDrive(requestBody);<br>          return new Response("OK", {<br>            status: 200<br>          });<br>        } catch (err) {<br>          return new Response(err.toString(), {<br>            status: 500<br>          });<br>        }<br>      } else if (request.method === "OPTIONS") {<br>        return new Response("", {<br>          status: 200,<br>          headers: {<br>            "Access-Control-Allow-Origin": "*"<br>          }<br>        });<br>      } else {<br>        return new Response("Bad Request", {<br>          status: 400<br>        });<br>      }<br>    default:<br>      return new Response(html, {<br>        status: 200,<br>        headers: {<br>          "Content-Type": "text/html; charset=utf-8",<br>          "Access-Control-Allow-Origin": "*"<br>        }<br>      });<br>  }<br>}<br>// https://stackoverflow.com/a/2117523<br>function uuidv4() {<br>  return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, c => {<br>    // tslint:disable-next-line:one-variable-per-declaration<br>    const r = (Math.random() * 16) | 0,<br>      // tslint:disable-next-line:triple-equals<br>      v = c == "x" ? r : (r & 0x3) | 0x8;<br>    return v.toString(16);<br>  });<br>}<br><br>class googleDrive {<br>  constructor(authConfig) {<br>    this.authConfig = authConfig;<br>    this.accessToken();<br>  }<br><br>  async getTeamDriveThemes() {<br>    let url = "https://www.googleapis.com/drive/v3/about";<br>    let requestOption = await this.requestOption();<br>    let params = { fields: "teamDriveThemes" };<br>    url += "?" + this.enQuery(params);<br>    let response = await fetch(url, requestOption);<br>    return await response.json();<br>  }<br><br>  async createAndShareTeamDrive(requestBody) {<br>    // Create team drive<br>    console.log("Creating TeamDrive");<br>    let url = "https://www.googleapis.com/drive/v3/drives";<br>    let requestOption = await this.requestOption(<br>      { "Content-Type": "application/json" },<br>      "POST"<br>    );<br>    let params = { requestId: uuidv4() };<br>    url += "?" + this.enQuery(params);<br>    let post_data = {<br>      name: requestBody.teamDriveName<br>    };<br>    if (<br>      requestBody.teamDriveThemeId &&<br>      requestBody.teamDriveThemeId !== "random"<br>    ) {<br>      post_data.themeId = requestBody.teamDriveThemeId;<br>    }<br>    requestOption.body = JSON.stringify(post_data);<br>    let response = await fetch(url, requestOption);<br>    let result = await response.json();<br>    const teamDriveId = result.id;<br>    console.log("Created TeamDrive ID", teamDriveId);<br><br>    // Get created drive user permission ID<br>    console.log(`Getting creator permission ID`);<br>    url = `https://www.googleapis.com/drive/v3/files/${teamDriveId}/permissions`;<br>    params = { supportsAllDrives: true };<br>    params.fields = "permissions(id,emailAddress)";<br>    url += "?" + this.enQuery(params);<br>    requestOption = await this.requestOption();<br>    response = await fetch(url, requestOption);<br>    result = await response.json();<br>    const currentUserPermissionID = result.permissions[0].id;<br>    console.log(currentUserPermissionID);<br><br>    // Share team drive with email address<br>    console.log(`Sharing the team drive to ${requestBody.emailAddress}`);<br>    url = `https://www.googleapis.com/drive/v3/files/${teamDriveId}/permissions`;<br>    params = { supportsAllDrives: true };<br>    url += "?" + this.enQuery(params);<br>    requestOption = await this.requestOption(<br>      { "Content-Type": "application/json" },<br>      "POST"<br>    );<br>    post_data = {<br>      role: "organizer",<br>      type: "user",<br>      emailAddress: requestBody.emailAddress<br>    };<br>    requestOption.body = JSON.stringify(post_data);<br>    response = await fetch(url, requestOption);<br>    await response.json();<br><br>    // Delete creator from the team drive<br>    console.log("Deleting creator from the team drive");<br>    url = `https://www.googleapis.com/drive/v3/files/${teamDriveId}/permissions/${currentUserPermissionID}`;<br>    params = { supportsAllDrives: true };<br>    url += "?" + this.enQuery(params);<br>    requestOption = await this.requestOption({}, "DELETE");<br>    response = await fetch(url, requestOption);<br>    return await response.text();<br>  }<br><br>  async accessToken() {<br>    console.log("accessToken");<br>    if (<br>      this.authConfig.expires == undefined ||<br>      this.authConfig.expires < Date.now()<br>    ) {<br>      const obj = await this.fetchAccessToken();<br>      if (obj.access_token != undefined) {<br>        this.authConfig.accessToken = obj.access_token;<br>        this.authConfig.expires = Date.now() + 3500 * 1000;<br>      }<br>    }<br>    return this.authConfig.accessToken;<br>  }<br><br>  async fetchAccessToken() {<br>    console.log("fetchAccessToken");<br>    const url = "https://www.googleapis.com/oauth2/v4/token";<br>    const headers = {<br>      "Content-Type": "application/x-www-form-urlencoded"<br>    };<br>    const post_data = {<br>      client_id: this.authConfig.client_id,<br>      client_secret: this.authConfig.client_secret,<br>      refresh_token: this.authConfig.refresh_token,<br>      grant_type: "refresh_token"<br>    };<br><br>    let requestOption = {<br>      method: "POST",<br>      headers: headers,<br>      body: this.enQuery(post_data)<br>    };<br><br>    const response = await fetch(url, requestOption);<br>    return await response.json();<br>  }<br><br>  async requestOption(headers = {}, method = "GET") {<br>    const accessToken = await this.accessToken();<br>    headers["authorization"] = "Bearer " + accessToken;<br>    return { method: method, headers: headers };<br>  }<br><br>  enQuery(data) {<br>    const ret = [];<br>    for (let d in data) {<br>      ret.push(encodeURIComponent(d) + "=" + encodeURIComponent(data[d]));<br>    }<br>    return ret.join("&");<br>  }<br>}
    var authConfig = {
    version: "1.0.1-fix1",
    dailyLimit: true, // 是否限制每一个邮箱每天只能提交一次请求
    client_id: "",
    client_secret: "",
    refresh_token: "", // 授权 token
    domain: "", // 面页中显示本站团队盘域, 可不填
    // 黑名单, 免费版没有数据库, 一个可行思路是从自己服务器上获取, 可自行实现
    black_list: ["example@gmail.com"]
    };

    var gd;

    var today;

    var html = `
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8" />
    <meta
    name="viewport"
    content="width=device-width, initial-scale=1.0,maximum-scale=1.0, user-scalable=no"
    />
    <title>创建Google TeamDrive</title>
    <link
    rel="stylesheet"
    href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
    />
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <script
    src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"
    integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1"
    crossorigin="anonymous"
    ></script>
    <script
    src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"
    integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM"
    crossorigin="anonymous"
    ></script>
    <!--源码地址: https://github.com/yyuueexxiinngg/some-scripts/blob/master/workers/google/drive/create-share-teamdrive.js-->
    </head>
    <body>
    <div id="app">
    <div id="container" class="container">
    <div class="row">
    <div class="col-sm-8 offset-sm-2 col-md-6 offset-md-3 text-center">
    <h1>创建Google TeamDrive</h1>
    <p>${authConfig.version}</p>
    ${
    authConfig.domain
    ? ` <h5>本站团队盘域为: ${authConfig.domain}</h5>`
    : ""
    }
    <p>
    后端多个API请求, 过程耗时较长, 请耐心等待,
    <span style="color: red"><b>切勿重复提交</b></span>
    </p>
    <br />
    <div class="info-form text-left">
    <form id="teamDriveForm">
    <div class="form-group">
    <label for="teamDriveName" class="sr-only">
    TeamDrive 名称
    </label>
    <input
    type="text"
    class="form-control"
    id="teamDriveName"
    placeholder="TeamDrive 名称"
    />
    </div>
    <div class="form-group">
    <label for="emailAddress" class="sr-only">
    您的GMail邮箱地址
    </label>
    <input
    type="email"
    class="form-control"
    id="emailAddress"
    placeholder="您的GMail邮箱地址"
    />
    </div>
    <div class="form-check">
    <input
    type="checkbox"
    class="form-check-input"
    id="customTheme"
    value=""
    />
    <label class="form-check-label" for="customTheme">
    自定TeamDrive主题头图
    </label>
    </div>
    <div id="customThemeSection" class="d-none">
    <div id="teamDriveThemePreview"></div>
    <div id="teamDriveThemeOptions">
    <div class="form-check">
    <input
    class="form-check-input"
    type="radio"
    name="teamDriveTheme"
    id="teamDriveThemeOptionRandom"
    value="random"
    checked
    />
    <label
    class="form-check-label"
    for="teamDriveThemeOptionRandom"
    >
    随机
    </label>
    </div>
    </div>
    </div>
    <button type="submit" class="btn btn-primary">Submit</button>
    </form>
    </div>
    </div>
    </div>
    </div>
    </div>
    <div
    class="modal fade"
    id="loadMe"
    tabindex="-1"
    role="dialog"
    aria-labelledby="loadMeLabel"
    >
    <div class="modal-dialog modal-sm" role="document">
    <div class="modal-content">
    <div class="modal-body text-center">
    <div class="d-flex justify-content-center">
    <div class="spinner-border" role="status">
    <span class="sr-only">正在创建中...</span>
    </div>
    </div>
    <div clas="loader-txt">
    <p>正在创建中...</p>
    </div>
    </div>
    </div>
    </div>
    </div>
    <footer class="page-footer font-small blue">
    <div class="footer-copyright text-center py-3">
    © 2020 源码:
    <a
    href="https://www.24s.net/?golink=aHR0cHM6Ly9lbnN1LmNjL2dvL2FIUjBjSE02THk5bmFYUm9kV0l1WTI5dEwzbDVkWFZsWlhoNGFXbHVibWRuTDNOdmJXVXRjMk55YVhCMGN5OWliRzlpTDIxaGMzUmxjaTkzYjNKclpYSnpMMmR2YjJkc1pTOWtjbWwyWlM5amNtVmhkR1V0YzJoaGNtVXRkR1ZoYldSeWFYWmxMbXB6" target="_blank"
    >
    yyuueexxiinngg
    </a>
    <br />
    Special Thanks:
    <a href="https://github.com/donwa/goindex">
    donwa
    </a>
    </div>
    </footer>
    </body>
    <script>
    var teamDriveThemes;
    $("input[id=customTheme]").change(function() {
    if ($(this).is(":checked")) {
    $("#customThemeSection").removeClass("d-none");
    } else {
    $("#customThemeSection").addClass("d-none");
    $("input[name=teamDriveTheme]")[0].click();
    }
    });
    $.get("/teamDriveThemes", function(json) {
    teamDriveThemes = json.teamDriveThemes;
    $.each(json.teamDriveThemes, function(i, item) {
    $("#teamDriveThemeOptions").append(\`
    <div class="form-check">
    <input
    class="form-check-input"
    type="radio"
    name="teamDriveTheme"
    id="teamDriveThemeOption-\${item.id}"
    value="\${item.id}"
    />
    <label class="form-check-label" for="teamDriveThemeOption-\${item.id}">
    \${item.id}
    </label>
    </div>
    \`);
    });
    $("input[name=teamDriveTheme]").change(function() {
    var themeId = this.value;
    if (themeId === "random") {
    $("#teamDriveThemePreview").html("");
    } else {
    var theme = teamDriveThemes.find(function(t) {
    return t.id == themeId;
    });
    $("#teamDriveThemePreview").html(
    \`
    <div class="card" style="background-color: \${theme.colorRgb}">
    <img src="\${theme.backgroundImageLink}" class="card-img-top" alt="\${theme.id}" />
    <div class="card-body">
    <h5 class="card-text" style="color: white">
    \${theme.id}
    </h5>
    </div>
    </div>
    \`
    );
    }
    });
    $("#teamDriveForm").on("submit", function(event) {
    event.preventDefault();
    $("#loadMe").modal({
    backdrop: "static", //remove ability to close modal with click
    keyboard: false, //remove option to close with keyboard
    show: true //Display loader!
    });
    $.ajax({
    type: "POST",
    url: "/drive",
    data: JSON.stringify({
    teamDriveName: $("input[id=teamDriveName]").val(),
    teamDriveThemeId: $("input[name=teamDriveTheme]:checked").val(),
    emailAddress: $("input[id=emailAddress]").val()
    }),
    success: function(data) {
    $("#loadMe").modal("hide");
    alert("成功!");
    },
    error: function(request, status, error) {
    $("#loadMe").modal("hide");
    alert("失败!" + request.responseText);
    },
    contentType: "application/json"
    });
    });
    });
    </script>
    <style type="text/css">
    .card-img-top {
    width: 100%;
    object-fit: cover;
    }
    </style>
    </html>
    `;

    addEventListener("fetch", event => {
    event.respondWith(handleRequest(event.request));
    });

    var dailyLimit = [];

    /**
    * Fetch and log a request
    * @param {Request} request
    */
    async function handleRequest(request) {
    if (authConfig.dailyLimit) {
    if (!today) today = new Date().getDate();

    // Remove email rate limit every day
    if (new Date().getDate() != today) {
    today = new Date().getDate();
    dailyLimit.length = 0;
    }
    }

    if (gd == undefined) {
    gd = new googleDrive(authConfig);
    }
    let url = new URL(request.url);
    let path = url.pathname;

    switch (path) {
    case "/teamDriveThemes":
    let teamDriveThemes = await gd.getTeamDriveThemes();
    return new Response(JSON.stringify(teamDriveThemes), {
    status: 200,
    headers: {
    "Content-Type": "application/json",
    "Access-Control-Allow-Origin": "*"
    }
    });
    case "/drive":
    if (request.method === "POST") {
    const requestBody = await request.json();

    if (authConfig.dailyLimit) {
    if (dailyLimit.includes(requestBody.emailAddress)) {
    return new Response("每天只允许提交一次", {
    status: 429
    });
    } else {
    dailyLimit.push(requestBody.emailAddress);
    }
    }

    if (authConfig.black_list.includes(requestBody.emailAddress)) {
    return new Response("Failed", {
    status: 429
    });
    }

    try {
    let result = await gd.createAndShareTeamDrive(requestBody);
    return new Response("OK", {
    status: 200
    });
    } catch (err) {
    return new Response(err.toString(), {
    status: 500
    });
    }
    } else if (request.method === "OPTIONS") {
    return new Response("", {
    status: 200,
    headers: {
    "Access-Control-Allow-Origin": "*"
    }
    });
    } else {
    return new Response("Bad Request", {
    status: 400
    });
    }
    default:
    return new Response(html, {
    status: 200,
    headers: {
    "Content-Type": "text/html; charset=utf-8",
    "Access-Control-Allow-Origin": "*"
    }
    });
    }
    }
    // https://stackoverflow.com/a/2117523
    function uuidv4() {
    return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, c => {
    // tslint:disable-next-line:one-variable-per-declaration
    const r = (Math.random() * 16) | 0,
    // tslint:disable-next-line:triple-equals
    v = c == "x" ? r : (r & 0x3) | 0x8;
    return v.toString(16);
    });
    }

    class googleDrive {
    constructor(authConfig) {
    this.authConfig = authConfig;
    this.accessToken();
    }

    async getTeamDriveThemes() {
    let url = "https://www.googleapis.com/drive/v3/about";
    let requestOption = await this.requestOption();
    let params = { fields: "teamDriveThemes" };
    url += "?" + this.enQuery(params);
    let response = await fetch(url, requestOption);
    return await response.json();
    }

    async createAndShareTeamDrive(requestBody) {
    // Create team drive
    console.log("Creating TeamDrive");
    let url = "https://www.googleapis.com/drive/v3/drives";
    let requestOption = await this.requestOption(
    { "Content-Type": "application/json" },
    "POST"
    );
    let params = { requestId: uuidv4() };
    url += "?" + this.enQuery(params);
    let post_data = {
    name: requestBody.teamDriveName
    };
    if (
    requestBody.teamDriveThemeId &&
    requestBody.teamDriveThemeId !== "random"
    ) {
    post_data.themeId = requestBody.teamDriveThemeId;
    }
    requestOption.body = JSON.stringify(post_data);
    let response = await fetch(url, requestOption);
    let result = await response.json();
    const teamDriveId = result.id;
    console.log("Created TeamDrive ID", teamDriveId);

    // Get created drive user permission ID
    console.log(`Getting creator permission ID`);
    url = `https://www.googleapis.com/drive/v3/files/${teamDriveId}/permissions`;
    params = { supportsAllDrives: true };
    params.fields = "permissions(id,emailAddress)";
    url += "?" + this.enQuery(params);
    requestOption = await this.requestOption();
    response = await fetch(url, requestOption);
    result = await response.json();
    const currentUserPermissionID = result.permissions[0].id;
    console.log(currentUserPermissionID);

    // Share team drive with email address
    console.log(`Sharing the team drive to ${requestBody.emailAddress}`);
    url = `https://www.googleapis.com/drive/v3/files/${teamDriveId}/permissions`;
    params = { supportsAllDrives: true };
    url += "?" + this.enQuery(params);
    requestOption = await this.requestOption(
    { "Content-Type": "application/json" },
    "POST"
    );
    post_data = {
    role: "organizer",
    type: "user",
    emailAddress: requestBody.emailAddress
    };
    requestOption.body = JSON.stringify(post_data);
    response = await fetch(url, requestOption);
    await response.json();

    // Delete creator from the team drive
    console.log("Deleting creator from the team drive");
    url = `https://www.googleapis.com/drive/v3/files/${teamDriveId}/permissions/${currentUserPermissionID}`;
    params = { supportsAllDrives: true };
    url += "?" + this.enQuery(params);
    requestOption = await this.requestOption({}, "DELETE");
    response = await fetch(url, requestOption);
    return await response.text();
    }

    async accessToken() {
    console.log("accessToken");
    if (
    this.authConfig.expires == undefined ||
    this.authConfig.expires < Date.now()
    ) {
    const obj = await this.fetchAccessToken();
    if (obj.access_token != undefined) {
    this.authConfig.accessToken = obj.access_token;
    this.authConfig.expires = Date.now() + 3500 * 1000;
    }
    }
    return this.authConfig.accessToken;
    }

    async fetchAccessToken() {
    console.log("fetchAccessToken");
    const url = "https://www.googleapis.com/oauth2/v4/token";
    const headers = {
    "Content-Type": "application/x-www-form-urlencoded"
    };
    const post_data = {
    client_id: this.authConfig.client_id,
    client_secret: this.authConfig.client_secret,
    refresh_token: this.authConfig.refresh_token,
    grant_type: "refresh_token"
    };

    let requestOption = {
    method: "POST",
    headers: headers,
    body: this.enQuery(post_data)
    };

    const response = await fetch(url, requestOption);
    return await response.json();
    }

    async requestOption(headers = {}, method = "GET") {
    const accessToken = await this.accessToken();
    headers["authorization"] = "Bearer " + accessToken;
    return { method: method, headers: headers };
    }

    enQuery(data) {
    const ret = [];
    for (let d in data) {
    ret.push(encodeURIComponent(d) + "=" + encodeURIComponent(data[d]));
    }
    return ret.join("&");
    }
    }

    将修改后的代码粘贴到 CloudFlare 部署。

    绑域名

    1. 先让需要绑定的域名通过cf,指向ip随意。

    2. 添加Route

    测试

    做了一个测试站:https://curly-field-dc43.ensucc0214.workers.dev/
    有兴趣的,可以试试。

    其他
    英国谢菲尔德大学:
    https://gdrive.zppcw.cn/

    404 NOT FOUND:
    https://gd.404edu.workers.dev/

    https://gd.zxd.workers.dev/

    http://leon.educationhost.cloud/

    swccd.edu团队盘:https://teamdrive.xcpx.workers.dev/

    洛杉矶加利福尼亚大学团队盘:https://ucla.ur.workers.dev/

    日本国際大学团队盘:
    https://iuj.ur.workers.dev/

    自动创建:
    https://www.teamdrive.workers.dev

[/rihide]  

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
Sometimes, we are not waiting for somebody or something. We are waiting to be changed as time goes by.
有时候,我们并不是在等什么人或什么事。我们只是在静待岁月改变自己
评论 共1条
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片快捷回复

    暂无评论内容