diff --git a/docs/webhook-config.md b/docs/webhook-config.md index db6d4d1ef..2e41ad2cc 100644 --- a/docs/webhook-config.md +++ b/docs/webhook-config.md @@ -40,6 +40,21 @@ Sample configuration (tested using IFTTT). 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. +You can set the POST body format to Form-Encoded (default) or JSON-Encoded. Use `"format": "form"` or `"format": "json"` respectively. Example configuration for Mattermost Cloud integration: + +```json + "webhook": { + "enabled": true, + "url": "https://.cloud.mattermost.com/hooks/", + "format": "json", + "webhookstatus": { + "text": "Status: {status}" + } + }, +``` + +The result would be POST request with e.g. `{"text":"Status: running"}` body and `Content-Type: application/json` header which results `Status: running` message in the Mattermost channel. + 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 diff --git a/freqtrade/rpc/webhook.py b/freqtrade/rpc/webhook.py index 5796201b5..5a30a9be8 100644 --- a/freqtrade/rpc/webhook.py +++ b/freqtrade/rpc/webhook.py @@ -28,6 +28,12 @@ class Webhook(RPCHandler): self._url = self._config['webhook']['url'] + self._format = self._config['webhook'].get('format', 'form') + + if self._format != 'form' and self._format != 'json': + raise NotImplementedError('Unknown webhook format `{}`, possible values are ' + '`form` (default) and `json`'.format(self._format)) + def cleanup(self) -> None: """ Cleanup pending module resources. @@ -66,7 +72,14 @@ class Webhook(RPCHandler): def _send_msg(self, payload: dict) -> None: """do the actual call to the webhook""" + if self._format == 'form': + kwargs = {'data': payload} + elif self._format == 'json': + kwargs = {'json': payload} + else: + raise NotImplementedError('Unknown format: {}'.format(self._format)) + try: - post(self._url, data=payload) + post(self._url, **kwargs) except RequestException as exc: logger.warning("Could not call webhook url. Exception: %s", exc) diff --git a/tests/rpc/test_rpc_webhook.py b/tests/rpc/test_rpc_webhook.py index 4ca547390..5361cd947 100644 --- a/tests/rpc/test_rpc_webhook.py +++ b/tests/rpc/test_rpc_webhook.py @@ -225,3 +225,15 @@ def test__send_msg(default_conf, mocker, caplog): mocker.patch("freqtrade.rpc.webhook.post", post) webhook._send_msg(msg) assert log_has('Could not call webhook url. Exception: ', caplog) + + +def test__send_msg_with_json_format(default_conf, mocker, caplog): + default_conf["webhook"] = get_webhook_dict() + default_conf["webhook"]["format"] = "json" + webhook = Webhook(RPC(get_patched_freqtradebot(mocker, default_conf)), default_conf) + msg = {'text': 'Hello'} + post = MagicMock() + mocker.patch("freqtrade.rpc.webhook.post", post) + webhook._send_msg(msg) + + assert post.call_args[1] == {'json': msg}