Rocket.Chat構築でちょっと詰まったところまとめ

# tl;dr

Rocket.Chatを構築した時にちょっと詰まった部分を書き出してみることにします。
また構築するかどうかはさておき。

# GridFSの場合、ファイルのアップロードができない

アップロードしたファイルを保存するファイルシステムとしてGridFSを使用した場合に、ファイルをアップロードしてもプログレスバーが0%から進まないという事象です。
どれだけ待っても進まない。

## `/tmp/ufs` の権限が不足している

`/var/log/messages` を見ると以下のようなエラーログが出力されていることが確認できます。

```:/var/log/messages
Oct 10 12:15:11 hoge rocketchat: ufs: cannot write chunk of file "hjsjd98n8ZTr9yrS7" (EACCES: permission denied, open '/tmp/ufs/hjsjd98n8ZTr9yrS7')
Oct 10 12:15:11 hoge rocketchat: ufs: cannot delete temp file "/tmp/ufs/hjsjd98n8ZTr9yrS7" (ENOENT: no such file or directory, unlink '/tmp/ufs/hjsjd98n8ZTr9yrS7')
Oct 10 12:15:11 hoge rocketchat: [Error: FileNotFound: no file with id hjsjd98n8ZTr9yrS7 found]
```

Rocket.ChatでGridFSを選択してファイルをアップロードした場合、MongoDBに直接保存されるわけではありません。
一時的に `/tmp/ufs` に保存された後、GridFSに送り込むような感じでしょうか。
仕組み自体は[これ](https://github.com/jalik/jalik-ufs)を使っているみたいです。

この `/tmp/ufs` の権限が正常でないとファイルをアップロードしても0%で停止してしまいます。
エラーログは `/var/log/messages` に出力されますが、ブラウザ上には特段何も表示されません。
`/tmp/ufs` はデフォルトではオーナ、グループともに `root` であり、パーミッションは `0755` です。
今回、 `root` ではなくRocket.Chatサービス動作用のシステムアカウントである
 `rocketchat` というユーザを予め作成してサービスを動かしていた為 `/tmp/ufs` に対し書き込みができない状態に陥っていました。

そこで `/tmp/ufs` のオーナ、グループをRocket.Chatを動作させているユーザである `rocketchat` に変更。

```shell-session
$ ls -ld /tmp/ufs
drwxr-xr-x. 2 root root 6 Oct 10 12:10 /tmp/ufs
$ sudo chown rocketchat. /tmp/ufs
$ ls -ld /tmp/ufs
drwxr-xr-x. 2 rocketchat rocketchat 6 Oct 10 12:10 /tmp/ufs
```

これで問題なくアップロードができるようになりました。
めでたし。

# Web APIでユーザ作成しようとするとログにエラーが出力される

Web APIからユーザを作ろうとすると、以下のようなログが出力されてしまいます。

```
Oct 10 12:59:52 hoge rocketchat: Error while handling the setting of the avatar from a url (https://secure.gravatar.com/avatar/55502f40dc8b7c769880b10874abc9d0?default=404&size=200) for test: { [Error: connect ECONNREFUSED 192.0.73.2:443]
Oct 10 12:59:52 hoge rocketchat: code: 'ECONNREFUSED',
Oct 10 12:59:52 hoge rocketchat: errno: 'ECONNREFUSED',
Oct 10 12:59:52 hoge rocketchat: syscall: 'connect',
Oct 10 12:59:52 hoge rocketchat: address: '192.0.73.2',
Oct 10 12:59:52 hoge rocketchat: port: 443 }
```

場合によっては `502 Bad Gateway` だったり、 `curl: (52) Empty reply from server` が返る場合もあります。
`502 Bad Gateway` の場合は2分程度プロンプトが返って来なかったりします。
`curl: (52) Empty reply from server` は比較的すぐにプロンプトが戻ってきます。
どちらもユーザ作成時の結果は返ってきませんが、ユーザ自体はちゃんと作成されます。

## Gravatarを無効にする

ログを見ればわかることではあるのですが、ユーザ作成時、Rocket.Chat が Gravatar にアクセスしてアイコンを取得しようとするみたいです。
そのため、管理画面から Gravatar へアクセスする設定を無効化してあげる必要があります。
`管理` → `アカウント` → `アバター` の順に選択し、`Set Default Avatar` を **いいえ** にして、変更を保存するだけです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/76791/3d7f7498-e46c-c138-31a6-9d83c7b838e0.png)

余計に通信しなくなって良いのではないでしょうか。
仕事なんかで構築して使う場合Gravatarにアクセスする必要はないでしょうし、本設定は無効にしておいて良いと思います。

# パスワード変更時のダイアログメッセージの表現が分かりづらい

以下のメッセージを見てください。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/76791/d59abdca-9a00-94b2-490f-6a893bc4d226.png)

上記のメッセージ、 **新しいパスワードを入力してほしい** という意味と **現行のパスワードを入力してほしい** という意味と、どちらにも取れますよね。
このメッセージは、アカウントのプロフィールに新しいパスワードを入力して `[変更を保存]` をクリックすると表示されるので、前者の **新しいパスワードを入力してほしい** という意味なんだと解釈してしまいがちだと思います。
しかも **「もう一度」** なんて言葉が入っているので **さっき入れた新しいパスワードをもう一度入れるればいいんだな**  という意味に捉えてしまいますよね。
流れ的にもそう解釈するのが自然だと思いますが、そうするとハマります。

このメッセージの意味するところは後者の **現行のパスワードを入力してほしい** の方になるのです。
紛らわしいというか、ミスリードを誘っているというか。。
原文は `For your security, you must enter your current password to continue` なのですが、日本語訳だと `current` の部分がすっぽり抜けてしまっています。
もしかしたら古いバージョンでは新規パスワードを2回入力する方式だったのかもしれません。
しかもパスワードを打ち間違えると次に入力するまで1分間待たなくてはなりません。
普通にしんどい。

## メッセージを変更する

これではユーザが混乱する可能性があるので、メッセージを変更してしまいましょう。
本来であれば翻訳プロジェクトに参加して大元の修正を掛けるのがベターだとは思うのですが、いつマージされるか不明ですし、参加方法もまずメールを送るなど、ちょっと敷居が高いように感じます。
また、英語に自信がないので参加しても良いのだろうかと感じるなど。。

ではどうするか。
Rocket.Chat は優秀なので管理画面からメッセージをカスタマイズすることができます。
今回はそれを使ってメッセージを変更することにしましょう。

メッセージを変更するには、jsonで定義されている `key:value` を探し出す必要があります。
この定義は Rocket.Chat の実行ディレクトリ内にあるファイル
 `/opt/rocketchat/programs/server/packages/rocketchat_i18n.js`[^1] に記載されています。
[^1]: パスは一例。私の場合は `/opt` の下に `rocketchat` というディレクトリ名で展開しているので `/opt/rocketchat/...` となります。
このファイルには各言語のメッセージが記載されているのですが、容量削減のためなのか、jsonがほとんど改行やインデントをされておらず、各言語のメッセージが一行にずらずらと羅列されているような形となっています。
そのため、適当にコマンドを使って出力を加工して絞り込みましょう。
私は以下のようにしましたが、分かり易ければOKです。

```shell-session:コマンド例
$ cat /opt/rocketchat/programs/server/packages/rocketchat_i18n.js | grep '\[\"ja\"\]\[namespace\]' | sed -e 's/,/,\n/g' | grep "パスワード"
"Accounts_AllowPasswordChange":"パスワードの変更を許可する",
"Accounts_PasswordReset":"パスワードを再設定する",
"Accounts_UserAddedEmail_Default":"<h2>ようこそ<h1> [Site_Name] </h1></h2><p> [Site_URL]に移動し、今日利用可能な最高のオープンソースのチャットソリューションを試してみてください！ </p><p> [email]とパスワード：[password]あなたはあなたの電子メールを使用してログインすることができます。あなたはあなたの最初のログイン後に変更する必要があります。",
"Accounts_UserAddedEmail_Description":"あなたは、次のプレースホルダを使用するこ とがあります。 <br /><ul><li> [name]、[fname]、[lname]ユーザのフルネーム、姓または名の、それぞれ。 </li><li>ユーザーの電子メールのための[email]。 </li><li>ユー ザーのパスワードの[password]。 </li><li> [Site_Name]と[Site_URL]アプリケーション名とURLのそれぞれ。 </li></ul>",
"Analytics_features_users_Description":"ユーザー（パスワードのリセット回数、プロフィール画像の変更など）に関連するアクションに関連するカスタムイベントを追跡します。",
"Confirm_password":"パスワードの確認",
"error-invalid-password":"無効なパスワード",
...
```

出力の中から該当メッセージを探します。
今回は以下が対象です。

```:必要なkey：value
"For_your_security_you_must_enter_your_current_password_to_continue":"セキュリティーの為、続けるにはもう一度パスワードを入力してください",
"Please_enter_your_password":"パスワードをもう一度入力してください",
```

`For_your_security_you_must_enter_your_current_password_to_continue` と `Please_enter_your_password` の値を変更します。
こいつらはコピーするなりどこかに貼り付けるなり一字一句記憶するなりしてください。

`管理` → `全般` → `Translations` の順に選択すると、 `Custom Translations` というjsonフォーマットでメッセージを変更できる画面が表示されるので、以下のようなjsonフォーマットを貼り付けます。

```json:translations
{
  "ja": {
    "Please_enter_your_password":"パスワードの入力",
    "For_your_security_you_must_enter_your_current_password_to_continue":"セキュリティー確保の為、パスワードの変更を続行するには、現行のパスワードを入力する必要があります"
  }
}
```

メッセージはちょっと意訳しています。原文にこだわらなければもっと分かりやすく出来ると思いますが、とりあえずこれで伝わるでしょう。多分。
画面の表示は以下のような感じになります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/76791/761e7d2b-ffc1-f09b-53b4-bebdb4e90ef7.png)

変更を保存して、パスワードの変更を試してみます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/76791/f714a9f1-8910-062e-4c26-3dd3188b33fc.png)

メッセージが変わっていれば設定完了です。
変わっていない場合はkeyのスペルがおかしいか、jsonフォーマットが正しくないのかもしれません。
他のメッセージで分かりづらい部分があれば、同じようにメッセージの内容を調査して変更できます。
かなり柔軟ですよね。

# Rocket.Chat version 0.58.x で、IE11からユーザの作成ができない

試したのは0.58.3と0.58.4ですが、chrome, Vivaldi, firefoxからはユーザ作成が出来るのにIEからは一切できませんでした。
何ができないかというと、ユーザ作成時にクリックして開く必要がある右側のサイドバーが一切開かないのですね。
ユーザ情報、ルームの情報なんかも確認できませんでした。

## 0.58.x は使わない？ or IEは非推奨にする？ (or 互換表示を無効にする？)

どうやってもサイドバーが開きません。
仕方ないので 0.57.x 系にダウングレードして使うことにしました。
できるだけ最新を使いたかったのですが、残念。

・・・と思っていたのですが、IEの互換表示機能が影響していた(?)ようです。
ちゃんと調査をしていないので一概にそうとは言えないのですが、互換表示を無効にしたところサイドバーが開くようになりました。

・・・しかし、その後互換表示機能を再度有効にしてみたところ、その状態でもサイドバーが出るようになっていました。
なので原因は不明のままです。
最初詰まった時にブラウザの開発機能を使っていれば良かったんですが、そこまで考えが及んでいませんでした。
どなたかご存知でしたら教えてください。
環境によるのかな。

# 所感

node.jsよくわからないですね。MongoDBも良く分かっていないです。nginxも。
とりあえず使えてはいるけどこういったものを弄る度にどういった仕組みで動いているのかもどんな処理が働いているのかもわからないので「何もわからない・・・何も・・・。」という気分になって悲しい。