# 如何整合

### **OxOffice Online 主機**

儘管可以和 Web 伺服器安裝在同一臺主機，不過，我們建議將 OxOffice Online 安裝在專用的 VM 或伺服器。這部伺服器（WOPI 客戶端），必須能讓外部網際網路連線，而且還要能夠連線到您的 WOPI 伺服器（您的雲端應用系統）。

### **開出編輯 iframe 頁面的網站**

我們假設您希望將編輯功能整合到現有網站中。 因此，在網站上，您需要提供一個 iframe，其中將顯示OxOffice Online 的編輯介面和文件本身。

要設定 iframe，WOPI 主機（您的雲端應用系統）需要從 WOPI 客戶端（OxOffice Online 伺服器）上定義的位置讀取 discovery XML。 位址如下：

<table border="1" id="bkmrk-https%3A%2F%2F%3Cwopi-%E5%AE%A2%E6%88%B6%E7%AB%AF-ur" style="border-collapse: collapse; width: 100%;"><colgroup><col style="width: 99.8765%;"></col></colgroup><tbody><tr><td>https://&lt;WOPI 客戶端 URL&gt;:&lt;port&gt;/hosting/discovery</td></tr></tbody></table>

這會得到 discovery.xml，其中包含各種文件格式的 **urlsrc**。 **urlsrc** 為編輯文件用的 iframe 需要使用的位址。

接著您需要為欲編輯的檔案，提供一個名為 **WOPISrc** 的位址，**WOPISrc** 網址看起來如下：

<table border="1" id="bkmrk-https%3A%2F%2F%3Cwopi-%E4%B8%BB%E6%A9%9F-url" style="border-collapse: collapse; width: 100%;"><colgroup><col style="width: 100%;"></col></colgroup><tbody><tr><td>https://&lt;WOPI 主機 URL&gt;/&lt;...&gt;/wopi/files/&lt;file id&gt;</td></tr></tbody></table>

這裡的 `/wopi/` 實際上可以是任何以 `wopi` 開頭的字串，像是 `/wopifiles/` 或 `/wopi_implementation/` 都可以，但為了簡單起見，我們之後只會使用 `/wopi/`。

`<file id>` 必須以 base64 編碼，也就是說只能有英文 `A-Z` 或 `a-z`、數字 `0-9` 以及 `-` 和 `_` 符號。

### **使用者驗證**

為了能夠安全地存取文件，您的應用程式必須將身份驗證用的 token 傳遞給 OxOffice Online 的 access\_token。對 OxOffice Online 而言，token 可以是任何隨機的數字或字串，它會在存取文件過程中（WOPI 客戶端對 WOPI 主機）當作 URL 的一部份傳遞。

唯一的要求是，對於識別使用者而言，token 必須是唯一的，不能和其他使用者重複，意即，若 WOPI 客戶端對 **WOPISrc** 所指定的 URL 進行存取時時，您必須檢查所傳遞的 token 是否與當初建立 iframe 所傳遞的 token 相符，否則您的應用程序應該拒絕錯誤的 token 存取檔案

目前這是唯一支援的身份驗證方式。

### **連接雲端硬碟**

作為 WOPI 主機，您的應用程式必須為 OxOffice Online （WOPI 客戶端）實作幾個進入點，以便 OxOffice Online 下載使用者想要編輯的檔案，以及傳回更新檔案。

WOPI 客戶端（OxOffice Online）會呼叫上面所建立的 **WOPISrc** 來下載檔案：

```
GET https://<WOPI 主機 URL>/<...>/wopi/files/<file id>/contents?access_token=<token>
```

以及傳回更新檔案：

```none
POST https://<WOPI 主機 URL>/<...>/wopi/files/<file id>/contents?access_token=<token>
```

目前，OxOffice Online 使用 4 個 WOPI 的檔案操作，分別是：**CheckFileInfo**、**GetFile**、**PutFile** 以及 **PutRelativeFile**。

您的應用程式，必須產生參照檔案及使用者的唯一 token，該 token 可以為固定或過期，只要檔案編輯期間，可供辨識即可。該 token 會透過 URL 的 access\_token=&lt;token&gt; 傳遞，您的應用程式也可以在接收的 HTTP header 中，取得 OxOffice Online 傳遞的 token。

```
Authorization: Bearer <token>
```

並且需支援下列 4 個功能：

1. #### **CheckFileInfo**：以下 URL 被呼叫時，至少要以 JSON 格式，傳回 BaseFileName 和 Size。
    
    ```
    GET https://<WOPI 主機 URL>/<...>/wopi/files/<file id>?access_token=<token>
    ```
    
    ##### **OxOffice Online 可用的 CheckFileInfo 屬性列表：**  
    
    
    <table border="1" style="border-collapse: collapse; width: 102.011%; height: 714.469px;"><colgroup><col style="width: 23.8926%;"></col><col style="width: 14.6309%;"></col><col style="width: 9.93289%;"></col><col style="width: 51.5436%;"></col></colgroup><tbody><tr style="height: 57.7812px;"><td class="align-center" style="height: 57.7812px;">屬性</td><td style="height: 57.7812px;">型別
    
    （Data type）
    
    </td><td style="height: 57.7812px;">必要
    
    Required
    
    </td><td style="height: 57.7812px;">說明</td></tr><tr style="height: 29.7969px;"><td style="height: 29.7969px;">BaseFileName</td><td style="height: 29.7969px;">string</td><td style="height: 29.7969px;"><span style="color: rgb(224, 62, 45);">yes</span></td><td style="height: 29.7969px;">不含路徑的檔案名稱，用來顯示在使用者的編輯畫面。</td></tr><tr style="height: 29.7969px;"><td style="height: 29.7969px;">OwnerId</td><td style="height: 29.7969px;">string</td><td style="height: 29.7969px;"><span style="color: rgb(224, 62, 45);">yes</span></td><td style="height: 29.7969px;">識別該檔案擁有者的唯一 ID</td></tr><tr style="height: 29.7969px;"><td style="height: 29.7969px;">Size</td><td style="height: 29.7969px;">number (int64)</td><td style="height: 29.7969px;"><span style="color: rgb(224, 62, 45);">yes</span></td><td style="height: 29.7969px;">以 bytes 為單位的檔案大小，64 位元長整數。</td></tr><tr style="height: 29.7969px;"><td style="height: 29.7969px;">UserId</td><td style="height: 29.7969px;">string</td><td style="height: 29.7969px;"><span style="color: rgb(224, 62, 45);">yes</span></td><td style="height: 29.7969px;">存取該檔案的使用者 ID。</td></tr><tr style="height: 29.7969px;"><td style="height: 29.7969px;">UserFriendlyName </td><td style="height: 29.7969px;">string</td><td style="height: 29.7969px;">no</td><td style="height: 29.7969px;">使用者名稱，用來顯示在使用者的編輯畫面。</td></tr><tr style="height: 29.7969px;"><td style="height: 29.7969px;">UserCanWrite</td><td style="height: 29.7969px;">boolean</td><td style="height: 29.7969px;">no</td><td style="height: 29.7969px;">如果要能夠編輯，必須設為 true，預設為 false。</td></tr><tr><td>UserCanNotWriteRelative</td><td>boolean</td><td>no</td><td>禁止使用者重新命名或另存新檔。預設 true。</td></tr><tr style="height: 68.9844px;"><td style="height: 68.9844px;">PostMessageOrigin</td><td style="height: 68.9844px;">string</td><td style="height: 68.9844px;">no</td><td style="height: 68.9844px;">這是告訴 OxOffice Online。 [<span class="doc">PostMessage API</span>](https://docs.ossii.com.tw/books/oxoffice-online-8LU/page/postmessage-api) 的 WOPI 主機位址。若未指定，將無法接收 OxOffice Online 傳來的狀態。</td></tr><tr style="height: 68.9844px;"><td style="height: 68.9844px;">HidePrintOption</td><td style="height: 68.9844px;">boolean</td><td style="height: 68.9844px;">no</td><td style="height: 68.9844px;">隱藏 OxOffice Online 的列印按鈕。但可透過 [<span class="doc">PostMessage API</span>](https://docs.ossii.com.tw/books/oxoffice-online-8LU/page/postmessage-api) 來實作 WOPI 主機自己的列印 UI。</td></tr><tr style="height: 29.7969px;"><td style="height: 29.7969px;">DisablePrint</td><td style="height: 29.7969px;">boolean</td><td style="height: 29.7969px;">no</td><td style="height: 29.7969px;">禁止列印文件。此外，也會在 UI 中隱藏列印選項。</td></tr><tr style="height: 52.9844px;"><td style="height: 52.9844px;">HideSaveOption</td><td style="height: 52.9844px;">boolean</td><td style="height: 52.9844px;">no</td><td style="height: 52.9844px;">隱藏 OxOffice Online 的存檔按鈕。但仍可透過 [<span class="doc">PostMessage API</span>](https://docs.ossii.com.tw/books/oxoffice-online-8LU/page/postmessage-api) 觸發，這並不會影響自動存檔功能。</td></tr><tr style="height: 57.7812px;"><td style="height: 57.7812px;">HideExportOption</td><td style="height: 57.7812px;">boolean</td><td style="height: 57.7812px;">no</td><td style="height: 57.7812px;">隱藏 OxOffice Online「下載為…」 按鈕及選項，但仍可透過 [<span class="doc">PostMessage API</span>](https://docs.ossii.com.tw/books/oxoffice-online-8LU/page/postmessage-api) 觸發。
    
    </td></tr><tr><td>DisableInactiveMessages</td><td>boolean</td><td>no</td><td>當停止編輯文件一段時間後，預設會在文件編輯區顯示提示文字。若禁用此功能，您監聽的 JavaScript，就必須在取得 Session\_Closed 或 User\_Idle 的 [<span class="doc">PostMessage API</span>](https://docs.ossii.com.tw/books/oxoffice-online-8LU/page/postmessage-api) 時，自行向使用者提供適當的訊息。
    
    </td></tr><tr style="height: 29.7969px;"><td style="height: 29.7969px;">DisableExport</td><td style="height: 29.7969px;">boolean</td><td style="height: 29.7969px;">no</td><td style="height: 29.7969px;">禁止匯出或下載文件。此外，也會在 UI 中隱藏下載選項。</td></tr><tr style="height: 46.5938px;"><td style="height: 46.5938px;">DisableCopy</td><td style="height: 46.5938px;">boolean</td><td style="height: 46.5938px;">no</td><td style="height: 46.5938px;">禁止複製內容到剪貼簿，但文件內部仍然可以複製以及貼上外部資料。</td></tr><tr><td>DownloadAsPostMessage</td><td>boolean</td><td>no</td><td>WOPI 主機自行接管下載任務，例如使用者觸發列印、權螢幕投影簡報以及其他檔案下載功能時，將觸發名為 Download\_As 的 [<span class="doc">PostMessage API</span>](https://docs.ossii.com.tw/books/oxoffice-online-8LU/page/postmessage-api)，傳送的值中，包含以下 JSON：
    
    ```json
    {
    	Type: 'print'|'slideshow'|'export',
    	URL: '...實際下載的 URL...'
    }
    ```
    
    </td></tr><tr style="height: 46.5938px;"><td style="height: 46.5938px;">EnableOwnerTermination</td><td style="height: 46.5938px;">boolean</td><td style="height: 46.5938px;">no</td><td style="height: 46.5938px;">授予檔案擁有者可以終止其他共編者編輯的權利，意即可在共編時，將其他共編者踢出共編行列。</td></tr><tr style="height: 46.5938px;"><td style="height: 46.5938px;">LastModifiedTime</td><td style="height: 46.5938px;">string</td><td style="height: 46.5938px;">no</td><td style="height: 46.5938px;">檔案最後修改時間。使用 ISO8601 格式表示之 UTC 日期時間（YYYY-MM-DDThh:mm:ss.nnnnZ）。</td></tr><tr style="height: 29.7969px;"><td style="height: 29.7969px;">UserExtraInfo</td><td style="height: 29.7969px;">object</td><td style="height: 29.7969px;">no</td><td style="height: 29.7969px;">使用者延伸資訊。請參考：[**UserExtraInfo Details**](https://docs.ossii.com.tw/books/oxoffice-online-8LU/page/8efb1#bkmrk-userextrainfo-detail-0)。</td></tr></tbody></table>
    
    ##### **UserExtraInfo Details**：
    
    <table border="1" style="border-collapse: collapse; width: 100%; height: 469.516px;"><colgroup><col style="width: 23.8926%;"></col><col style="width: 14.6309%;"></col><col style="width: 9.93397%;"></col><col style="width: 51.5425%;"></col></colgroup><tbody><tr style="height: 57.7812px;"><td class="align-center" style="height: 57.7812px;">屬性</td><td style="height: 57.7812px;">型別
    
    （Data type）
    
    </td><td style="height: 57.7812px;">必要
    
    Required
    
    </td><td style="height: 57.7812px;">說明</td></tr><tr><td>avatar</td><td>string
    
    </td><td>no
    
    </td><td>使用者頭像位址。</td></tr><tr><td>mail</td><td>string
    
    </td><td>no
    
    </td><td>使用者的電子郵件位址。</td></tr><tr><td>ip</td><td>string
    
    </td><td>no
    
    </td><td>使用者的 IP 位址。由於 OxOffice Online 可能透過 reverse proxy 轉址，所以自行抓取的 IP 可能不正確，此種狀況下，需透過您的應用程式，將使用者 IP 置於此屬性。</td></tr><tr><td>watermark</td><td>object
    
    </td><td>no
    
    </td><td>自訂編輯浮水印。請參考[ **Watermark Details**](https://docs.ossii.com.tw/books/oxoffice-online-8LU/page/8efb1#bkmrk-watermark-details%EF%BC%9A)。</td></tr></tbody></table>
    
    ##### **Watermark Details**：
    
    <table border="1" style="border-collapse: collapse; width: 100%; height: 469.516px;"><colgroup><col style="width: 23.8926%;"></col><col style="width: 14.6309%;"></col><col style="width: 9.93397%;"></col><col style="width: 51.5425%;"></col></colgroup><tbody><tr style="height: 57.7812px;"><td class="align-center" style="height: 57.7812px;">屬性</td><td style="height: 57.7812px;">型別
    
    （Data type）
    
    </td><td style="height: 57.7812px;">必要
    
    Required
    
    </td><td style="height: 57.7812px;">說明</td></tr><tr style="height: 29.7969px;"><td style="height: 29.7969px;">editing</td><td style="height: 29.7969px;">boolean</td><td style="height: 29.7969px;">no</td><td style="height: 29.7969px;">編輯時啟用，預設為 false。</td></tr><tr><td>printing</td><td>boolean</td><td>no</td><td>列印時啟用，預設為 false。</td></tr><tr><td>opacity</td><td>number(double)</td><td>no</td><td>不透明度。範圍 0.01-1.00預設為 0.20。此值愈小愈透明。</td></tr><tr><td>familyname</td><td>string</td><td>no</td><td>字型名稱。</td></tr><tr><td>angle</td><td>number(int)</td><td>no</td><td>旋轉角度。範圍 0-360，預設為 45°</td></tr><tr><td>color</td><td>string</td><td>no</td><td>CSS #rrggbb 表示之顏色。預設 #000000
    
    </td></tr><tr><td>bold</td><td>boolean</td><td>no</td><td>粗體。預設為 false。
    
    </td></tr><tr><td>italic</td><td>boolean</td><td>no</td><td>斜體。預設為 false。
    
    </td></tr><tr><td>outline</td><td>boolean</td><td>no</td><td>空心字。預設為 false。
    
    </td></tr><tr><td>shadow</td><td>boolean</td><td>no</td><td>陰影字。預設為 false。
    
    </td></tr><tr><td>text</td><td>string</td><td>no</td><td>浮水印文字，若需多行，各行需以 \\n 分隔。
    
    </td></tr></tbody></table>
2. #### **GetFile**：取得欲編輯的檔案**。**該 URL 被呼叫時，您的應用程式必須回傳檔案，給WOPI 客戶端（OxOffice Online）。
    
    ```
    GET https://<WOPI 主機 URL>/<...>/wopi/files/<id>/contents?access_token=<token>
    ```
3. #### ******PutFile******：更新正在編輯的檔案**。**該 URL 被呼叫時，您的應用程式必須接收 WOPI 客戶端（OxOffice Online）傳來的檔案。
    
    ```
    POST https://<WOPI host URL>/<...>/wopi/files/<id>/contents?access_token=<token>
    ```
    
    WOPI 主機必須檢查 OxOffice Online 傳來的標頭 – `X-WOPI-Override` 是否為英文大寫 **PUT**。
    
    再檢查 – `X-LOOL-WOPI-Timestamp`，這個標頭含有 ISO8601 格式的最近修改時間，您的應用程式需檢查該時間是否與雲端硬碟的最近修改時間一致，若不符合，則 WOPI 主機不應將之儲存到雲端硬碟，須回應給 OxOffice Oline 一個 HTTP 409 的狀態碼，以及一個 OxOffice Online 特定狀態碼：
    
    ```json
    {
    	'ＬOOLStatusCode': 1010
    }
    ```
    
    若時間相符，且應用程式成功儲存更新的檔案後，需回應 JSON 內容，格式同 [**CheckFileInfo**](https://docs.ossii.com.tw/books/oxoffice-online-8LU/page/8efb1#bkmrk-oxoffice-online-%E5%8F%AF%E7%94%A8%E7%9A%84-) 的 LastModifiedTime，以便讓 OxOffice Online 與雲端硬碟之間，保持檔案時間同步：
    
    ```json
    {
      "LastModifiedTime": "YYYY-MM-DDThh:mm:ss.nnnnZ"
    }
    ```
    
    <p class="callout info">此外，**PutFile** 時，OxOffice Online 另外會帶入以下幾個標頭：  
    `X-LOOL-WOPI-IsModifiedByUser` – 使用者是否在存檔之前修改了文件（true），或者他們只是按了存檔（false）卻沒有進行任何修改。  
    `X-LOOL-WOPI-IsAutosave` – 自動存檔（true）或使用者按了「存檔」（false）按鈕。  
    `X-LOOL-WOPI-IsExitSave` – 當所有編輯者（共編狀態）都結束編輯，或離線時，將觸發自動存檔，並且該標頭會被設成 true。  
    </p>
4. #### ****PutRelativeFile：另存新檔或更改檔名。****該 URL 被呼叫時，您的應用程式必須接收 WOPI 客戶端（OxOffice Online）傳來的檔案。  
    
    
    ```
    POST https://<WOPI host URL>/<...>/wopi/files/<id>?access_token=<token>
    ```
    
    WOPI 主機必須檢查 OxOffice Online 傳來的標頭 – `X-WOPI-Override` 是否為英文大寫 **PUT\_RELATIVE**。
    
    如果您的應用程式不想讓使用者另存新檔或重新命名的話，請將 [**CheckFileInfo**](https://docs.ossii.com.tw/books/oxoffice-online-8LU/page/8efb1#bkmrk-oxoffice-online-%E5%8F%AF%E7%94%A8%E7%9A%84-) 中的 UserCanNotWriteRelative 設成 true。  
    否則執行此功能時，OxOffice Online 會帶以下標頭：  
    `X-WOPI-SuggestedTarget` – UTF-7 編碼的新檔名。