Microsoft Graph Communications - Bot joining call - Microsoft Teams - botframework

Ok. So let me try to set the stage here.
I have a Microsoft Teams Application that has a Bot (Bot Framework v4) associated with it.
I have a use case where when a specific type of compliance activity happens, I need my bot to join the scheduled meeting and participate.
I am able to send a meeting invitation to an email account associated with the bot, and the bot accepts the invite.
According to this documentation, I should be able to join the meeting in progress.
(https://learn.microsoft.com/en-us/graph/api/application-post-calls?view=graph-rest-1.0&tabs=http) - Specifically "Example 5"
According to what I am reading, once you have the required Graph Permissions on your App Id that's associated, you only need 3 pieces of information to join the call (Passed in through a communications/call/create).
Post to https://graph.microsoft.com/v1.0/communications/calls :
Body:
{
"#odata.type": "#microsoft.graph.call",
"callbackUri": "https://bot.contoso.com/callback",
"requestedModalities": [
"audio"
],
"mediaConfig": {
"#odata.type": "#microsoft.graph.serviceHostedMediaConfig",
"preFetchMedia": []
},
"chatInfo": {
"#odata.type": "#microsoft.graph.chatInfo",
"threadId": "19:meeting_XXXXXXXXXXXXXXXX#thread.v2",
"messageId": "0"
},
"meetingInfo": {
"#odata.type": "#microsoft.graph.organizerMeetingInfo",
"organizer": {
"#odata.type": "#microsoft.graph.identitySet",
"user": {
"#odata.type": "#microsoft.graph.identity",
"id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"tenantId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"displayName": "Drew Jenkel"
}
},
"tenantId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"allowConversationWithoutHost": true
}
}
Upon doing this, I'm getting a 403 / Forbidden:
{
"error": {
"code": "7505",
"message": "Request authorization tenant mismatch.",
"innerError": {
"request-id": "30739bd2-37b2-4bfc-9c52-36d72a4aa54e",
"date": "2020-06-08T16:47:36"
}
}
}
Has anyone seen anything this this?

Related

Send Conversation History API returning HTTP 400 BotFramework

I'm trying to sendConversation History API provided by Microsoft in BotFramework Documentation. It takes Transcript object (array of activities) as the input. But I've getting HTTP 400 Bad Request when using trying that.
I'm making a POST request on this and authenticating it using JWT Token generated by client credentials for the bot.
https://directline.botframework.com/v3/conversations/HBoZPkTiBYOAadigqEqFaJ-us/activities/history
This is the error I get.
{
"error": {
"code": "BadSyntax",
"message": "Invalid or missing activities"
}
}
This is the activity array payload that I'm using
[
{
"type": "message",
"id": "HBoZPkTiBYOAadigqEqFaJ-us|0000003",
"timestamp": "2022-09-05T08:10:00.3574378Z",
"localTimestamp": "2022-09-05T13:39:57.633+05:30",
"localTimezone": "Asia/Calcutta",
"serviceUrl": "https://directline.botframework.com/",
"channelId": "directline",
"from": {
"id": "dl_uID1",
"name": "userName"
},
"conversation": {
"id": "HBoZPkTiBYOAadigqEqFaJ-us"
},
"recipient": {
"id": "bot-name-dev#abcd",
"name": "bot-name-dev"
},
"textFormat": "plain",
"locale": "en-GB",
"text": "hi",
"channelData": {
"clientActivityID": "1662365337633rmq6e8mbm09",
"clientTimestamp": "2022-09-05T08:09:57.633Z"
}
}
]
I'm not able to figure out what's the correct format of activity object that it is expecting.
Create the bot and get it connected to the Direct Line. Get the secret keys of the site that need to connect.
Before calling SendConversationHistory if the message is delivered to the recipient, it will create the bad request error message as it is unable to get the conversation history as the message was already received. SendConversationHistory must be called before sending the message then the Conversation History will be tracked. The below screens will be helpful to create the DirectLine connection to the bot created. Then needed to add the trusted sites to DirectLine. Then proceed with the code sample mentioned below which takes the conversation history.
Click on Create a resource
Search for bot and click on create
Select Channels
Get the App Service Extension Keys and click on Default_site
Click on the toggle and enable the enhanced authentication options and add the website which we need to communicate.
In the code block of the current working application, to get the conversation history, use the following code block.
foreach (var a in activities)
{
incrementId++;
// Use your own ID format
a.Id = string.Concat("history|", incrementId.ToString().PadLeft(7, '0'));
a.ChannelData = null;
a.Conversation = new ConversationAccount(id: convId);
if (a.From.Name == message.Recipient.Name)
{
// Bot to recipient connection
a.Recipient = message.From;
a.From = message.Recipient;
}
else
{
// User to bot connection (here bot will be the recipient)
a.Recipient = message.Recipient;
a.From = message.From;
}
}
After connecting with Microsoft, I found this is the correct payload for this API.
{
"activities": [
{
"type": "message",
"id": "whatever-conversation-id-in|0000000",
"timestamp": "2022-11-20T20:14:26.242902Z",
"serviceUrl": "https://directline.botframework.com/",
"channelId": "directline",
"from": {
"id": "dl_test_id",
"name": ""
},
"conversation": {
"id": "whatever-conversation-id-in"
},
"recipient": {
"id": "ABC_bot",
"name": "ABC_bot"
},
"text": "Hello Bot"
}
]
}

Send proactive chat message to initiator of Microsoft Teams Calling Bot voice caller

I have a teams bot that can answer 1-to-1 voice calls. During the call I want the bot to be able to send chat messages to the user and be able to reference user data (like their name).
Although an incoming call does have a encrypted source identity, from my experiments it appears this is not a valid user id for proactive messaging.
Interestingly enough this is easily possible in group calls as it starts passing you participant lists (which i've done before), but 1-to-1 calls appear to rely on the source field which effectively leaves the user as anonymous.
{
"#odata.type": "#microsoft.graph.commsNotifications",
"value": [
{
"#odata.type": "#microsoft.graph.commsNotification",
"changeType": "created",
"resource": "/app/calls/4a1f2c00-831f-4e4e-9d7c-1648b6dddb73",
"resourceUrl": "/communications/calls/4a1f2c00-831f-4e4e-9d7c-1648b6dddb73",
"resourceData": {
"#odata.type": "#microsoft.graph.call",
"state": "incoming",
"direction": "incoming",
"callbackUri": "https://...",
"source": {
"#odata.type": "#microsoft.graph.participantInfo",
"id": "7684a0ea-7db6-4f3e-a339-eb46e16d57f0",
"identity": {
"#odata.type": "#microsoft.graph.identitySet",
"encrypted": {
"#odata.type": "#microsoft.graph.identity",
"id": "1g7qrdwga2udafuebrjcyobchnq7r4xigupowjluuccfdceufmew6ush6wlx-kellf96ky2nnhsl084rn6vegqmwawiqpux0kk5aw5lqq9oydrewxe9awkrk_uh_0nxat", // <-- not a valid chat user
"tenantId": "{tenancyId}",
"identityProvider": "None"
}
},
"endpointType": "default",
"region": "apac",
"languageId": "en-us"
},
"targets": [
{
"#odata.type": "#microsoft.graph.invitationParticipantInfo",
"identity": {
"#odata.type": "#microsoft.graph.identitySet",
"application": {
"#odata.type": "#microsoft.graph.identity",
"id": "a2716ab5-9b38-4364-8869-b9b8deeff897",
"identityProvider": "AAD"
}
},
"endpointType": "default",
"id": "023126f0-904f-4c01-a78d-03f28e77e7a7",
"region": null,
"languageId": null
}
],
"tenantId": "{Azure Tenancy}",
"myParticipantId": "023126f0-904f-4c01-a78d-03f28e77e7a7",
"callChainId": "37de77c7-54b3-4d04-9e9c-181e5f5b5773",
"incomingContext": {
"#odata.type": "#microsoft.graph.incomingContext",
"sourceParticipantId": "7684a0ea-7db6-4f3e-a339-eb46e16d57f0"
},
"id": "4a1f2c00-831f-4e4e-9d7c-1648b6dddb73"
}
}
]
}
Yes, we can able to send the chat messages by creating Responder Call handler from bot.
Could you please try to implement the sample code.
In the sample code, will have a class named "ResponderCallHandler.cs", please have a look.

Microsoft bot framework for teams capturing unique user id

We are building a product integration using ms teams and ms bots. We are having an existing integration with Slack already. In the slack World we identify a unique user by TEAM_ID and USER_ID . In case of Teams I can see even id in the from node is a very long string suggesting its unique. Below payload is one example coming to our server. Can someone confirm if using id from the from node is wont change a particular user ever?
the user id being assumed unqiue to a user below is "29:1374Bmi6ngJLBlF9oGVcDuTaBbMfJmcOF9eUvQVdx_rgYh5spPNQ5Mi6fLdVvCiT7mQPMNytT0zGk_iAUtvqKAwXXXX"
{
"_activity": {
"id": "1576102076169",
"from": {
"id": "29:1374Bmi6ngJLBlF9oGVcDuTaBbMfJmcOF9eUvQVdx_rgYh5spPNQ5Mi6fLdVvCiT7mQPMNytT0zGk_iAUtvqKAwXXXX",
"name": "My Name",
"aadObjectId": "37a2516a-baf2-41d8-a406-a067888d676c"
},
"conversation": {
"conversationType": "personal",
"tenantId": "9bfb3569-994e-4908-855c-c7f6c1a94100",
"id": "a:1DcGjCAgiuinvuzR0Mx6dR9uJOB3YUwjMdLOiGTAwQ7KWSGsiEijNfvir66ep7k0fABwoSXxCAACx2_3GflfTNIZL7XMkfjrMm0v8OzJJ7vvIFKasqrClrZ_T-8dDfdT0"
},
"channelData": {
"tenant": {
"id": "9bfb3569-994e-4908-855c-c7f6c1a94100"
}
},
"text": "contact mat",
"textFormat": "plain",
"type": "message",
"channelId": "msteams",
"serviceUrl": "https://smba.trafficmanager.net/amer/",
"recipient": {
"id": "28:a835cf1d-83a8-4ae9-845a-23a68a1df442",
"name": "FlashCX.ai"
}
}
}
#Moblize IT Yes the id obtained from activity.from.id is the unique id for user and it wont change.

How do we get to know to which response user has reacted(like/dislike) on MS teams?

We need help in understanding how Microsoft teams like and dislike works with BotFramework. When user clicks on like option provided in background we are getting reactionID but how do we get to know for which specific message user has given his feedback. Do we have this feasibility on Teams?
You can find it in the replyToId. Example from the docs:
The messageReaction event is sent when a user adds or removes his or her reaction to a message which was originally sent by your bot. replyToId contains the ID of the specific message.
{
"reactionsAdded": [
{
"type": "like"
}
],
"type": "messageReaction",
"timestamp": "2017-10-16T18:45:41.943Z",
"id": "f:9f78d1f3",
"channelId": "msteams",
"serviceUrl": "https://smba.trafficmanager.net/amer-client-ss.msg/",
"from": {
"id": "29:1I9Is_Sx0O-Iy2rQ7Xz1lcaPKlO9eqmBRTBuW6XzkFtcjqxTjPaCMij8BVMdBcL9L_RwWNJyAHFQb0TRzXgyQvA",
"aadObjectId": "c33aafc4-646d-4543-9d4c-abd28e4d2110"
},
"conversation": {
"isGroup": true,
"id": "19:3629591d4b774aa08cb0887902eee7c1#thread.skype"
},
"recipient": {
"id": "28:f5d48856-5b42-41a0-8c3a-c5f944b679b0",
"name": "SongsuggesterLocal"
},
"channelData": {
"channel": {
"id": "19:3629591d4b774aa08cb0887902eee7c1#thread.skype"
},
"team": {
"id": "19:efa9296d959346209fea44151c742e73#thread.skype"
},
"tenant": {
"id": "72f988bf-86f1-41af-91ab-2d7cd011db47"
}
},
"replyToId": "1:19uJ8TZA1cZcms7-2HLOW3pWRF4nSWEoVnRqc0DPa_kY"
}
Note, however, that this replyToId is specific to Teams and I don't believe it will persist if you set it yourself. Once you have that, you can update the activity.
If you're trying to analyze which messages are reacted to, you might want to log the outgoing activity's Id and Text in TurnContext.OnSendActivities. Then, when a reaction comes in, you can use the new Activity Handler to handle the message and add the reaction to your log. I believe this would come in OnUnrecognizedActivityTypeAsync. This is similar to the previous link, update the activity.

Trustpilot invitation api weird result

Trying to create invitations using their API, I get a proper result back, however the status is "notsent". There is zero debug information to go by, so I'm wondering if anyone else has seen this and might have ideas for fixing the issue.
Here's an example of a response I got from their api:
{
"businessUnitId": "<business unit id here>",
"businessUserId": "<business user id here>",
"createdTime": "2018-10-02T09:58:35.135569Z",
"id": "<invitation id here>",
"locale": "da-DK",
"preferredSendTime": "2018-10-09T09:58:34Z",
"recipient": {
"email": "<email goes here>",
"name": "<name goes here>"
},
"redirectUri": "http://trustpilot.com",
"referenceId": "<our ref id>",
"replyTo": "trustpilot#boozt.com",
"sender": {
"email": "noreply.invitations#trustpilotmail.com",
"name": "Booztlet.com"
},
"sentTime": null,
"source": "InvitationApi",
"status": "notsent",
"tags": [],
"templateId": "57cfc1a660e1cc0620b53a38"
}
So, the NotSent status code is expected for new invitations. This is because invitations are sent asynchronously - at around the time you put in as your "preferredSendTime".
If you login to your account at https://businessapp.b2b.trustpilot.com/#/invitations/invitation-history, you should be able to see the invitation you created, and whether it was sent or not (since you specified October 9th as your preferredSendTime, the invitation will still be queued until that point)

Resources