Confluence ServerのREST APIを用いたページコピー

#１行概要
Confluence Serverの"Get content by id"と"Create content"APIを併用してコピーAPIを実現した。

#はじめに
[Confluence](https://www.atlassian.com/ja/software/confluence)（以下、コンフル）はAtlassian社が開発している、いわゆる企業向けウィキシステム。
私が4月から勤務している会社でもコンフルを導入しており、主に議事録や週報の作成・共有に使っている。

ふと週報を作成していて、コピー・命名作業が面倒だったので半自動化したいと思い立った。

#Confluence Server REST APIについて
コンフルのAPIはREST形式になっており、パラメータを指定して叩くとJSON形式でデータが返ってくる。
利用中のサービスによって**Server REST API**か**Clound REST API**を選択することになるが、弊社の場合は前者になる。
なお、後者の方が圧倒的に用意されているAPIメソッドが多い。（コピーAPIも用意されている。）

- [0からREST APIについて調べてみた](https://qiita.com/masato44gm/items/dffb8281536ad321fb08)
- [Confluence Server REST API Reference](https://docs.atlassian.com/ConfluenceServer/rest/7.3.5/)　←こちらを使用
- [Confluence Clound REST API Reference](https://developer.atlassian.com/cloud/confluence/rest/)

#実装
###1. 前準備
まず、ページのコピーと自動命名を行うスクリプトを格納するページを新規に作成する。
コピーをしたいページ、コピーを置きたいページとは異なるので注意。
新規ページ作成後「HTML」マクロを埋め込む。
<img width="232" alt="html.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/488859/8956f0b8-d050-2bf1-e4f8-e3ee53a85cde.png">

###2. 処理の記述
次のスクリプトを記述する。

大まかな処理の流れは次の通り。
① Ajaxで**[Get content by id](https://docs.atlassian.com/ConfluenceServer/rest/7.3.5/#api/content-getContentById)**APIを叩く
② コピー元のページBody情報を取得
③ Ajaxをネストし**[Create content](https://docs.atlassian.com/ConfluenceServer/rest/7.3.5/#api/content-createContent)**APIを叩く
④ コピー元のページBodyをコピー先のページBodyに代入
⑤ おわり

今回はコピー先のページタイトルに、コピー日の日付（yyyymmdd形式）を指定している

```html

<script type="text/javascript">
$(() => {
  $("#btn").click(() => {
    /**
     * コピー元のページID、コピー先のページID、スペースキーの指定
     */
    const SRC_PAGE_ID = "【コピー元のページID】";
    const DST_PAGE_ID = "【コピー先のページID】";
    const SPACE_KEY = "【スペースキー】";

    /**
     * ページタイトルの指定
     */
    const today = new Date();
    const pageTitle = 
      today.getFullYear()
      + ("0"+ (today.getMonth() +1)).slice(-2) 
      + ("0"+ today.getDate()).slice(-2);

    /** 
     * 通信用ヘッダー
     */
    const headers = {
      "Accept": "application/json",
      "content-type": "application/json"
    };

    /**
     * ①② コピー元の情報取得
     */
    $.ajax({
      type: "get",
      url: "https://【ドメイン名】/rest/api/content/" + SRC_PAGE_ID + "?expand=body.view",
      headers: headers,
    })
    .done((result) => {
      console.log(result);
      const srcPageBody = result.body.view.value;
      /**
       * ③④ コピー先の作成
       */
      $.ajax({
        type: "post",
        url: "https://【ドメイン名】/rest/api/content",
        headers: headers,
        data: JSON.stringify({
          "type": "page",
          "ancestors": [{
            "id": DST_PAGE_ID
          }],
          "title": pageTitle,
          "space": {
            "key": SPACE_KEY
          },
          "body": {
            "storage": {
              "value": srcPageBody,
              "representation": "storage"
            }
          }
        }),
        success: () => {
          alert("Done");
        },
        error: () => {
          alert("Error:コピー先の作成に失敗しました。");
        }
      });
    })
    .fail(() => {
      alert("Error:コピー元の取得に失敗しました");
    });			
  })
})
</script>
<button id="btn">ページコピー</button>
```

###3. パラメータの説明
- **SRC_PAGE_ID**、**DST_PAGE_ID**：コピー元、コピー先のページID
- **SPACE_KEY**：各スペースの一意IDで「スペース>スペース ディレクトリ」から確認可能

>ページIDは、ページURL
>https://【ドメイン名】/pages/viewpage.action?pageid=
>の末尾9桁の数字

###4. 挙動
まずページ上には、`<button id="btn">ページコピー</button>`で記述したボタンが配置されており、ボタンを押下するとスクリプトが動く。
コピー元ページの取得とコピー先ページの作成に成功すると、alertメッセージ「Done」と表示される。
![done.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/488859/ac1f0570-ff64-832a-2b4c-0191ba839c1f.png)

ページをリフレッシュすると、元のページツリーから
<img width="109" alt="copymae.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/488859/e3a907c7-e8fc-e94f-6531-161b6ce35309.png">
指定したコピー先に新規ページが作成されている。
<img width="117" alt="copyato.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/488859/e1939c2d-bcf8-3019-1c91-cf26549db205.png">
ここでは、SRC_PAGE_IDに「テストタイトルです」、DST_PAGE_IDに「02_COPY」というタイトルのペーのIDを指定しており、
*DST_PAGE_IDが親で、コピー日の日付をタイトルにした、SRC_PAGE_IDの中身のページ*を作成することができた。

###5. 確認
[Get content by id](https://docs.atlassian.com/ConfluenceServer/rest/7.3.5/#api/content-getContentById)で取得した中身を、`console.log(result)`から開発者メニューで確認することができる。
![object.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/488859/bf50f9e9-af0f-a2f5-cc73-0a98dc3b17c8.png)

#おわりに
Confluence ServerのREST APIを利用したコピーメソッドを実現した。
同様に、MoveやCommentといった*Cloud APIにはあって、Server APIにはないメソッド*がまだ多数ある。それらも実現できたらいいね（遠い目）。