Rasa Integration MS Teams -> no metadata

Hello, as per documentation i did play around with MS teams integration. Docu writes with an actionserver running and the following in action.py:

import logging

from typing import Dict, Text, Any, List, Union, Optional

from rasa_sdk import Action, Tracker

from rasa_sdk.executor import CollectingDispatcher

from rasa_sdk.forms import FormAction, REQUESTED_SLOT

from rasa_sdk.events import AllSlotsReset, SlotSet, EventType, SessionStarted, ActionExecuted

logger = logging.getLogger(name)

class ActionSessionStart(Action): def name(self) → Text: return “action_session_start”

async def run(
  self, dispatcher, tracker: Tracker, domain: Dict[Text, Any]
) -> List[Dict[Text, Any]]:

    metadata = tracker.get_slot("session_started_metadata")

    # Do something with the metadata

    logger.debug(metadata)

    # the session should begin with a `session_started` event and an `action_listen`
    # as a user message follows
    return [SessionStarted(), ActionExecuted("action_listen")]

i should get the metadata (including the UserID).

The log file of the action server shows:

  • 2021-06-28 16:38:29 DEBUG rasa_sdk.executor - Received request to run ‘action_session_start’
  • 2021-06-28 16:38:29 DEBUG actions.actions - None
  • 2021-06-28 16:38:29 DEBUG rasa_sdk.executor - Finished running ‘action_session_start’

Any Idea whats going wrong? Bot is working, actionserver is called and it is exactly like in doku … but not working

  • Rasa Version : 2.7.1
  • Minimum Compatible Version: 2.6.0
  • Rasa SDK Version : 2.7.0
  • Rasa X Version : 0.41.1
  • Python Version : 3.8.10
  • Operating System : macOS-10.16-x86_64-i386-64bit

i did check the inbound call and first and lastname are in, but not the userId nor email… how can i access this information?

{ “text”:“hallo from bot”, “textFormat”:“plain”, “type”:“message”, “timestamp”:“2021-07-05T07:02:15.191155Z”, “localTimestamp”:“202105T09:02:15.191155+02:00”, “id”:“1625468535166”, “channelId”:“msteams”, “serviceUrl”:“https://smba.trafficmanager.net/emea/”, “from”: {“id”:“xxxg”,

“name”: “first Lastname

,“aadObjectId”:“53bf16cf-e500-4724-be43-72c0ae3fc078”},

“conversation”:{“conversationType”:“personal”,“tenantId”:“31ab271c-xxx-4870-b483-xx”,“id”:“a:xxxxxxx-k_HscpEPqEM2SSy2d6P”},“recipient”:{“id”:“28:xxx-8d5d-4d8e-8d43-5b143b51bf32”,“name”:“SvenTest”},“entities”:[{“locale”:“de-DE”,“country”:“DE”,“platform”:“Windows”,“timezone”:“Europe/Berlin”,“type”:“clientInfo”}],“channelData”:{“tenant”:{“id”:“xxx”}},“locale”:“de-DE”,“localTimezone”:“Europe/Berlin”}

just a workaround … in botframework.py:

    @botframework_webhook.route("/webhook", methods=["POST"])
    async def webhook(request: Request) -> HTTPResponse:
        postdata = request.json

        metadata = self.get_metadata(request)

        if metadata is None:
            metadata = {'name' : None}
            metadata['name']=postdata['from']['name']

gives me the metadata filled: {‘name’: ‘xxx xxx’} seems a bug in botframework

Did some further research. The add metadata function in botframework.py comes from channel.py and is empty, so it seems to be expected to add custom code there. This is a bad design, as both are part of the rasa package. So I opened a feature request to allwo custumization of metadata from outside. Teams working with git would have a major issue with the actual way of implementation

Thanks a lot for opening the feature request :pray:

There is an example in MS Botbuilder :slight_smile:

    # on first usr message respond with some info from the user object, this is just for prove of concept
    user = await self.get_teams_user(turn_context)
    name = user.name
    user_id = user.id
    email = user.email
    if not bot_user_state.did_welcome_user:
        bot_user_state.did_welcome_user = True
        await turn_context.send_activity(
            f"""Danke für deine Nachricht, {name}. 
            Deine Teams-Email-Adresse ist: "{email}"."""
        )
    if turn_context.activity.text.lower() == "ja":
        card = Activity(
        text="Hier ist dein Ticket:",
        type=ActivityTypes.message,
        attachments=[self.create_adaptive_card_attachment()],
        )
        return await turn_context.send_activity(card)
    elif turn_context.activity.text.lower() == "nein": 
        bot_answer = f"Alles klar."
        return await turn_context.send_activity(bot_answer)

async def get_teams_user(self, turn_context: TurnContext):
    """
    Returns the user object received from the Teams context
    """
    if turn_context.activity.channel_id == "msteams":
        usr = await TeamsInfo.get_member(turn_context, turn_context.activity.from_property.id)
        return usr
    else:
        # this part is needed to fake a teams user object in the emulator 
        # environment and ensures that rest of the code can be unchanged 
        # regardless of Teams or emulator
        class Emulator_usr:
            def __init__(self, turn_context: TurnContext):
                self.id = turn_context.activity.recipient.id
                self.name = "User"
                self.given_name = "User"
                self.email = "emulator_user@email.de"
        emulator_usr = Emulator_usr(turn_context)
        return emulator_usr