Merge pull request #1024 from freqtrade/feature/webhook

Feature/webhook
This commit is contained in:
Matthias 2018-07-18 20:39:57 +02:00 committed by GitHub
commit 7134c15e86
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 412 additions and 35 deletions

View File

@ -4,13 +4,12 @@
[![Coverage Status](https://coveralls.io/repos/github/freqtrade/freqtrade/badge.svg?branch=develop&service=github)](https://coveralls.io/github/freqtrade/freqtrade?branch=develop)
[![Maintainability](https://api.codeclimate.com/v1/badges/5737e6d668200b7518ff/maintainability)](https://codeclimate.com/github/freqtrade/freqtrade/maintainability)
Simple High frequency trading bot for crypto currencies designed to
support multi exchanges and be controlled via Telegram.
Simple High frequency trading bot for crypto currencies designed to support multi exchanges and be controlled via Telegram.
![freqtrade](https://raw.githubusercontent.com/freqtrade/freqtrade/develop/docs/assets/freqtrade-screenshot.png)
## Disclaimer
This software is for educational purposes only. Do not risk money which
you are afraid to lose. USE THE SOFTWARE AT YOUR OWN RISK. THE AUTHORS
AND ALL AFFILIATES ASSUME NO RESPONSIBILITY FOR YOUR TRADING RESULTS.
@ -23,18 +22,18 @@ We strongly recommend you to have coding and Python knowledge. Do not
hesitate to read the source code and understand the mechanism of this bot.
## Exchange marketplaces supported
- [X] [Bittrex](https://bittrex.com/)
- [X] [Binance](https://www.binance.com/)
- [ ] [113 others to tests](https://github.com/ccxt/ccxt/). _(We cannot guarantee they will work)_
## Features
- [x] **Based on Python 3.6+**: For botting on any operating system -
Windows, macOS and Linux
- [x] **Based on Python 3.6+**: For botting on any operating system - Windows, macOS and Linux
- [x] **Persistence**: Persistence is achieved through sqlite
- [x] **Dry-run**: Run the bot without playing money.
- [x] **Backtesting**: Run a simulation of your buy/sell strategy.
- [x] **Strategy Optimization by machine learning**: Use machine learning to optimize your buy/sell
strategy parameters with real exchange data.
- [x] **Strategy Optimization by machine learning**: Use machine learning to optimize your buy/sell strategy parameters with real exchange data.
- [x] **Whitelist crypto-currencies**: Select which crypto-currency you want to trade.
- [x] **Blacklist crypto-currencies**: Select which crypto-currency you want to avoid.
- [x] **Manageable via Telegram**: Manage the bot with Telegram
@ -43,38 +42,43 @@ strategy parameters with real exchange data.
- [x] **Performance status report**: Provide a performance status of your current trades.
## Table of Contents
- [Quick start](#quick-start)
- [Documentations](https://github.com/freqtrade/freqtrade/blob/develop/docs/index.md)
- [Installation](https://github.com/freqtrade/freqtrade/blob/develop/docs/installation.md)
- [Configuration](https://github.com/freqtrade/freqtrade/blob/develop/docs/configuration.md)
- [Strategy Optimization](https://github.com/freqtrade/freqtrade/blob/develop/docs/bot-optimization.md)
- [Backtesting](https://github.com/freqtrade/freqtrade/blob/develop/docs/backtesting.md)
- [Hyperopt](https://github.com/freqtrade/freqtrade/blob/develop/docs/hyperopt.md)
- [Installation](https://github.com/freqtrade/freqtrade/blob/develop/docs/installation.md)
- [Configuration](https://github.com/freqtrade/freqtrade/blob/develop/docs/configuration.md)
- [Strategy Optimization](https://github.com/freqtrade/freqtrade/blob/develop/docs/bot-optimization.md)
- [Backtesting](https://github.com/freqtrade/freqtrade/blob/develop/docs/backtesting.md)
- [Hyperopt](https://github.com/freqtrade/freqtrade/blob/develop/docs/hyperopt.md)
- [Basic Usage](#basic-usage)
- [Bot commands](#bot-commands)
- [Telegram RPC commands](#telegram-rpc-commands)
- [Support](#support)
- [Help](#help--slack)
- [Bugs](#bugs--issues)
- [Feature Requests](#feature-requests)
- [Pull Requests](#pull-requests)
- [Help](#help--slack)
- [Bugs](#bugs--issues)
- [Feature Requests](#feature-requests)
- [Pull Requests](#pull-requests)
- [Requirements](#requirements)
- [Min hardware required](#min-hardware-required)
- [Software requirements](#software-requirements)
- [Min hardware required](#min-hardware-required)
- [Software requirements](#software-requirements)
## Quick start
Freqtrade provides a Linux/macOS script to install all dependencies and help you to configure the bot.
```bash
git clone git@github.com:freqtrade/freqtrade.git
git checkout develop
cd freqtrade
./setup.sh --install
```
_Windows installation is explained in [Installation doc](https://github.com/freqtrade/freqtrade/blob/develop/docs/installation.md)_
## Documentation
We invite you to read the bot documentation to ensure you understand how the bot is working.
- [Index](https://github.com/freqtrade/freqtrade/blob/develop/docs/index.md)
- [Installation](https://github.com/freqtrade/freqtrade/blob/develop/docs/installation.md)
- [Configuration](https://github.com/freqtrade/freqtrade/blob/develop/docs/configuration.md)
@ -86,7 +90,6 @@ We invite you to read the bot documentation to ensure you understand how the bot
- [Backtesting](https://github.com/freqtrade/freqtrade/blob/develop/docs/backtesting.md)
- [Hyperopt](https://github.com/freqtrade/freqtrade/blob/develop/docs/hyperopt.md)
## Basic Usage
### Bot commands
@ -125,17 +128,15 @@ optional arguments:
```
### Telegram RPC commands
Telegram is not mandatory. However, this is a great way to control your
bot. More details on our
[documentation](https://github.com/freqtrade/freqtrade/blob/develop/docs/index.md)
Telegram is not mandatory. However, this is a great way to control your bot. More details on our [documentation](https://github.com/freqtrade/freqtrade/blob/develop/docs/index.md)
- `/start`: Starts the trader
- `/stop`: Stops the trader
- `/status [table]`: Lists all open trades
- `/count`: Displays number of open trades
- `/profit`: Lists cumulative profit from all finished trades
- `/forcesell <trade_id>|all`: Instantly sells the given trade
(Ignoring `minimum_roi`).
- `/forcesell <trade_id>|all`: Instantly sells the given trade (Ignoring `minimum_roi`).
- `/performance`: Show performance of each finished trade grouped by pair
- `/balance`: Show account balance per currency
- `/daily <n>`: Shows profit or loss per day, over the last n days
@ -144,20 +145,23 @@ bot. More details on our
## Development branches
The project is currently setup in two main branches:
- `develop` - This branch has often new features, but might also cause
breaking changes.
- `master` - This branch contains the latest stable release. The bot
'should' be stable on this branch, and is generally well tested.
The project is currently setup in two main branches:
- `develop` - This branch has often new features, but might also cause breaking changes.
- `master` - This branch contains the latest stable release. The bot 'should' be stable on this branch, and is generally well tested.
## Support
### Help / Slack
For any questions not covered by the documentation or for further
information about the bot, we encourage you to join our slack channel.
- [Click here to join Slack channel](https://join.slack.com/t/highfrequencybot/shared_invite/enQtMjQ5NTM0OTYzMzY3LWMxYzE3M2MxNDdjMGM3ZTYwNzFjMGIwZGRjNTc3ZGU3MGE3NzdmZGMwNmU3NDM5ZTNmM2Y3NjRiNzk4NmM4OGE).
### [Bugs / Issues](https://github.com/freqtrade/freqtrade/issues?q=is%3Aissue)
If you discover a bug in the bot, please
[search our issue tracker](https://github.com/freqtrade/freqtrade/issues?q=is%3Aissue)
first. If it hasn't been reported, please
@ -166,6 +170,7 @@ ensure you follow the template guide so that our team can assist you as
quickly as possible.
### [Feature Requests](https://github.com/freqtrade/freqtrade/labels/enhancement)
Have you a great idea to improve the bot you want to share? Please,
first search if this feature was not [already discussed](https://github.com/freqtrade/freqtrade/labels/enhancement).
If it hasn't been requested, please
@ -174,6 +179,7 @@ and ensure you follow the template guide so that it does not get lost
in the bug reports.
### [Pull Requests](https://github.com/freqtrade/freqtrade/pulls)
Feel like our bot is missing a feature? We welcome your pull requests!
Please read our
[Contributing document](https://github.com/freqtrade/freqtrade/blob/develop/CONTRIBUTING.md)
@ -181,16 +187,18 @@ to understand the requirements before sending your pull-requests.
**Note** before starting any major new feature work, *please open an issue describing what you are planning to do* or talk to us on [Slack](https://join.slack.com/t/highfrequencybot/shared_invite/enQtMjQ5NTM0OTYzMzY3LWMxYzE3M2MxNDdjMGM3ZTYwNzFjMGIwZGRjNTc3ZGU3MGE3NzdmZGMwNmU3NDM5ZTNmM2Y3NjRiNzk4NmM4OGE). This will ensure that interested parties can give valuable feedback on the feature, and let others know that you are working on it.
**Important:** Always create your PR against the `develop` branch, not
`master`.
**Important:** Always create your PR against the `develop` branch, not `master`.
## Requirements
### Min hardware required
To run this bot we recommend you a cloud instance with a minimum of:
* Minimal (advised) system requirements: 2GB RAM, 1GB disk space, 2vCPU
- Minimal (advised) system requirements: 2GB RAM, 1GB disk space, 2vCPU
### Software requirements
- [Python 3.6.x](http://docs.python-guide.org/en/latest/starting/installation/)
- [pip](https://pip.pypa.io/en/stable/installing/)
- [git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)

View File

@ -41,6 +41,11 @@ The table below will list all configuration parameters.
| `telegram.enabled` | true | Yes | Enable or not the usage of Telegram.
| `telegram.token` | token | No | Your Telegram bot token. Only required if `telegram.enabled` is `true`.
| `telegram.chat_id` | chat_id | No | Your personal Telegram account id. Only required if `telegram.enabled` is `true`.
| `webhook.enabled` | false | No | Enable useage of Webhook notifications
| `webhook.url` | false | No | URL for the webhook. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details.
| `webhook.webhookbuy` | false | No | Payload to send on buy. Only required if `webhook.enabled` is `true`. See the [webhook documentationV](webhook-config.md) for more details.
| `webhook.webhooksell` | false | No | Payload to send on sell. Only required if `webhook.enabled` is `true`. See the [webhook documentationV](webhook-config.md) for more details.
| `webhook.webhookstatus` | false | No | Payload to send on status calls. Only required if `webhook.enabled` is `true`. See the [webhook documentationV](webhook-config.md) for more details.
| `db_url` | `sqlite:///tradesv3.sqlite` | No | Declares database URL to use. NOTE: This defaults to `sqlite://` if `dry_run` is `True`.
| `initial_state` | running | No | Defines the initial application state. More information below.
| `strategy` | DefaultStrategy | No | Defines Strategy class to use.

View File

@ -27,6 +27,7 @@ Pull-request. Do not hesitate to reach us on
- [Test your strategy with Backtesting](https://github.com/freqtrade/freqtrade/blob/develop/docs/backtesting.md)
- [Find optimal parameters with Hyperopt](https://github.com/freqtrade/freqtrade/blob/develop/docs/hyperopt.md)
- [Control the bot with telegram](https://github.com/freqtrade/freqtrade/blob/develop/docs/telegram-usage.md)
- [Receive notifications via webhook](https://github.com/freqtrade/freqtrade/blob/develop/docs/webhook-config.md)
- [Contribute to the project](https://github.com/freqtrade/freqtrade/blob/develop/CONTRIBUTING.md)
- [How to contribute](https://github.com/freqtrade/freqtrade/blob/develop/CONTRIBUTING.md)
- [Run tests & Check PEP8 compliance](https://github.com/freqtrade/freqtrade/blob/develop/CONTRIBUTING.md)

74
docs/webhook-config.md Normal file
View File

@ -0,0 +1,74 @@
# Webhook usage
This page explains how to configure your bot to talk to webhooks.
## Configuration
Enable webhooks by adding a webhook-section to your configuration file, and setting `webhook.enabled` to `true`.
Sample configuration (tested using IFTTT).
```json
"webhook": {
"enabled": true,
"url": "https://maker.ifttt.com/trigger/<YOUREVENT>/with/key/<YOURKEY>/",
"webhookbuy": {
"value1": "Buying {pair}",
"value2": "limit {limit:8f}",
"value3": "{stake_amount:8f} {stake_currency}"
},
"webhooksell": {
"value1": "Selling {pair}",
"value2": "limit {limit:8f}",
"value3": "profit: {profit_amount:8f} {stake_currency}"
},
"webhookstatus": {
"value1": "Status: {status}",
"value2": "",
"value3": ""
}
},
```
The url in `webhook.url` should point to the correct url for your webhook. If you're using [IFTTT](https://ifttt.com) (as shown in the sample above) please insert our event and key to the url.
Different payloads can be configured for different events. Not all fields are necessary, but you should configure at least one of the dicts, otherwise the webhook will never be called.
### Webhookbuy
The fields in `webhook.webhookbuy` are filled when the bot executes a buy. Parameters are filled using string.format.
Possible parameters are:
* exchange
* pair
* market_url
* limit
* stake_amount
* stake_amount_fiat
* stake_currency
* fiat_currency
### Webhooksell
The fields in `webhook.webhooksell` are filled when the bot sells a trade. Parameters are filled using string.format.
Possible parameters are:
* exchange
* pair
* gain
* market_url
* limit
* amount
* open_rate
* current_rate
* profit_amount
* profit_percent
* profit_fiat
* stake_currency
* fiat_currency
### Webhookstatus
The fields in `webhook.webhookstatus` are used for regular status messages (Started / Stopped / ...). Parameters are filled using string.format.
The only possible value here is `{status}`.

View File

@ -100,6 +100,15 @@ CONF_SCHEMA = {
},
'required': ['enabled', 'token', 'chat_id']
},
'webhook': {
'type': 'object',
'properties': {
'enabled': {'type': 'boolean'},
'webhookbuy': {'type': 'object'},
'webhooksell': {'type': 'object'},
'webhookstatus': {'type': 'object'},
},
},
'db_url': {'type': 'string'},
'initial_state': {'type': 'string', 'enum': ['running', 'stopped']},
'internals': {

View File

@ -19,8 +19,7 @@ from freqtrade.analyze import Analyze
from freqtrade.exchange import Exchange
from freqtrade.fiat_convert import CryptoToFiatConverter
from freqtrade.persistence import Trade
from freqtrade.rpc import RPCMessageType
from freqtrade.rpc import RPCManager
from freqtrade.rpc import RPCManager, RPCMessageType
from freqtrade.state import State
logger = logging.getLogger(__name__)

View File

@ -23,6 +23,12 @@ class RPCManager(object):
from freqtrade.rpc.telegram import Telegram
self.registered_modules.append(Telegram(freqtrade))
# Enable Webhook
if freqtrade.config.get('webhook', {}).get('enabled', False):
logger.info('Enabling rpc.webhook ...')
from freqtrade.rpc.webhook import Webhook
self.registered_modules.append(Webhook(freqtrade))
def cleanup(self) -> None:
""" Stops all enabled rpc modules """
logger.info('Cleaning up rpc modules ...')

66
freqtrade/rpc/webhook.py Normal file
View File

@ -0,0 +1,66 @@
"""
This module manages webhook communication
"""
import logging
from typing import Any, Dict
from requests import post, RequestException
from freqtrade.rpc import RPC, RPCMessageType
logger = logging.getLogger(__name__)
logger.debug('Included module rpc.webhook ...')
class Webhook(RPC):
""" This class handles all webhook communication """
def __init__(self, freqtrade) -> None:
"""
Init the Webhook class, and init the super class RPC
:param freqtrade: Instance of a freqtrade bot
:return: None
"""
super().__init__(freqtrade)
self._config = freqtrade.config
self._url = self._config['webhook']['url']
def cleanup(self) -> None:
"""
Cleanup pending module resources.
This will do nothing for webhooks, they will simply not be called anymore
"""
pass
def send_msg(self, msg: Dict[str, Any]) -> None:
""" Send a message to telegram channel """
try:
if msg['type'] == RPCMessageType.BUY_NOTIFICATION:
valuedict = self._config['webhook'].get('webhookbuy', None)
elif msg['type'] == RPCMessageType.SELL_NOTIFICATION:
valuedict = self._config['webhook'].get('webhooksell', None)
elif msg['type'] == RPCMessageType.STATUS_NOTIFICATION:
valuedict = self._config['webhook'].get('webhookstatus', None)
else:
raise NotImplementedError('Unknown message type: {}'.format(msg['type']))
if not valuedict:
logger.info("Message type %s not configured for webhooks", msg['type'])
return
payload = {key: value.format(**msg) for (key, value) in valuedict.items()}
self._send_msg(payload)
except KeyError as exc:
logger.exception("Problem calling Webhook. Please check your webhook configuration. "
"Exception: %s", exc)
def _send_msg(self, payload: dict) -> None:
"""do the actual call to the webhook"""
try:
post(self._url, data=payload)
except RequestException as exc:
logger.warning("Could not call webhook url. Exception: %s", exc)

View File

@ -127,3 +127,33 @@ def test_send_msg_telegram_enabled(mocker, default_conf, caplog) -> None:
assert log_has("Sending rpc message: {'type': status, 'status': 'test'}", caplog.record_tuples)
assert telegram_mock.call_count == 1
def test_init_webhook_disabled(mocker, default_conf, caplog) -> None:
""" Test _init() method with Webhook disabled """
caplog.set_level(logging.DEBUG)
conf = deepcopy(default_conf)
conf['telegram']['enabled'] = False
conf['webhook'] = {'enabled': False}
rpc_manager = RPCManager(get_patched_freqtradebot(mocker, conf))
assert not log_has('Enabling rpc.webhook ...', caplog.record_tuples)
assert rpc_manager.registered_modules == []
def test_init_webhook_enabled(mocker, default_conf, caplog) -> None:
"""
Test _init() method with Webhook enabled
"""
caplog.set_level(logging.DEBUG)
default_conf['telegram']['enabled'] = False
default_conf['webhook'] = {'enabled': True, 'url': "https://DEADBEEF.com"}
rpc_manager = RPCManager(get_patched_freqtradebot(mocker, default_conf))
assert log_has('Enabling rpc.webhook ...', caplog.record_tuples)
len_modules = len(rpc_manager.registered_modules)
assert len_modules == 1
assert 'webhook' in [mod.name for mod in rpc_manager.registered_modules]

View File

@ -0,0 +1,179 @@
from unittest.mock import MagicMock
import pytest
from requests import RequestException
from freqtrade.rpc import RPCMessageType
from freqtrade.rpc.webhook import Webhook
from freqtrade.tests.conftest import get_patched_freqtradebot, log_has
def get_webhook_dict() -> dict:
return {
"enabled": True,
"url": "https://maker.ifttt.com/trigger/freqtrade_test/with/key/c764udvJ5jfSlswVRukZZ2/",
"webhookbuy": {
"value1": "Buying {pair}",
"value2": "limit {limit:8f}",
"value3": "{stake_amount:8f} {stake_currency}"
},
"webhooksell": {
"value1": "Selling {pair}",
"value2": "limit {limit:8f}",
"value3": "profit: {profit_amount:8f} {stake_currency}"
},
"webhookstatus": {
"value1": "Status: {status}",
"value2": "",
"value3": ""
}
}
def test__init__(mocker, default_conf):
"""
Test __init__() method
"""
default_conf['webhook'] = {'enabled': True, 'url': "https://DEADBEEF.com"}
webhook = Webhook(get_patched_freqtradebot(mocker, default_conf))
assert webhook._config == default_conf
def test_cleanup(default_conf, mocker) -> None:
"""
Test cleanup() method - not needed for webhook
"""
pass
def test_send_msg(default_conf, mocker):
""" Test send_msg for Webhook rpc class"""
default_conf["webhook"] = get_webhook_dict()
msg_mock = MagicMock()
mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock)
webhook = Webhook(get_patched_freqtradebot(mocker, default_conf))
msg = {
'type': RPCMessageType.BUY_NOTIFICATION,
'exchange': 'Bittrex',
'pair': 'ETH/BTC',
'market_url': "http://mockedurl/ETH_BTC",
'limit': 0.005,
'stake_amount': 0.8,
'stake_amount_fiat': 500,
'stake_currency': 'BTC',
'fiat_currency': 'EUR'
}
msg_mock = MagicMock()
mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock)
webhook.send_msg(msg=msg)
assert msg_mock.call_count == 1
assert (msg_mock.call_args[0][0]["value1"] ==
default_conf["webhook"]["webhookbuy"]["value1"].format(**msg))
assert (msg_mock.call_args[0][0]["value2"] ==
default_conf["webhook"]["webhookbuy"]["value2"].format(**msg))
assert (msg_mock.call_args[0][0]["value3"] ==
default_conf["webhook"]["webhookbuy"]["value3"].format(**msg))
# Test sell
msg_mock = MagicMock()
mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock)
msg = {
'type': RPCMessageType.SELL_NOTIFICATION,
'exchange': 'Bittrex',
'pair': 'ETH/BTC',
'gain': "profit",
'market_url': "http://mockedurl/ETH_BTC",
'limit': 0.005,
'amount': 0.8,
'open_rate': 0.004,
'current_rate': 0.005,
'profit_amount': 0.001,
'profit_percent': 0.20,
'stake_currency': 'BTC',
}
webhook.send_msg(msg=msg)
assert msg_mock.call_count == 1
assert (msg_mock.call_args[0][0]["value1"] ==
default_conf["webhook"]["webhooksell"]["value1"].format(**msg))
assert (msg_mock.call_args[0][0]["value2"] ==
default_conf["webhook"]["webhooksell"]["value2"].format(**msg))
assert (msg_mock.call_args[0][0]["value3"] ==
default_conf["webhook"]["webhooksell"]["value3"].format(**msg))
# Test notification
msg = {
'type': RPCMessageType.STATUS_NOTIFICATION,
'status': 'Unfilled sell order for BTC cancelled due to timeout'
}
msg_mock = MagicMock()
mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock)
webhook.send_msg(msg)
assert msg_mock.call_count == 1
assert (msg_mock.call_args[0][0]["value1"] ==
default_conf["webhook"]["webhookstatus"]["value1"].format(**msg))
assert (msg_mock.call_args[0][0]["value2"] ==
default_conf["webhook"]["webhookstatus"]["value2"].format(**msg))
assert (msg_mock.call_args[0][0]["value3"] ==
default_conf["webhook"]["webhookstatus"]["value3"].format(**msg))
def test_exception_send_msg(default_conf, mocker, caplog):
"""Test misconfigured notification"""
default_conf["webhook"] = get_webhook_dict()
default_conf["webhook"]["webhookbuy"] = None
webhook = Webhook(get_patched_freqtradebot(mocker, default_conf))
webhook.send_msg({'type': RPCMessageType.BUY_NOTIFICATION})
assert log_has(f"Message type {RPCMessageType.BUY_NOTIFICATION} not configured for webhooks",
caplog.record_tuples)
default_conf["webhook"] = get_webhook_dict()
default_conf["webhook"]["webhookbuy"]["value1"] = "{DEADBEEF:8f}"
msg_mock = MagicMock()
mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock)
webhook = Webhook(get_patched_freqtradebot(mocker, default_conf))
msg = {
'type': RPCMessageType.BUY_NOTIFICATION,
'exchange': 'Bittrex',
'pair': 'ETH/BTC',
'market_url': "http://mockedurl/ETH_BTC",
'limit': 0.005,
'stake_amount': 0.8,
'stake_amount_fiat': 500,
'stake_currency': 'BTC',
'fiat_currency': 'EUR'
}
webhook.send_msg(msg)
assert log_has("Problem calling Webhook. Please check your webhook configuration. "
"Exception: 'DEADBEEF'", caplog.record_tuples)
msg_mock = MagicMock()
mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock)
msg = {
'type': 'DEADBEEF',
'status': 'whatever'
}
with pytest.raises(NotImplementedError):
webhook.send_msg(msg)
def test__send_msg(default_conf, mocker, caplog):
"""Test internal method - calling the actual api"""
default_conf["webhook"] = get_webhook_dict()
webhook = Webhook(get_patched_freqtradebot(mocker, default_conf))
msg = {'value1': 'DEADBEEF',
'value2': 'ALIVEBEEF',
'value3': 'FREQTRADE'}
post = MagicMock()
mocker.patch("freqtrade.rpc.webhook.post", post)
webhook._send_msg(msg)
assert post.call_count == 1
assert post.call_args[1] == {'data': msg}
assert post.call_args[0] == (default_conf['webhook']['url'], )
post = MagicMock(side_effect=RequestException)
mocker.patch("freqtrade.rpc.webhook.post", post)
webhook._send_msg(msg)
assert log_has('Could not call webhook url. Exception: ', caplog.record_tuples)