Merge pull request #3448 from Theagainmen/Telegram_emojis_V2
Added emoji's to the Telegram RPC
This commit is contained in:
commit
6aed16c146
@ -19,7 +19,6 @@ logger = logging.getLogger(__name__)
|
|||||||
|
|
||||||
logger.debug('Included module rpc.telegram ...')
|
logger.debug('Included module rpc.telegram ...')
|
||||||
|
|
||||||
|
|
||||||
MAX_TELEGRAM_MESSAGE_LENGTH = 4096
|
MAX_TELEGRAM_MESSAGE_LENGTH = 4096
|
||||||
|
|
||||||
|
|
||||||
@ -29,6 +28,7 @@ def authorized_only(command_handler: Callable[..., None]) -> Callable[..., Any]:
|
|||||||
:param command_handler: Telegram CommandHandler
|
:param command_handler: Telegram CommandHandler
|
||||||
:return: decorated function
|
:return: decorated function
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def wrapper(self, *args, **kwargs):
|
def wrapper(self, *args, **kwargs):
|
||||||
""" Decorator logic """
|
""" Decorator logic """
|
||||||
update = kwargs.get('update') or args[0]
|
update = kwargs.get('update') or args[0]
|
||||||
@ -133,7 +133,7 @@ class Telegram(RPC):
|
|||||||
else:
|
else:
|
||||||
msg['stake_amount_fiat'] = 0
|
msg['stake_amount_fiat'] = 0
|
||||||
|
|
||||||
message = ("*{exchange}:* Buying {pair}\n"
|
message = ("\N{LARGE BLUE CIRCLE} *{exchange}:* Buying {pair}\n"
|
||||||
"*Amount:* `{amount:.8f}`\n"
|
"*Amount:* `{amount:.8f}`\n"
|
||||||
"*Open Rate:* `{limit:.8f}`\n"
|
"*Open Rate:* `{limit:.8f}`\n"
|
||||||
"*Current Rate:* `{current_rate:.8f}`\n"
|
"*Current Rate:* `{current_rate:.8f}`\n"
|
||||||
@ -144,7 +144,8 @@ class Telegram(RPC):
|
|||||||
message += ")`"
|
message += ")`"
|
||||||
|
|
||||||
elif msg['type'] == RPCMessageType.BUY_CANCEL_NOTIFICATION:
|
elif msg['type'] == RPCMessageType.BUY_CANCEL_NOTIFICATION:
|
||||||
message = "*{exchange}:* Cancelling Open Buy Order for {pair}".format(**msg)
|
message = "\N{WARNING SIGN} *{exchange}:* " \
|
||||||
|
"Cancelling Open Buy Order for {pair}".format(**msg)
|
||||||
|
|
||||||
elif msg['type'] == RPCMessageType.SELL_NOTIFICATION:
|
elif msg['type'] == RPCMessageType.SELL_NOTIFICATION:
|
||||||
msg['amount'] = round(msg['amount'], 8)
|
msg['amount'] = round(msg['amount'], 8)
|
||||||
@ -153,7 +154,9 @@ class Telegram(RPC):
|
|||||||
microsecond=0) - msg['open_date'].replace(microsecond=0)
|
microsecond=0) - msg['open_date'].replace(microsecond=0)
|
||||||
msg['duration_min'] = msg['duration'].total_seconds() / 60
|
msg['duration_min'] = msg['duration'].total_seconds() / 60
|
||||||
|
|
||||||
message = ("*{exchange}:* Selling {pair}\n"
|
msg['emoji'] = self._get_sell_emoji(msg)
|
||||||
|
|
||||||
|
message = ("{emoji} *{exchange}:* Selling {pair}\n"
|
||||||
"*Amount:* `{amount:.8f}`\n"
|
"*Amount:* `{amount:.8f}`\n"
|
||||||
"*Open Rate:* `{open_rate:.8f}`\n"
|
"*Open Rate:* `{open_rate:.8f}`\n"
|
||||||
"*Current Rate:* `{current_rate:.8f}`\n"
|
"*Current Rate:* `{current_rate:.8f}`\n"
|
||||||
@ -172,14 +175,14 @@ class Telegram(RPC):
|
|||||||
' / {profit_fiat:.3f} {fiat_currency})`').format(**msg)
|
' / {profit_fiat:.3f} {fiat_currency})`').format(**msg)
|
||||||
|
|
||||||
elif msg['type'] == RPCMessageType.SELL_CANCEL_NOTIFICATION:
|
elif msg['type'] == RPCMessageType.SELL_CANCEL_NOTIFICATION:
|
||||||
message = ("*{exchange}:* Cancelling Open Sell Order "
|
message = ("\N{WARNING SIGN} *{exchange}:* Cancelling Open Sell Order "
|
||||||
"for {pair}. Reason: {reason}").format(**msg)
|
"for {pair}. Reason: {reason}").format(**msg)
|
||||||
|
|
||||||
elif msg['type'] == RPCMessageType.STATUS_NOTIFICATION:
|
elif msg['type'] == RPCMessageType.STATUS_NOTIFICATION:
|
||||||
message = '*Status:* `{status}`'.format(**msg)
|
message = '*Status:* `{status}`'.format(**msg)
|
||||||
|
|
||||||
elif msg['type'] == RPCMessageType.WARNING_NOTIFICATION:
|
elif msg['type'] == RPCMessageType.WARNING_NOTIFICATION:
|
||||||
message = '*Warning:* `{status}`'.format(**msg)
|
message = '\N{WARNING SIGN} *Warning:* `{status}`'.format(**msg)
|
||||||
|
|
||||||
elif msg['type'] == RPCMessageType.CUSTOM_NOTIFICATION:
|
elif msg['type'] == RPCMessageType.CUSTOM_NOTIFICATION:
|
||||||
message = '{status}'.format(**msg)
|
message = '{status}'.format(**msg)
|
||||||
@ -189,6 +192,20 @@ class Telegram(RPC):
|
|||||||
|
|
||||||
self._send_msg(message)
|
self._send_msg(message)
|
||||||
|
|
||||||
|
def _get_sell_emoji(self, msg):
|
||||||
|
"""
|
||||||
|
Get emoji for sell-side
|
||||||
|
"""
|
||||||
|
|
||||||
|
if float(msg['profit_percent']) >= 5.0:
|
||||||
|
return "\N{ROCKET}"
|
||||||
|
elif float(msg['profit_percent']) >= 0.0:
|
||||||
|
return "\N{EIGHT SPOKED ASTERISK}"
|
||||||
|
elif msg['sell_reason'] == "stop_loss":
|
||||||
|
return"\N{WARNING SIGN}"
|
||||||
|
else:
|
||||||
|
return "\N{CROSS MARK}"
|
||||||
|
|
||||||
@authorized_only
|
@authorized_only
|
||||||
def _status(self, update: Update, context: CallbackContext) -> None:
|
def _status(self, update: Update, context: CallbackContext) -> None:
|
||||||
"""
|
"""
|
||||||
|
@ -1225,7 +1225,7 @@ def test_send_msg_buy_notification(default_conf, mocker) -> None:
|
|||||||
'open_date': arrow.utcnow().shift(hours=-1)
|
'open_date': arrow.utcnow().shift(hours=-1)
|
||||||
})
|
})
|
||||||
assert msg_mock.call_args[0][0] \
|
assert msg_mock.call_args[0][0] \
|
||||||
== '*Bittrex:* Buying ETH/BTC\n' \
|
== '\N{LARGE BLUE CIRCLE} *Bittrex:* Buying ETH/BTC\n' \
|
||||||
'*Amount:* `1333.33333333`\n' \
|
'*Amount:* `1333.33333333`\n' \
|
||||||
'*Open Rate:* `0.00001099`\n' \
|
'*Open Rate:* `0.00001099`\n' \
|
||||||
'*Current Rate:* `0.00001099`\n' \
|
'*Current Rate:* `0.00001099`\n' \
|
||||||
@ -1247,7 +1247,7 @@ def test_send_msg_buy_cancel_notification(default_conf, mocker) -> None:
|
|||||||
'pair': 'ETH/BTC',
|
'pair': 'ETH/BTC',
|
||||||
})
|
})
|
||||||
assert msg_mock.call_args[0][0] \
|
assert msg_mock.call_args[0][0] \
|
||||||
== ('*Bittrex:* Cancelling Open Buy Order for ETH/BTC')
|
== ('\N{WARNING SIGN} *Bittrex:* Cancelling Open Buy Order for ETH/BTC')
|
||||||
|
|
||||||
|
|
||||||
def test_send_msg_sell_notification(default_conf, mocker) -> None:
|
def test_send_msg_sell_notification(default_conf, mocker) -> None:
|
||||||
@ -1280,7 +1280,7 @@ def test_send_msg_sell_notification(default_conf, mocker) -> None:
|
|||||||
'close_date': arrow.utcnow(),
|
'close_date': arrow.utcnow(),
|
||||||
})
|
})
|
||||||
assert msg_mock.call_args[0][0] \
|
assert msg_mock.call_args[0][0] \
|
||||||
== ('*Binance:* Selling KEY/ETH\n'
|
== ('\N{WARNING SIGN} *Binance:* Selling KEY/ETH\n'
|
||||||
'*Amount:* `1333.33333333`\n'
|
'*Amount:* `1333.33333333`\n'
|
||||||
'*Open Rate:* `0.00007500`\n'
|
'*Open Rate:* `0.00007500`\n'
|
||||||
'*Current Rate:* `0.00003201`\n'
|
'*Current Rate:* `0.00003201`\n'
|
||||||
@ -1308,7 +1308,7 @@ def test_send_msg_sell_notification(default_conf, mocker) -> None:
|
|||||||
'close_date': arrow.utcnow(),
|
'close_date': arrow.utcnow(),
|
||||||
})
|
})
|
||||||
assert msg_mock.call_args[0][0] \
|
assert msg_mock.call_args[0][0] \
|
||||||
== ('*Binance:* Selling KEY/ETH\n'
|
== ('\N{WARNING SIGN} *Binance:* Selling KEY/ETH\n'
|
||||||
'*Amount:* `1333.33333333`\n'
|
'*Amount:* `1333.33333333`\n'
|
||||||
'*Open Rate:* `0.00007500`\n'
|
'*Open Rate:* `0.00007500`\n'
|
||||||
'*Current Rate:* `0.00003201`\n'
|
'*Current Rate:* `0.00003201`\n'
|
||||||
@ -1338,7 +1338,8 @@ def test_send_msg_sell_cancel_notification(default_conf, mocker) -> None:
|
|||||||
'reason': 'Cancelled on exchange'
|
'reason': 'Cancelled on exchange'
|
||||||
})
|
})
|
||||||
assert msg_mock.call_args[0][0] \
|
assert msg_mock.call_args[0][0] \
|
||||||
== ('*Binance:* Cancelling Open Sell Order for KEY/ETH. Reason: Cancelled on exchange')
|
== ('\N{WARNING SIGN} *Binance:* Cancelling Open Sell Order for KEY/ETH. '
|
||||||
|
'Reason: Cancelled on exchange')
|
||||||
|
|
||||||
msg_mock.reset_mock()
|
msg_mock.reset_mock()
|
||||||
telegram.send_msg({
|
telegram.send_msg({
|
||||||
@ -1348,7 +1349,7 @@ def test_send_msg_sell_cancel_notification(default_conf, mocker) -> None:
|
|||||||
'reason': 'timeout'
|
'reason': 'timeout'
|
||||||
})
|
})
|
||||||
assert msg_mock.call_args[0][0] \
|
assert msg_mock.call_args[0][0] \
|
||||||
== ('*Binance:* Cancelling Open Sell Order for KEY/ETH. Reason: timeout')
|
== ('\N{WARNING SIGN} *Binance:* Cancelling Open Sell Order for KEY/ETH. Reason: timeout')
|
||||||
# Reset singleton function to avoid random breaks
|
# Reset singleton function to avoid random breaks
|
||||||
telegram._fiat_converter.convert_amount = old_convamount
|
telegram._fiat_converter.convert_amount = old_convamount
|
||||||
|
|
||||||
@ -1382,7 +1383,7 @@ def test_warning_notification(default_conf, mocker) -> None:
|
|||||||
'type': RPCMessageType.WARNING_NOTIFICATION,
|
'type': RPCMessageType.WARNING_NOTIFICATION,
|
||||||
'status': 'message'
|
'status': 'message'
|
||||||
})
|
})
|
||||||
assert msg_mock.call_args[0][0] == '*Warning:* `message`'
|
assert msg_mock.call_args[0][0] == '\N{WARNING SIGN} *Warning:* `message`'
|
||||||
|
|
||||||
|
|
||||||
def test_custom_notification(default_conf, mocker) -> None:
|
def test_custom_notification(default_conf, mocker) -> None:
|
||||||
@ -1441,7 +1442,7 @@ def test_send_msg_buy_notification_no_fiat(default_conf, mocker) -> None:
|
|||||||
'open_date': arrow.utcnow().shift(hours=-1)
|
'open_date': arrow.utcnow().shift(hours=-1)
|
||||||
})
|
})
|
||||||
assert msg_mock.call_args[0][0] \
|
assert msg_mock.call_args[0][0] \
|
||||||
== '*Bittrex:* Buying ETH/BTC\n' \
|
== '\N{LARGE BLUE CIRCLE} *Bittrex:* Buying ETH/BTC\n' \
|
||||||
'*Amount:* `1333.33333333`\n' \
|
'*Amount:* `1333.33333333`\n' \
|
||||||
'*Open Rate:* `0.00001099`\n' \
|
'*Open Rate:* `0.00001099`\n' \
|
||||||
'*Current Rate:* `0.00001099`\n' \
|
'*Current Rate:* `0.00001099`\n' \
|
||||||
@ -1477,7 +1478,7 @@ def test_send_msg_sell_notification_no_fiat(default_conf, mocker) -> None:
|
|||||||
'close_date': arrow.utcnow(),
|
'close_date': arrow.utcnow(),
|
||||||
})
|
})
|
||||||
assert msg_mock.call_args[0][0] \
|
assert msg_mock.call_args[0][0] \
|
||||||
== '*Binance:* Selling KEY/ETH\n' \
|
== '\N{WARNING SIGN} *Binance:* Selling KEY/ETH\n' \
|
||||||
'*Amount:* `1333.33333333`\n' \
|
'*Amount:* `1333.33333333`\n' \
|
||||||
'*Open Rate:* `0.00007500`\n' \
|
'*Open Rate:* `0.00007500`\n' \
|
||||||
'*Current Rate:* `0.00003201`\n' \
|
'*Current Rate:* `0.00003201`\n' \
|
||||||
@ -1487,6 +1488,29 @@ def test_send_msg_sell_notification_no_fiat(default_conf, mocker) -> None:
|
|||||||
'*Profit:* `-57.41%`'
|
'*Profit:* `-57.41%`'
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('msg,expected', [
|
||||||
|
({'profit_percent': 20.1, 'sell_reason': 'roi'}, "\N{ROCKET}"),
|
||||||
|
({'profit_percent': 5.1, 'sell_reason': 'roi'}, "\N{ROCKET}"),
|
||||||
|
({'profit_percent': 2.56, 'sell_reason': 'roi'}, "\N{EIGHT SPOKED ASTERISK}"),
|
||||||
|
({'profit_percent': 1.0, 'sell_reason': 'roi'}, "\N{EIGHT SPOKED ASTERISK}"),
|
||||||
|
({'profit_percent': 0.0, 'sell_reason': 'roi'}, "\N{EIGHT SPOKED ASTERISK}"),
|
||||||
|
({'profit_percent': -5.0, 'sell_reason': 'stop_loss'}, "\N{WARNING SIGN}"),
|
||||||
|
({'profit_percent': -2.0, 'sell_reason': 'sell_signal'}, "\N{CROSS MARK}"),
|
||||||
|
])
|
||||||
|
def test__sell_emoji(default_conf, mocker, msg, expected):
|
||||||
|
del default_conf['fiat_display_currency']
|
||||||
|
msg_mock = MagicMock()
|
||||||
|
mocker.patch.multiple(
|
||||||
|
'freqtrade.rpc.telegram.Telegram',
|
||||||
|
_init=MagicMock(),
|
||||||
|
_send_msg=msg_mock
|
||||||
|
)
|
||||||
|
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||||
|
telegram = Telegram(freqtradebot)
|
||||||
|
|
||||||
|
assert telegram._get_sell_emoji(msg) == expected
|
||||||
|
|
||||||
|
|
||||||
def test__send_msg(default_conf, mocker) -> None:
|
def test__send_msg(default_conf, mocker) -> None:
|
||||||
mocker.patch('freqtrade.rpc.telegram.Telegram._init', MagicMock())
|
mocker.patch('freqtrade.rpc.telegram.Telegram._init', MagicMock())
|
||||||
bot = MagicMock()
|
bot = MagicMock()
|
||||||
|
Loading…
Reference in New Issue
Block a user