# Hiển thị tiện ích mở rộng API trên Internet công cộng bằng cách sử dụng Cloudflare Workers

## Bắt đầu

Vì Phần Mở Rộng API của ChatX yêu cầu một địa chỉ internet công khai làm Điểm Cuối API, chúng ta cần triển khai phần mở rộng API của mình đến một địa chỉ internet công khai. Ở đây, chúng tôi sử dụng Cloudflare Workers để triển khai phần mở rộng API của chúng tôi.

Chúng ta sao chép [Repository GitHub Mẫu](https://github.com/crazywoola/dify-extension-workers), chứa một phần mở rộng API đơn giản. Chúng ta có thể sửa đổi điều này như là một cơ sở.

```
git clone https://github.com/crazywoola/dify-extension-workers.git
cp wrangler.toml.example wrangler.toml
```

Mở tệp `wrangler.toml` và sửa `tên` và `compatibility_date` thành tên ứng dụng của bạn và ngày tương thích của bạn.

Một cấu hình quan trọng ở đây là `TOKEN` trong `vars`, mà bạn sẽ cần cung cấp khi thêm phần mở rộng API vào ChatX. Vì lý do bảo mật, nên sử dụng một chuỗi ngẫu nhiên làm Token. Bạn không nên viết Token trực tiếp trong mã nguồn mà phải chuyển qua biến môi trường. Do đó, đừng commit wrangler.toml của bạn vào kho lưu trữ mã nguồn của bạn.

```
name = "dify-extension-example"
compatibility_date = "2023-01-01"

[vars]
TOKEN = "bananaiscool"
```

Phần mở rộng API này trả về một câu trích dẫn ngẫu nhiên từ Breaking Bad. Bạn có thể sửa đổi logic của phần mở rộng API này trong `src/index.ts`. Ví dụ này cho thấy cách tương tác với một API bên thứ ba.

```
// ⬇️ implement your logic here ⬇️
// point === "app.external_data_tool.query"
// https://api.breakingbadquotes.xyz/v1/quotes
const count = params?.inputs?.count ?? 1;
const url = `https://api.breakingbadquotes.xyz/v1/quotes/${count}`;
const result = await fetch(url).then(res => res.text())
// ⬆️ implement your logic here ⬆️
```

Repository này đơn giản hóa tất cả các cấu hình ngoại trừ logic kinh doanh. Bạn có thể trực tiếp sử dụng các lệnh `npm` để triển khai phần mở rộng API của bạn.

```
npm run deploy
```

Sau khi triển khai thành công, bạn sẽ nhận được một địa chỉ internet công khai, mà bạn có thể thêm vào ChatX làm `Điểm Cuối` API. Vui lòng lưu ý không bỏ lỡ đường dẫn điểm cuối.

<figure><img src="https://docs.dify.ai/~gitbook/image?url=https%3A%2F%2F3866086014-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FRncMhlfeYTrpujwzDIqw%252Fuploads%252Fgit-blob-f030cb5e11eb589b89f1e95e67ae73b24be10d9d%252Fapi_extension_edit.png%3Falt%3Dmedia&#x26;width=768&#x26;dpr=4&#x26;quality=100&#x26;sign=2b4eff4c84275ab03b2743c81671def8059b5b4c6adad4c14106adcd6ee49d6f" alt=""><figcaption><p>Thêm Điểm Cuối API vào ChatX</p></figcaption></figure>

<figure><img src="https://content.gitbook.com/content/SK9x6AT8FGi77omZphkL/blobs/X49gLZiaUcP9tLVUxMS5/Capture.JPG" alt=""><figcaption><p>Thêm Công Cụ API trong trang chỉnh sửa Ứng dụng</p></figcaption></figure>

## Những Logic Khác TL;DR

### Về Bearer Auth

```
import { bearerAuth } from "hono/bearer-auth";

(c, next) => {
    const auth = bearerAuth({ token: c.env.TOKEN });
    return auth(c, next);
},
```

Logic xác thực Bearer của chúng tôi được hiển thị như trên. Chúng tôi sử dụng gói `hono/bearer-auth` cho xác thực Bearer. Bạn có thể sử dụng `c.env.TOKEN` trong `src/index.ts` để lấy Token.

### Về Xác Thực Tham Số

```
import { z } from "zod";
import { zValidator } from "@hono/zod-validator";

const schema = z.object({
  point: z.union([
    z.literal("ping"),
    z.literal("app.external_data_tool.query"),
  ]), // Restricts 'point' to two specific values
  params: z
    .object({
      app_id: z.string().optional(),
      tool_variable: z.string().optional(),
      inputs: z.record(z.any()).optional(),
      query: z.any().optional(),  // string or null
    })
    .optional(),
});
```

Chúng tôi sử dụng `zod` để định nghĩa các loại tham số. Bạn có thể sử dụng `zValidator` trong `src/index.ts` để kiểm tra tham số. Lấy các tham số được xác thực qua `const { point, params } = c.req.valid("json");`. Điểm của chúng tôi chỉ có hai giá trị, vì vậy chúng tôi sử dụng `z.union` cho định nghĩa. `params` là một tham số tùy chọn, được định nghĩa với `z.optional`. Nó bao gồm một tham số `inputs`, một loại `Record<string, any>` đại diện cho một đối tượng với khóa chuỗi và giá trị bất kỳ. Loại này có thể đại diện cho bất kỳ đối tượng nào. Bạn có thể lấy tham số `count` trong `src/index.ts` bằng cách sử dụng `params?.inputs?.count.`

### Truy Cập Nhật ký của Cloudflare Workers

```
wrangler tail
```

## Nội Dung Tham Khảo

* [Cloudflare Workers](https://workers.cloudflare.com/)
* [Cloudflare Workers CLI](https://developers.cloudflare.com/workers/cli-wrangler/install-update)
* [Example GitHub Repository](https://github.com/crazywoola/dify-extension-workers)
