クジラを見守るBOT(旧GOXアドレス監視BOT)

新しく書く必要があるか疑問ですが、少々変更したので書くことにしました。Twitterでもう終わりとか書きましたがasim氏の記事に触発されてしまい変更を加えました。決してLINE通知がうざくなったわけではありません、はい。以下に変更点を書きます。
1.APIをchainFlyerへ変更。
2.DiscordのBOTへの通知を加えた。
1のAPI変更ですが、前のBOTで使っていたAPIが稀に値を取得しないようなのでやっぱ日本だろ!ってことでbitflyerに用意されているAPIにしました。2のDiscordのBOTのソースはasim氏の記事を参考というよりほぼそのままコピーして書きました。DiscordのBOTの設定の仕方などはasim氏の記事を参考にしてください。
では、以下ソースです。

#!/usr/bin/python3
# coding: utf-8

import requests
import csv
import json
import time
import logging
import logging.handlers
import pandas as pd
import numpy as np
import datetime
from decimal import *

def addressList_to_csv():
    # 監視したいアドレス一覧CSVを用意してそれを読み込み、口座一覧を取得して別のCSVに書き込む
    # 口座一覧用リスト
    sumarryadd_list = []
    # 監視アドレス一覧を読み込む
    with open('./Whale_address.csv', 'r') as af_list:
        ard = csv.DictReader(af_list)
        # アドレス一覧から取得したアドレスを使って口座の残高その他を取得
        for atc_row in ard:
            atc_r = requests.get('https://chainflyer.bitflyer.jp/v1/address/' + str(atc_row['address']))
            atc_data = atc_r.json()
            # 残高が0以外のアドレスをリストに登録(アドレス、残高)
            if atc_data['unconfirmed_balance'] != 0:
                atc_add_list = {"address": atc_data['address'], "unconfirmed_balance": atc_data['unconfirmed_balance']}
                sumarryadd_list.append(atc_add_list)
        # あまり早くまわすとエラーがでるので休憩
        time.sleep(0.6)
    # リストをpandasのデータフレームに格納
    d_list = pd.DataFrame(sumarryadd_list)
    # CSVに口座一覧を書き込み(indexはなし)
    d_list.to_csv('./check_Whale_address.csv', header=True, index=False)
    logger.info("=========== Make AddressList ===========")

def discord(disc_message, url):
    # Discordで発行したWebhookのURLを入れる
    discord_webhook_url = url
    d_data = {"content": " " + disc_message + " "}
    requests.post(discord_webhook_url, data=d_data)

if __name__ == '__main__':
    # 自分のLINEトークンを入れる
    line_notify_token = ''
    line_notify_url = 'https://notify-api.line.me/api/notify'
    # logging設定
    # ログの出力名を設定
    logger = logging.getLogger('Whale_BOTLog')
    # ログレベルの設定
    logger.setLevel(10)
    # ログの出力形式の設定
    formatter = logging.Formatter('%(asctime)s:%(lineno)d:%(levelname)s:%(message)s')
    # ログの出力ローテーションハンドル
    trh = logging.handlers.TimedRotatingFileHandler(filename='./Whale_BOT.log', when='midnight', backupCount=10)
    trh.setLevel(10)
    trh.setFormatter(formatter)
    logger.addHandler(trh)
    # ログのコンソール出力設定
    sh = logging.StreamHandler()
    logger.addHandler(sh)
    sh.setFormatter(formatter)
    # アドレス更新監視フラグ
    flg_change = False
    logger.info("=========== Monitoring ===========")
    while True:
        try:
            # flg_changeがTrueの場合、監視を続ける
            if flg_change:
                # CSVの監視対象口座一覧を取得
                with open('./check_Whale_address.csv', 'r') as f_list:
                    rd = csv.DictReader(f_list)
                    for row in rd:
                        r = requests.get('https://chainflyer.bitflyer.jp/v1/address/' + str(row['address']))
                        data = r.json()
                        logger.info("=========== Chack Address ===========:" + str(row['address']))
                        # 監視対象の口座に動きがあった場合、LINEに飛ばす
                        if Decimal(data['unconfirmed_balance']) != Decimal(row['unconfirmed_balance']):
                            # 変数に値を設定(送金チェックに使用)
                            d_c_balance = Decimal(data['unconfirmed_balance'])/100000000
                            r_c_balance = Decimal(row['unconfirmed_balance'])/100000000
                            # t_valueに以前の残高と今回の残高の差分を設定
                            t_value = r_c_balance - d_c_balance
                            # 500BTC以上の移動のみ検出するようにする
                            if (t_value >= 500) or (t_value <= -500):
                                # 入金変数初期化
                                r_value = 0
                                # 出金変数初期化
                                s_value = 0
                                # 以前の残高と今回取得した値を比較して入金されたか出金されたかを判別する
                                # 以前の残高から今回の残高を引いた値が0より大きい場合
                                if t_value > 0:
                                    # そのまま送金変数へ
                                    s_value = t_value
                                # 以前の残高から今回の残高を引いた値が0より小さい場合
                                else:
                                    # 値がマイナスになってるのでプラスにして入金変数へ
                                    r_value = -t_value
                                # 日付
                                now = datetime.datetime.now()
                                # Discord、LINEのメッセージを作成
                                message = (str(now) + "\n" +
                                           "クジラ注意報 アドレス:\n" +
                                           "『" + str(row['address']) + "』\n" +
                                           "に動きがありました。\n" +
                                           "以前の保有量『" + str('{:.8f}'.format(r_c_balance)) + "BTC』\n" +
                                           "現在の保有量『" + str('{:.8f}'.format(d_c_balance)) + "BTC』\n" +
                                           "入金したのは『" + str('{:.8f}'.format(r_value)) + "BTC』、" + "\n" +
                                           "送金したのは『" + str('{:.8f}'.format(s_value)) + "BTC』になります。" + "\n" +
                                           "お気を付けください。" + "\n" +
                                           "https://chainflyer.bitflyer.jp/Address/" + str(row['address']))
                                # メッセージとDiscordで発行したWebhookのURLを入れる
                                discord(message, '')
                                # 以下LINE通知設定
                                payload = {'message': message}
                                headers = {'Authorization': 'Bearer ' + line_notify_token}
                                line_notify = requests.post(line_notify_url, data=payload, headers=headers)
                            # ログ出力(ログは500BTC未満の移動も出力する)
                            logger.info("Caution!!!!!\n" +
                                        "Address is :" + str(row['address']) + "\n" +
                                        "Before is :" + str('{:.8f}'.format(r_c_balance)) + "\n" +
                                        "After is :" + str('{:.8f}'.format(d_c_balance)) + "\n" +
                                        "Fluctuation " + str('{:.8f}'.format(t_value)) + "BTC")
                            # アドレスが更新されているので次回のループではリストを更新する
                            flg_change = False
                    # あまり早く回すとエラーが出るので休憩
                    time.sleep(0.6)
            # flg_changeがFalseの場合、監視リストを取り直してflg_changeをTrueに戻す
            else:
                addressList_to_csv()
                flg_change = True
            time.sleep(60)
        except Exception as x:
            logger.info(x)
            time.sleep(5)

以下、大口と呼ばれるBITCOINを0.4%以上保有するアドレス(大手取引所含む)と将来売るだろうGOXのアドレスになります。GOXのアドレスはBITCOINを保有していないアドレスは削除しました。以下のアドレスをコピーしてファイル名『Whale_address.csv』とし、実行ファイルと同じ場所においてください。

address
17KcBp8g76Ue8pywgうjta4q8Ds6wK4bEKp7
19c8sUa54yQuRTVDfJa3iDkkCaFkzBJLPB
1HdKXsNQtzDcfB6PGM7DWTgX9vhBWsz1ak
1MvpYtqgBH7CXbTutrSVCTNHPzm9vakuRy
18M1Z337NqLtK9V69bssnQUYsvb7hmfSFS
1NA3Tj4b1jtx9eGELe31Jw4DrzTqKP3ayH
1BXyJc6BVuTFnHQCcjiWX2xmCPNVfaSZeb
1BzK87zuqidZn489Wb2oLSktrjKrX7TLKe
14p4w3TRCd6NMRSnzTmgdvQhNnbrAmzXmy
1KFDUSZuapMv7YaDmL6cyrHTQhma1MtFYs
1DedUxzgwErg4ipNi988wPgLk5thwciKcc
1Pq7hooZbEAz5y3QMnqFY8C5xqTdrjUwcA
1FhRuUkk8Bfx8FJDemtxhKAR4F8GCNKrXG
1Drshi4RAuvxk4T6Bkq959ZvLbvy7b1wvD
13xGCc4TPSYY9GYxBGVNox82KxyjkFnxMX
1Hb8DmmvvtTYv5RBLuGtDxznkZwVpd5Vjy
13ahgw8sM95EDbugT3tdb8TYoMU46Uw7PX
17Tf4bVQaCzwWrDWGRPC97RLCHnU4LY8Qr
13sXfpp2V16nnxYvW9FHHoBdMa3k98uJw8
1JztCg7eKSkb1vi7NzGJynXpLZmoaFtYud
13dXFMyG22EsUsvaWhCqUo7SXuX7rBPog6
13Wv5hGhubAWgSPWtXYh6s1s7HX2N1psYg
14mP6caC5dFhHdVAPCjPKM8Nm36MBDR5pM
18YDgRhxsomuBZ1g9d8Y1JuRmxDhF8Bvff
1GyDutntMuYyA2vQGW5HFcKLfx4cbDdbJq
1N5X4kcZ56uRh24XrZoztS9Vb8G7j1Joop
1JtgU6Uo1RAt5eiMf34EehyatUezBQP36C
16jZZkMYqjUWUtQ9DfDvHdH5ko5BcnH9XQ
1HuPVqz2xvf1rdNFUqd62vRTyxP3jeX9Ch
12KkeeRkiNS13GMbg7zos9KRn9ggvZtZgx
1H4K3dGfNbAN4AUfyUrpkGpjrd83sntDpV
1HzEPuenagLEWj68igDXBBXrzc293RuR5V
12T4oSNd4t9ty9fodgNd47TWhK35pAxDYN
195HvmjXgoF3M5vFaBC8swZPhwrE7VhxRD
1Mm9brripN4RPTzkGnRrbt5uDWdqbfk2iX
1LzwbLgdKd4eFLkpRdeajkH1YJkVCip2zj
1MPJJzRaT8vLhowNB4dVyWRxxu79dq7WkB
19eihBKk6e5YD2QXAe4SVUsxRLLnTDKsfv
1CZsoJfkknbnW5fKrt1oR7N1ALE5WmDGP1
1GkZQcDy8V6pmHFZqUBUBCnN9dc2hoWasD
14USZ558Rr28AZwdJQyciSQkN4JT1cEoj2
15SeCwVCFx5cWyrcdD1Zp1D1zxjH2SELPg
15U4VsmWG1cdXAtizvQsW4r7iMxzp64Tgu
1BDZBTb4KE5oq6wAgA6EvAe3uCFRrAbPao
1LueUjEuBgc7cQhsWT8zAfTjcWmrNBZXaR
1FrV9hv1AW34BGJvobJatyzUWYDWB9epRW
156HpsWfgkWYLT63uhTAGUSUF3ZMnB9WWj
1HX4s3JeFU3x1eQgPNQVAdx6FoCtbb1hr8
19KiFrafXEyJCUDYFEv3B6tBUwyfFo7kNU
1PRXQEoL8vzEzoJJ9hbtAP6NaV2daccAUn
1G23Uzwj55k2A9TRwaTknqGav66oDTkWCu
18ok25NTkdrUzdByFJCNVsqVYkujZ8aP45
1JVU43LNKXqa9W5fCh8tppxDDEWgfeNg46
1LLc8aA9C9LLULGbYCYSFKXgxKP2DXdCqP
18hcZVFPqDNAovJmb9vA6hEJrDz6uWXNGh
1HweN9p41BY2RBunsPqyVuheEq7gVoxA9u
16w6sZBDP58yyeyZAcvnxcEGJpwR9amM6g
19Cr4zXpKw43xLJhFZW9iv4DDNtQk2TDeB
1C5aU4Xnpd3txbxehk46UZgiuNB8QdpHCH
15kNZcrhxeFZgVVLK2Yjzd69tRidbFdJEZ
1Ar6meJQCkNoC9wnPcyRNNpzX5fBDaGcKd
17etv2L3nhk6SCcWSNW4eoZkBy84izAm17
15QcKCa84ZCHxbsqXDoKhi5XbmQB8jPEAd
1MkyfwJf7uhWTmVGGQXfcT5ip31DoHMxsz
1JVmoJT3471FjsX5H4hAeR1RyrDgpkHbpm
1LS5EFRRMDgMQusW6zokQUHjzNUfy6HHCQ
199Yxz2TJGtND3QKsHTptTJivqSaUZBvku
1PxGTuJzDx1ceFHx4Z5CHaWuhiPBNovmZD
14LuAvrRzAmeikgaafs7H5695xs5dVXqA5
1LncfoCX1yzuiW3hzejarvgZ1WahnAQ4o4
3D2oetdNuZUqQHPJmcMDDHYoqkyNVsFk9r
16rCmCmbuWDhPjWTrpQGaU3EPdZF7MTdUk
3Nxwenay9Z8Lc9JBiywExpnEFiLp6Afp8v
16ftSEQ4ctQFDtVZiUBusQUjRrGhM3JYwe
3Cbq7aT1tY8kMxWLbitaG7yT6bPbKChq64
1KAt6STtisWMMVo5XGdos9P7DBNNsFfjx7
1FeexV6bAHb8ybZjqQMjJrcCrHGW9sb6uF
18rnfoQgGo1HqvVQaAN4QnxjYE7Sez9eca
336xGpGweq1wtY4kRTuA4w6d7yDkBU9czU
1PnMfRF2enSZnR6JSexxBHuQnxG8Vo5FVK
1HQ3Go3ggs8pFnXuHVHRytPCq5fGG8Hbhx
1PnMfRF2enSZnR6JSexxBHuQnxG8Vo5FVK
1AhTjUMztCihiTyA4K6E3QEpobjWLwKhkR
1DiHDQMPFu4p84rkLn6Majj2LCZZZRQUaa
1EBHA1ckUWzNKN7BMfDwGTx6GKEbADUozX
1LdRcdxfbSnmCYYNdeYpUnztiYzVfBEQeC
1JCe8z4jJVNXSjohjM4i9Hh813dLCNx2Sy
1AC4fMwgY8j9onSbXEWeH6Zan8QGMSdmtA

最後にこのソースを使っているDiscordを載せておきます。間違いなく放置でたいした活動はしないと思うので通知だけほしいという人用になります。あとAWSで動いているのでそのうち止まるかもしれません。予定では2019年の3月くらいまでは大丈夫です。ではご覧いただきありがとうございました。

追記:
1.500BTC未満の移動の検出をやめました。
2.複数のDiscordに送信することを想定してDiscord関数に引数を追加
3.数値の精度を上げるためにDecimal関数を使用
4.クジラ報告のメッセージを変更
5.小数点以下の値のフォーマットを修正
6.LINE通知にアドレスのURLを追加
7.使用する残高を「確定残高」から「未確定残高」に変更することにより、報告をアドレスが送金してからすぐにできるように変更。「報告精度」よりも「報告速度」を重視しました

クジラを見守る会

この記事が気に入ったらサポートをしてみませんか?