Slack から Mattermost へデータ移行

**この記事で解説すること：**

Amazon Lightsail の Ubuntu に立ち上げた Mattermost に、Slack のデータを移行させます。

Mattermost を操作する `mmctl` コマンドについては、以下を参考にしてください。

https://docs.mattermost.com/manage/mmctl-command-line-tool.html#mmctl-commands

Ubuntu への Mattermost のインストール方法は、以下の記事をご覧ください。

https://qiita.com/takaoS/items/48f440b3c11f2e18a661


## インポートの準備

それでは、インポートの準備を進めていきます。
※ 事前に、インポート先となる Mattermost のチームを作成しておいてください。

少し順番が前後しますが、公式の手順に沿って行っていきます。

https://docs.mattermost.com/onboard/migrating-to-mattermost.html#migrating-from-slack

### 作業用ディレクトリの作成

SSH でサーバー(Amazon Lightsail インスタンスの Ubuntu) に入り、今回の作業用ディレクトリを作成しておきます。
```
$ mkdir tmp
```

### 必要ファイルのダウンロード

Slack データをインポートするには「mmetl」と「slack-advanced-exporter」を使用します。

それらをインストールするため、先ほど作成した tmp/ ディレクトリに必要なファイルをダウンロードします。

```
$ cd tmp
$ wget https://github.com/mattermost/mmetl/releases/download/0.0.1/mmetl.linux-amd64.tar.gz
$ wget https://github.com/grundleborg/slack-advanced-exporter/releases/download/v0.4.0/slack-advanced-exporter.linux-amd64.tar.gz
```

もし、Ubuntu 以外で使用する場合は、OS ごとにダウンロードするファイルを選択します。

https://github.com/mattermost/mmetl/releases/

https://github.com/grundleborg/slack-advanced-exporter/releases/


### 必要ファイルの解凍

先ほどダウンロードした圧縮ファイルを解凍します。
```
$ tar -zxvf slack-advanced-exporter.linux-amd64.tar.gz
$ tar -zxvf mmetl.linux-amd64.tar.gz
```

### インポート元データの準備

次は サーバー操作から一旦離れて、Slack の公式の手順通りにデータをエクスポートします。

https://slack.com/intl/ja-jp/help/articles/201658943-%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%B9%E3%83%9A%E3%83%BC%E3%82%B9%E3%81%AE%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92%E3%82%A8%E3%82%AF%E3%82%B9%E3%83%9D%E3%83%BC%E3%83%88%E3%81%99%E3%82%8B

エクスポートした ZIPファイルを FTPソフトでサーバーに転送します。

今回は FileZilla を利用し、先ほど作成した `tmp/` ディレクトリに転送します。
接続方法は以下の記事を参照させていただきました。

https://took.jp/lightsail%E3%82%A4%E3%83%B3%E3%82%B9%E3%82%BF%E3%83%B3%E3%82%B9%E3%81%ABfilezilla%E3%81%A7ftp%E6%8E%A5%E7%B6%9A/

### Slack API OAuth Token の発行

Mattermost の公式の解説 (以下のURL) の「Next, follow these steps to create a bot token:」の 1 〜 9 のステップを実行します。

https://docs.mattermost.com/onboard/migrating-to-mattermost.html#migrating-from-slack-using-the-mattermost-mmetl-tool-and-bulk-import

### エクスポートしたデータにメールアドレス情報を紐付け

Slack のエクスポートデータには添付ファイルとメールアドレスは含まれていないため、それらを紐付けます。
まずはメールアドレスを紐付けます。
```
$ ./slack-advanced-exporter --input-archive {Slackからエクスポートしたファイル} --output-archive export-with-emails.zip fetch-emails --api-token {発行したslack API トークン}
```

「export-with-emails.zip」というファイルが作成されます。

### エクスポートしたデータにファイルの情報を紐づけ

次に、添付ファイルを紐付けます。
```
$ ./slack-advanced-exporter --input-archive export-with-emails.zip --output-archive export-with-emails-and-attachments.zip fetch-attachments
```

「export-with-emails-and-attachments.zip」というファイルが作成されます。

以上で、インポートするファイルの用意ができました。

## Mattermost 用にファイル変換 & 圧縮

次は、これらのファイルを Mattermost 用に変換していきます。

この後の作業で Mattermost を操作するためのコマンドである `mmctl` を使用しますが、まだパスを通していないので、公式のように
```
$ mmctl import upload hogehoge.zip
```

と入力しても、実行されません。

そのため、事前にパスを通すか、毎回パスを指定して実行するか を行うよう注意してください。

パスを指定して実行するなら、今回の場合は、
```
$ /opt/mattermost/bin/mmctl import upload hogehoge.zip
```

となります。

それでは、インポートするファイルを Mattermost 用に変換していきましょう。


### インポートするファイルを変換
```
$ ./mmetl transform slack --team {チーム名} --file export-with-emails-and-attachments.zip --output slack-export.jsonl
```

「slack-export.jsonl」というファイルと、「bulk-export-attachments」というフォルダが作成されます。

{チーム名} には、事前に Mattermost で作成したチーム名を入力します。

もし分からない場合は、以下のコマンドでチーム名の一覧を確認できます。
```
$ mmctl team list
```

上述したように、`mmctl` コマンドのパスに注意してください。

### bulk-export-attachments/ フォルダを data に移動
```
$ mkdir data
$ mv bulk-export-attachments data
```

### zip コマンドをインストール (まだインストールされていない場合のみ)
```
$ sudo apt update
$ sudo apt install zip
```

### それらを圧縮
```
$ zip -r slack-export.zip data slack-export.jsonl
```

「slack-export.zip」という圧縮ファイルが作成されます。

以上で、Mattermost 用にインポートファイルを変換・圧縮が完了しました。


## Mattermost にインポート

それでは最後に、Mattermost にインポートしていきます。

### ログイン
```
$ mmctl auth login http://localhost:8065

//「Connection name」：適当な文字列
//「Username」：Mattermost で作成した管理者ユーザー名
// 「Password」：Mattermost で作成した管理者ユーザーのパスワード
```

### Mattermostのチームの最大ユーザー数を増やす
```
$ mmctl config set TeamSettings.MaxUsersPerTeam {増やしたい人数}
```

{増やしたい人数} には、Mattermost の最大ユーザー数を指定します。(500 など)

人数を増やしておかないと、後でインポートした際に以下のようにエラーになります
```
$ mmctl import job show {Import process job IDの値}

// Status: error
// Data: BulkImport: Unable to import team membership because no more members are allowed in that team, limit exceeded …
```

インポートについては後述します。

### インポートファイルのアップロード
```
$ mmctl import upload slack-export.zip
Upload session successfully created, ID: gobrahsndinuubja6ax1pbjnrh  // ID が生成される
Import file successfully uploaded, name: ru5u8cyqt3na3xmqyha67jjp5w
```

ファイルサイズが大きすぎると、`Error: failed to create upload session: : Unable to upload file. File is too large.` といったエラーが表示されるようです。

この場合は、以下のコマンドで Mattermost の最大ファイルサイズを変更してください。
```
$ mmctl config set FileSettings.MaxFileSize {増やしたいサイズ}
```

{増やしたいサイズ} には、アップロードするサイズよりも大きい値を選択します。

これを実行してもエラーが出る場合は、サーバー側でファイルサイズオーバーが起きている可能性がありますので、サーバー側 (Nginx) の設定を変更します。

### アップロードしたファイル名を確認
```
$ mmctl import list available
```

今回は、以下のファイル名でアップロードされました。

gobrahsndinuubja6ax1pbjnrh_slack-export.zip

アップロード時に発行された ID と同じ値が使われています。

### インポート
```
$ mmctl import process {先ほど確認したアップロードファイル名}
Import process job successfully created, ID: pqnw1q6aw3riikdhbof3xx84ey  // ID が生成される
```

{先ほど確認したアップロードファイル名} は、`mmctl import list available` コマンドで確認した ZIP ファイルです。

### インポート状況の確認
```
$ mmctl import job show {先ほどの Import process job IDの値}
```

実行後、`Status: in_progress` と表示されれば成功です。

### インポートされているか確認

Mattermost を起動し、Slack のチャンネルがインポートされているか確認します。

最初はサイドバーに表示されていないので、チャンネル名を検索して探します。
インポートされていない場合は、一旦 Mattermost を再起動すると表示されるはずです。

また、以下のコマンドでもチャンネルの一覧を確認できます。
```
$ mmctl channel list {チーム名}
```


以上で Slack から Mattermost へのデータ移行が完了しました。

## チャンネル名がランダムな英数字に変換される件について

Slack でのチャンネル名が日本語だと、Mattermost に移行した際に チャンネル名だけランダムな文字列になってしまうようです。

色々と試してみましたが、対処法としては

- Mattermost への移行後に、一つずつ手作業でチャンネル名を修正する
- Slack からデータをエクスポートする前に、Slack で半角英数字のみのチャンネル名に変更する

のどちらかしか解決策がなさそうです…💦

### 試したこと

- Slack データの差分追加は可能
	- 例：8/31 までの Slack データA を入れた後、9/1 からの Slack データB をインポートすると、データA でインポートした Mattermost 上のチャンネルの続きに、データB のメッセージのやり取りが追加されます
- 差分データをインポートする前に Mattermost のチャンネルでメッセージを送っても、そのメッセージも含めて時系列順に差分インポートされる
	- つまり、Slack と Mattermost の同時運用も可能
- 途中で Slack のチャンネル名を変更しても、Slack データの差分追加が可能
- でも、 Mattermost に追加されたチャンネル名を変更すると、Slack データの差分追加はされない
	- 例：データA でインポートした Mattermost 上のチャンネル (チャンネル名変更済み) の他に、データB のチャンネル (Mattermost で変更する前と同じチャンネル名) が新たに生成される
		- 新たに生成されるチャンネルは、データB でエクスポートしたメッセージ期間のみの内容
- Mattermost 上のチャンネル名だけ変えて URL は変更しなかったとしても、差分インポートするとチャンネル名が元に戻って (ランダムな文字列に戻って) しまう
	- Mattermost のチャンネルの URL は「https://{example.com}/{チーム名}/{チャンネル名}」となる