Ejemplo n.º 1
0
def send_daily_report(hours_of_day: list):
    audience = get_all_humans_for_telegram_notifications(
        hours_of_day=hours_of_day)

    # create bot
    bot = get_telegram_bot_instance()
    # send to audience
    notify_admin = True
    count = 0
    for member in audience:
        try:
            human = Human(human_id=member[HumanProperties.ID.value])

            # get most recent coordinates
            most_recent_location = human.get_most_recent_location()
            if most_recent_location is None:
                return "NOTHING TO SHOW. SHARE YOUR LOCATION FIRST."
            lat, lng = most_recent_location
            human.send_proximity_alert(lat=lat, lng=lng)
            count += 1

        except Exception as e:
            if notify_admin:
                bot.send_message(
                    chat_id=int(
                        CONFIG.get('telegram-credentials-telegram-admin-id')),
                    text="[ADMIN] `send_daily_report` exception : {}".format(
                        e))
                notify_admin = False

    # alert admin
    bot.send_message(
        chat_id=int(CONFIG.get('telegram-credentials-telegram-admin-id')),
        text="[ADMIN] Sent proximity report to {}/{} humans.".format(
            count, len(audience)))
Ejemplo n.º 2
0
def fulfill_help_request(human: Human) -> bool:
    bot = get_telegram_bot_instance()
    try:
        log_sent_message(bot.send_message(
            chat_id=human.telegram_human_id,
            text="Click here to talk to us: @OpendemicTeam"
        ), human_id=human.id)
    except Exception as e:
        logger.error(e)
        return False
    return True
Ejemplo n.º 3
0
def fulfill_report_telegram_command(human: Human) -> bool:
    bot = get_telegram_bot_instance()
    try:
        log_sent_message(bot.send_message(
            chat_id=human.telegram_human_id,
            text="See options below 👇",
            reply_markup=get_telegram_menu()
        ), human_id=human.id)
    except Exception as e:
        logger.error(e)
        return False
    return True
Ejemplo n.º 4
0
def fulfill_invalid_telegram_command(human: Human) -> bool:
    bot = get_telegram_bot_instance()
    try:
        log_sent_message(bot.send_message(
            chat_id=human.telegram_human_id,
            text="Oops... This command is not valid. Type `/` to see valid commands.",
            reply_markup=get_telegram_menu()
        ), human_id=human.id)
    except Exception as e:
        logger.error(e)
        return False
    return True
Ejemplo n.º 5
0
def fulfill_log_symptom(human: Human, symptom_name: str) -> bool:
    bot = get_telegram_bot_instance()

    try:
        human.log_symptom(symptom_name=symptom_name)

        log_sent_message(bot.send_message(
            chat_id=human.telegram_human_id,
            text="Noted!"
        ), human_id=human.id)
    except Exception as e:
        logger.error(e)
        return False
    return True
Ejemplo n.º 6
0
def fulfill_my_map_request(human: Human) -> bool:
    bot = get_telegram_bot_instance()
    try:
        bot.send_message(
            chat_id=human.telegram_human_id,
            text="See who's around you 👇",
            parse_mode='markdown',
            reply_markup=make_reply_keyboard_markup(markup_map=[
                {'text': "🌍 See Map", 'url': CONFIG.get('client-url')},
            ])
        )
    except Exception as e:
        logger.error(e)
        return False
    return True
Ejemplo n.º 7
0
def send_feedback_request(hours_of_day: list):
    audience = get_all_humans_for_telegram_notifications(
        hours_of_day=hours_of_day)

    # create bot
    bot = get_telegram_bot_instance()

    # send to audience
    notify_admin = True
    count = 0
    for member in audience:
        try:
            bot.send_message(
                chat_id=member[HumanProperties.TELEGRAM_HUMAN_ID.value],
                text=
                "*[🤙 Feedback Request]* Please share your feedback on the product by clicking here: @OpendemicTeam",
                parse_mode='markdown',
                reply_markup=get_telegram_menu())
        except Exception as e:
            if notify_admin:
                bot.send_message(
                    chat_id=int(
                        CONFIG.get('telegram-credentials-telegram-admin-id')),
                    text="[ADMIN] `send_feedback_request` exception : {}".
                    format(e))
                notify_admin = False
            # try to unsubscribe
            try:
                human = Human(human_id=member[HumanProperties.ID.value])
                human.unsubscribe()
            except Exception as unsb_e:
                pass
        else:
            count += 1

    # alert admin
    bot.send_message(
        chat_id=int(CONFIG.get('telegram-credentials-telegram-admin-id')),
        text="[ADMIN] Sent feedback request to {}/{} humans.".format(
            count, len(audience)))
Ejemplo n.º 8
0
def send_reminders(hours_of_day: list):
    audience = get_all_humans_for_telegram_notifications(
        hours_of_day=hours_of_day)

    # create bot
    bot = get_telegram_bot_instance()

    # send to audience
    notify_admin = True
    count = 0
    for member in audience:
        try:
            bot.send_message(
                chat_id=member[HumanProperties.TELEGRAM_HUMAN_ID.value],
                text=
                "👇 Remember to report your location (always) and symptoms (if any) 👇",
                reply_markup=get_telegram_menu())

        except Exception as e:
            if notify_admin:
                bot.send_message(
                    chat_id=int(
                        CONFIG.get('telegram-credentials-telegram-admin-id')),
                    text="[ADMIN] `send_reminders` exception : {}".format(e))
                notify_admin = False
            # try to unsubscribe
            try:
                human = Human(human_id=member[HumanProperties.ID.value])
                human.unsubscribe()
            except Exception as unsb_e:
                pass
        else:
            count += 1

    # alert admin
    bot.send_message(chat_id=int(
        CONFIG.get('telegram-credentials-telegram-admin-id')),
                     text="[ADMIN] Sent reminder to {}/{} humans.".format(
                         count, len(audience)))
Ejemplo n.º 9
0
	def send_proximity_alert(self, lat: float, lng: float) -> bool:
		if self.telegram_human_id is None:
			return False

		alert_message = get_proximity_alert(lat=lat, lng=lng)

		bot = get_telegram_bot_instance()
		try:
			bot.send_message(
				chat_id=self.telegram_human_id,
				text=alert_message,
				parse_mode='markdown',
				reply_markup=make_reply_keyboard_markup(markup_map=[
					{'text': "🌍 See Map", 'url': CONFIG.get('client-url')},
				])
			)
		except Exception as e:
			logger.error(e)
			self.unsubscribe()
			return False
		else:
			return True
Ejemplo n.º 10
0
def process_telegram_update(update: Update):
    bot = get_telegram_bot_instance()

    # get payload attributes
    if update.callback_query is not None:
        telegram_human_id = int(update.callback_query.from_user.id)
        telegram_message_timestamp = datetime.datetime.fromtimestamp(update.callback_query.message.date)
        telegram_message_id = int(update.callback_query.message.message_id)
        try:
            bot.delete_message(chat_id=telegram_human_id, message_id=telegram_message_id)
        except Exception as e:
            pass
    elif update.message is not None:
        telegram_human_id = int(update.message.from_user.id)
        telegram_message_timestamp = datetime.datetime.fromtimestamp(update.message.date)
        telegram_message_id = int(update.message.message_id)
    else:
        return '', 204

    # typing animation
    try:
        bot.send_chat_action(
            chat_id=telegram_human_id,
            action='typing'
        )
    except Exception as e:
        return '', 204
    else:
        time.sleep(0.1)

    # detect action type
    is_message = False
    is_callback = False
    callback_data = None
    message_content_type = None
    message_is_command = False
    message_text = None
    telegram_command = None
    is_reply = False
    reply_to_message_id = None
    if update.callback_query is not None:
        # fetch callback data
        callback_data = update.callback_query.data
        is_callback = True
    if update.message is not None:
        # set flag
        is_message = True
        is_reply = update.message.reply_to_message is not None
        if is_reply:
            reply_to_message_id = update.message.reply_to_message.message_id

        # fetch message content type
        message_content_type = update.message.content_type

        # case message is text
        if message_content_type == 'text':
            message_text = update.message.text

            # case message is Telegram command
            if TelegramCommand.is_telegram_command(data=message_text):
                telegram_command = TelegramCommand(data=message_text)
                message_is_command = True

    logger.debug("[TELEGRAM WEBHOOK REQUEST] human : {}".format(telegram_human_id))
    logger.debug("[TELEGRAM WEBHOOK REQUEST] timestamp : {}".format(telegram_message_timestamp))
    logger.debug("[TELEGRAM WEBHOOK REQUEST] message : {}".format(telegram_message_id))

    # authenticate human
    human_exists, human_id = verify_telegram_id_exists(telegram_human_id=telegram_human_id)

    # log message
    if is_callback:
        action_type = CONFIG.get('INTENT-ACTION')
        action_value = callback_data
    elif is_message:
        if message_is_command:
            action_type = CONFIG.get('TELEGRAM-COMMAND')
            action_value = telegram_command.command
        else:
            action_type = message_content_type
            action_value = message_text
    log_action(
        human_id=human_id,
        telegram_human_id=telegram_human_id,
        from_human=True,
        action_type=action_type,
        action_value=action_value,
        local_timestamp=telegram_message_timestamp,
        message_id=telegram_message_id
    )

    # redirect to landing unless
    if human_exists:
        # fetch human
        human = Human(human_id=human_id)
    else:
        try:
            log_sent_message(bot.send_message(
                chat_id=telegram_human_id,
                text="Welcome to Opendemic!",
                reply_markup=get_telegram_menu()
            ), human_id=human_id)
        except Exception as e:
            return '', 204
        else:
            human, err = create_human(telegram_human_id=telegram_human_id)
            if err is not None:
                logger.error(err)
                return '', 204

            log_sent_message(bot.send_message(
                chat_id=telegram_human_id,
                text="""
                    *Opendemic* is an non-profit anonymous COVID-19 proximity alert system.
                    
Here is how it works ⬇️:

1. Anonymously share your location and symptoms as much as you can (we'll send you reminders to prompt you)
2. You'll get an alert if you've been in close proximity to a potential COVID-19 case
3. *Opendemic* will only share anonymous data with public health authorities 
                """,
                parse_mode='markdown',
                reply_markup=get_telegram_menu()
            ), human_id=human_id)

            return '', 204

    # case callback
    if is_callback:
        # process callback
        fulfill_intent(
            intent=callback_data,
            human_id=human_id
        )

    elif is_message:

        # case text
        if message_content_type == 'text':

            # case command
            if message_is_command:

                # process command
                fulfill_telegram_command(
                    telegram_command=telegram_command,
                    human_id=human_id
                )

            # case free-form message
            else:
                if is_reply:
                    log_action(
                        human_id=human_id,
                        telegram_human_id=telegram_human_id,
                        from_human=True,
                        action_type="REPLY_TO[{}]".format(reply_to_message_id),
                        action_value=message_text,
                        local_timestamp=telegram_message_timestamp,
                        message_id=telegram_message_id,
                        tag=CONFIG.get('REFER-REPLY-ACTION')
                    )
                else:
                    valid_intent = fulfill_intent(
                        intent=message_text,
                        human_id=human_id
                    )
                    if not valid_intent:
                        try:
                            log_sent_message(bot.send_message(
                                chat_id=telegram_human_id,
                                text="Please use '/' commands to communicate with *Opendemic*.",
                                parse_mode="Markdown"
                            ), human_id=human_id)
                        except Exception as e:
                            return '', 204

        # case location
        elif message_content_type == 'location':
            try:
                log_sent_message(bot.reply_to(
                    message=update.message,
                    text=random.choice([
                        "Thanks for sharing your location 🙏",
                        "Great, got it!",
                        "Thanks! We'll keep that secure."
                    ])
                ), human_id=human_id)
            except Exception as e:
                return '', 204
            else:
                human.log_location(
                    latitude=update.message.location.latitude,
                    longitude=update.message.location.longitude
                )

        # case photo
        elif message_content_type == 'photo':
            try:
                log_sent_message(bot.reply_to(
                    message=update.message,
                    text=random.choice([
                        "Thanks for the pic! But we can't process it just yet.",
                        "Cannot process photos just yet, though we are sure that's a great pic!"
                    ])
                ), human_id=human_id)
                log_sent_message(bot.send_message(
                    chat_id=telegram_human_id,
                    text="Please use '/' commands to communicate with *Opendemic*.",
                    parse_mode="Markdown"
                ), human_id=human_id)
            except Exception:
                return '', 204

        # case documents
        elif message_content_type == 'document':
            try:
                log_sent_message(bot.reply_to(
                    message=update.message,
                    text=random.choice([
                        "Thanks for the document! But we can't process it just yet.",
                        "Cannot process photos just yet, though we are sure that's a great document!"
                    ])
                ), human_id=human_id)
                log_sent_message(bot.send_message(
                    chat_id=telegram_human_id,
                    text="Please use '/' commands to communicate with *Opendemic*.",
                    parse_mode="Markdown"
                ), human_id=human_id)
            except Exception as e:
                return '', 204

        # case sticker
        elif message_content_type == 'sticker':
            try:
                log_sent_message(bot.reply_to(
                    message=update.message,
                    text=random.choice([
                        "Thanks for the sticker! But we can't process it just yet.",
                        "Cannot process stickers just yet, though that looks like a great sticker!"
                    ])
                ), human_id=human_id)
                log_sent_message(bot.send_message(
                    chat_id=telegram_human_id,
                    text="Please use '/' commands to communicate with *Opendemic*.",
                    parse_mode="Markdown"
                ), human_id=human_id)
            except Exception:
                return '', 204

    return '', 204