Exemplo n.º 1
0
import os
import signal
import threading

from bot import ReminderBot


def signals_handler(sig, frame):
    print(f"\n[INFO] Stop signal received, stopping the program...")

    bot.stop()
    stop.set()


print("[INFO] press Ctrl+C to stop the program...")
signal.signal(signal.SIGINT, signals_handler)
signal.signal(signal.SIGTERM, signals_handler)

bot = ReminderBot(os.environ["TOKEN"])
bot.start()

stop = threading.Event()

stop.wait()
Exemplo n.º 2
0
class BotTests(TestCase):
    def setUp(self):
        self.bot = ReminderBot()

    def tearDown(self):
        pass

    @mock.patch('bot.collect.next_alert.get_utc_now')
    def test_create_alert_model(self, mock_utc_now):
        mock_utc_now.return_value = datetime.fromisoformat(
            '2020-06-01T10:00:00+00:00')

        self.bot.receive_message(twilio_request_prototype)

        expected = {
            'phone_number': '+17735551234',
            'timezone': 'America/Chicago',
            'alert_day': 'monday',
            'alert_time': '09:30:00',
            'in_progress': 0,
            'next_alert_at': '2020-06-15T14:30:00+00:00'
        }
        actual = self.bot.create_alert_model()

        self.assertEqual(expected, actual)

    @mock.patch('bot.reminder_bot.twilio_client.send_sms')
    def test_say_intro(self, mock_create_message):
        expected_sid = 'SM87105da94bff44b999e4e6eb90d8eb6a'
        expected_error_code = None

        mock_create_message.return_value.sid = expected_sid
        mock_create_message.return_value.error_code = expected_error_code

        actual = self.bot.say_intro('+17735551234')

        self.assertTrue(mock_create_message.called)
        self.assertEqual(expected_sid, actual.sid)
        self.assertEqual(expected_error_code, actual.error_code)

    @mock.patch('bot.reminder_bot.twilio_client.send_sms')
    def test_say_intro_raises_exception(self, mock_send_sms):
        mock_send_sms.side_effect = ReminderBotException()

        self.bot.receive_message(twilio_request_prototype)
        with self.assertRaises(ReminderBotException):
            self.bot.say_intro('+17735551234')

    @mock.patch('bot.reminder_bot.twilio_client.send_sms')
    def test_say_reminder(self, mock_create_message):
        expected_sid = 'SM87105da94bff44b999e4e6eb90d8eb6a'
        expected_error_code = None

        mock_create_message.return_value.sid = expected_sid
        mock_create_message.return_value.error_code = expected_error_code

        actual = self.bot.say_reminder('+17735551234')

        self.assertTrue(mock_create_message.called)
        self.assertEqual(expected_sid, actual.sid)
        self.assertEqual(expected_error_code, actual.error_code)

    @mock.patch('bot.reminder_bot.twilio_client.send_sms')
    def test_say_reminder_raises_exception(self, mock_send_sms):
        mock_send_sms.side_effect = ReminderBotException()

        self.bot.receive_message(twilio_request_prototype)
        with self.assertRaises(ReminderBotException):
            self.bot.say_reminder('+17735551234')

    def test_say_thanks(self):
        self.bot.receive_message(twilio_request_prototype)
        actual = self.bot.say_thanks()

        # make sure 'say' is in the list of actions
        self.assertTrue(any(x['say'] is not None for x in actual['actions']))

    def test_next_alert_valid(self):
        # change the form post to something valid
        form_post = twilio_request_prototype
        form_post['CurrentInput'] = 'Monday'

        self.bot.receive_message(form_post)
        expected = {'valid': True}
        actual = self.bot.validate_next_alert()

        self.assertEqual(expected, actual)

    def test_next_alert_invalid(self):
        # change the form post to something invalid
        form_post = twilio_request_prototype
        form_post['CurrentInput'] = 'this is wrong'
        self.bot.receive_message(form_post)
        expected = {'valid': False}
        actual = self.bot.validate_next_alert()

        self.assertEqual(expected, actual)

    @mock.patch('bot.reminder_bot.alerts.create_alert')
    def test_subscribe(self, mock_create_alert):
        self.bot.receive_message(twilio_request_prototype)
        actual = self.bot.subscribe()

        self.assertTrue(mock_create_alert.called)
        self.assertIsNone(actual)

    @mock.patch('bot.reminder_bot.alerts.delete_alert')
    def test_unsubscribe(self, mock_delete_alert):
        self.bot.receive_message(twilio_request_prototype)
        actual = self.bot.unsubscribe()

        self.assertTrue(mock_delete_alert.called)
        self.assertIsNone(actual)
Exemplo n.º 3
0
 def setUp(self):
     self.bot = ReminderBot()
Exemplo n.º 4
0
def found_a_job():
    bot = ReminderBot()
    bot.receive_message(request.form)
    bot.unsubscribe()
    return bot.say_congrats()
Exemplo n.º 5
0
def fallback():
    bot = ReminderBot()
    bot.receive_message(request.form)
    return bot.say_fallback()
Exemplo n.º 6
0
def subscribe():
    bot = ReminderBot()
    bot.receive_message(request.form)
    bot.subscribe()
    return bot.say_thanks()
Exemplo n.º 7
0
def validate_next_alert():
    bot = ReminderBot()
    bot.receive_message(request.form)
    return bot.validate_next_alert()
Exemplo n.º 8
0
def ask_next_alert():
    bot = ReminderBot()
    bot.receive_message(request.form)
    return bot.ask_next_alert()
Exemplo n.º 9
0
def say_intro():
    bot = ReminderBot()
    bot.say_intro(request.form['phone_number'])
    return {}
Exemplo n.º 10
0
"""
Lambda function that sends alerts

Invoked via CloudWatch events on a schedule.
"""
from datetime import datetime
from bot import ReminderBot, ReminderBotException
from bot.collect import CollectNextAlert
from bot.repo import alerts as alerts_repo

bot = ReminderBot()


def lambda_handler(event, context):
    pending_alerts = alerts_repo.get_pending_alerts()
    in_progress_alerts = apply_in_progress(pending_alerts)
    sms_alerts = send_sms(in_progress_alerts)
    return pending_alerts


def apply_in_progress(alerts):
    """
    Apply the in_progress flag to alerts

    Prevents other processes from picking them up while being processed
    """
    for alert in alerts:
        alerts_repo.set_in_progress(alert['phone_number'])
    return alerts