2017-10-13 21:56:18 +02:00
|
|
|
from telegram.ext import Updater, CommandHandler
|
2017-10-05 09:17:02 +02:00
|
|
|
from telegram import ParseMode
|
|
|
|
from block_io import BlockIo, BlockIoAPIError
|
2017-10-06 11:23:04 +02:00
|
|
|
import logging
|
2017-10-05 09:37:34 +02:00
|
|
|
import os
|
2017-12-21 19:56:14 +01:00
|
|
|
import urllib.request
|
|
|
|
import json
|
2018-06-27 20:00:36 +02:00
|
|
|
import argparse
|
2017-10-05 09:17:02 +02:00
|
|
|
|
2018-06-27 20:00:36 +02:00
|
|
|
# BLOCK_IO_API_KEY = os.environ['BLOCK_IO_API_KEY']
|
|
|
|
# BLOCK_IO_PIN = os.environ['BLOCK_IO_PIN']
|
|
|
|
# TELEGRAM_API_KEY = os.environ['TELEGRAM_API_KEY']
|
|
|
|
# NETWORK = os.environ['NETWORK']
|
|
|
|
|
|
|
|
# Parsing arguments
|
|
|
|
|
|
|
|
parser = argparse.ArgumentParser(description='Dogetipbot telegram')
|
|
|
|
parser.add_argument('--block-io-api-key')
|
|
|
|
parser.add_argument('--block-io-pin')
|
|
|
|
parser.add_argument('--telegram-api-key')
|
|
|
|
parser.add_argument('--network')
|
|
|
|
|
|
|
|
args = parser.parse_args()
|
|
|
|
|
|
|
|
BLOCK_IO_API_KEY = args.block_io_api_key
|
|
|
|
BLOCK_IO_PIN = args.block_io_pin
|
|
|
|
TELEGRAM_API_KEY = args.telegram_api_key
|
|
|
|
NETWORK = args.network
|
2017-10-05 09:17:02 +02:00
|
|
|
|
2017-10-06 11:23:04 +02:00
|
|
|
# Logging
|
|
|
|
|
2017-10-06 11:26:19 +02:00
|
|
|
logging.basicConfig(level=logging.ERROR,
|
2017-10-13 21:56:18 +02:00
|
|
|
format='%(asctime)s - %(name)s - %(levelname)s - \
|
|
|
|
%(message)s')
|
2017-10-06 11:23:04 +02:00
|
|
|
|
2017-10-05 09:17:02 +02:00
|
|
|
# Exceptions
|
|
|
|
|
2017-10-13 21:56:18 +02:00
|
|
|
|
2017-10-05 09:17:02 +02:00
|
|
|
class NoAccountError(Exception):
|
|
|
|
pass
|
|
|
|
|
2017-10-13 21:56:18 +02:00
|
|
|
|
2017-10-08 17:08:29 +02:00
|
|
|
class NotEnoughDoge(Exception):
|
2017-10-05 09:17:02 +02:00
|
|
|
pass
|
|
|
|
|
2017-10-13 21:56:18 +02:00
|
|
|
|
2017-10-05 09:17:02 +02:00
|
|
|
class AccountExisting(Exception):
|
|
|
|
pass
|
|
|
|
|
2017-10-13 21:56:18 +02:00
|
|
|
|
2017-10-08 17:41:05 +02:00
|
|
|
class NotValidUnit(Exception):
|
|
|
|
pass
|
|
|
|
|
2017-10-13 21:56:18 +02:00
|
|
|
|
2017-10-05 09:17:02 +02:00
|
|
|
# BlockIO
|
|
|
|
|
|
|
|
version = 2
|
|
|
|
block_io = BlockIo(BLOCK_IO_API_KEY, BLOCK_IO_PIN, version)
|
|
|
|
|
|
|
|
# Core functions
|
|
|
|
|
2017-10-13 21:56:18 +02:00
|
|
|
|
2017-10-05 09:17:02 +02:00
|
|
|
def get_balance(account):
|
|
|
|
try:
|
|
|
|
response = block_io.get_address_by(label=account)
|
|
|
|
except BlockIoAPIError:
|
|
|
|
raise NoAccountError(account)
|
|
|
|
else:
|
2017-10-13 21:56:18 +02:00
|
|
|
return (float(response['data']['available_balance']),
|
|
|
|
float(response['data']['pending_received_balance']))
|
|
|
|
|
2017-10-05 09:17:02 +02:00
|
|
|
|
2017-12-21 19:56:14 +01:00
|
|
|
def get_value(amount):
|
2017-12-21 20:06:32 +01:00
|
|
|
if(NETWORK == "DOGE"):
|
2017-12-21 19:56:14 +01:00
|
|
|
with urllib.request.urlopen("https://api.coinmarketcap.com/v1/ticker" +
|
|
|
|
"/dogecoin/?convert=EUR") as url:
|
|
|
|
data = json.loads(url.read().decode())
|
2017-12-21 20:09:08 +01:00
|
|
|
return round(float(data[0]['price_eur'])*amount, 2)
|
2017-12-21 19:56:14 +01:00
|
|
|
|
|
|
|
|
2017-10-05 09:17:02 +02:00
|
|
|
def create_address(account):
|
|
|
|
try:
|
|
|
|
response = block_io.get_new_address(label=account)
|
|
|
|
except BlockIoAPIError:
|
|
|
|
raise AccountExisting
|
|
|
|
else:
|
|
|
|
return response['data']['address']
|
|
|
|
|
2017-10-13 21:56:18 +02:00
|
|
|
|
2017-10-05 09:17:02 +02:00
|
|
|
def get_address(account):
|
|
|
|
try:
|
|
|
|
response = block_io.get_address_by(label=account)
|
|
|
|
except BlockIoAPIError:
|
|
|
|
raise NoAccountError(account)
|
|
|
|
else:
|
|
|
|
return response['data']['address']
|
|
|
|
|
2017-10-13 21:56:18 +02:00
|
|
|
|
2017-10-05 09:17:02 +02:00
|
|
|
def transaction(sender, receiver, amount):
|
|
|
|
try:
|
2017-10-05 12:20:35 +02:00
|
|
|
if get_balance(sender)[0] > amount:
|
2017-10-13 21:56:18 +02:00
|
|
|
get_address(receiver)
|
|
|
|
return block_io.withdraw_from_labels(amounts=amount,
|
|
|
|
from_labels=sender,
|
|
|
|
to_labels=receiver,
|
|
|
|
priority="low")
|
2017-10-05 09:17:02 +02:00
|
|
|
else:
|
2017-10-08 17:08:29 +02:00
|
|
|
raise NotEnoughDoge
|
|
|
|
except NoAccountError:
|
|
|
|
raise
|
2017-10-05 09:17:02 +02:00
|
|
|
|
2017-10-13 21:56:18 +02:00
|
|
|
|
2017-10-05 09:37:34 +02:00
|
|
|
def address_transaction(account, address, amount):
|
|
|
|
try:
|
2017-10-05 12:20:35 +02:00
|
|
|
if get_balance(account)[0] > amount:
|
2017-10-13 21:56:18 +02:00
|
|
|
return block_io.withdraw_from_labels(amounts=amount,
|
|
|
|
from_labels=account,
|
|
|
|
to_addresses=address,
|
|
|
|
priority="low")
|
2017-10-05 09:37:34 +02:00
|
|
|
else:
|
2017-10-08 17:08:29 +02:00
|
|
|
return NotEnoughDoge
|
|
|
|
except NoAccountError:
|
|
|
|
raise
|
2017-10-05 09:37:34 +02:00
|
|
|
|
2017-10-05 09:17:02 +02:00
|
|
|
# Telegram functions
|
|
|
|
|
2017-10-13 21:56:18 +02:00
|
|
|
|
2017-10-05 09:17:02 +02:00
|
|
|
def start(bot, update):
|
2017-10-13 21:56:18 +02:00
|
|
|
bot.send_message(chat_id=update.message.chat_id,
|
|
|
|
text="Bark ! Je suis un tipbot Dogecoin ! \n\n \
|
|
|
|
Pour commencer envoyez moi /register")
|
|
|
|
|
2017-10-05 09:17:02 +02:00
|
|
|
|
|
|
|
def dogetip(bot, update, args):
|
2017-10-08 17:29:52 +02:00
|
|
|
try:
|
2017-10-08 17:21:06 +02:00
|
|
|
montant = int(args[0])
|
|
|
|
unit = args[1]
|
|
|
|
destinataire = args[2][1:]
|
2017-10-08 17:29:52 +02:00
|
|
|
except (IndexError, ValueError):
|
2017-10-13 21:56:18 +02:00
|
|
|
bot.send_message(chat_id=update.message.chat_id,
|
|
|
|
text="Syntaxe : /dogetip xxx doge @destinataire")
|
2017-10-08 17:29:52 +02:00
|
|
|
else:
|
2017-10-08 17:21:06 +02:00
|
|
|
try:
|
|
|
|
if unit == "doge":
|
2017-10-13 21:56:18 +02:00
|
|
|
response = transaction(update.message.from_user.username,
|
|
|
|
destinataire, montant)
|
2017-10-08 17:41:05 +02:00
|
|
|
else:
|
|
|
|
raise NotValidUnit(unit)
|
2017-10-08 17:21:06 +02:00
|
|
|
except NotEnoughDoge:
|
|
|
|
message = "Pas assez de doge @" + update.message.from_user.username
|
|
|
|
except NoAccountError as e:
|
|
|
|
message = "Vous n'avez pas de compte @" + str(e) + '\n\n' \
|
|
|
|
+ "Utilisez /register pour démarrer"
|
2017-10-08 17:41:05 +02:00
|
|
|
except NotValidUnit as e:
|
2017-10-08 17:43:18 +02:00
|
|
|
message = str(e) + " n'est pas une unité valide"
|
2017-10-08 17:21:06 +02:00
|
|
|
else:
|
|
|
|
txid = response['data']['txid']
|
|
|
|
message = '🚀 Transaction effectuée 🚀\n\n' \
|
2017-10-13 21:56:18 +02:00
|
|
|
+ str(montant) + ' ' + NETWORK + '\n' \
|
|
|
|
+ '@' + update.message.from_user.username + ' → @' \
|
|
|
|
+ destinataire + '\n\n' \
|
|
|
|
+ '<a href="https://chain.so/tx/' + NETWORK + '/' \
|
|
|
|
+ txid + '">Voir la transaction</a>'
|
|
|
|
|
|
|
|
bot.send_message(chat_id=update.message.chat_id,
|
|
|
|
parse_mode=ParseMode.HTML, text=message)
|
2017-10-05 14:59:12 +02:00
|
|
|
|
2017-10-05 09:17:02 +02:00
|
|
|
|
|
|
|
def register(bot, update):
|
|
|
|
try:
|
|
|
|
address = create_address(update.message.from_user.username)
|
|
|
|
except AccountExisting:
|
2017-10-13 21:56:18 +02:00
|
|
|
bot.send_message(chat_id=update.message.chat_id,
|
|
|
|
text="Vous avez déjà un compte")
|
2017-10-05 09:17:02 +02:00
|
|
|
else:
|
|
|
|
bot.send_message(chat_id=update.message.chat_id, text=address)
|
|
|
|
|
2017-10-13 21:56:18 +02:00
|
|
|
|
2017-10-05 09:17:02 +02:00
|
|
|
def infos(bot, update):
|
|
|
|
try:
|
|
|
|
address = get_address(update.message.from_user.username)
|
2017-10-13 21:56:18 +02:00
|
|
|
balance, unconfirmed_balance = \
|
|
|
|
get_balance(update.message.from_user.username)
|
2017-12-21 19:56:14 +01:00
|
|
|
value = get_value(balance)
|
2017-10-05 09:17:02 +02:00
|
|
|
except NoAccountError as e:
|
2017-10-13 21:56:18 +02:00
|
|
|
bot.send_message(chat_id=update.message.chat_id,
|
|
|
|
text="Vous n'avez pas de compte @" + str(e) + '\n\n'
|
|
|
|
+ "Utilisez /register pour démarrer")
|
2017-10-05 09:17:02 +02:00
|
|
|
else:
|
2017-10-13 21:56:18 +02:00
|
|
|
bot.send_message(chat_id=update.message.chat_id,
|
|
|
|
text=address + "\n\n" +
|
2017-12-21 19:56:14 +01:00
|
|
|
str(balance) + " " + NETWORK +
|
|
|
|
" (" + str(value) + " €)" + "\n" +
|
2017-10-13 21:56:18 +02:00
|
|
|
str(unconfirmed_balance) + " " +
|
|
|
|
NETWORK + " unconfirmed")
|
|
|
|
|
2017-10-05 09:17:02 +02:00
|
|
|
|
2017-10-05 09:37:34 +02:00
|
|
|
def withdraw(bot, update, args):
|
|
|
|
montant = int(args[0])
|
|
|
|
unit = args[1]
|
|
|
|
address = args[2]
|
|
|
|
|
|
|
|
if unit == "doge":
|
2017-10-13 21:56:18 +02:00
|
|
|
response = address_transaction(update.message.from_user.username,
|
|
|
|
address, montant)
|
2017-10-05 09:37:34 +02:00
|
|
|
|
|
|
|
txid = response['data']['txid']
|
|
|
|
|
2017-10-13 21:56:18 +02:00
|
|
|
bot.send_message(chat_id=update.message.chat_id,
|
|
|
|
parse_mode=ParseMode.MARKDOWN,
|
|
|
|
text="Transaction effectuée !\n" +
|
|
|
|
"[tx](https://chain.so/tx/" + NETWORK + "/" + txid + ")")
|
2017-10-05 09:37:34 +02:00
|
|
|
|
2017-10-08 16:21:52 +02:00
|
|
|
|
2017-10-05 09:17:02 +02:00
|
|
|
# Telegram initialisation
|
|
|
|
|
|
|
|
updater = Updater(token=TELEGRAM_API_KEY)
|
|
|
|
dispatcher = updater.dispatcher
|
|
|
|
|
|
|
|
start_handler = CommandHandler('start', start)
|
|
|
|
dispatcher.add_handler(start_handler)
|
|
|
|
|
|
|
|
dogetip_handler = CommandHandler('dogetip', dogetip, pass_args=True)
|
|
|
|
dispatcher.add_handler(dogetip_handler)
|
|
|
|
|
|
|
|
register_handler = CommandHandler('register', register)
|
|
|
|
dispatcher.add_handler(register_handler)
|
|
|
|
|
|
|
|
infos_handler = CommandHandler('infos', infos)
|
|
|
|
dispatcher.add_handler(infos_handler)
|
|
|
|
|
2017-10-05 09:37:34 +02:00
|
|
|
withdraw_handler = CommandHandler('withdraw', withdraw, pass_args=True)
|
|
|
|
dispatcher.add_handler(withdraw_handler)
|
2017-10-08 16:18:30 +02:00
|
|
|
|
2018-06-27 20:00:36 +02:00
|
|
|
def main():
|
|
|
|
updater.start_polling()
|
|
|
|
updater.idle()
|