# Presigned 檔案上傳模式

目前在 MaiAgent 上需要上傳檔案的地方有兩處

1. 知識庫文件上傳
2. 訊息用到的附件上傳

## Presigned 上傳模式

MaiAgent 支援 **Presigned 上傳模式**，此模式允許客戶端直接將檔案上傳至雲端儲存（如 S3），而不需經過伺服器中繼。使用此模式時，伺服器僅負責生成具有時效性與安全性的 Presigned URL，客戶端利用該 URL 直接進行檔案上傳。

#### 與傳統上傳模式的差異：

1. **資料流向**
   * 傳統模式：檔案須經過伺服器，再由伺服器上傳到雲端儲存。
   * Presigned 模式：檔案由客戶端直接上傳至雲端，避免伺服器處理檔案的負擔。
2. **效能與成本**
   * 傳統模式可能導致伺服器資源消耗過大，並增加資料傳輸成本。
   * Presigned 模式減少伺服器負載，提高效能並降低傳輸成本。
3. **安全性**
   * Presigned URL 包含簽名與有效期，確保上傳請求僅限於授權用戶在指定時間內使用。

此模式特別適合大檔案或高頻率上傳的場景，提升效率的同時保持高度的安全性。

#### 預簽上傳流程圖

```mermaid
sequenceDiagram
    participant Client as Client
    participant Server as Sever
    participant S3 as Storage(S3)

    Note over Client,S3: 預簽上傳流程
    
    Client->>+Server: 1. 請求預簽 URL
    Note right of Client: POST /api/v1/presigned<br/>包含檔名、類型、大小
    
    Server->>Server: 2. 驗證請求參數
    Server->>Server: 3. 產生預簽參數
    Note right of Server: 設定有效期、權限等
    Server-->>-Client: 4. 回傳預簽 URL 和參數
    
    Client->>+S3: 5. 使用預簽 URL 直接上傳
    Note right of Client: POST 到預簽 URL<br/>可監控上傳進度
    S3-->>-Client: 6. 上傳完成回應
    
    opt 上傳完成通知
        Client->>+Server: 7. 通知上傳完成
        Note right of Client: POST /api/v1/upload/complete
        Server->>Server: 8. 更新資料庫記錄
        Server-->>-Client: 9. 確認回應
    end
```

#### 傳統上傳流程圖

```mermaid
sequenceDiagram
    participant Client as Client
    participant Server as Server
    participant S3 as Storage(S3)

    Note over Client,S3: 傳統上傳流程
    
    Client->>+Server: 1. 上傳檔案請求
    Note right of Client: POST /api/v1/upload<br/>檔案內容包含在請求中
    
    Server->>Server: 2. 驗證檔案<br/>(大小、類型、格式)
    Server->>Server: 3. 儲存暫存檔
    
    Server->>+S3: 4. 上傳檔案至 S3
    Note right of Server: 使用 AWS SDK<br/>上傳暫存檔
    S3-->>-Server: 5. 上傳成功回應
    
    Server->>Server: 6. 清理暫存檔
    Server-->>-Client: 7. 回傳上傳結果
    Note left of Server: 回傳 S3 檔案位置
```

***

#### Presigned 上傳檔案

以下描述如何使用 MaiAgent 提供的 API 完成檔案的 Presigned 上傳過程。

#### 1. **取得 Presigned URL**

**Endpoint**

`POST https://api.maiagent.ai/api/v1/upload-presigned-url/`

**說明**

客戶端向伺服器發送請求，取得一個 Presigned URL，該 URL 用於直接上傳檔案至雲端儲存。

**請求參數**

| 參數名稱        | 型別        | 必填 | 說明                                                                                                     |
| ----------- | --------- | -- | ------------------------------------------------------------------------------------------------------ |
| `filename`  | `string`  | 是  | 上傳檔案的名稱                                                                                                |
| `modelName` | `string`  | 是  | <p>模組名稱，用於分類上傳的檔案用途<br></p><p>知識庫請填寫<code>chatbot-file</code></p><p>訊息附件請填寫<code>attachment</code></p> |
| `fieldName` | `string`  | 是  | 檔案字段名稱，用於標識檔案用途                                                                                        |
| `fileSize`  | `integer` | 是  | 檔案大小（以位元組為單位）                                                                                          |

**範例請求**

```bash
curl --location 'https://api.maiagent.ai/api/v1/upload-presigned-url/' \
--header 'Authorization: Api-Key ' \
--header 'Content-Type: application/json' \
--data '{
    "filename": "Products_example.xlsx",
    "modelName": "chatbot-file",
    "fieldName": "file",
    "fileSize": 5881
}'
```

**回應範例**

```json
{
    "url": "https://s3.ap-northeast-1.amazonaws.com/whizchat-media-prod-django.playma.app",
    "fields": {
        "key": "media/chatbots/chatbot-file/d83c88aa-3874-49a6-b01e-1948ae48b747.xlsx",
        "x-amz-algorithm": "AWS4-HMAC-SHA256",
        "x-amz-credential": "AKIATIVCN4X5JXWAP43M/20241129/ap-northeast-1/s3/aws4_request",
        "x-amz-date": "20241129T012318Z",
        "policy": "eyJleHBpcmF0aW9uIjogIjIwMjQtMTEtMjlUMDI6MjM6MThaIiwgImNvbmRpdGlvbnMiOiBbWyJjb250ZW50LWxlbmd0aC1yYW5nZSIsIDAsIDEwNDg1NzYwMF0sIHsiYnVja2V0IjogIndoaXpjaGF0LW1lZGlhLXByb2QtZGphbmdvLnBsYXltYS5hcHAifSwgeyJrZXkiOiAibWVkaWEvY2hhdGJvdHMvY2hhdGJvdC1maWxlL2Q4M2M4OGFhLTM4NzQtNDlhNi1iMDFlLTE5NDhhZTQ4Yjc0Ny54bHN4In0sIHsieC1hbXotYWxnb3JpdGhtIjogIkFXUzQtSE1BQy1TSEEyNTYifSwgeyJ4LWFtei1jcmVkZW50aWFsIjogIkFLSUFUSVZDTjRYNUpYV0FQNDNNLzIwMjQxMTI5L2FwLW5vcnRoZWFzdC0xL3MzL2F3czRfcmVxdWVzdCJ9LCB7IngtYW16LWRhdGUiOiAiMjAyNDExMjlUMDEyMzE4WiJ9XX0=",
        "x-amz-signature": "0254b3baa65c3a69eaeeccd0a3d027bc7952c1587cc96437c096eb1b76e1d692"
    }
}
```

***

#### 2. **上傳檔案至雲端儲存**

**說明**

使用從上述步驟取得的 `url` 和 `fields`，直接將檔案上傳至雲端儲存。

**範例請求**

```bash
curl --location 'https://s3.ap-northeast-1.amazonaws.com/whizchat-media-prod-django.playma.app' \
--form 'key="media/chatbots/chatbot-file/d83c88aa-3874-49a6-b01e-1948ae48b747.xlsx"' \
--form 'x-amz-algorithm="AWS4-HMAC-SHA256"' \
--form 'x-amz-credential="AKIATIVCN4X5JXWAP43M/20241129/ap-northeast-1/s3/aws4_request"' \
--form 'x-amz-date="20241129T012318Z"' \
--form 'policy="eyJleHBpcmF0aW9uIjogIjIwMjQtMTEtMjlUMDI6MjM6MThaIiwgImNvbmRpdGlvbnMiOiBbWyJjb250ZW50LWxlbmd0aC1yYW5nZSIsIDAsIDEwNDg1NzYwMF0sIHsiYnVja2V0IjogIndoaXpjaGF0LW1lZGlhLXByb2QtZGphbmdvLnBsYXltYS5hcHAifSwgeyJrZXkiOiAibWVkaWEvY2hhdGJvdHMvY2hhdGJvdC1maWxlL2Q4M2M4OGFhLTM4NzQtNDlhNi1iMDFlLTE5NDhhZTQ4Yjc0Ny54bHN4In0sIHsieC1hbXotYWxnb3JpdGhtIjogIkFXUzQtSE1BQy1TSEEyNTYifSwgeyJ4LWFtei1jcmVkZW50aWFsIjogIkFLSUFUSVZDTjRYNUpYV0FQNDNNLzIwMjQxMTI5L2FwLW5vcnRoZWFzdC0xL3MzL2F3czRfcmVxdWVzdCJ9LCB7IngtYW16LWRhdGUiOiAiMjAyNDExMjlUMDEyMzE4WiJ9XX0="' \
--form 'x-amz-signature="0254b3baa65c3a69eaeeccd0a3d027bc7952c1587cc96437c096eb1b76e1d692"' \
--form 'file=@"/Users/maiagent/Downloads/Products_example.png"'

```

***


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.maiagent.ai/tech/api-integration/api_knowledge.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
