妻のLINEの移行に失敗したので復活させなければ……

## 経緯

妻がスマホを買い替えたので、LINEの移行を行うことになりました。安請け合いをして、適当にボタンをポチポチ……。LINEの移行に失敗し、全トークが消えてしまいました。こんな危険な作業はしっかりと手順書をつくり、実行者と確認者の2人を用意するべきではないでしょうか。

いろいろ解決策を考えてみましたが、どうにもならないようです。妻が深い深い溜息をつき、悲しそうにしていたのでなんとか復活させる方法を考えました。

## LINEのトーク履歴をWEBで表示するようにできる……かな？

妻のトークは消えてしまいましたが、その相手にはトークが残っています。どうやらそれをtext形式で保存する機能もあるようです。このtextをうまいことパースして、ラインのように表示することはできないかと考えました。

以下のようなテキストを拾うことができます。(妻とまだ結婚していない時期のラインです)

```text
2020/12/7(月)
6:10	妻	おはよ
7:01	自分	おはよう
7:01	自分	好きやで
7:11	妻	起きたん
好きよ
7:11	自分	好き
7:11	自分	またね
7:11	妻	またね
7:50	妻	二度寝からおはよ
7:50	自分	おはよう
7:50	自分	可愛いね
```

これをうまいことパースして、DBに登録し、あとはフロント側でうまいことCSSをつくればなんとかなるな……と思いました。

ということで成果物です。
[成果物](https://github.com/araera111/line_text_converter "成果物")

cloneしてtalk.txtを配置し、mongodbのURIを変更すれば使えます。
どういう処理をしているのか解説していきます。

```TypeScript:main.ts
const main = async () => {
  /* ここでファイルを読み込む */
	const file = await readFileSync('talk.txt', 'utf-8');

  /* conv関数で分割する */
	const split = conv(file);

  /* mongoDBに保存する */
	insertLineMessage(split);
};
main();
```

急いでつくったので……とりあえず動け！ という感じ。

```TypeScript:main.ts
const conv = (str: string): Message[] => {
  /* 改行ごとに配列に入れる */
	const splitStr = str.split('\n');

  /* まだメッセージがつづいているかどうかのフラグ */
	let isContinueMessage = false;

  /* メッセージがつづいていたら入れる */
	let continueMessage = '';

  /* 結果をここに保存していく */
	let result: Message[] = [];

  /* 現在の日付を保存しておく */
	let date: string;

	splitStr.forEach((message) => {

    /* もし日付だった場合の処理 */
		if (isLineDate(message)) {

      /* つづかないのでfalse */
			isContinueMessage = false;

			const beforeDate = date;


			date = message;

      /* 前回のメッセージがつづいているかどうかで判断する */
			result =
				continueMessage !== ''
					? [...result, convertLineMessage(continueMessage, beforeDate), convertLineDate(message)]
					: [...result, convertLineDate(message)];
			continueMessage = '';
		}

    /* タブがあるかどうか。タブがあったらだいたいメッセージが新しい */
		if (hasTab(message)) {
      /* 今後のメッセージはつづき */
			isContinueMessage = true;
			result =
				continueMessage !== ''
					? [...result, convertLineMessage(continueMessage, date)]
					: [...result];
			continueMessage = message;
		}
    /* タブがなければ前回のメッセージのつづき */
		if (!hasTab(message) && isContinueMessage) {
			continueMessage = continueMessage + message + '\n';
		}
	});

	return result;
};

```

こんな感じで地道に正規表現を使いつつ処理していきました。

あとはmongodbにinsertすれば準備完了。

下記のようなJSONに変換できます。

```TypeScript
[{
  "type": "date",
  "date": "2020-12-07",
  "name": "date",
  "time": "",
  "text": "2020/12/7(月)"
},{
  "type": "text",
  "name": "妻",
  "time": "6:10",
  "text": "おはよ",
  "date": "2020-12-07"
},{
  "type": "text",
  "name": "私",
  "time": "7:01",
  "text": "おはよう",
  "date": "2020-12-07"
},{
  "type": "text",
  "name": "自分",
  "time": "7:01",
  "text": "好きやで",
  "date": "2020-12-07"
},{
  "type": "text",
  "name": "妻",
  "time": "7:11",
  "text": "起きたん好きよ\n",
  "date": "2020-12-07"
},{
  "type": "text",
  "name": "自分",
  "time": "7:11",
  "text": "好き",
  "date": "2020-12-07"
},{
  "type": "text",
  "name": "自分",
  "time": "7:11",
  "text": "またね",
  "date": "2020-12-07"
},{
  "type": "text",
  "name": "妻",
  "time": "7:11",
  "text": "またね",
  "date": "2020-12-07"
},{
  "type": "text",
  "name": "妻",
  "time": "7:50",
  "text": "二度寝からおはよ",
  "date": "2020-12-07"
},{
  "type": "text",
  "name": "自分",
  "time": "7:50",
  "text": "おはよう",
  "date": "2020-12-07"
},{
  "type": "text",
  "name": "自分",
  "time": "7:50",
  "text": "可愛いね",
  "date": "2020-12-07"
}]
```


フロントエンドでどう表示するか……の部分は次回。