Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion libraries/botbuilder-core/botbuilder/core/activity_handler.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
from typing import List

from botbuilder.schema import ActivityTypes, ChannelAccount
from botbuilder.schema import ActivityTypes, ChannelAccount, MessageReaction
from .turn_context import TurnContext


Expand All @@ -27,6 +28,8 @@ async def on_turn(self, turn_context: TurnContext):
await self.on_message_activity(turn_context)
elif turn_context.activity.type == ActivityTypes.conversation_update:
await self.on_conversation_update_activity(turn_context)
elif turn_context.activity.type == ActivityTypes.message_reaction:
await self.on_message_reaction_activity(turn_context)
elif turn_context.activity.type == ActivityTypes.event:
await self.on_event_activity(turn_context)
else:
Expand Down Expand Up @@ -64,6 +67,27 @@ async def on_members_removed_activity(
): # pylint: disable=unused-argument
return

async def on_message_reaction_activity(self, turn_context: TurnContext):
if turn_context.activity.reactions_added is not None:
await self.on_reactions_added(
turn_context.activity.reactions_added, turn_context
)

if turn_context.activity.reactions_removed is not None:
await self.on_reactions_removed(
turn_context.activity.reactions_removed, turn_context
)

async def on_reactions_added( # pylint: disable=unused-argument
self, message_reactions: List[MessageReaction], turn_context: TurnContext
):
return

async def on_reactions_removed( # pylint: disable=unused-argument
self, message_reactions: List[MessageReaction], turn_context: TurnContext
):
return

async def on_event_activity(self, turn_context: TurnContext):
if turn_context.activity.name == "tokens/response":
return await self.on_token_response_event(turn_context)
Expand Down
98 changes: 98 additions & 0 deletions libraries/botbuilder-core/tests/test_activity_handler.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
from typing import List

import aiounittest
from botbuilder.core import ActivityHandler, BotAdapter, TurnContext
from botbuilder.schema import (
Activity,
ActivityTypes,
ChannelAccount,
ConversationReference,
MessageReaction,
)


class TestingActivityHandler(ActivityHandler):
def __init__(self):
self.record: List[str] = []

async def on_message_activity(self, turn_context: TurnContext):
self.record.append("on_message_activity")
return await super().on_message_activity(turn_context)

async def on_members_added_activity(
self, members_added: ChannelAccount, turn_context: TurnContext
):
self.record.append("on_members_added_activity")
return await super().on_members_added_activity(members_added, turn_context)

async def on_members_removed_activity(
self, members_removed: ChannelAccount, turn_context: TurnContext
):
self.record.append("on_members_removed_activity")
return await super().on_members_removed_activity(members_removed, turn_context)

async def on_message_reaction_activity(self, turn_context: TurnContext):
self.record.append("on_message_reaction_activity")
return await super().on_message_reaction_activity(turn_context)

async def on_reactions_added(
self, message_reactions: List[MessageReaction], turn_context: TurnContext
):
self.record.append("on_reactions_added")
return await super().on_reactions_added(message_reactions, turn_context)

async def on_reactions_removed(
self, message_reactions: List[MessageReaction], turn_context: TurnContext
):
self.record.append("on_reactions_removed")
return await super().on_reactions_removed(message_reactions, turn_context)

async def on_token_response_event(self, turn_context: TurnContext):
self.record.append("on_token_response_event")
return await super().on_token_response_event(turn_context)

async def on_event(self, turn_context: TurnContext):
self.record.append("on_event")
return await super().on_event(turn_context)

async def on_unrecognized_activity_type(self, turn_context: TurnContext):
self.record.append("on_unrecognized_activity_type")
return await super().on_unrecognized_activity_type(turn_context)


class NotImplementedAdapter(BotAdapter):
async def delete_activity(
self, context: TurnContext, reference: ConversationReference
):
raise NotImplementedError()

async def send_activities(self, context: TurnContext, activities: List[Activity]):
raise NotImplementedError()

async def update_activity(self, context: TurnContext, activity: Activity):
raise NotImplementedError()


class TestActivityHandler(aiounittest.AsyncTestCase):
async def test_message_reaction(self):
# Note the code supports multiple adds and removes in the same activity though
# a channel may decide to send separate activities for each. For example, Teams
# sends separate activities each with a single add and a single remove.

# Arrange
activity = Activity(
type=ActivityTypes.message_reaction,
reactions_added=[MessageReaction(type="sad")],
reactions_removed=[MessageReaction(type="angry")],
)
turn_context = TurnContext(NotImplementedAdapter(), activity)

# Act
bot = TestingActivityHandler()
await bot.on_turn(turn_context)

# Assert
assert len(bot.record) == 3
assert bot.record[0] == "on_message_reaction_activity"
assert bot.record[1] == "on_reactions_added"
assert bot.record[2] == "on_reactions_removed"