【React】LINEアプリにソックリなWEBチャットBOTを作ってみた！！【Redux Starter Kit】

## はじめに

ある日、衝動にかられて・・・
React × Redux + α で LINEアプリにソックリなWEBチャットBOTを作ってみた！！

Reactで作ったLINEモドキなので名前は **RINE** (笑)！

[こちらのサイト](https://rine.netlify.com/)から見れます！
<a href="https://rine.netlify.com/"><img src="https://raw.githubusercontent.com/cacarrot/RINE/master/public/favicon.ico" width="50px" height="50px" alt="RINE"></a>
↑自作したオリジナルアイコン

ちなみに、隠し機能も仕込んであります。
トーク画面で「バルス」と投稿すると・・・！！？

## 主な画面と機能概要

|ホーム画面|トーク一覧画面|トーク画面|
|:--|:--|:--|
|![1_home.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111365/a6b432ca-de9a-be0a-33d7-35611172be29.png)|![2_talk.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111365/9f6a95bc-0e46-9fbb-0f51-fd92481b54f4.png)|![3_talk_detail.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111365/0c99d00f-5453-5bde-84b7-16111a0e6a24.png)|
|<ul><li>友達リストを実装しても役に立たないので、あえて本物とはちょっと違う感じにしてみた</li></ul>|<ul><li>2種類のボットから選択できる</li><li>選択すると→のトーク画面に遷移</li></ul>|<ul><li>テキストと写真が投稿できる</li><li>投稿するとボットからテキストや写真の返信がくる</li><li>上部のメニューからノートの投稿もできる</li></ul>|

- この他にオマケで、フィード画面とノート画面も作ったけど、ここでは省略
- 本物のLINEにあるタイムライン画面やニュース画面などは未実装

## 主な利用技術／ライブラリ／API

- 言語
  - [Typescript](https://www.typescriptlang.org/)
- フレームワーク／ライブラリ
  - [React](https://reactjs.org/)
  - [Create React App](https://create-react-app.dev/)
  - [Redux](https://redux.js.org/)
  - [Redux Starter Kit](https://github.com/reduxjs/redux-starter-kit)
  - [Redux Persist](https://github.com/rt2zz/redux-persist)
  - [Connected React Router](https://github.com/supasate/connected-react-router)
  - [styled-components](https://github.com/styled-components/styled-components)
  - [Storybook](https://github.com/storybookjs/storybook)
  - [react-icons](https://github.com/react-icons/react-icons)
- ホスティングサービス／サーバレスファンクション
  - [Netlify](https://www.netlify.com/)
  - [Netlify Functions](https://www.netlify.com/docs/functions/)
- チャットボットAPI
  - [A3RT Talk API](https://a3rt.recruit-tech.co.jp/product/talkAPI/)
  - [Noby API](https://webapi.cotogoto.ai/)
- その他
  - [Progressive web apps](https://developer.mozilla.org/ja/docs/Web/Progressive_web_apps)
  - [Atomic Design](http://atomicdesign.bradfrost.com/)
  - [Ducks style](https://github.com/erikras/ducks-modular-redux)

## ソースコード

ソースコードは[こちらのリポジトリ](https://github.com/cacarrot/RINE)に置いてある。
微妙にサイズの調整とかバグとかもあるので、気が向いたらまた随時更新するかも。

## 実装におけるポイント

### メッセージの投稿

- トークメッセージの履歴はすべてReduxのStateに保存
  - [Redux Persist](https://github.com/rt2zz/redux-persist)でLocalStorageに永続化
- ボットの発言には、以下のAPIを利用
  - [A3RT Talk API](https://a3rt.recruit-tech.co.jp/product/talkAPI/)
  - [Noby API](https://webapi.cotogoto.ai/)

### 写真の投稿

- 投稿した写真はBase64にエンコードして保存。
- ただし、Base64のような巨大なデータの保存には、LocalStorageには向かない（デスクトップだと大丈夫だが、特にモバイルだと容量の壁にあたりやすい）ため、IndexedDBに保存

### メッセージ受信時にバイブレーションさせる

- [Vibration API](https://developer.mozilla.org/ja/docs/Web/Guide/API/Vibration)を利用すれば、ブラウザでもバイブレーションが再現できる。
  - [ソースコード(VibrationUtil.ts)](https://github.com/cacarrot/RINE/blob/master/src/utils/VibrationUtil.ts)参照

### メッセージを読み上げる

- [Web Speech API](https://developer.mozilla.org/ja/docs/Web/API/Web_Speech_API)を利用すれば、ブラウザでも読み上げが再現できる。
  - [ソースコード(SpeechUtil.ts)](https://github.com/cacarrot/RINE/blob/master/src/utils/SpeechUtil.ts)参照

### 完全な静的サイト

- 完全な静的サイトとして実装し、[Netlify](https://www.netlify.com/)にデプロイ
- オマケ機能として実装したフィード画面は、呼び出し先がCORSで引っかかるので、[Netlify Functions](https://www.netlify.com/docs/functions/)をCORS Proxyとして利用

### PWA対応

- リアルっぽさを追求したかったので、[ホームスクリーン](https://developer.mozilla.org/ja/docs/Web/Progressive_web_apps/Installable_PWAs)にも対応

## 感想と教訓

### 全般

- 見た目は簡単に見えるが、コードとしてはそれなりの規模になるし、作るのには予想以上に骨が折れる。
- やはり、[Redux Starter Kit](https://github.com/reduxjs/redux-starter-kit)は最高に扱いやすい。
- [A3RT Talk API](https://a3rt.recruit-tech.co.jp/product/talkAPI/)に比べると、[Noby API](https://webapi.cotogoto.ai/)はちょっとレスポンスが遅い気がする。

### コンポーネント設計ってやっぱり重要

- Atomic Designっぽく分類してみたものの、実装中に、コンポーネントとして分けるべきかどうか迷う場面が多々あった。
- クラス設計と同じで、一度大きなコンポーネントを作ってしまうと、分けるのが面倒で苦労する。先にちゃんとコンポーネント設計をしてから実装したほうが後々のリファクタの労力は減る。

### デザイン・スタイル設計ってやっぱり重要

- 見た目（主にスタイルシート）をいかに本物に近づけられるか試行錯誤したのが一番苦労した点かもしれない。
- CSSフレームワークは使わず、全部自前でCSS書いた。
- [styled-components](https://github.com/styled-components/styled-components)を利用したが、コンポーネント設計と同様、これも共通化設計をちゃんとしないと、カオスになる（なった）
- アイコンは、[react-icons](https://github.com/react-icons/react-icons)っていうのを利用したけど、本物のLINEで使われているものに近いアイコンがなかなかなかったりもした。

## さいごに

自分のスマホにPWAとしてホームスクリーンを追加してみたところ・・・
わぁ！本物のLINEとそっくりだ！！

![ss.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111365/438e843e-59ac-e587-62fe-96ffea832d2e.png)

こちらからは以上です。