其他 Google Workspace (GWS) API 相关的博客文章似乎都是关于 Docs & Sheets(也就是它们的 API),但代码示例几乎总是文件操作,例如将 Google 文档导出为 PDF 文件 或将 CSV 文件导入 Google 表格中。文件操作通常与 Google Drive API 相关,而不是“编辑器”API。而这篇博客文章则打破了这种模式,启动了一个将 Markdown 转换为 Google 文档的转换器;是的,使用的是 Docs(而不是 Drive)API!通过这篇文章,读者将学到如何通过编程方式创建新的 Google 文档,并向其中写入和格式化文本。
你发现了一个专注于向 Python(和有时是 Node.js)开发者展示如何使用 Google 开发者生态系统的不同部分(从 API 到计算和 AI/ML 平台)的博客,在这里我提供像润滑油一样的帮助来帮助你减少入门时的阻力。无论你对哪个主题感兴趣,我基本上都能帮到你:
- Google Cloud/GCP (AI/ML,Serverless)
- Google Workspace/GWS (Gmail、Drive、Docs、Sheets等服务)
- YouTube
- 地图服务
- Gemini
- 像API密钥和OAuth客户端ID这样的基础设置(其中OAuth客户端ID主要用于GWS API)
我对大部分的 GWS 内容都感到有点“不满”:它们 仅仅覆盖了 Drive API。太无聊了!Workspace 有那么多其他 API,如果我不去探索 另一个 GWS API,对你们来说都没有好处。所以今天我就选了 Google Docs API。
灵感和动力的应用这个示例应用受到了两个熟悉项目的启发。之前,我创建了一个工具,该工具可以导入并解析类似Markdown语法的演示文稿大纲,并将其转换成Microsoft PowerPoint演示文稿。你甚至可以设置模板并启动幻灯片演示!紧接着,为Microsoft Word、Excel和Outlook开发了其他脚本,并在我的一本Python书中(详见第七章“编程Microsoft Office”)有所介绍。(对粉丝和读者来说:是的,我知道我需要更新这个版本,并把代码上传到GitHub上吧!)
在 Google Slides API 发布之后,我希望能够为 Slides 创建一个类似的工具,然而一位同事抢先一步用 md2googleslides
实现了一个类似工具,该项目支持完整的 Markdown 和多种内容,广受好评并被大量星标。这样一个大型工具对于像这样的简短内容来说会显得过于复杂,所以我选择了最基本的 Markdown 子集,仅支持下划线(_
)用于斜体和星号(*
)用于加粗:
使用任何这些指令格式化的文件,从 Markdown 中提取文本,创建一个 Google 文档,插入文本,然后按照标记指令格式化。(其他版本的 Markdown 或维基标记使用单个符号(两者之一)表示斜体,双符号表示加粗,但我为了简化正则表达式选择了更简单的实现方式。)
虽然你可以使用 Google 文档中的 Markdown 编辑功能以及 导入和导出 Markdown 文件,但如果你需要处理成百上千个生成的 Markdown 文件,你不会希望手动通过用户界面来处理这么多文件。要真正实现自动化,而不仅仅是一次处理一个文件,你需要 API 的力量来实现这个目标。
📝 注意:备选版本使用较旧的 Python(OAuth2)认证库
在这篇文章中有一个应用的备选版本:主脚本使用的是当前的 Python Google 认证库,而备选版本(名为 *-old.py
)则使用 较旧的认证库,该库虽然自2017年起已被弃用,但仍然被广泛使用(而且遗憾的是,在许多在线示例中也是如此)。它作为一个迁移工具,帮助仍在使用旧版本的用户进行升级。
📝 注意:代码示例兼容 Python 2 和 3
为了帮助 Python 2 用户升级和迁移至 Python 3,这些示例脚本兼容 Python 2.x 和 3.x。然而,这意味着您不会找到仅属于 Python 3 的特性,比如 f-string、类型注解或 async
和 await
。如果读者愿意提交一个纯 Python 3 版本,我很欢迎相关的 PR 请求。
代码
这个应用有四个版本,Python和Node.js各有两个版本的实现,所有这些都在代码库的repo文件夹中可以访问。代码库的repo文件夹链接为:
导入
[md2docs.py](https://github.com/wescpy/google/tree/main/apps/md2docs/python/md2docs.py)
这个导入代码如下:
Python
from __future__ import print_function
import os.path
import re
from google.auth.transport.requests import Request
from google.oauth2 import credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient import discovery
进入全屏 退出全屏
标准库导入使 Python 3 的 print()
函数可以在 Python 2 中使用(在 Python 3.x 中不再使用),通过 os
模块访问文件系统,并通过 re
模块处理正则表达式。接着导入 Google API 和认证客户端库。
对于仍然使用旧版认证库的开发人员,这里有一些在 md2docs-old.py
文件中的等效导入语句:
from __future__ import print_function
import re
from googleapiclient import discovery
from httplib2 import Http
from oauth2client import file, client, tools
按这儿切换全屏
JavaScript(一种编程语言)
来看 JavaScript,以下是针对 Node.js ES 模块的等效代码示例,该代码位于此链接:md2docs.mjs
:
import fs from 'node:fs/promises';
import path from 'node:path';
import process from 'node:process';
import { authenticate } from '@google-cloud/local-auth';
import { google } from 'googleapis';
全屏模式(按 Esc 退出)
如果你更喜欢 CommonJS,那么文件是md2docs.js
,而这些代码片段看起来像这样。
const fs = require('fs').promises;
const path = require('path');
const process = require('process');
const { authenticate } = require('@google-cloud/local-auth');
const { google } = require('googleapis');
你可以看到,这些代码行是用来引入并使用Node.js的几个核心模块的。
全屏 退出全屏
就像他们的 Python 双胞胎一样,这些包也使用了文件系统操作包以及 Google 安全和 API 访问。这里就是这两个 JavaScript 版本之间的差异,其余代码都是相同的,无论是 ES 模块还是 CommonJS。
安全:
接下来是常量和验证码:
Python (一种编程语言)
FILENAME = 'quickbrownfox.md' # 将此更改为自己的 Markdown 文件
creds = None
SCOPES = 'https://www.googleapis.com/auth/documents'
TOKENS = 'storage.json'
if os.path.exists(TOKENS):
creds = credentials.Credentials.from_authorized_user_file(TOKENS)
if creds is None or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file('client_secret.json', SCOPES)
creds = flow.run_local_server()
with open(TOKENS, 'w') as token:
token.write(creds.to_json())
DOCS = discovery.build('docs', 'v1', credentials=creds)
全屏模式 退出全屏
旧版本的认证使用起来更简单,因为该库管理OAuth令牌的存储(因此无需自己管理)。
FILENAME = 'quickbrownfox.md' # 请将其替换为你自己的 Markdown 文件
SCOPES = 'https://www.googleapis.com/auth/documents'
store = file.Storage('storage.json')
creds = store.get()
if not creds or creds.invalid:
flow = client.flow_from_clientsecrets('client_secret.json', SCOPES)
creds = tools.run_flow(flow, store)
DOCS = discovery.build('docs', 'v1', http=creds.authorize(Http()))
# 用于操作 Google 文档的 API 对象
全屏显示 退出全屏
除此之外,两个 Python 版本是相同的。JavaScript 代码的工作方式与 Python 类似,但略有不同之处:每个功能都被拆分并分配到单独的函数中,并改进了常量和命名约定:
JavaScript
const FILENAME = 'quickbrownfox.md'; // 请将此改为你的 Markdown 文件名
const CREDENTIALS_PATH = path.join(process.cwd(), 'client_secret.json');
const TOKEN_STORE_PATH = path.join(process.cwd(), 'storage.json');
const SCOPES = [ 'https://www.googleapis.com/auth/documents' ];
async function loadSavedCredentialsIfExist() {
try {
const content = await fs.readFile(TOKEN_STORE_PATH);
// 从 TOKEN_STORE_PATH 读取内容并将其存储为 content 变量
const credentials = JSON.parse(content);
return google.auth.fromJSON(credentials);
} catch (err) {
return null;
}
}
async function saveCredentials(client) {
const content = await fs.readFile(CREDENTIALS_PATH);
const keys = JSON.parse(content);
const key = keys.installed || keys.web;
const payload = JSON.stringify({
type: 'authorized_user',
client_id: key.client_id,
client_secret: key.client_secret,
refresh_token: client.credentials.refresh_token,
access_token: client.credentials.access_token,
token_expiry: client.credentials.token_expiry,
scopes: client.credentials.scopes,
});
// 将凭据保存至 TOKEN_STORE_PATH 文件
await fs.writeFile(TOKEN_STORE_PATH, payload);
}
async function authorize() {
var client = await loadSavedCredentialsIfExist();
if (client) return client;
client = await authenticate({
scopes: SCOPES,
keyfilePath: CREDENTIALS_PATH,
});
// 如果有凭证,将凭证保存至 TOKEN_STORE_PATH
if (client.credentials) await saveCredentials(client);
return client;
}
全屏切换
顶部的指针指向了quickbrownfox.md
数据文件,但其内容是随意的。你可以随意更改内容,或者将代码指向你自己的Markdown文件。为了演示,这里提供的quickbrownfox.md
文件包含如下Markdown数据:
那只快速的棕色狐狸跳过了那几只懒狗。
点击全屏,退出全屏
安全码是必需的,因为最终用户必须授予你的代码访问他们的数据的权限;在这种情况下,是代表他们创建文档。("authz")授权要求你创建一个客户端ID和密钥对,然后从你的Google开发者项目下载文件。
有关这段代码的详细信息以及如何为GWS API进行“认证”的操作可以在 OAuth客户端ID三部曲(主要是最后一篇文章)中找到,所以这里就不赘述了。如果你是新手或需要复习相关知识,请查看这些文章。在代码审查之后,我会提供运行示例所需的设置步骤,但请参阅这些文章获取所有相关细节。
Python 安全代码片段以 DOCS
结束,DOCS
是一个 Docs API 客户端对象,用于 Docs API 调用的服务端点。(在许多官方 Google 代码示例中,不是描述性的常量 DOCS
,而你会看到使用 service
作为变量名,现在你知道为什么了。)对于 JavaScript,不是使用全局变量,而是由主驱动程序管理,并将它传递给每个需要 API 调用的函数。
阅读和解析 Markdown 语法
下一步是阅读并解析 Markdown 文件中的内容。
Python
def read_parse_md(fname):
# 读取并解析 Markdown 文件的函数
# 读取文件内容,找到并替换加粗和斜体的文本,同时记录这些更改的位置
with open(fname, 'r') as f:
content = f.read()
actions = []
# 使用正则表达式找出所有加粗和斜体的文本
matches = re.findall(r'(([_*])([^\2]+?)\2)', content)
for match in matches:
md, dl, pt = match
i = content.find(md)
j = i + len(pt) + 1
content = content.replace(md, pt)
# 根据前缀判断是加粗还是斜体
action = 'bold' if dl == '*' else 'italic'
actions.append((action, i, j))
return content, actions
全屏模式 开启/退出
JavaScript
async function read_parse_md(fname) {
var contentBuf = await fs.readFile(fname);
var content = await contentBuf.toString('utf-8');
let actions = [];
const matches = content.matchAll(/(([_*])([^\2]+?)\2)/g);
for (const match of matches) {
const [ md, dl, pt ] = match.slice(1, 4);
var i = content.indexOf(md);
var j = i + pt.length + 1;
content = content.replace(md, pt);
var action = (dl === '*') ? '加粗' : '斜体';
actions.push([ action, i, j ]);
}
return [ content, actions ];
}
点击此处进入全屏模式,再点击此处退出全屏模式
两个示例几乎是一行行相同的,所以我们一起来分析它们吧。read_parse_md()
这个函数确实做到了:它读取和解析 Markdown 文件,将 Markdown 标记转换为通过 Docs API 发出的格式化操作 actions。
正则表达式(“regex”)用于匹配需要用下划线表示斜体的字符串,例如 _sample_
,以及需要用星号表示加粗的字符串,例如 *sample*
。一次遍历 content
字符串,将每个样式请求转换为 API "样式操作"。
这个正则表达式看起来可能有点复杂,但它的基本工作原理是这样的:寻找一个开头的 _
或 *
并将其符号保存为 \2
(第二个匹配模式)。找到一个匹配后,以非贪婪方式 ?
找到最少字符的闭合符号,并保存整个标记文本(md
)、纯文本(pt
)以及分隔符(dl
)。对于 "_sample_
",md
为 _sample_
,dl
是 _
,pt
是 sample
,将 action
设置为 italic
。下表展示了所有这些值:
正则 | 正则匹配 | 保存到变量 | 描述 | 示例 |
---|---|---|---|---|
((...\2) (最外层的括号 () ) |
\1 |
"Markdown:" md |
完整的匹配字符串 | _sample_ |
([_*]) |
\2 |
"Delimiter:" dl |
Markdown 标记 | _ |
([^\2]+?) |
\3 |
"Plain Text:" pt |
去掉分隔符的匹配字符串 | sample |
正则表达式及匹配结果
最简单的方法来“解读”这些匹配组是 \1
表示第一个左括号,\2
表示第二个,以此类推。
要让文档 API 对任何文本应用样式,它必须知道文本的位置信息,也就是说你的请求必须提供位置信息以及操作。这些是原始偏移:一个起始位置 (i
) 和一个结束位置 (j
)。所有样式请求都将以这种方式处理,将 (action
, i
, j
) 添加到 actions
数组中。
最后,所有标记将被清除,content
"还原"为纯文本。actions
数组包含了通过API进行样式设置的所有"操作指令"。
创建和编辑 Google 文档
有了所有的内容和指令,我们需要编写代码来创建一个空的新 Google 文档,并将数据字符串写进去。每个任务都需要用到一个函数:
功能 | 描述 |
---|---|
create_doc() |
创建新的或空的 Google 文档并返回其文件 ID |
write_text() |
将文本写入指定文件 ID 的文档中 |
Python 代码
下面的代码定义了两个函数:`create_doc` 和 `write_text`。`create_doc` 函数用于创建一个文档并将文件名作为标题,返回文档的 ID。`write_text` 函数用于在指定位置插入文本。
def create_doc(fname):
# 返回创建文档后的文档ID
return DOCS.documents().create(
body={'title': fname}).execute().get('documentId')
def write_text(text, docs_id):
requests = [{'insertText': {'location': {'index': 1}, 'text': text}}]
DOCS.documents().batchUpdate(body={'requests': requests},
documentId=docs_id, fields='').execute()
进入全屏 退出全屏
JavaScript(一种编程语言)
async function create_doc(DOCS, fname) {
const rsp = await DOCS.documents.create({ requestBody: { title: fname } });
return rsp.data.documentId;
}
// 创建文档函数
async function write_text(DOCS, text, docs_id) {
const requests = [ { insertText: { location: { index: 1 }, text: text } } ];
await DOCS.documents.batchUpdate({
requestBody: { requests: requests },
documentId: docs_id
});
}
// 写入文本到文档的函数
切换到全屏 切换回正常模式
创建一个新的 Google 文档只需要提供文档名称;本例中即为移除 .md
文件扩展名的 Markdown 文件名,也就是去掉 .md
的 Markdown 文件名。create_doc()
函数会发出请求,并返回新生成的文档(即 Google Drive 中的文件)的文件 ID。
更新 Google 文档需要一个或多个请求,比如 这个 API 请求。在这个具体例子中,请求类型是 InsertTextRequest
,至少需要两个参数。
- 要插入的文本
text
(请保留英文原样) - 要插入的位置(索引位置或偏移值)
在新的文档里,在索引 1(而不是 0)处插入内容是正确的位置。Node.js 版本的 write_text()
函数唯一的区别在于,API 客户端对象 DOCS
在每次调用时传递,而在 Python 中,则使用同一个全局变量。
在 Google 文档中排版文本
拼图的最后一块是一个格式化 Google 文档中文本的函数;这个函数是用来格式化 Google 文档中文本的:
Python
def format_text(actions, docs_id):
'format text with requested Markdown styling'
requests = [{
'updateTextStyle': {
'range': {'startIndex': i, 'endIndex': j},
'textStyle': {style: True}, 'fields': style,
}
} for style, i, j in actions]
DOCS.documents().batchUpdate(body={'requests': requests},
documentId=docs_id, fields='').execute()
全屏,退出全屏
JavaScript(一种脚本语言)
async function format_text(DOCS, actions, docs_id) {
const requests = [];
for (const [ style, i, j ] of actions) {
requests.push({
updateTextStyle: {
range: { startIndex: i, endIndex: j },
textStyle: { [ style ]: true }, fields: style
}
});
}
await DOCS.documents.batchUpdate({
requestBody: { requests: requests },
documentId: docs_id
});
}
全屏模式/退出全屏
它使用文档的文件ID(docs_id
)和样式操作数组(actions
),构建一个等效的updateTextStyle
API请求数组,这意味着每个请求包括加粗或斜体命令以及受影响文本的位置。
在处理完 actions
并将其内容输出后,如果 requests
看起来像一个 JSON 对象的数组,你完全正确。
[{'updateTextStyle': {'斜体': True,
'范围': {'结束索引': 17, '起始索引': 4},
'文本样式': {'italic': True}}},
{'updateTextStyle': {'粗体': True,
'范围': {'结束索引': 47, '起始索引': 37},
'文本样式': {'bold': True}}}]
全屏 退出全屏.
它最后一件事是将数组和文件ID传递给API来执行请求。这是一个非常基础的Markdown指令处理程序。目的是让你开始熟悉Docs API,而不是编写一个完整的Markdown解析器,你可以根据需要尝试编写一个完整的Markdown解析器作为练习。
主要驱动力
虽然这些功能都很不错,但需要一个“主要的”程序来把这些功能整合在一起。它们分别是:
Python
if __name__ == '__main__':
text, actions = read_parse_md(FILENAME)
print('** 解析 Markdown 文件 %r 并获取其样式操作' % FILENAME)
docs_fn = FILENAME.replace('.md', '') # 去掉 MD 文件扩展名
docs_id = create_doc(docs_fn)
print('** 创建文档 %r (ID: %s)' % (docs_fn, docs_id))
write_text(text, docs_id)
print('** 将 %r 插入文档' % text)
format_text(actions, docs_id)
print('** 完成文档中的 Markdown 格式化' % actions)
进入全屏 退出全屏
JavaScript(一种编程语言)
async function md2docs(authClient) {
const DOCS = google.docs({ version: 'v1', auth: authClient });
const [ text, 操作] = await read_parse_md(FILENAME);
console.log(`** 解析了 Markdown 文件 '${FILENAME}' 及样式操作`);
const docs_fn = await FILENAME.replace('.md', '');
const docs_id = await create_doc(DOCS, docs_fn);
console.log(`** 创建了文档 '${docs_fn}' (ID: ${docs_id})`);
await write_text(DOCS, text, docs_id);
console.log(`** 将文本插入文档:${text.replace(/\n/g, "\\n")}`);
await format_text(DOCS, 操作, docs_id);
console.log(`** 文档中的 Markdown 格式化完成:`, 操作);
}
authorize().then(md2docs).catch(console.error);
点击全屏 点击退出全屏
这两个代码段的功能只有细微差别,具体表现在:
- 在 JS 中,
DOCS
API 客户端对象仅限于此代码块,而 Python 中则是全局的。 - JS 代码的最后一行调用
authorize()
函数,并将返回的authClient
对象传递给主要的md2docs()
函数,该函数可以捕获并记录异常信息。
不管您用哪种语言,这个 app 的做法如下:
- 读取并解析 Markdown 内容
- 新建一个空白的 Google 文档
- 将纯文本内容写入文档
- 在文档中完成所有格式化要求
运行脚本时,输出会严格按照那个配方。不过,在运行任何脚本之前,你需要先完成以下这些必要的步骤:
- 创建新项目 从云/开发人员控制台 或使用
gcloud projects create . . .
命令;或者复用现有项目。 - 启用 Google Docs API。选择以下三种常见方式之一来启用 API:
- DevConsole 手动 -- 从 DevConsole 手动启用 API,步骤如下:
-
访问 DevConsole
- 在页面右侧找到并点击“启用”按钮;在左侧导航栏中点击 库 选项卡,搜索“Docs”,并启用。
- DevConsole 链接 -- 如果你是第一次使用 Google API 或者没有手动在 DevConsole 中启用 API 的经验,可以这样做:
- 命令行 (
gcloud
) -- 喜欢在终端操作的人可以使用 Cloud Shell 或者在本地计算机上,通过已安装的 Cloud SDK 包含的gcloud
命令行工具。
-
如果你是这种情况,使用此命令启用 API:
gcloud services enable docs.googleapis.com
- 使用此命令确认已启用的 API:
gcloud services list
- 创建 OAuth 客户端 ID 和密钥 凭证 并下载到本地文件系统作为
client_secret.json
。如果没有这个文件,代码示例将 无法运行。 - 安装 Google API 客户端库 :
-
NodeJS (16+): 使用以下命令安装所需包:
-
npm i
(使用package.json
) -
或者手动安装包:
npm i googleapis @google-cloud/local-auth
-
Python 2 或 3 (新认证方式): 在你的正常或
virtualenv
环境中运行此命令,这是大多数人使用的标准方式: -
pip install -r requirements.txt
(或pip3
) -
或者手动安装包:
pip install -U pip google-api-python-client google-auth-httplib2 google-auth-oauthlib
-
Python 2 或 3 (旧认证方式): 如果你仍然使用旧的 Python 认证库并且有旧代码,运行此命令以确保你拥有最新版本的这些库:
-
pip install -r requirements-old.txt
(或pip3
) -
或者手动安装包:
pip install -U pip google-api-python-client oauth2client
(或pip3
) - 例如,对于 Python 特别地来说,这里的 2.x 指的是 2.7,如果你正计划迁移到 3.x,你 绝对 不应该使用任何旧的版本。对于 3.x,几乎所有的版本应该都可以工作,但建议使用 3.9 或更新版本。
做好了以上所有事情后,你就可以开始了哦。顺便说一下,运行这个应用的成本应该不会有任何额外费用。
运行这个脚本程序⚠️ 请注意:成本: "免费" 到一定限度
尽管许多 Google 产品和 API 是免费的,但并非所有产品和 API 都是免费的。尽管如此,使用 GWS API 不是完全 "免费",但它完全包括在您每月的 "订阅" 中,无论是付费订阅者(定价详情)还是免费的 Google 消费者账户(带有 或 不带有 Gmail,Gmail 是可选的),这意味着您的每月订阅费用为零。然而,这种 "免费" 使用是有一定限制的……请遵守每个 API 的既定配额限制。不出所料,付费订阅者比免费账户拥有更多的配额。虽然没有广泛公开,您可以在 Google Apps Script 配额页面 上查看详细的限制。
但每种语言渲染的对象会有一些细微的差别,如下所示,类似于你看到的,因为我们知道这些应用的“运行原理”,运行这些应用会产生我们预期的结果。
Python(一种编程语言)
$ python md2docs.py
** 解析 Markdown 文件 'quickbrownfox.md' 并执行样式操作
** 生成 'quickbrownfox' (ID: bfENGvI9vCE2cabBCqv3Hq6qvFoL0nfDPfQZeZLY6ubQ)
** 将 'The quick, brown fox jumped over the lazy dogs.\n' 插入到文档中
** 完成文档的 Markdown 格式化:[斜体(4, 17), 粗体(37, 47)]
全屏模式 全屏退出
JavaScript
$ node md2docs.mjs
** 解析了 Markdown 文件 'quickbrownfox.md' 并执行了相应的样式操作
** 创建了 'quickbrownfox' (ID: ATjQg2PqFQxqmiRNIi1TL9gjXBFWV7cw0i4ytGtddt7K)
** 将 'The quick, brown fox jumped over the lazy dogs.\n' 插入到文档中
** 完成了文档的 Markdown 格式化:[ ['斜体', 4, 17], ['加粗', 37, 47] ]
进入全屏 退出全屏
如果你能在文本刚添加到 Google 文档的瞬间暂停应用并打开,就会看到类似这样的内容。
插入到 Google 文档中的简单文本
然而,除非你暂停执行,否则很难截到图,因为格式化很快就会开始,也就是说,你看到的将是最终结果。
Google 文档中的格式化字符串
概要和接下来的步骤现在你知道如何使用正则表达式创建一个简陋的Markdown解析器,更重要的是,你学会了如何使用Google Docs API。
- 创建一个新的 Google 文档文件
- 在 Google 文档中输入文本
- 在 Google 文档中设置文本格式
虽然该示例用来开始一个简单的 Markdown 解析器,但主要目的是让读者熟悉这个 API,这个 API 上线时间不长(于 2017 年推出)。如果你想支持更丰富的 Markdown 语法,可以考虑用 Python 的 markdown2
或者 Node.js 的 Showdown。
如果你将这篇帖子中演示的示例脚本与将 Google 文档导出为 PDF 文件帖子中的示例结合起来,你就会拥有一个解决方案,该方案可以自动获取 Markdown 文件,生成格式化的 Google 文档文件,并导出相应的 PDF 以供使用,供您组织或客户使用。
你也可以更进一步:将有价值的企业数据从一组庞大的 CSV 文件中提取出来并导入到 Google 表格中,将它们导入,然后利用 Gemini API 生成内容摘要,撰写一系列 Google 文档,最后生成 PDF 文件给你的老板、管理层,甚至是付费客户。
这些只是些想法。我的目的是通过展示可能来激发你的灵感。在未来的文章中,我还会介绍其他的 GWS API。为了好玩,我还会写一篇“codegen”(代码生成)的文章,让像 ChatGPT 和 Gemini 这样的大语言模型来生成这样的应用,讨论我得到的结果,并进行比较。
总结
如果你在这篇文章中发现了错误或 bug,或者你有想让我讨论的话题,请在下方留言或在仓库中提交 issue。我乐于在旅途中遇到用户……你可以在我的咨询页面旅行日历中查看我是否会访问你的社区。
参考文献下面是一些可能对你有用的、与本文相关的资源。
代码片段
谷歌文档 API
GWS APIs 和 OAuth2 相关信息
- 所有 GWS API 文档链接
- OAuth 同意屏幕和范围信息
- OAuth2 文档链接
Google API, 客户端库工具
作者的其他相关文章
-
GWS API 特定用例
-
使用 Google Docs API 合并邮件 文章与视频
-
将 Google 文档转换为 PDF 文章
-
将 CSV 文件上传至 Google 表格 文章
-
GWS API 入门内容(主要涉及 Drive API)
-
Codelab(动手教程)
-
GWS API 一般信息
-
使用 OAuth 客户端 ID 和 GWS API 三个系列文章
-
GWS/G Suite 开发者概览 文章和视频(面向所有开发者,但最初是针对学生的)
-
访问 GWS/G Suite REST API 文章和视频(面向所有开发者,但最初是针对学生的)
-
使用 Gmail、Drive、Docs、Sheets、Slides(全面介绍 GWS/G Suite 开发)视频(较长)
-
GWS API 视频系列
-
Launchpad Online(包含 GWS 及其他 Google API)
-
GWS/G Suite Dev Show(仅涉及 GWS API)
-
Google API 一般信息
-
Google API 入门 文章和视频
-
Python 授权样板代码审查 视频
- 导入和导出 MIME 类型(StackOverflow)
免责声明: 我曾在多个GWS产品团队工作,时间大约在2013年至2018年之间。尽管产品信息力求准确,但这些观点仅仅是个人看法。
(保留原格式)
郑雅硕(Wesley Chun), MSCS,是Google Cloud (GCP) 和 Google Workspace (GWS) 的Google Developer Expert (GDE),著有普雷蒂斯霍尔畅销书“Core Python”系列,合著有“Python Web Development with Django”,并且曾在Linux Journal及CNET撰文。他经营CyberWeb,专注于GCP及GWS API和无服务器平台,提供Python及App Engine迁移服务,以及Python培训及工程服务。郑雅硕曾是雅虎邮件的原始工程师之一,并在谷歌的产品团队工作了超过13年,代表他们的API发言,制作样本应用、代码实验室和视频,涉及无服务器迁移和GWS开发者。他拥有加州大学的计算机科学、数学和音乐学位,是Python软件基金会的成员,也是Fellow,并热衷于旅行,参加世界各地的开发者会议、用户组活动和大学。关注他@wescpy以及他的技术博客。觉得这些内容有用的话,联系CyberWeb以获取专业服务或买他一杯咖啡(或茶)。