[PowerShell]QQのメッセージ受信通知をLINEでスマホに飛ばす

未だに根強いシェアを誇るQQ

中国で最も利用されているメッセンジャーアプリといえばWeChatだろう。

日本でいうLINEに似た立ち位置のコミュニケーションツールだ。

ただ、皆WeChatしか使っていないかというと違っていて、QQを使っている人も未だに少なくない。

QQは古くからあるPC向けのメッセンジャー(チャット)ツールだが、今はスマホにも対応していて通話や支払い機能など、他のアプリと遜色ない機能を搭載ている。

 

残念なことにQQ Android版が終わってる

今でもQQを使う機会が頻繁にあるため、スマホにはAndroid版のQQをインストールしているのだが

001.jpg

QQのダウンロードページでAndroidを選択すると、Google Playストアに移動する...わけではなく、apkファイルがダウンロードされる

そう、公式アプリなのに野良apk配布なのである。

まぁ中国のAndroidアプリではありがちな話ではあるが、今の時代WeChatもWeiboもREDもBilibiliも(バージョンはちょっと古いけど)Google Playストアで配布しているのに、未だに野良apkとは...ちょっと信じられない。

 

 

遂にGoogle Playプロテクトに引っかかる

背に腹は代えられないので野良apkからインストールして使っていたのだが、ある日Google Playプロテクトで有害なアプリとして認定されてしまった。

002.jpg

Playストアで配布しないということは、よからぬ動きをしていて審査に通らないんだろうということは何となく想像していたが、本当に引っかかるとは...。

ここまで来ると即アンインストールするレベルなのだが、他に代替案がないためどうしようもない。野良を許してないiOSを見習えよ。

 

メッセージが自動受信されなくなる

これまではメッセージを受信したらすぐ通知が出ていたのが、この頃から自分でQQアプリを立ち上げないとメッセージを受信しなくなってしまった。

有害アプリ認定されてバックグラウンドの動きを止められてしまったのだろうか。

とにかく不便で仕方がないので、自宅PCにWindows版QQをインストールしてPCから音が鳴るようにすることで、自宅にいる間はメッセージに気付けるようにはなった。

スマホ版のQQは同時に1台しかログインできないが、PC版は並行ログインして使えるので助かった。

 

何とかしてスマホに通知したい

スマホ側のタスクキルを止めたりQQが裏側に行かないよういじったりしてみたが改善されず、もはや正攻法は通用しなさそう...。

ということで、PCのQQでメッセージ受信したらその内容をLINEでスマホに伝える仕組みを作ることにした。

自宅PCは普段つけっぱなしなので理論上は24時間対応できるはずだ。

 

ウィンドウの内容を読み取る

まずはQQのチャットウィンドウから文字情報を読み取るツールを作って...と考えていたが、同じことをやってくれるツールが既にあったためこちらをトライ。

しかし、この方法ではウィンドウ内部の文字列を読み取ることはできなかった。

流石にそこまで簡単に読み取れてしまうとセキュリティ的にダメか。

 

ログファイルを探す

次はログファイルやメッセージファイルの取得。

ログファイルはC:\Users\{ユーザー名}\AppData\Local\Tencent\QQGuildに出力されているようだが、

各ファイルの更新日付を見てもメッセージ受信の度にログが更新されているわけではなさそう。ダメだ。

 

メッセージデータを探す

次に探すのはメッセージデータが保存されているファイル。

QQの個人フォルダはC:\Users\{ユーザー名}\Documents\Tencent Files\{QQ ID番号}に作成される。

010.jpg

このフォルダを見ると、メッセージを受信する度にファイルがいくつか更新されている。

  • メッセージ受信の度に更新されているファイル:
    • Msg3.0index.db
    • Msg3.0index.db-journal
  • 個別のチャットウィンドウを開く度に更新されているファイル:
    • Msg3.0.db
    • Msg3.0.db-journal

見つけたぞ、ここに受信したメッセージが格納されているに違いない...!

 

データベースを覗き見る

これら.dbファイルをテキストエディタで開いてみるとSQLite header 3と書いてあり、SQLiteのデータベースファイルだということが分かる。

007.jpg

ということで早速SQLite3をダウンロードして中身を覗いてみたが...

008.jpg

なぜかデータベースファイルとして認識できず、中身を見ることはできなかった。

Google検索してみると、同じことを試した人がいたようだ。

009.jpg

やり取りから類推するにSQLiteを暗号化するSQLCipherというものが使われているのだろう。

残念ながら暗号化されてしまっているのであれば中身を見るのは難しそうだ。

まぁ今回はメッセージを受信したことさえ分かればいいので、上記データベースファイルが更新されたら通知する、というシンプルな仕組みにしよう。

 

ファイル更新日を取得する

Windows上で簡単なスクリプトを組むのであればPowerShell一択。LinuxならシェルとかPythonを使うんだけど。

$(Get-ItemProperty 001.txt).LastWriteTime

ファイルの更新日はこれで取得できるらしい。簡単だ。

 

LINE Notifyで通知する

PowerShellからLINE Notifyを経由してLINE通知を飛ばす方法はこちらを参考にした

こちらもめちゃくちゃ簡単だ。

 

できあがったPowerShellコード

あとは定期的にファイル更新日をチェックし、前回から変わっていればLINE通知を飛ばすようにした。

# 監視するファイル(QQメッセージ受信時に更新される)
$filename = "C:\Users\{ユーザー名}\Documents\Tencent Files\{QQ ID番号}\Msg3.0index.db-journal"

# ファイルの更新日
$lastTime = (Get-ItemProperty $filename).LastWriteTime

# パラメータ設定
# Line Notify エンドポイント
$uri    =  "https://notify-api.line.me/api/notify"

# トークン
$token  = "Bearer あなたのLINE Notifyアクセストークン"

# トークンをリクエストヘッダ内Authorizationに指定
$header = @{Authorization=$token}

# ファイルの更新日を5秒ごとに監視して変更があれば通知する
for(;;){
    if ($lastTime -eq (Get-ItemProperty $filename).LastWriteTime) {
        //前回と変わっていなければ何もしない
    }
    else {
        echo "File Changed!" + $(Get-ItemProperty $filename).LastWriteTime
        
        # POSTパラメータにメッセージを指定
        $body   = @{message="メッセージを受信したよ"}

        # ★リクエスト実行
        $res = Invoke-RestMethod -Uri $uri -Method Post -Headers $header -Body $body 

        # デバッグ用結果表示
        echo $res
        
        $lastTime = (Get-ItemProperty $filename).LastWriteTime
    }
  Start-Sleep -s 5
}

試しにQQからメッセージを送ってみると、

011.jpg

このようにほぼ同時にLINEにメッセージが届くようになった。

これでひとまずメッセージを取りこぼすことはなくなるだろう。

 

課題もある

とりあえずメッセージの通知はできるようになったが、このままでは使いにくい点も多々ある。

「もうメッセージに気付いているのに延々とLINEでも通知が来てしまう」とか。

向こうからのメッセージに気付いてやり取りを開始したが、やり取り中もずっと向こうからの返信を検知して通知が来てしまうのが煩わしい。

 

また「自分が送ったメッセージでもLINEでも通知が来てしまう」という問題も。

自分が送ったメッセージもPC版のQQが受信し、データベースファイルを更新してしまうようだ。

これでは双方がメッセージを送る度に通知が来てしまい、ちょっと煩すぎる。

 

仕組みの限界はある

ファイルの更新日をチェックするという単純な方法のため、「スマホ側のQQを操作中はLINE通知をオフにしたい」というような複雑なロジックは組みづらい。

「前回通知してから5分間は通知しない」とか、単純な仕組みでもある程度は緩和できそうだが。

本当はこちらからコマンドを送信して一時的にオフにできるようにするとか、もっと機能強化したいところだが、あまり手の込んだことをやり始めると収拾がつかなくなるので可能な限りシンプルにしておきたい。

もうちょっといいやり方があったらいいんだけどなぁ、と思う一方で「ちゃんとアプリ作れよテンセント!」という思いがどうしてもこみ上げてしまう。頼むよ...。

コメントする