11
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

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

Last updated at Posted at 2022-08-28

経緯

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

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

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

妻のトークは消えてしまいましたが、その相手にはトークが残っています。どうやらそれを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をつくればなんとかなるな……と思いました。

ということで成果物です。
成果物

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

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

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

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

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

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に変換できます。

[{
  "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"
}]

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

11
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?