8000 port: Add Teams read receipt event (#6356) by gandiddi · Pull Request #2167 · microsoft/botbuilder-python · GitHub
[go: up one dir, main page]

Skip to content

port: Add Teams read receipt event (#6356) #2167

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Sep 11, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
TabRequest,
TabSubmit,
MeetingParticipantsEventDetails,
ReadReceiptInfo,
)
from botframework.connector import Channels
from ..serializer_helper import deserializer_helper
Expand Down Expand Up @@ -906,6 +907,10 @@ async def on_event_activity(self, turn_context: TurnContext):
the scope of a channel.
"""
if turn_context.activity.channel_id == Channels.ms_teams:
if turn_context.activity.name == "application/vnd.microsoft.readReceipt":
return await self.on_teams_read_receipt_event(
turn_context.activity.value, turn_context
)
if turn_context.activity.name == "application/vnd.microsoft.meetingStart":
return await self.on_teams_meeting_start_event(
turn_context.activity.value, turn_context
Expand All @@ -931,6 +936,19 @@ async def on_event_activity(self, turn_context: TurnContext):

return await super().on_event_activity(turn_context)

async def on_teams_read_receipt_event(
self, read_receipt_info: ReadReceiptInfo, turn_context: TurnContext
): # pylint: disable=unused-argument
"""
Override this in a derived class to provide logic for when the bot receives a read receipt event.

:param read_receipt_info: Information regarding the read receipt. i.e. Id of the message last read by the user.
:param turn_context: A context object for this turn.

:returns: A task that represents the work queued to execute.
"""
return

async def on_teams_meeting_start_event(
self, meeting: MeetingStartEventDetails, turn_context: TurnContext
): # pylint: disable=unused-argument
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
TabSubmit,
TabContext,
MeetingParticipantsEventDetails,
ReadReceiptInfo,
)
from botframework.connector import Channels
from simple_adapter import SimpleAdapter
Expand Down Expand Up @@ -318,6 +319,14 @@ async def on_event_activity(self, turn_context: TurnContext):
self.record.append("on_event_activity")
return await super().on_event_activity(turn_context)

async def on_teams_read_receipt_event(
self, read_receipt_info: ReadReceiptInfo, turn_context: TurnContext
):
self.record.append("on_teams_read_receipt_event")
return await super().on_teams_read_receipt_event(
turn_context.activity.value, turn_context
)

async def on_teams_meeting_start_event(
self, meeting: MeetingStartEventDetails, turn_context: TurnContext
):
Expand Down Expand Up @@ -1141,6 +1150,24 @@ async def test_typing_activity(self):
assert len(bot.record) == 1
assert bot.record[0] == "on_typing_activity"

async def test_on_teams_read_receipt_event(self):
activity = Activity(
type=ActivityTypes.event,< 10000 /td>
name="application/vnd.microsoft.readReceipt",
channel_id=Channels.ms_teams,
value={"lastReadMessageId": "10101010"},
)

turn_context = TurnContext(SimpleAdapter(), activity)

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

assert len(bot.record) == 2
assert bot.record[0] == "on_event_activity"
assert bot.record[1] == "on_teams_read_receipt_event"

async def test_on_teams_meeting_start_event(self):
activity = Activity(
type=ActivityTypes.event,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
from ._models_py3 import UserMeetingDetails
from ._models_py3 import TeamsMeetingMember
from ._models_py3 import MeetingParticipantsEventDetails
from ._models_py3 import ReadReceiptInfo

__all__ = [
"AppBasedLinkQuery",
Expand Down Expand Up @@ -161,4 +162,5 @@
"UserMeetingDetails",
"TeamsMeetingMember",
"MeetingParticipantsEventDetails",
"ReadReceiptInfo",
]
51 changes: 51 additions & 0 deletions libraries/botbuilder-schema/botbuilder/schema/teams/_models_py3.py
Original file line number Diff line number Diff line change
Expand Up @@ -2568,3 +2568,54 @@ class MeetingParticipantsEventDetails(Model):
def __init__(self, *, members: List[TeamsMeetingMember] = None, **kwargs) -> None:
super(MeetingParticipantsEventDetails, self).__init__(**kwargs)
self.members = members


class ReadReceiptInfo(Model):
"""General information about a read receipt.

:param last_read_message_id: The id of the last read message.
:type last_read_message_id: str
"""

_attribute_map = {
"last_read_message_id": {"key": "lastReadMessageId", "type": "str"},
}

def __init__(self, *, last_read_message_id: str = None, **kwargs) -> None:
FC68 super(ReadReceiptInfo, self).__init__(**kwargs)
self.last_read_message_id = last_read_message_id

@staticmethod
def is_message_read(compare_message_id, last_read_message_id):
"""
Helper method useful for determining if a message has been read.
This method converts the strings to integers. If the compare_message_id is
less than or equal to the last_read_message_id, then the message has been read.

:param compare_message_id: The id of the message to compare.
:param last_read_message_id: The id of the last message read by the user.
:return: True if the compare_message_id is less than or equal to the last_read_message_id.
"""
if not compare_message_id or not last_read_message_id:
return False

try:
compare_message_id_long = int(compare_message_id)
last_read_message_id_long = int(last_read_message_id)
except ValueError:
return False

return compare_message_id_long <= last_read_message_id_long

def is_message_read_instance(self, compare_message_id):
"""
Helper method useful for determining if a message has been read.
If the compare_message_id is less than or equal to the last_read_message_id,
then the message has been read.

:param compare_message_id: The id of the message to compare.
:return: True if the compare_message_id is less than or equal to the last_read_message_id.
"""
return ReadReceiptInfo.is_message_read(
compare_message_id, self.last_read_message_id
)
28 changes: 28 additions & 0 deletions libraries/botbuilder-schema/tests/teams/test_read_receipt_info.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

import aiounittest
from botbuilder.schema.teams import ReadReceiptInfo


class TestReadReceiptInfo(aiounittest.AsyncTestCase):
def test_read_receipt_info(self):
# Arrange
test_cases = [
("1000", "1000", True),
("1001", "1000", True),
("1000", "1001", False),
("1000", None, False),
(None, "1000", False),
]

for last_read, compare, is_read in test_cases:
# Act
info = ReadReceiptInfo(last_read_message_id=last_read)

# Assert
self.assertEqual(info.last_read_message_id, last_read)
self.assertEqual(info.is_message_read_instance(compare), is_read)
self.assertEqual(
ReadReceiptInfo.is_message_read(compare, last_read), is_read
)
Loading
0