diff --git a/docs/configuration.md b/docs/configuration.md
index 556414e21..e773e1878 100644
--- a/docs/configuration.md
+++ b/docs/configuration.md
@@ -215,16 +215,18 @@ Mandatory parameters are marked as **Required**, which means that they are requi
| `telegram.balance_dust_level` | Dust-level (in stake currency) - currencies with a balance below this will not be shown by `/balance`.
**Datatype:** float
| `telegram.reload` | Allow "reload" buttons on telegram messages.
*Defaults to `True`.
**Datatype:** boolean
| `telegram.notification_settings.*` | Detailed notification settings. Refer to the [telegram documentation](telegram-usage.md) for details.
**Datatype:** dictionary
+| `telegram.allow_custom_messages` | Enable the sending of Telegram messages from strategies via the dataprovider.send_msg() function.
**Datatype:** Boolean
| | **Webhook**
| `webhook.enabled` | Enable usage of Webhook notifications
**Datatype:** Boolean
| `webhook.url` | URL for the webhook. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details.
**Datatype:** String
-| `webhook.webhookentry` | Payload to send on entry. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details.
**Datatype:** String
-| `webhook.webhookentrycancel` | Payload to send on entry order cancel. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details.
**Datatype:** String
-| `webhook.webhookentryfill` | Payload to send on entry order filled. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details.
**Datatype:** String
-| `webhook.webhookexit` | Payload to send on exit. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details.
**Datatype:** String
-| `webhook.webhookexitcancel` | Payload to send on exit order cancel. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details.
**Datatype:** String
-| `webhook.webhookexitfill` | Payload to send on exit order filled. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details.
**Datatype:** String
-| `webhook.webhookstatus` | Payload to send on status calls. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details.
**Datatype:** String
+| `webhook.entry` | Payload to send on entry. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details.
**Datatype:** String
+| `webhook.entry_cancel` | Payload to send on entry order cancel. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details.
**Datatype:** String
+| `webhook.entry_fill` | Payload to send on entry order filled. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details.
**Datatype:** String
+| `webhook.exit` | Payload to send on exit. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details.
**Datatype:** String
+| `webhook.exit_cancel` | Payload to send on exit order cancel. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details.
**Datatype:** String
+| `webhook.exit_fill` | Payload to send on exit order filled. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details.
**Datatype:** String
+| `webhook.status` | Payload to send on status calls. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details.
**Datatype:** String
+| `webhook.allow_custom_messages` | Enable the sending of Webhook messages from strategies via the dataprovider.send_msg() function.
**Datatype:** Boolean
| | **Rest API / FreqUI / Producer-Consumer**
| `api_server.enabled` | Enable usage of API Server. See the [API Server documentation](rest-api.md) for more details.
**Datatype:** Boolean
| `api_server.listen_ip_address` | Bind IP address. See the [API Server documentation](rest-api.md) for more details.
**Datatype:** IPv4
diff --git a/docs/deprecated.md b/docs/deprecated.md
index beceb12ab..3b5b28b81 100644
--- a/docs/deprecated.md
+++ b/docs/deprecated.md
@@ -66,11 +66,11 @@ We will keep a compatibility layer for 1-2 versions (so both `buy_tag` and `ente
#### Naming changes
-Webhook terminology changed from "sell" to "exit", and from "buy" to "entry".
+Webhook terminology changed from "sell" to "exit", and from "buy" to "entry", removing "webhook" in the process.
-* `webhookbuy` -> `webhookentry`
-* `webhookbuyfill` -> `webhookentryfill`
-* `webhookbuycancel` -> `webhookentrycancel`
-* `webhooksell` -> `webhookexit`
-* `webhooksellfill` -> `webhookexitfill`
-* `webhooksellcancel` -> `webhookexitcancel`
+* `webhookbuy`, `webhookentry` -> `entry`
+* `webhookbuyfill`, `webhookentryfill` -> `entry_fill`
+* `webhookbuycancel`, `webhookentrycancel` -> `entry_cancel`
+* `webhooksell`, `webhookexit` -> `exit`
+* `webhooksellfill`, `webhookexitfill` -> `exit_fill`
+* `webhooksellcancel`, `webhookexitcancel` -> `exit_cancel`
diff --git a/docs/strategy_migration.md b/docs/strategy_migration.md
index ac65abff4..b971b81ea 100644
--- a/docs/strategy_migration.md
+++ b/docs/strategy_migration.md
@@ -50,12 +50,12 @@ Note : `forcesell`, `forcebuy`, `emergencysell` are changed to `force_exit`, `fo
* `force_sell` -> `force_exit`
* `emergency_sell` -> `emergency_exit`
* Webhook terminology changed from "sell" to "exit", and from "buy" to entry
- * `webhookbuy` -> `webhookentry`
- * `webhookbuyfill` -> `webhookentryfill`
- * `webhookbuycancel` -> `webhookentrycancel`
- * `webhooksell` -> `webhookexit`
- * `webhooksellfill` -> `webhookexitfill`
- * `webhooksellcancel` -> `webhookexitcancel`
+ * `webhookbuy` -> `entry`
+ * `webhookbuyfill` -> `entry_fill`
+ * `webhookbuycancel` -> `entry_cancel`
+ * `webhooksell` -> `exit`
+ * `webhooksellfill` -> `exit_fill`
+ * `webhooksellcancel` -> `exit_cancel`
* Telegram notification settings
* `buy` -> `entry`
* `buy_fill` -> `entry_fill`
diff --git a/docs/telegram-usage.md b/docs/telegram-usage.md
index 055512f26..db4a309d0 100644
--- a/docs/telegram-usage.md
+++ b/docs/telegram-usage.md
@@ -77,6 +77,7 @@ Example configuration showing the different settings:
"enabled": true,
"token": "your_telegram_token",
"chat_id": "your_telegram_chat_id",
+ "allow_custom_messages": true,
"notification_settings": {
"status": "silent",
"warning": "on",
@@ -115,6 +116,7 @@ Example configuration showing the different settings:
`show_candle` - show candle values as part of entry/exit messages. Only possible values are `"ohlc"` or `"off"`.
`balance_dust_level` will define what the `/balance` command takes as "dust" - Currencies with a balance below this will be shown.
+`allow_custom_messages` completely disable strategy messages.
`reload` allows you to disable reload-buttons on selected messages.
## Create a custom keyboard (command shortcut buttons)
diff --git a/docs/webhook-config.md b/docs/webhook-config.md
index 3677ebe89..00c369919 100644
--- a/docs/webhook-config.md
+++ b/docs/webhook-config.md
@@ -10,37 +10,37 @@ Sample configuration (tested using IFTTT).
"webhook": {
"enabled": true,
"url": "https://maker.ifttt.com/trigger//with/key//",
- "webhookentry": {
+ "entry": {
"value1": "Buying {pair}",
"value2": "limit {limit:8f}",
"value3": "{stake_amount:8f} {stake_currency}"
},
- "webhookentrycancel": {
+ "entry_cancel": {
"value1": "Cancelling Open Buy Order for {pair}",
"value2": "limit {limit:8f}",
"value3": "{stake_amount:8f} {stake_currency}"
},
- "webhookentryfill": {
+ "entry_fill": {
"value1": "Buy Order for {pair} filled",
"value2": "at {open_rate:8f}",
"value3": ""
},
- "webhookexit": {
+ "exit": {
"value1": "Exiting {pair}",
"value2": "limit {limit:8f}",
"value3": "profit: {profit_amount:8f} {stake_currency} ({profit_ratio})"
},
- "webhookexitcancel": {
+ "exit_cancel": {
"value1": "Cancelling Open Exit Order for {pair}",
"value2": "limit {limit:8f}",
"value3": "profit: {profit_amount:8f} {stake_currency} ({profit_ratio})"
},
- "webhookexitfill": {
+ "exit_fill": {
"value1": "Exit Order for {pair} filled",
"value2": "at {close_rate:8f}.",
"value3": ""
},
- "webhookstatus": {
+ "status": {
"value1": "Status: {status}",
"value2": "",
"value3": ""
@@ -57,7 +57,7 @@ You can set the POST body format to Form-Encoded (default), JSON-Encoded, or raw
"enabled": true,
"url": "https://.cloud.mattermost.com/hooks/",
"format": "json",
- "webhookstatus": {
+ "status": {
"text": "Status: {status}"
}
},
@@ -88,17 +88,30 @@ Optional parameters are available to enable automatic retries for webhook messag
"url": "https://",
"retries": 3,
"retry_delay": 0.2,
- "webhookstatus": {
+ "status": {
"status": "Status: {status}"
}
},
```
+Custom messages can be sent to Webhook endpoints via the `self.dp.send_msg()` function from within the strategy. To enable this, set the `allow_custom_messages` option to `true`:
+
+```json
+ "webhook": {
+ "enabled": true,
+ "url": "https://",
+ "allow_custom_messages": true,
+ "strategy_msg": {
+ "status": "StrategyMessage: {msg}"
+ }
+ },
+```
+
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.
-### Webhookentry
+### Entry
-The fields in `webhook.webhookentry` are filled when the bot executes a long/short. Parameters are filled using string.format.
+The fields in `webhook.entry` are filled when the bot executes a long/short. Parameters are filled using string.format.
Possible parameters are:
* `trade_id`
@@ -118,9 +131,9 @@ Possible parameters are:
* `current_rate`
* `enter_tag`
-### Webhookentrycancel
+### Entry cancel
-The fields in `webhook.webhookentrycancel` are filled when the bot cancels a long/short order. Parameters are filled using string.format.
+The fields in `webhook.entry_cancel` are filled when the bot cancels a long/short order. Parameters are filled using string.format.
Possible parameters are:
* `trade_id`
@@ -139,9 +152,9 @@ Possible parameters are:
* `current_rate`
* `enter_tag`
-### Webhookentryfill
+### Entry fill
-The fields in `webhook.webhookentryfill` are filled when the bot filled a long/short order. Parameters are filled using string.format.
+The fields in `webhook.entry_fill` are filled when the bot filled a long/short order. Parameters are filled using string.format.
Possible parameters are:
* `trade_id`
@@ -160,9 +173,9 @@ Possible parameters are:
* `current_rate`
* `enter_tag`
-### Webhookexit
+### Exit
-The fields in `webhook.webhookexit` are filled when the bot exits a trade. Parameters are filled using string.format.
+The fields in `webhook.exit` are filled when the bot exits a trade. Parameters are filled using string.format.
Possible parameters are:
* `trade_id`
@@ -184,9 +197,9 @@ Possible parameters are:
* `open_date`
* `close_date`
-### Webhookexitfill
+### Exit fill
-The fields in `webhook.webhookexitfill` are filled when the bot fills a exit order (closes a Trade). Parameters are filled using string.format.
+The fields in `webhook.exit_fill` are filled when the bot fills a exit order (closes a Trade). Parameters are filled using string.format.
Possible parameters are:
* `trade_id`
@@ -209,9 +222,9 @@ Possible parameters are:
* `open_date`
* `close_date`
-### Webhookexitcancel
+### Exit cancel
-The fields in `webhook.webhookexitcancel` are filled when the bot cancels a exit order. Parameters are filled using string.format.
+The fields in `webhook.exit_cancel` are filled when the bot cancels a exit order. Parameters are filled using string.format.
Possible parameters are:
* `trade_id`
@@ -234,9 +247,9 @@ Possible parameters are:
* `open_date`
* `close_date`
-### Webhookstatus
+### Status
-The fields in `webhook.webhookstatus` are used for regular status messages (Started / Stopped / ...). Parameters are filled using string.format.
+The fields in `webhook.status` are used for regular status messages (Started / Stopped / ...). Parameters are filled using string.format.
The only possible value here is `{status}`.
@@ -280,7 +293,6 @@ You can configure this as follows:
}
```
-
The above represents the default (`exit_fill` and `entry_fill` are optional and will default to the above configuration) - modifications are obviously possible.
Available fields correspond to the fields for webhooks and are documented in the corresponding webhook sections.
@@ -288,3 +300,13 @@ Available fields correspond to the fields for webhooks and are documented in the
The notifications will look as follows by default.

+
+Custom messages can be sent from a strategy to Discord endpoints via the dataprovider.send_msg() function. To enable this, set the `allow_custom_messages` option to `true`:
+
+```json
+ "discord": {
+ "enabled": true,
+ "webhook_url": "https://discord.com/api/webhooks/",
+ "allow_custom_messages": true,
+ },
+```
diff --git a/freqtrade/constants.py b/freqtrade/constants.py
index e0eb5e288..27968bb1b 100644
--- a/freqtrade/constants.py
+++ b/freqtrade/constants.py
@@ -5,7 +5,7 @@ bot constants
"""
from typing import Any, Dict, List, Literal, Tuple
-from freqtrade.enums import CandleType
+from freqtrade.enums import CandleType, RPCMessageType
DEFAULT_CONFIG = 'config.json'
@@ -282,6 +282,7 @@ CONF_SCHEMA = {
'enabled': {'type': 'boolean'},
'token': {'type': 'string'},
'chat_id': {'type': 'string'},
+ 'allow_custom_messages': {'type': 'boolean', 'default': True},
'balance_dust_level': {'type': 'number', 'minimum': 0.0},
'notification_settings': {
'type': 'object',
@@ -344,6 +345,8 @@ CONF_SCHEMA = {
'format': {'type': 'string', 'enum': WEBHOOK_FORMAT_OPTIONS, 'default': 'form'},
'retries': {'type': 'integer', 'minimum': 0},
'retry_delay': {'type': 'number', 'minimum': 0},
+ **dict([(x, {'type': 'object'}) for x in RPCMessageType]),
+ # Below -> Deprecated
'webhookentry': {'type': 'object'},
'webhookentrycancel': {'type': 'object'},
'webhookentryfill': {'type': 'object'},
diff --git a/freqtrade/rpc/discord.py b/freqtrade/rpc/discord.py
index c48508300..8be0eab68 100644
--- a/freqtrade/rpc/discord.py
+++ b/freqtrade/rpc/discord.py
@@ -11,13 +11,12 @@ logger = logging.getLogger(__name__)
class Discord(Webhook):
def __init__(self, rpc: 'RPC', config: Config):
- # super().__init__(rpc, config)
+ self._config = config
self.rpc = rpc
- self.config = config
self.strategy = config.get('strategy', '')
self.timeframe = config.get('timeframe', '')
- self._url = self.config['discord']['webhook_url']
+ self._url = config['discord']['webhook_url']
self._format = 'json'
self._retries = 1
self._retry_delay = 0.1
@@ -31,19 +30,21 @@ class Discord(Webhook):
def send_msg(self, msg) -> None:
- if msg['type'].value in self.config['discord']:
+ if msg['type'].value in self._config['discord']:
logger.info(f"Sending discord message: {msg}")
msg['strategy'] = self.strategy
msg['timeframe'] = self.timeframe
- fields = self.config['discord'].get(msg['type'].value)
+ fields = self._config['discord'].get(msg['type'].value)
color = 0x0000FF
if msg['type'] in (RPCMessageType.EXIT, RPCMessageType.EXIT_FILL):
profit_ratio = msg.get('profit_ratio')
color = (0x00FF00 if profit_ratio > 0 else 0xFF0000)
-
+ title = msg['type'].value
+ if 'pair' in msg:
+ title = f"Trade: {msg['pair']} {msg['type'].value}"
embeds = [{
- 'title': f"Trade: {msg['pair']} {msg['type'].value}",
+ 'title': title,
'color': color,
'fields': [],
@@ -51,7 +52,7 @@ class Discord(Webhook):
for f in fields:
for k, v in f.items():
v = v.format(**msg)
- embeds[0]['fields'].append( # type: ignore
+ embeds[0]['fields'].append(
{'name': k, 'value': v, 'inline': True})
# Send the message to discord channel
diff --git a/freqtrade/rpc/rpc_manager.py b/freqtrade/rpc/rpc_manager.py
index e3b31d225..9c25723b0 100644
--- a/freqtrade/rpc/rpc_manager.py
+++ b/freqtrade/rpc/rpc_manager.py
@@ -88,10 +88,13 @@ class RPCManager:
"""
while queue:
msg = queue.popleft()
- self.send_msg({
- 'type': RPCMessageType.STRATEGY_MSG,
- 'msg': msg,
- })
+ logger.info('Sending rpc strategy_msg: %s', msg)
+ for mod in self.registered_modules:
+ if mod._config.get(mod.name, {}).get('allow_custom_messages', False):
+ mod.send_msg({
+ 'type': RPCMessageType.STRATEGY_MSG,
+ 'msg': msg,
+ })
def startup_messages(self, config: Config, pairlist, protections) -> None:
if config['dry_run']:
diff --git a/freqtrade/rpc/webhook.py b/freqtrade/rpc/webhook.py
index bb3b3922f..19c4166b3 100644
--- a/freqtrade/rpc/webhook.py
+++ b/freqtrade/rpc/webhook.py
@@ -3,7 +3,7 @@ This module manages webhook communication
"""
import logging
import time
-from typing import Any, Dict
+from typing import Any, Dict, Optional
from requests import RequestException, post
@@ -41,36 +41,44 @@ class Webhook(RPCHandler):
"""
pass
+ def _get_value_dict(self, msg: Dict[str, Any]) -> Optional[Dict[str, Any]]:
+ whconfig = self._config['webhook']
+ # Deprecated 2022.10 - only keep generic method.
+ if msg['type'] in [RPCMessageType.ENTRY]:
+ valuedict = whconfig.get('webhookentry')
+ elif msg['type'] in [RPCMessageType.ENTRY_CANCEL]:
+ valuedict = whconfig.get('webhookentrycancel')
+ elif msg['type'] in [RPCMessageType.ENTRY_FILL]:
+ valuedict = whconfig.get('webhookentryfill')
+ elif msg['type'] == RPCMessageType.EXIT:
+ valuedict = whconfig.get('webhookexit')
+ elif msg['type'] == RPCMessageType.EXIT_FILL:
+ valuedict = whconfig.get('webhookexitfill')
+ elif msg['type'] == RPCMessageType.EXIT_CANCEL:
+ valuedict = whconfig.get('webhookexitcancel')
+ elif msg['type'] in (RPCMessageType.STATUS,
+ RPCMessageType.STARTUP,
+ RPCMessageType.WARNING):
+ valuedict = whconfig.get('webhookstatus')
+ elif msg['type'].value in whconfig:
+ # Allow all types ...
+ valuedict = whconfig.get(msg['type'].value)
+ elif msg['type'] in (
+ RPCMessageType.PROTECTION_TRIGGER,
+ RPCMessageType.PROTECTION_TRIGGER_GLOBAL,
+ RPCMessageType.WHITELIST,
+ RPCMessageType.ANALYZED_DF,
+ RPCMessageType.STRATEGY_MSG):
+ # Don't fail for non-implemented types
+ return None
+ return valuedict
+
def send_msg(self, msg: Dict[str, Any]) -> None:
""" Send a message to telegram channel """
try:
- whconfig = self._config['webhook']
- if msg['type'] in [RPCMessageType.ENTRY]:
- valuedict = whconfig.get('webhookentry')
- elif msg['type'] in [RPCMessageType.ENTRY_CANCEL]:
- valuedict = whconfig.get('webhookentrycancel')
- elif msg['type'] in [RPCMessageType.ENTRY_FILL]:
- valuedict = whconfig.get('webhookentryfill')
- elif msg['type'] == RPCMessageType.EXIT:
- valuedict = whconfig.get('webhookexit')
- elif msg['type'] == RPCMessageType.EXIT_FILL:
- valuedict = whconfig.get('webhookexitfill')
- elif msg['type'] == RPCMessageType.EXIT_CANCEL:
- valuedict = whconfig.get('webhookexitcancel')
- elif msg['type'] in (RPCMessageType.STATUS,
- RPCMessageType.STARTUP,
- RPCMessageType.WARNING):
- valuedict = whconfig.get('webhookstatus')
- elif msg['type'] in (
- RPCMessageType.PROTECTION_TRIGGER,
- RPCMessageType.PROTECTION_TRIGGER_GLOBAL,
- RPCMessageType.WHITELIST,
- RPCMessageType.ANALYZED_DF,
- RPCMessageType.STRATEGY_MSG):
- # Don't fail for non-implemented types
- return
- else:
- raise NotImplementedError('Unknown message type: {}'.format(msg['type']))
+
+ valuedict = self._get_value_dict(msg)
+
if not valuedict:
logger.info("Message type '%s' not configured for webhooks", msg['type'])
return
diff --git a/tests/rpc/test_rpc_manager.py b/tests/rpc/test_rpc_manager.py
index d71f38259..21c8b0813 100644
--- a/tests/rpc/test_rpc_manager.py
+++ b/tests/rpc/test_rpc_manager.py
@@ -99,6 +99,7 @@ def test_send_msg_telegram_error(mocker, default_conf, caplog) -> None:
def test_process_msg_queue(mocker, default_conf, caplog) -> None:
telegram_mock = mocker.patch('freqtrade.rpc.telegram.Telegram.send_msg')
+ default_conf['telegram']['allow_custom_messages'] = True
mocker.patch('freqtrade.rpc.telegram.Telegram._init')
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
@@ -108,8 +109,8 @@ def test_process_msg_queue(mocker, default_conf, caplog) -> None:
queue.append('Test message 2')
rpc_manager.process_msg_queue(queue)
- assert log_has("Sending rpc message: {'type': strategy_msg, 'msg': 'Test message'}", caplog)
- assert log_has("Sending rpc message: {'type': strategy_msg, 'msg': 'Test message 2'}", caplog)
+ assert log_has("Sending rpc strategy_msg: Test message", caplog)
+ assert log_has("Sending rpc strategy_msg: Test message 2", caplog)
assert telegram_mock.call_count == 2
diff --git a/tests/rpc/test_rpc_webhook.py b/tests/rpc/test_rpc_webhook.py
index 3bbb85d54..a8fd0c34b 100644
--- a/tests/rpc/test_rpc_webhook.py
+++ b/tests/rpc/test_rpc_webhook.py
@@ -3,7 +3,6 @@
from datetime import datetime, timedelta
from unittest.mock import MagicMock
-import pytest
from requests import RequestException
from freqtrade.enums import ExitType, RPCMessageType
@@ -337,34 +336,18 @@ def test_exception_send_msg(default_conf, mocker, caplog):
caplog)
default_conf["webhook"] = get_webhook_dict()
- default_conf["webhook"]["webhookentry"]["value1"] = "{DEADBEEF:8f}"
+ default_conf["webhook"]["strategy_msg"] = {"value1": "{DEADBEEF:8f}"}
msg_mock = MagicMock()
mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock)
webhook = Webhook(RPC(get_patched_freqtradebot(mocker, default_conf)), default_conf)
msg = {
- 'type': RPCMessageType.ENTRY,
- 'exchange': 'Binance',
- 'pair': 'ETH/BTC',
- 'limit': 0.005,
- 'order_type': 'limit',
- 'stake_amount': 0.8,
- 'stake_amount_fiat': 500,
- 'stake_currency': 'BTC',
- 'fiat_currency': 'EUR'
+ 'type': RPCMessageType.STRATEGY_MSG,
+ 'msg': 'hello world',
}
webhook.send_msg(msg)
assert log_has("Problem calling Webhook. Please check your webhook configuration. "
"Exception: 'DEADBEEF'", caplog)
- 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)
-
# Test no failure for not implemented but known messagetypes
for e in RPCMessageType:
msg = {