在本教程中,您将学习如何使用事件通知 在 PDF 文件上传到 R2 存储桶时进行处理。您将使用 Workers AI 汇总 PDF 并将摘要作为文本文件存储在同一存储桶中。
要继续,您需要:
- 拥有 R2 访问权限的 Cloudflare 账户 ↗。
- 已有 R2 存储桶。请参阅 R2 快速入门教程。
- 安装
Node.js↗。
Node.js 版本管理器
使用 Volta ↗ 或
nvm ↗ 等 Node 版本管理器,以避免权限问题并切换
Node.js 版本。本指南后面讨论的 Wrangler 需要 Node 版本 16.17.0 或更高。
您将创建一个新的 Worker 项目,使用 Static Assets 提供应用程序的前端。用户可以通过此前端上传 PDF 文件,然后由 Worker 进行处理。
通过运行以下命令创建新的 Worker 项目:
npm create cloudflare@latest -- pdf-summarizeryarn create cloudflare pdf-summarizerpnpm create cloudflare@latest pdf-summarizer进行设置时,请选择以下选项:
- 对于 What would you like to start with?,选择
Hello World example。 - 对于 Which template would you like to use?,选择
Worker only。 - 对于 Which language do you want to use?,选择
TypeScript。 - 对于 Do you want to use git for version control?,选择
Yes。 - 对于 Do you want to deploy your application?,选择
No(部署前我们还会做一些修改)。
导航到 pdf-summarizer 目录:
cd pdf-summarizer使用 Static Assets,您可以从 Worker 提供应用程序的前端。要使用 Static Assets,需要将所需的绑定添加到 Wrangler 文件。
{
"assets": {
"directory": "public"
}
}[assets]
directory = "public"接下来,创建 public 目录并添加 index.html 文件。index.html 文件应包含以下 HTML 代码:
点击查看 HTML 代码
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>PDF Summarizer</title>
<style>
body {
font-family: Arial, sans-serif;
display: flex;
flex-direction: column;
min-height: 100vh;
margin: 0;
background-color: #fefefe;
}
.content {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
}
.upload-container {
background-color: #f0f0f0;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.upload-button {
background-color: #4caf50;
color: white;
padding: 10px 15px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
}
.upload-button:hover {
background-color: #45a049;
}
footer {
background-color: #f0f0f0;
color: white;
text-align: center;
padding: 10px;
width: 100%;
}
footer a {
color: #333;
text-decoration: none;
margin: 0 10px;
}
footer a:hover {
text-decoration: underline;
}
</style>
</head>
<body>
<div class="content">
<div class="upload-container">
<h2>Upload PDF File</h2>
<form id="uploadForm" onsubmit="return handleSubmit(event)">
<input
type="file"
id="pdfFile"
name="pdfFile"
accept=".pdf"
required
/>
<button type="submit" id="uploadButton" class="upload-button">
Upload
</button>
</form>
</div>
</div>
<footer>
<a
href="https://developers.cloudflare.com/r2/buckets/event-notifications/"
target="_blank"
>R2 Event Notification</a
>
<a
href="https://developers.cloudflare.com/queues/get-started/#3-create-a-queue"
target="_blank"
>Cloudflare Queues</a
>
<a href="https://developers.cloudflare.com/workers-ai/" target="_blank"
>Workers AI</a
>
<a
href="https://github.com/harshil1712/pdf-summarizer-r2-event-notification"
target="_blank"
>GitHub Repo</a
>
</footer>
<script>
handleSubmit = async (event) => {
event.preventDefault();
// Disable the upload button and show a loading message
const uploadButton = document.getElementById("uploadButton");
uploadButton.disabled = true;
uploadButton.textContent = "Uploading...";
// get form data
const formData = new FormData(event.target);
const file = formData.get("pdfFile");
if (file) {
// call /api/upload endpoint and send the file
await fetch("/api/upload", {
method: "POST",
body: formData,
});
event.target.reset();
} else {
console.log("No file selected");
}
uploadButton.disabled = false;
uploadButton.textContent = "Upload";
};
</script>
</body>
</html>要查看应用程序的前端,请运行以下命令并导航到终端中显示的 URL:
npm run dev ⛅️ wrangler 3.80.2
-------------------
⎔ Starting local server...
[wrangler:inf] Ready on http://localhost:8787
╭───────────────────────────╮
│ [b] open a browser │
│ [d] open devtools │
│ [l] turn off local mode │
│ [c] clear console │
│ [x] to exit │
╰───────────────────────────╯在浏览器中打开 URL 时,您会看到一个文件上传表单。如果尝试上传文件,您会注意到文件未上传到服务器。这是因为前端未连接到后端。在下一步中,您将更新 Worker 来处理文件上传。
要处理文件上传,首先需要添加 R2 绑定。在 Wrangler 文件中添加以下代码:
{
"r2_buckets": [
{
"binding": "MY_BUCKET",
"bucket_name": "<R2_BUCKET_NAME>"
}
]
}[[r2_buckets]]
binding = "MY_BUCKET"
bucket_name = "<R2_BUCKET_NAME>"将 <R2_BUCKET_NAME> 替换为您的 R2 存储桶名称。
接下来,更新 src/index.ts 文件。src/index.ts 文件应包含以下代码:
export default {
async fetch(request, env, ctx): Promise<Response> {
// Get the pathname from the request
const pathname = new URL(request.url).pathname;
if (pathname === "/api/upload" && request.method === "POST") {
// Get the file from the request
const formData = await request.formData();
const file = formData.get("pdfFile") as File;
// Upload the file to Cloudflare R2
const upload = await env.MY_BUCKET.put(file.name, file);
return new Response("File uploaded successfully", { status: 200 });
}
return new Response("incorrect route", { status: 404 });
},
} satisfies ExportedHandler<Env>;上述代码执行以下操作:
- 检查请求是否为对
/api/upload端点的 POST 请求。如果是,则从请求中获取文件并使用 Workers API 将其上传到 Cloudflare R2。 - 如果请求不是对
/api/upload端点的 POST 请求,则返回 404 响应。
由于 Worker 代码使用 TypeScript 编写,您应运行以下命令添加必要的类型定义。虽然这不是必需的,但有助于避免错误。
npm run cf-typegen您可以重启开发服务器以测试更改:
npm run dev事件通知捕获 R2 存储桶中数据的变更。您需要创建新队列 pdf-summarize 来接收通知:
npx wrangler queues create pdf-summarizer将绑定添加到 Wrangler 文件:
{
"queues": {
"consumers": [
{
"queue": "pdf-summarizer"
}
]
}
}[[queues.consumers]]
queue = "pdf-summarizer"现在您有了接收事件通知的队列,需要更新 Worker 来处理事件通知。您需要添加 Queue 处理程序,从 PDF 中提取文本内容,使用 Workers AI 汇总内容,然后将其保存到 R2 存储桶。
更新 src/index.ts 文件以添加 Queue 处理程序:
export default {
async fetch(request, env, ctx): Promise<Response> {
// No changes in the fetch handler
},
async queue(batch, env) {
for (let message of batch.messages) {
console.log(`Processing the file: ${message.body.object.key}`);
}
},
} satisfies ExportedHandler<Env>;上述代码执行以下操作:
- 当新消息添加到队列时,会调用
queue处理程序。它遍历批次中的消息并记录文件名。
目前 queue 处理程序尚未执行任何操作。在后续步骤中,您将更新 queue 处理程序以从 PDF 中提取文本内容,使用 Workers AI 汇总内容,然后将其添加到存储桶。
要从 PDF 提取文本内容,Worker 将使用 unpdf ↗ 库。unpdf 库提供处理 PDF 文件的工具。
通过运行以下命令安装 unpdf 库:
npm i unpdfyarn add unpdfpnpm add unpdfbun add unpdf更新 src/index.ts 文件,从 unpdf 库导入所需模块:
import { extractText, getDocumentProxy } from "unpdf";接下来,更新 queue 处理程序以从 PDF 提取文本内容:
async queue(batch, env) {
for(let message of batch.messages) {
console.log(`Processing file: ${message.body.object.key}`);
// Get the file from the R2 bucket
const file = await env.MY_BUCKET.get(message.body.object.key);
if (!file) {
console.error(`File not found: ${message.body.object.key}`);
continue;
}
// Extract the textual content from the PDF
const buffer = await file.arrayBuffer();
const document = await getDocumentProxy(new Uint8Array(buffer));
const {text} = await extractText(document, {mergePages: true});
console.log(`Extracted text: ${text.substring(0, 100)}...`);
}
}上述代码执行以下操作:
queue处理程序从 R2 存储桶获取文件。queue处理程序使用unpdf库从 PDF 提取文本内容。queue处理程序记录文本内容。
要使用 Workers AI,需要将 Workers AI 绑定添加到 Wrangler 文件。Wrangler 文件应包含以下代码:
{
"ai": {
"binding": "AI"
}
}[ai]
binding = "AI"运行以下命令添加 AI 类型定义:
npm run cf-typegen更新 src/index.ts 文件以使用 Workers AI 汇总内容:
async queue(batch, env) {
for(let message of batch.messages) {
// Extract the textual content from the PDF
const {text} = await extractText(document, {mergePages: true});
console.log(`Extracted text: ${text.substring(0, 100)}...`);
// Use Workers AI to summarize the content
const result: AiSummarizationOutput = await env.AI.run(
"@cf/facebook/bart-large-cnn",
{
input_text: text,
}
);
const summary = result.summary;
console.log(`Summary: ${summary.substring(0, 100)}...`);
}
}queue 处理程序现在使用 Workers AI 汇总内容。
现在您有了摘要,需要将其添加到 R2 存储桶。更新 src/index.ts 文件以将摘要添加到 R2 存储桶:
async queue(batch, env) {
for(let message of batch.messages) {
// Extract the textual content from the PDF
// ...
// Use Workers AI to summarize the content
// ...
// Add the summary to the R2 bucket
const upload = await env.MY_BUCKET.put(`${message.body.object.key}-summary.txt`, summary, {
httpMetadata: {
contentType: 'text/plain',
},
});
console.log(`Summary added to the R2 bucket: ${upload.key}`);
}
}Queue 处理程序现在将摘要作为文本文件添加到 R2 存储桶。
您的 queue 处理程序已准备好处理传入的事件通知消息。需要使用 wrangler r2 bucket notification create 命令 为存储桶启用事件通知。以下命令为 pdf 后缀的 object-create 事件类型创建事件通知:
npx wrangler r2 bucket notification create <R2_BUCKET_NAME> --event-type object-create --queue pdf-summarizer --suffix "pdf"将 <R2_BUCKET_NAME> 替换为您的 R2 存储桶名称。
已为 pdf 后缀创建事件通知。当具有 pdf 后缀的新文件上传到 R2 存储桶时,将触发 pdf-summarizer 队列。
要部署 Worker,请运行 wrangler deploy 命令:
npx wrangler deploy在 wrangler deploy 命令的输出中,复制 URL。这是您已部署应用程序的 URL。
要测试应用程序,请导航到已部署应用程序的 URL 并上传 PDF 文件。或者,您可以使用 Cloudflare 仪表板 ↗ 上传 PDF 文件。
要查看日志,可以使用 wrangler tail 命令。
npx wrangler tail您将在终端中看到日志。您也可以导航到 Cloudflare 仪表板并在 Workers Logs 部分查看日志。
如果检查 R2 存储桶,您将看到摘要文件。
在本教程中,您学习了如何使用 R2 事件通知在上传时处理对象。您创建了一个上传 PDF 文件的应用程序,并创建了一个消费者 Worker 来生成 PDF 文件的摘要。您还学习了如何使用 Workers AI 汇总 PDF 文件的内容,并将摘要上传到 R2 存储桶。
您可以使用相同的方法处理其他类型的文件,例如图像、视频和音频文件。您还可以使用相同的方法处理其他类型的事件,例如对象删除和对象更新。
如果您想查看本教程的代码,可以在 GitHub ↗ 上找到。