Confluenceへの移行を楽にしたい


# 初めに

こんにちは、@reonyanarticleです。
この記事は[みらい翻訳のカレンダー | Advent Calendar 2022](https://qiita.com/advent-calendar/2022/miraitranslate)の19日目です。


最近、会社で使う文書管理ツールとしてConfluenceを使うようになりました。
今まで書いていた資料をConfluenceに移行したいと思ったのですが、以下の点で移行コストがかかってしまうと悩んでおり、なかなか踏み出せずにいました。
- 今までの資料はmarkdownでのみダウンロード可能(wordファイルは不可)
- markdownをConfluenceのページに直接貼り付けてもコードファイルと認識されるため、コピペでは難しそう
- Confluenceにmarkdownのマクロも存在するが、直接ページに貼られるわけではなく、枠ができてしまうのと、編集はマクロを書き直さないと変更できないため大変

というわけで、移行するのに悩んでいたのですが、markdownをConfluenceに移行できるツールの[md_to_conf](https://github.com/RittmanMead/md_to_conf)を見つけました。
これを使用したConfluenceへの移行方法を紹介できればと思います！

## 準備

`Confluence username`、`organisation name`、`API key`が必要なので取得します。
- `Confluence username`：Confluenceで使用しているユーザーネームのこと。メールアドレスでも大丈夫です。
- `organisation name`：`https://XXXX.atlassian.net/wiki/`に書かれている`XXXX`の部分です。
- `API key`：[https://id.atlassian.com/manage/api-tokens](https://id.atlassian.com/manage/api-tokens)で取得したAPIトークンです。


上記で取得した内容を`.zprofile`に記載します。(使用してるshellによって変わります。bashだと`.bash_profile`に記載すると思います。)

```shell
export CONFLUENCE_USERNAME='hoge'
export CONFLUENCE_API_KEY='abc123'
export CONFLUENCE_ORGNAME='foo'
```

また、markdownを移行したいスペース先のスペースキーを確認します。
`https://XXXX.atlassian.net/wiki/spaces/`の後に記載されている値がスペースキーです。（今回スペースキーを`SPACEKEY`とします。）

## 使い方

準備が終わったら、[md_to_conf](https://github.com/RittmanMead/md_to_conf)をインストールします。
インストール方法は`README`に記載してある通りに実行すれば問題なくインストールできます。
インストール後、コマンドを実行すると（markdownに特に問題なければ）移行できます。


```shell
python3 md2conf.py /path/to/markdown SPACEKEY
```

成功すると以下のような出力結果が得られます。
```shell
2022-12-16 15:29:10,080 - INFO - main [774] - 		----------------------------------
2022-12-16 15:29:10,081 - INFO - main [775] - 		Markdown to Confluence Upload Tool
2022-12-16 15:29:10,081 - INFO - main [776] - 		----------------------------------
2022-12-16 15:29:10,081 - INFO - main [778] - Markdown file: README.md
2022-12-16 15:29:10,081 - INFO - main [779] - Space Key:	SPACEKEY
2022-12-16 15:29:10,081 - INFO - main [785] - Title:		README
2022-12-16 15:29:10,197 - INFO - main [808] - Checking if Atlas page exists...
2022-12-16 15:29:10,197 - INFO - get_page [327] - 	Retrieving page information: README
2022-12-16 15:29:10,537 - INFO - create_page [528] - Creating page...
2022-12-16 15:29:11,849 - INFO - create_page [571] - Page created in スペース名 with ID: 0123456789.
2022-12-16 15:29:11,849 - INFO - create_page [572] - URL: https://XXXX.atlassian.net/wiki/spaces/SPACEKEY/pages/0123456789
2022-12-16 15:29:12,247 - INFO - main [839] - Markdown Converter completed successfully.
```

最後の出力結果の後、ブラウザでConfluenceが開きます。
開いたブラウザを見ると、スペースのページ直下に資料が作成されているのが確認できます。


もう少し細かい使い方を調べてみましょう。`--help`オプションを実行してみます。
```
% python3 md2conf.py --help
usage: md2conf.py [-h] [-u USERNAME] [-p APIKEY] [-o ORGNAME] [-a ANCESTOR] [-t ATTACHMENT [ATTACHMENT ...]] [-c] [-g] [-n] [-d] [-l LOGLEVEL] [-s]
                  [-v VERSION] [-mds MARKDOWNSRC] [--label LABELS] [--property PROPERTIES]
                  markdownFile spacekey

positional arguments:
  markdownFile          Full path of the markdown file to convert and upload.
  spacekey              Confluence Space key for the page. If omitted, will use user space.

optional arguments:
  -h, --help            show this help message and exit
  -u USERNAME, --username USERNAME
                        Confluence username if $CONFLUENCE_USERNAME not set.
  -p APIKEY, --apikey APIKEY
                        Confluence API key if $CONFLUENCE_API_KEY not set.
  -o ORGNAME, --orgname ORGNAME
                        Confluence organisation if $CONFLUENCE_ORGNAME not set. e.g. https://XXX.atlassian.net/wikiIf orgname contains a dot, considered as
                        the fully qualified domain name.e.g. https://XXX
  -a ANCESTOR, --ancestor ANCESTOR
                        Parent page under which page will be created or moved.
  -t ATTACHMENT [ATTACHMENT ...], --attachment ATTACHMENT [ATTACHMENT ...]
                        Attachment(s) to upload to page. Paths relative to the markdown file.
  -c, --contents        Use this option to generate a contents page.
  -g, --nogo            Use this option to skip navigation after upload.
  -n, --nossl           Use this option if NOT using SSL. Will use HTTP instead of HTTPS.
  -d, --delete          Use this option to delete the page instead of create it.
  -l LOGLEVEL, --loglevel LOGLEVEL
                        Use this option to set the log verbosity.
  -s, --simulate        Use this option to only show conversion result.
  -v VERSION, --version VERSION
                        Version of Confluence page (default is 1).
  -mds MARKDOWNSRC, --markdownsrc MARKDOWNSRC
                        Use this option to specify a markdown source (i.e. what processor this markdown was targeting). Possible values: bitbucket.
  --label LABELS        A list of labels to set on the page.
  --property PROPERTIES
                        A list of content properties to set on the page.

```

先ほど、profileに`Confluence username`、`organisation name`、`API key`を記載しましたが、それぞれ`--username`、`--orgname`、`--apikey`を上記コマンドの引数に渡すことでも実行することができます。
他に使用する可能性がある引数としては、
- `--nogo`：Confluenceにアップロード後、ブラウザでConfluenceを勝手に開かないようにするオプション。
- `--loglevel`：出力されるログレベルを指定するオプション。デフォルトは`INFO`で、pythonの`logging`モジュールに準拠したログレベルが指定可能

があります。他にも使いそうなのですが、私にConfluence力がないので他のオプションは使用できませんでした…[^1]
[^1]:Confluence力が上がったら、オプションの説明を追記しようと思います。

また、Confluenceで使用できる、`Information`、`Note`、`Warning`のマクロに対応しており、md内で
```md
> This is an info
```
と書くことでConfluenceのページで`Information`として出力されるようになります。
詳しくは[こちら](https://github.com/RittmanMead/md_to_conf#information-note-and-warning-macros)をご覧ください。

## 注意点

markdownを移行させようとして、最初に上記コマンドを実行したら、エラーになりました。
```shell
2022-12-16 15:29:10,080 - INFO - main [774] - 		----------------------------------
2022-12-16 15:29:10,081 - INFO - main [775] - 		Markdown to Confluence Upload Tool
2022-12-16 15:29:10,081 - INFO - main [776] - 		----------------------------------
2022-12-16 15:29:10,081 - INFO - main [778] - Markdown file: README.md
2022-12-16 15:29:10,081 - INFO - main [779] - Space Key:	SPACEKEY
2022-12-16 15:29:10,081 - INFO - main [785] - Title:		README
2022-12-16 15:29:10,197 - INFO - main [808] - Checking if Atlas page exists...
2022-12-16 15:29:10,197 - INFO - get_page [327] - 	Retrieving page information: README
2022-12-16 15:29:10,537 - INFO - create_page [528] - Creating page...
2022-12-16 15:29:10,662 - ERROR - create_page [561] - error: 400 Client Error: Bad Request for url: https://XXXX.atlassian.net/wiki/rest/api/content/ - b'{"statusCode":400,"data":{"authorized":true,"valid":true,"errors":[],"successful":true},"message":"com.atlassian.Confluence.api.service.exceptions.BadRequestException: Error parsing xhtml: Unexpected close tag </td>; expected </br>.\\n at [row,col {unknown-source}]: [1149,166]"}'
```

ログレベル`DEBUG`での実行と調査を行なったことで原因が判明しました。
markdownのtable内で改行として`<br>`を使用していると、閉じタグの対応とし`</td>`が対応されてしまっていました。
そのため、パーズに失敗しているとのことでした。
以下のように記載するとエラーになります。
```
| 1 | 2 | 3 |
| --- | --- | --- |
| a | b | c　<br> d |
| い | ろ | は |

```

移行する前にタグの対応が取れているか。不要な改行タグがないか確認しましょう。

## 最後に

他にも[markdown-to-confluence](https://github.com/duo-labs/markdown-to-confluence)とかあるのですが、これはGitHubリポジトリ内のmarkdownドキュメントをConfluenceに同期するようなプログラムなので今回は選択しませんでした。
少しでもConfluenceへの移行をしたいと思った人に役立てば幸いです！

明日は@mitonoがCloudFormation スタック更新時のspot枯渇を克服した(かもしれない)話を書いてくれます！
お楽しみに！