from subprocess import check_output import requests import json import os import time import random import datetime import telepot from telepot.loop import MessageLoop import telepot.api import urllib3 import logging ''' This script is based on the tutorial: http://www.instructables.com/id/Set-up-Telegram-Bot-on-Raspberry-Pi/ ''' ### configure gloabls here bot_api_key = "123:aaaaa" access_ids = [ 310989044, ] # array of user ids that can communicate with the bot master_chat_id = 310989044 # the chat id of the master that gets security notifications cryptoid_id = 353908 # magic?! id to get all transactions from cryptoid.info for the adress below tx_address = "DDyN3knkxb6U7dwmnqvhhAyt4AwRjsbASJ" pivx_cli_dir = "/home/pivx" # location of pivx-cli check_staking_dir = "/home/pivx" # location of check_staking.sh logfile = "bot.err" # name of the logfile # set up logger logging.basicConfig(filename=logfile,level=logging.INFO) # enable retry mechanism in connection pool telepot.api._pools = { 'default': urllib3.PoolManager(num_pools=3, maxsize=10, retries=3, timeout=30), } def sendMessageRetry(chat_id, msg, retry_limit = 3, parse_mode=""): # the ugly retry mechanism should not be necessary, but time will tell... for x in range(0, retry_limit): try: bot.sendMessage(chat_id, msg, parse_mode=parse_mode) return except Exception as e: logging.warning("Error sending message (%s)" % str(e)) time.sleep(2) logging.error("Couldn't send message, tried %d times" % retry_limit) def pivxGetLastTransaction(id): url = "https://chainz.cryptoid.info/explorer/address.tx.dws?coin=pivx&id=%d" % id response = requests.post(url) if response.ok: transactions = str(response.content)[2:-4].split("],[") t = transactions[0].split(",") # grab last transaction tx_hash = t[1].replace("\"", "") amount = t[4] return (tx_hash, float(amount)) else: raise Exception("Error in pivxGetLastTransaction occured: %s" % str(response)) def pivxGetAccountBalance(): j = json.loads(pivxGetInfo()) return j["balance"] def pivxGetInfo(): try: os.chdir(pivx_cli_dir) return str(check_output(["./pivx-cli", "getinfo"])) except CalledProcessError: raise Exception("Error while executing `%s/pivx-cli getinfo` occured" % pivx_cli_dir) def pivxCheckStaking(): try: os.chdir(check_staking_dir) return str(check_output(["./check_staking.sh", ""])) except CalledProcessError: raise Exception("Error while executing `%s/check_staking.sh` occured" % check_staking_dir) def printHelp(chat_id): msg = ""; msg += "/help - display this help.\r\n" msg += "/pivxinfo - reply with output of `pivx-cli getinfo`.\r\n" msg += "/pivxstaking - reply with output of `check_staking.sh`.\r\n" msg += "/roll - reply with a random integer between 1 and 6, like rolling a dice.\r\n" msg += "/time - reply with the current time, like a clock.\r\n" sendMessageRetry(chat_id, msg, parse_mode='Markdown') def handle(msg): chat_id = msg['chat']['id'] command = msg['text'] print 'Got command: %s' % command if msg['from']['id'] not in access_ids: sendMessageRetry(chat_id, "Access denied") sendMessageRetry(master_chat_id, "Access violation detected: %s" % str(msg)) return try: if command == '/help': printHelp(chat_id) elif command == '/pivxinfo': sendMessageRetry(chat_id, pivxGetInfo()) elif command == '/pivxstaking': sendMessageRetry(chat_id, pivxCheckStaking()) elif command == '/roll': sendMessageRetry(chat_id, random.randint(1,6)) elif command == '/time': sendMessageRetry(chat_id, str(datetime.datetime.now())) else: sendMessageRetry(chat_id, "I did not understand you. Type /help for a list of supported commands.") except Exception as e: msg = "Error in handle() occurred: %s" % str(e) logging.error(msg) sendMessageRetry(chat_id, msg) bot = telepot.Bot(bot_api_key) MessageLoop(bot, handle).run_as_thread() print 'I am listening ...' old_balance = None old_tx_hash = None while 1: try: # do this only once at the beginning # NB: we do it inside the loop in case it fails at the first time #if old_balance is None or old_tx_hash is None: if old_balance is None: old_balance = pivxGetAccountBalance() logging.info("Initial balance is: %f" % old_balance) #old_tx_hash, old_tx_amount = pivxGetLastTransaction(cryptoid_id) #logging.info("Initial transaction is: %s %f" % (old_tx_hash, old_tx_amount)) time.sleep(120) # do this only if initialization above was successful #if old_balance is not None and old_tx_hash is not None: if old_balance is not None: # handle (changed) account balance new_balance = pivxGetAccountBalance() diff = new_balance - old_balance if diff != 0: msg = "*Account balance changed* by %f piv" % diff logging.info(msg) sendMessageRetry(master_chat_id, msg, parse_mode='Markdown') old_balance = new_balance ''' # handle (new) transactions new_tx_hash, new_tx_amount = pivxGetLastTransaction(cryptoid_id) if new_tx_hash != old_tx_hash: msg = "*New transaction* on [address](http://www.presstab.pw/phpexplorer/PIVX/address.php?address=%s) detected. Tx amount = %f piv" % (tx_address, new_tx_amount) logging.info(msg) sendMessageRetry(master_chat_id, msg, parse_mode='Markdown') old_tx_hash = new_tx_hash ''' except Exception as e: msg = "Error in main loop occurred: %s" % str(e) logging.error(msg) sendMessageRetry(chat_id, msg)