Skip to content

Commit

Permalink
Merge pull request #129 from aviate-labs/128-feature/show-subject-in-…
Browse files Browse the repository at this point in the history
…slack-and-telegram

128-feature/show-subject-in-slack-and-telegram
  • Loading branch information
mourginakis authored Dec 4, 2023
2 parents 3f9d457 + 23b1638 commit c77b027
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 29 deletions.
1 change: 1 addition & 0 deletions node_monitor/bot_slack.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ class SlackBot:

def __init__(self, slack_token: str) -> None:
self.client = slack_sdk.WebClient(token=slack_token)


def send_message(
self, slack_channel_name: str,
Expand Down
6 changes: 5 additions & 1 deletion node_monitor/bot_telegram.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ def send_message(
) -> None | requests.exceptions.HTTPError:
"""Send a message to a single Telegram chat."""
max_message_length = 4096
message_parts = textwrap.wrap(message, width=max_message_length)

# TODO: use itertools.batched here when python version is updated to >=3.12.
message_parts = [
message[i:i + max_message_length]
for i in range(0, len(message), max_message_length)]

try:
for part in message_parts:
Expand Down
5 changes: 3 additions & 2 deletions node_monitor/node_monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ def broadcaster(node_provider_id: str,
"""Broadcasts a generic message to a subscriber through their
selected communication channel(s)."""
preferences = subscribers[node_provider_id]
dispatch = f"{subject}\n\n{message}"
if preferences['notify_email'] == True:
recipients = email_recipients.get(node_provider_id, [])
if recipients:
Expand All @@ -125,12 +126,12 @@ def broadcaster(node_provider_id: str,
if self.slack_bot:
channels = slack_channels.get(node_provider_id, [])
if channels:
err1 = self.slack_bot.send_messages(channels, message)
err1 = self.slack_bot.send_messages(channels, dispatch)
if preferences['notify_telegram'] == True:
if self.telegram_bot:
chats = telegram_chats.get(node_provider_id, [])
if chats:
err2 = self.telegram_bot.send_messages(chats, message)
err2 = self.telegram_bot.send_messages(chats, dispatch)
return None

return broadcaster
Expand Down
17 changes: 17 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,23 @@ def pytest_collection_modifyitems(config, items):
item.add_marker(skip_live_telegram)


@pytest.fixture
def fake_data():
fakenode = ic_api.Node(
dc_id='fake_dc_id',
dc_name='fake_dc_name',
node_id='fake_node_id',
node_operator_id='fake_node_operator_id',
node_provider_id='fake_node_provider_id',
node_provider_name='fake_node_provider_name',
owner='fake_owner',
region='fake_region',
status='DOWN',
subnet_id='fake_subnet_id',
)
fakelabel = {'fake_node_id': 'fake_label'}
return fakenode, fakelabel


## Create mock data for testing
## Data was pulled from the ic-api using cURL and stored in json files.
Expand Down
21 changes: 5 additions & 16 deletions tests/test_bot_email.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
from node_monitor.bot_email import EmailBot
import node_monitor.load_config as c
import node_monitor.node_monitor_helpers.messages as messages
import node_monitor.ic_api as ic_api
from tests.conftest import fake_data


# This test sends emails by default
# Usage to disable live email sending:
Expand Down Expand Up @@ -37,24 +38,12 @@ def test_send_emails_mock(mock_smtp):


@pytest.mark.live_email
def test_send_emails_network():
def test_send_emails_network(fake_data):
"""Send real emails over a network to a test inbox and check that
they were received."""

## Create a fake node model
fakenode = ic_api.Node(
dc_id = 'fake_dc_id',
dc_name = 'fake_dc_name',
node_id = 'fake_node_id',
node_operator_id = 'fake_node_operator_id',
node_provider_id = 'fake_node_provider_id',
node_provider_name = 'fake_node_provider_name',
owner = 'fake_owner',
region = 'fake_region',
status = 'DOWN',
subnet_id = 'fake_subnet_id',
)
fakelabel = {'fake_node_id': 'fake_label'}
## Generate fake node and label
fakenode, fakelabel = fake_data

## Init the authenticated email bot instance
email_bot = EmailBot(c.EMAIL_USERNAME, c.EMAIL_PASSWORD)
Expand Down
17 changes: 12 additions & 5 deletions tests/test_bot_slack.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,41 @@
from unittest.mock import patch

from node_monitor.bot_slack import SlackBot
import node_monitor.node_monitor_helpers.messages as messages
import node_monitor.load_config as c
from tests.conftest import fake_data


@patch("slack_sdk.WebClient")
def test_send_message(mock_web_client):
mock_client = mock_web_client.return_value

expected_channel = "#node-monitor"
expected_subject = "Subject message"
expected_message = "Hello, Slack!"
dispatch = f"{expected_subject}\n\n{expected_message}"

slack_bot = SlackBot(c.TOKEN_SLACK)
slack_bot.send_message(expected_channel, expected_message)
slack_bot.send_message(expected_channel, dispatch)

mock_client.chat_postMessage.assert_called_once_with(
channel=expected_channel,
text=expected_message)
text=f"{expected_subject}\n\n{expected_message}")


@pytest.mark.live_slack
def test_send_message_slack():
def test_send_message_slack(fake_data):
"""Send a real test message to a Slack workspace"""
fakenode, fakelabel = fake_data
slack_bot = SlackBot(c.TOKEN_SLACK)
slack_channel_name = "node-monitor"
message = "🔬 This is a test message from Node Monitor"

subject, message = messages.nodes_compromised_message([fakenode], fakelabel)
dispatch = f"{subject}\n\n{message}"

## SlackBot.send_message() normally returns an error without raising
## an exception to prevent NodeMonitor from crashing if the message
## fails to send. We make sure to raise it here to purposely fail the test.
err = slack_bot.send_message(slack_channel_name, message)
err = slack_bot.send_message(slack_channel_name, dispatch)
if err is not None:
raise err
19 changes: 14 additions & 5 deletions tests/test_bot_telegram.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,26 @@
from unittest.mock import patch

import node_monitor.load_config as c
import node_monitor.node_monitor_helpers.messages as messages
from node_monitor.bot_telegram import TelegramBot
from tests.conftest import fake_data


@patch("requests.post")
def test_send_message(mock_post):
telegram_bot = TelegramBot(c.TOKEN_TELEGRAM)
chat_id = "1234567890"
subject = "Test subject"
message = "Test message"
dispatch = f"{subject}\n\n{message}"
payload = {
"chat_id": chat_id,
"text": message
"text": f"{subject}\n\n{message}"
}
mock_response = mock_post.return_value
mock_response.raise_for_status.return_value = None

telegram_bot.send_message(chat_id, message)
telegram_bot.send_message(chat_id, dispatch)

mock_post.assert_called_once_with(
f"https://api.telegram.org/bot{telegram_bot.telegram_token}/sendMessage",
Expand All @@ -27,11 +32,15 @@ def test_send_message(mock_post):


@pytest.mark.live_telegram
def test_send_live_message():
def test_send_live_message(fake_data):
"""Send a real test message to a Telegram channel"""
fakenode, fakelabel = fake_data
telegram_bot = TelegramBot(c.TOKEN_TELEGRAM)
chat_id = "-1001925583150"
message = "🔬 This is a test message from Node Monitor"

err = telegram_bot.send_message(chat_id, message)
subject, message = messages.nodes_compromised_message([fakenode], fakelabel)
dispatch = f"{subject}\n\n{message}"

err = telegram_bot.send_message(chat_id, dispatch)
if err is not None:
raise err

0 comments on commit c77b027

Please sign in to comment.