Skip to content

Commit

Permalink
Merge branch 'main' into v-gandiddi/anonymous-query-link
Browse files Browse the repository at this point in the history
  • Loading branch information
tracyboehrer authored Oct 30, 2024
2 parents 50492d1 + a74532b commit 34859e7
Show file tree
Hide file tree
Showing 4 changed files with 275 additions and 0 deletions.
32 changes: 32 additions & 0 deletions libraries/botbuilder-core/botbuilder/core/activity_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ async def on_turn(

if turn_context.activity.type == ActivityTypes.message:
await self.on_message_activity(turn_context)
elif turn_context.activity.type == ActivityTypes.message_update:
await self.on_message_update_activity(turn_context)
elif turn_context.activity.type == ActivityTypes.message_delete:
await self.on_message_delete_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:
Expand Down Expand Up @@ -107,6 +111,34 @@ async def on_message_activity( # pylint: disable=unused-argument
"""
return

async def on_message_update_activity( # pylint: disable=unused-argument
self, turn_context: TurnContext
):
"""
Override this method in a derived class to provide logic specific to activities,
such as the conversational logic.
:param turn_context: The context object for this turn
:type turn_context: :class:`botbuilder.core.TurnContext`
:returns: A task that represents the work queued to execute
"""
return

async def on_message_delete_activity( # pylint: disable=unused-argument
self, turn_context: TurnContext
):
"""
Override this method in a derived class to provide logic specific to activities,
such as the conversational logic.
:param turn_context: The context object for this turn
:type turn_context: :class:`botbuilder.core.TurnContext`
:returns: A task that represents the work queued to execute
"""
return

async def on_conversation_update_activity(self, turn_context: TurnContext):
"""
Invoked when a conversation update activity is received from the channel when the base behavior of
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1065,3 +1065,73 @@ async def on_teams_meeting_participants_leave_event(
:returns: A task that represents the work queued to execute.
"""
return

async def on_message_update_activity(self, turn_context: TurnContext):
"""
Invoked when a message update activity is received, such as a message edit or undelete.
:param turn_context: A context object for this turn.
:returns: A task that represents the work queued to execute.
"""
if turn_context.activity.channel_id == Channels.ms_teams:
channel_data = TeamsChannelData().deserialize(
turn_context.activity.channel_data
)

if channel_data:
if channel_data.event_type == "editMessage":
return await self.on_teams_message_edit(turn_context)
if channel_data.event_type == "undeleteMessage":
return await self.on_teams_message_undelete(turn_context)

return await super().on_message_update_activity(turn_context)

async def on_message_delete_activity(self, turn_context: TurnContext):
"""
Invoked when a message delete activity is received, such as a soft delete message.
:param turn_context: A context object for this turn.
:returns: A task that represents the work queued to execute.
"""
if turn_context.activity.channel_id == Channels.ms_teams:
channel_data = TeamsChannelData().deserialize(
turn_context.activity.channel_data
)

if channel_data:
if channel_data.event_type == "softDeleteMessage":
return await self.on_teams_message_soft_delete(turn_context)

return await super().on_message_delete_activity(turn_context)

async def on_teams_message_edit(self, turn_context: TurnContext):
"""
Invoked when a Teams edit message event activity is received.
:param turn_context: A context object for this turn.
:returns: A task that represents the work queued to execute.
"""
return

async def on_teams_message_undelete(self, turn_context: TurnContext):
"""
Invoked when a Teams undo soft delete message event activity is received.
:param turn_context: A context object for this turn.
:returns: A task that represents the work queued to execute.
"""
return

async def on_teams_message_soft_delete(self, turn_context: TurnContext):
"""
Invoked when a Teams soft delete message event activity is received.
:param turn_context: A context object for this turn.
:returns: A task that represents the work queued to execute.
"""
return
139 changes: 139 additions & 0 deletions libraries/botbuilder-core/tests/teams/test_teams_activity_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
TabContext,
MeetingParticipantsEventDetails,
ReadReceiptInfo,
TeamsChannelData,
)
from botframework.connector import Channels
from simple_adapter import SimpleAdapter
Expand Down Expand Up @@ -359,6 +360,26 @@ async def on_teams_meeting_end_event(
turn_context.activity.value, turn_context
)

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

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

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

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

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

async def on_teams_meeting_participants_join_event(
self, meeting: MeetingParticipantsEventDetails, turn_context: TurnContext
):
Expand Down Expand Up @@ -1281,6 +1302,124 @@ async def test_on_teams_meeting_end_event(self):
assert bot.record[0] == "on_event_activity"
assert bot.record[1] == "on_teams_meeting_end_event"

async def test_message_update_activity_teams_message_edit(self):
# Arrange
activity = Activity(
type=ActivityTypes.message_update,
channel_data=TeamsChannelData(event_type="editMessage"),
channel_id=Channels.ms_teams,
)
turn_context = TurnContext(SimpleAdapter(), activity)

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

# Assert
self.assertEqual(2, len(bot.record))
self.assertEqual("on_message_update_activity", bot.record[0])
self.assertEqual("on_teams_message_edit", bot.record[1])

async def test_message_update_activity_teams_message_undelete(self):
# Arrange
activity = Activity(
type=ActivityTypes.message_update,
channel_data=TeamsChannelData(event_type="undeleteMessage"),
channel_id=Channels.ms_teams,
)
turn_context = TurnContext(SimpleAdapter(), activity)

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

# Assert
self.assertEqual(2, len(bot.record))
self.assertEqual("on_message_update_activity", bot.record[0])
self.assertEqual("on_teams_message_undelete", bot.record[1])

async def test_message_update_activity_teams_message_undelete_no_msteams(self):
# Arrange
activity = Activity(
type=ActivityTypes.message_update,
channel_data=TeamsChannelData(event_type="undeleteMessage"),
)
turn_context = TurnContext(SimpleAdapter(), activity)

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

# Assert
self.assertEqual(1, len(bot.record))
self.assertEqual("on_message_update_activity", bot.record[0])

async def test_message_update_activity_teams_no_channel_data(self):
# Arrange
activity = Activity(
type=ActivityTypes.message_update,
channel_id=Channels.ms_teams,
)
turn_context = TurnContext(SimpleAdapter(), activity)

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

# Assert
self.assertEqual(1, len(bot.record))
self.assertEqual("on_message_update_activity", bot.record[0])

async def test_message_delete_activity_teams_message_soft_delete(self):
# Arrange
activity = Activity(
type=ActivityTypes.message_delete,
channel_data=TeamsChannelData(event_type="softDeleteMessage"),
channel_id=Channels.ms_teams,
)
turn_context = TurnContext(SimpleAdapter(), activity)

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

# Assert
self.assertEqual(2, len(bot.record))
self.assertEqual("on_message_delete_activity", bot.record[0])
self.assertEqual("on_teams_message_soft_delete", bot.record[1])

async def test_message_delete_activity_teams_message_soft_delete_no_msteams(self):
# Arrange
activity = Activity(
type=ActivityTypes.message_delete,
channel_data=TeamsChannelData(event_type="softDeleteMessage"),
)
turn_context = TurnContext(SimpleAdapter(), activity)

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

# Assert
self.assertEqual(1, len(bot.record))
self.assertEqual("on_message_delete_activity", bot.record[0])

async def test_message_delete_activity_teams_no_channel_data(self):
# Arrange
activity = Activity(
type=ActivityTypes.message_delete,
channel_id=Channels.ms_teams,
)
turn_context = TurnContext(SimpleAdapter(), activity)

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

# Assert
self.assertEqual(1, len(bot.record))
self.assertEqual("on_message_delete_activity", bot.record[0])

async def test_on_teams_meeting_participants_join_event(self):
# arrange
activity = Activity(
Expand Down
34 changes: 34 additions & 0 deletions libraries/botbuilder-core/tests/test_activity_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@ 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_message_update_activity(self, turn_context: TurnContext):
self.record.append("on_message_update_activity")
return await super().on_message_update_activity(turn_context)

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

async def on_members_added_activity(
self, members_added: ChannelAccount, turn_context: TurnContext
):
Expand Down Expand Up @@ -208,6 +216,32 @@ async def test_invoke_should_not_match(self):
assert bot.record[0] == "on_invoke_activity"
assert adapter.activity.value.status == int(HTTPStatus.NOT_IMPLEMENTED)

async def test_on_message_update_activity(self):
activity = Activity(type=ActivityTypes.message_update)

adapter = TestInvokeAdapter()
turn_context = TurnContext(adapter, activity)

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

assert len(bot.record) == 1
assert bot.record[0] == "on_message_update_activity"

async def test_on_message_delete_activity(self):
activity = Activity(type=ActivityTypes.message_delete)

adapter = TestInvokeAdapter()
turn_context = TurnContext(adapter, activity)

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

assert len(bot.record) == 1
assert bot.record[0] == "on_message_delete_activity"

async def test_on_end_of_conversation_activity(self):
activity = Activity(type=ActivityTypes.end_of_conversation)

Expand Down

0 comments on commit 34859e7

Please sign in to comment.