← Cloudflare R2 / r2 / tutorials
Использование уведомлений о событиях для создания сводки PDF-файлов при загрузке
В этом руководстве вы узнаете, как использовать уведомления о событиях чтобы обрабатывать PDF-файл при его загрузке в бакет R2. Вы будете использовать Workers AI , чтобы создать краткое содержание PDF-файла и сохранить его в виде текстового файла в том же бакете.
Предварительные требования
Чтобы продолжить, вам потребуется:
- A Аккаунт Cloudflare ↗ с доступом к R2.
- У вас уже есть бакет R2. См. Руководство по началу работы с R2.
- Установка
Node.js↗.
менеджер версий Node.js
Используйте менеджер версий Node, например Volta ↗ или
nvm ↗ чтобы избежать проблем с правами доступа и менять
версии Node.js. Wrangler, рассмотренная
далее в этом руководстве, требует версии Node 16.17.0 или более поздней версии.
1. Создать новый проект
Вы создадите новый проект Worker, который будет использовать Static Assets чтобы обслуживать фронтенд вашего приложения. Пользователь может загрузить PDF-файл через этот фронтенд, который затем будет обработан вашим Worker.
Создайте новый проект Worker, выполнив следующие команды:
npm create cloudflare@latest -- pdf-summarizerДля настройки выберите следующие параметры:
- Для С чего вы хотите начать?, выберите
Hello World example. - Для Какой шаблон вы хотите использовать?, выберите
Worker only. - Для Какой язык вы хотите использовать?, выберите
TypeScript. - Для Хотите использовать git для контроля версий?, выберите
Yes. - Для Хотите развернуть приложение?, выберите
No(мы внесём некоторые изменения перед развёртыванием).
Перейдите в pdf-summarizer каталог:
cd pdf-summarizer2. Создать фронтенд
С помощью 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, который будет обрабатывать загрузку файла.
3. Обработать загрузку файлов
Чтобы обработать загрузку файла, сначала нужно добавить привязку 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>;Приведённый выше код выполняет следующее:
- Проверьте, является ли запрос POST-запросом к
/api/uploadконечная точка. Если это так, файл извлекается из запроса и загружается в Cloudflare R2 с помощью API Workers. - Если запрос не является POST-запросом к
/api/uploadконечная точка, она возвращает ответ 404.
Поскольку код Worker написан на TypeScript, выполните следующую команду, чтобы добавить необходимые определения типов. Это не обязательно, но поможет избежать ошибок.
npm run cf-typegenВы можете перезапустить сервер разработки, чтобы проверить изменения:
npm run dev4. Создать очередь
Уведомления о событиях фиксируют изменения данных в вашем бакете R2. Вам нужно будет создать новую очередь pdf-summarize чтобы получать уведомления:
npx wrangler queues create pdf-summarizerДобавьте привязку в файл Wrangler:
{
"queues": {
"consumers": [
{
"queue": "pdf-summarizer"
}
]
}
}[[queues.consumers]]
queue = "pdf-summarizer"5. Обработка уведомлений о событиях
Теперь, когда у вас есть очередь для получения уведомлений о событиях, нужно обновить 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 для создания краткого содержания и затем добавлял его в бакет.
6. Извлечь текстовое содержимое из PDF
Чтобы извлечь текстовое содержимое из PDF, Worker будет использовать unpdf ↗ библиотека. unpdf библиотека предоставляет инструменты для работы с файлами PDF.
Установите unpdf библиотеку установите с помощью следующей команды:
npm i 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обработчик извлекает текстовое содержимое из PDF с помощьюunpdfбиблиотека. -
queueобработчик записывает в лог текстовое содержимое.
7. Использовать Workers AI для составления сводки содержимого
Чтобы использовать 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 для создания краткого содержания.
8. Добавить сводку в бакет R2
Теперь, когда у вас есть сводка, добавьте её в бакет R2. Обновите src/index.ts файл, чтобы добавить сводку в bucket 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}`);
}
}Обработчик очереди теперь добавляет сводку в бакет R2 в виде текстового файла.
9. Включить уведомления о событиях
Ваш queue обработчик готов обрабатывать входящие сообщения уведомлений о событиях. Теперь нужно включить уведомления о событиях с помощью wrangler r2 bucket notification create команда для вашего бакета. Следующая команда создает уведомление о событии для object-create тип события для pdf суффикс:
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 очередь запускается.
10. Развернуть Worker
Чтобы развернуть Worker, выполните wrangler deploy команда:
npx wrangler deployВ выводе wrangler deploy команду и скопируйте URL. Это URL вашего развёрнутого приложения.
11. Тестирование
Чтобы протестировать приложение, перейдите по URL-адресу развернутого приложения и загрузите PDF-файл. Либо вы можете использовать Панель управления Cloudflare ↗ , чтобы загрузить PDF-файл.
Чтобы просмотреть журналы, можно использовать wrangler tail команда.
npx wrangler tailЛоги появятся в вашем терминале. Их также можно посмотреть в панели управления Cloudflare, в разделе Workers Logs.
Если вы проверите свой бакет R2, то увидите файл сводки.
Заключение
В этом руководстве вы узнали, как использовать уведомления о событиях R2 для обработки объекта при загрузке. Вы создали приложение для загрузки PDF-файла и Worker-обработчик, который формирует сводку по PDF-файлу. Вы также узнали, как использовать Workers AI для создания сводки содержимого PDF-файла и загрузки этой сводки в бакет R2.
Тот же подход можно использовать для обработки других типов файлов, например изображений, видео и аудио. Он также подходит для обработки других типов событий, например удаления или обновления объекта.
Если вы хотите посмотреть код этого руководства, вы найдёте его на GitHub ↗.