GROWI でAPIを使ってみる

概要

GROWI はAPIを利用して操作することが可能です。
今回は、APIをいくつか試してみようと思います。

GROWI のAPI

GROWI のAPIドキュメントを参照すると、 ExportHealthcheck に関するAPIしか記載がありません。
GROWI REST API v3 | GROWI Docs

ドキュメントにはまとまっていませんが、下記にその他の豊富なAPIが定義されています。
https://github.com/weseek/growi/blob/1ad5b697c857db760f293dbb10e3b0e9b09ea93d/src/server/routes/index.js

API Tokenの生成

APIを利用するには、まず API Token の生成が必要です。

右上 ユーザー名 > ユーザー設定 を開きます。
API設定」タブを開きます。
f:id:Aqutam:20190921173149p:plain

API Tokenを更新」ボタンをクリックします。
f:id:Aqutam:20190921195038p:plain

APIを呼ぶ前に

1. コマンドのインストール

macのターミナルでAPIの呼び出しを試します。
その際、 jq コマンドと nkf コマンドを使います。

jq がない場合は、先にインストールしてください。
Download jq

macの場合は、homebrew でインストールできます。

$ brew install jq

nkf がない場合も、先にインストールしてください。
macの場合は、これも homebrew でインストールできます。

$ brew install nkf

2. API Tokenの変換

APIcurl コマンドを使って呼び出します。
その際「API Tokenの生成」で作成したAPI Tokenを利用しますが、このままセットするとエラーになってしまうので、URL Encodeしておきます。

$ echo "[API Token]" | nkf -WwMQ | tr = %

例えば、API Tokenが =/0123456789/abcdef/= だとした場合は、URL Encodeすると下記のようになります。

$ echo "=/0123456789/abcdef/=" | nkf -WwMQ | tr = %
%3D%2F0123456789%2Fabcdef%2F%3D

APIを使ってみる

1. ページの一覧を取得する [/_api/pages.list]

ページの一覧の取得は、 /_api/pages.list で行えます。
APIを呼び出すために、 curl コマンドに下記を設定します。

  • app名: xxxxx.growi.cloudxxxxx の部分です。
  • access_token: 「2. API Tokenの変換」で準備したURL Encode済みのAPI Tokenです。
  • user: 右上に表示されているログイン中のユーザー名です。

下記のようにページの一覧が取得できました。

$ curl -s "https://[app名].growi.cloud/_api/pages.list?access_token=[URL Encode済みAPI Token]&user=[ユーザー名]" | jq .
{
  "pages": [
    {
      "status": "published",
      "grant": 4,
      "grantedUsers": [
        "5d53b1e3403080003a491d6c"
      ],
      "liker": [],
      "seenUsers": [
        "5d53b1e3403080003a491d6c"
      ],
      "commentCount": 0,
      "_id": "5d84f0ec87339600517b338a",
      "createdAt": "2019-09-20T15:31:56.653Z",
      "updatedAt": "2019-09-20T15:31:56.870Z",
      "path": "/test",
      "creator": "5d53b1e3403080003a491d6c",
      "lastUpdateUser": {
        "isGravatarEnabled": false,
        "isEmailPublished": true,
        "lang": "ja",
        "status": 2,
        "admin": true,
        "_id": "5d53b1e3403080003a491d6c",
        "createdAt": "2019-08-14T07:01:55.366Z",
        "name": "名前",
        "username": "ユーザー名",
        "email": "メールアドレス"
      },
      "redirectTo": null,
      "grantedGroup": null,
      "__v": 1,
      "revision": "5d8610eb43cc8400554f9775",
      "id": "5d84f0ec87339600517b338a"
    },
    {
      "status": "published",
      "grant": 1,
      "grantedUsers": [],
      "liker": [],
      "seenUsers": [
        "5d53b1e3403080003a491d6c"
      ],
      "commentCount": 0,
      "_id": "5d831e595799980050f87f72",
      "createdAt": "2019-09-19T06:21:13.745Z",
      "updatedAt": "2019-09-19T06:21:13.760Z",
      "path": "/Templates/%E6%89%8B%E9%A0%86%E6%9B%B8/title",
      "creator": "5d53b1e3403080003a491d6c",
      "lastUpdateUser": {
        "isGravatarEnabled": false,
        "isEmailPublished": true,
        "lang": "ja",
        "status": 2,
        "admin": true,
        "_id": "5d53b1e3403080003a491d6c",
        "createdAt": "2019-08-14T07:01:55.366Z",
        "name": "名前",
        "username": "ユーザー名",
        "email": "メールアドレス"
      },
      "redirectTo": null,
      "grantedGroup": null,
      "__v": 1,
      "revision": "5d831e595799980050f87f73",
      "id": "5d831e595799980050f87f72"
    },
    ...
  ],
  "totalCount": 85,
  "offset": 0,
  "limit": 51,
  "ok": true
}

2. 指定したページの情報を取得する [/_api/pages.get]

指定したページの中身を取得します。
/_api/pages.get で行います。
curl コマンドに下記を設定します。

  • app名: xxxxx.growi.cloudxxxxx の部分です。
  • access_token: 「2. API Tokenの変換」で準備したURL Encode済みのAPI Tokenです。
  • page_id: 「1. ページの一覧を取得する [/_api/pages.list]」のレスポンスの任意の .pages[].id を選択します。例として 5d84f0ec87339600517b338a を指定します。
$ curl -s "https://[app名].growi.cloud/_api/pages.get?access_token=[URL Encode済みAPI Token]&page_id=5d84f0ec87339600517b338a" | jq .
{
  "page": {
    "status": "published",
    "grant": 1,
    "grantedUsers": [],
    "liker": [],
    "seenUsers": [
      "5d53b1e3403080003a491d6c"
    ],
    "commentCount": 0,
    "_id": "5d84f0ec87339600517b338a",
    "createdAt": "2019-09-20T15:31:56.653Z",
    "updatedAt": "2019-09-21T12:00:43.124Z",
    "path": "/test",
    "creator": {
      "isGravatarEnabled": false,
      "isEmailPublished": true,
      "lang": "ja",
      "status": 2,
      "admin": true,
      "_id": "5d53b1e3403080003a491d6c",
      "createdAt": "2019-08-14T07:01:55.366Z",
      "name": "名前",
      "username": "ユーザー名",
      "email": "メールアドレス"
    },
    "lastUpdateUser": {
      "isGravatarEnabled": false,
      "isEmailPublished": true,
      "lang": "ja",
      "status": 2,
      "admin": true,
      "_id": "5d53b1e3403080003a491d6c",
      "createdAt": "2019-08-14T07:01:55.366Z",
      "name": "名前",
      "username": "ユーザー名",
      "email": "メールアドレス"
    },
    "redirectTo": null,
    "grantedGroup": null,
    "__v": 3,
    "revision": {
      "format": "markdown",
      "_id": "5d8610eb43cc8400554f9775",
      "createdAt": "2019-09-21T12:00:43.122Z",
      "path": "/test",
      "body": "## 概要\nGROWI.cloud は esa.io や Qiita:team から直接インポートできる便利な機能があります。<br>\n今回、このインポート機能を利用して esa.io から GROWI.cloud へ移行しました。<br>\nインポート機能を利用する際、ハマった所があったため、備忘録としてまとめます。\n\n## esa.io から GROWI への移行\n\n### 1. esa.io の設定\n\nGROWI から esa.io の記事を取得できるように、 esa.io で Personal access token を作成します。<br>\nSETTINGS > Applications にある Personal access tokens 右の Generate new token ボタンをクリックします。\n\n![ORG__DSC0030.jpeg (2.1 MB)](https://img.esa.io/uploads/production/attachments/xxxxx/2019/09/21/xxxxx/xxxxx.jpeg)\n\n下記を設定して Save ボタンをクリックします。\n\n- Token description: 何でもよいので目的がわかる名前をつけます。 例) GROWI\n- Select scopes: Readにのみチェックします。",
      "author": {
        "isGravatarEnabled": false,
        "isEmailPublished": true,
        "lang": "ja",
        "status": 2,
        "admin": true,
        "_id": "5d53b1e3403080003a491d6c",
        "createdAt": "2019-08-14T07:01:55.366Z",
        "name": "名前",
        "username": "ユーザー名",
        "email": "メールアドレス"
      },
      "hasDiffToPrev": true,
      "__v": 0
    },
    "id": "5d84f0ec87339600517b338a"
  },
  "ok": true
}

3. 画像をアップロードする [/_api/attachments.add]

画像のアップロードをするためには、 /_api/attachments.add を使います。
API名から推測できる通り、このAPIはページに対して画像をアップロードして紐付けます。
アップロードしただけでは、記事内に配置されないため、ページを編集するAPIもしくはWeb UIでコンテンツを書き換える必要があります。
curl コマンドは下記を設定します。

  • app名: xxxxx.growi.cloudxxxxx の部分です。
  • access_token: 上記までのAPIとは違い、URL Encodeしていない「API Tokenの生成」で作成したAPI Tokenをセットします。
  • file: @ファイルフルパス の形式でアップロードする画像を指定します。
  • page_id: 画像をアタッチしたい、「1. ページの一覧を取得する [/_api/pages.list]」のレスポンスの任意の .pages[].id を選択します。例として 5d84f0ec87339600517b338a を指定します。

アップロードに成功すると、下記のような結果が返ってきます。

$ curl -s -X POST -F "access_token=[URL EncodeしていないAPI Token]" -F file=@/path/to/image.jpeg -F page_id=5d84f0ec87339600517b338a https://[app名].growi.cloud/_api/attachments.add | jq .
{
  "page": {
    "status": "published",
    "grant": 1,
    "grantedUsers": [],
    "liker": [],
    "seenUsers": [
      "5d53b1e3403080003a491d6c"
    ],
    "commentCount": 0,
    "_id": "5d84f0ec87339600517b338a",
    "createdAt": "2019-09-20T15:31:56.653Z",
    "updatedAt": "2019-09-21T12:00:43.124Z",
    "path": "/test",
    "creator": "5d53b1e3403080003a491d6c",
    "lastUpdateUser": "5d53b1e3403080003a491d6c",
    "redirectTo": null,
    "grantedGroup": null,
    "__v": 3,
    "revision": "5d8610eb43cc8400554f9775",
    "id": "5d84f0ec87339600517b338a"
  },
  "attachment": {
    "fileSize": 2094923,
    "_id": "5d86407b43cc8400554f977c",
    "createdAt": "2019-09-21T15:23:39.544Z",
    "page": "5d84f0ec87339600517b338a",
    "creator": "5d53b1e3403080003a491d6c",
    "originalName": "ORG__DSC0030_2.jpeg",
    "fileName": "1e26426f80e91863eb13fb3c61f52305.jpeg",
    "fileFormat": "image/jpeg",
    "__v": 0,
    "filePathProxied": "/attachment/5d86407b43cc8400554f977c",
    "downloadPathProxied": "/download/5d86407b43cc8400554f977c",
    "id": "5d86407b43cc8400554f977c"
  },
  "pageCreated": false,
  "ok": true
}

Web UIでも実際にファイルがアップロードされているか確認してみます。
下記のように、 https://[app名].growi.cloud/ の後ろに、 page_id を指定するとそのページを表示できます。

https://[app名].growi.cloud/[page_id]

例)
https://[app名].growi.cloud/5d84f0ec87339600517b338a

ページを開き、一番下にある Attachments に画像が追加されていることが確認できます。

f:id:Aqutam:20190922003802p:plain

4. ページを編集する [/_api/pages.update]

ページの書き換えは、/_api/pages.update を使います。
このAPIを使って、「3. 画像をアップロードする [/_api/attachments.add]」でアタッチした画像をページに埋め込んでみます。
curl コマンドは下記を設定します。
リクエストパラメータは -d オプションで JSON 形式で指定します。

  • app名: xxxxx.growi.cloud の xxxxx の部分です。
  • access_token: ここでもURL Encodeしていない「API Tokenの生成」で作成したAPI Tokenをセットします。
  • body: ページの内容を記載します。ここを編集してアタッチした画像を埋め込みます。編集方法は後述します。
  • page_id: 「1. ページの一覧を取得する [/_api/pages.list]」のレスポンスの任意の .pages[].id を選択します。例として 5d84f0ec87339600517b338a を指定します。
  • revision_id: 「1. ページの一覧を取得する [/_api/pages.list]」のレスポンスで、 .pages[].id と同じハッシュに指定されている .pages[].revision を指定します。
  • grant: 今回は 1 を指定します。

body パラメータは下記のように追加を行いました。
末尾に \n\n![ORG__DSC0030_2.jpeg](/attachment/5d86459f43cc8400554f977d) を追加しています。
markdown の画像埋め込み書式で記載し、パスに /attachment/[attachment id] を指定します。

[変更前]
## タイトル\n本文本文本文

[変更後]
## タイトル\n本文本文本文\n\n[ORG__DSC0030_2.jpeg](/attachment/5d86459f43cc8400554f977d)

リクエストとレスポンスは下記のようになります。

curl -s -X POST \
-H 'Content-Type:application/json' \
-d '{"access_token":"[URL EncodeしていないAPI Token]","body":"## タイトル\n本文本文本文\n\n[ORG__DSC0030_2.jpeg](/attachment/5d86459f43cc8400554f977d)","revision_id":"5d8610eb43cc8400554f9775","grant":1}' \
https://[app名].growi.cloud/_api/pages.update | jq .
{
  "page": {
    "status": "published",
    "grant": 1,
    "grantedUsers": [],
    "liker": [],
    "seenUsers": [
      "5d53b1e3403080003a491d6c"
    ],
    "commentCount": 0,
    "_id": "5d84f0ec87339600517b338a",
    "createdAt": "2019-09-20T15:31:56.653Z",
    "updatedAt": "2019-09-21T15:52:21.581Z",
    "path": "/test",
    "creator": {
      "isGravatarEnabled": false,
      "isEmailPublished": true,
      "lang": "ja",
      "status": 2,
      "admin": true,
      "_id": "5d53b1e3403080003a491d6c",
      "createdAt": "2019-08-14T07:01:55.366Z",
      "name": "名前",
      "username": "ユーザー名",
      "email": "メールアドレス"
    },
    "lastUpdateUser": {
      "isGravatarEnabled": false,
      "isEmailPublished": true,
      "lang": "ja",
      "status": 2,
      "admin": true,
      "_id": "5d53b1e3403080003a491d6c",
      "createdAt": "2019-08-14T07:01:55.366Z",
      "name": "名前",
      "username": "ユーザー名",
      "email": "メールアドレス"
    },
    "redirectTo": null,
    "grantedGroup": null,
    "__v": 3,
    "revision": {
      "format": "markdown",
      "_id": "5d86473543cc8400554f977e",
      "createdAt": "2019-09-21T15:52:21.579Z",
      "path": "/test",
      "body": "## タイトル\n本文本文本文\n\n[ORG__DSC0030_2.jpeg](/attachment/5d86459f43cc8400554f977d)",
      "author": {
        "isGravatarEnabled": false,
        "isEmailPublished": true,
        "lang": "ja",
        "status": 2,
        "admin": true,
        "_id": "5d53b1e3403080003a491d6c",
        "createdAt": "2019-08-14T07:01:55.366Z",
        "name": "名前",
        "username": "ユーザー名",
        "email": "メールアドレス"
      },
      "hasDiffToPrev": true,
      "__v": 0
    },
    "id": "5d84f0ec87339600517b338a"
  },
  "ok": true
}

Web UIで記事を開いてみると、末尾に画像の記述が追加され、画像が表示されていることが確認できます。

f:id:Aqutam:20190922011921p:plain

以上、APIを利用してGROWIをかなり柔軟に操作できることがわかりました。