Adaptivecards Send POST call to external API in MS Teams - microsoft-teams

I am building a script that pushes adaptive card messages to an MS Teams channel connector via a webhook requesting the approval of a supervisor.
I want to put two buttons on the bottom of the message, one to decline and another to approve the request. For this, I need to push a boolean value to an API endpoint. My initial idea was to create an API endpoint accepting a JSON body and looking into the JSON body for approval over a POST request but apparently, this is no longer supported in MS Teams and then I was thinking to use Action.OpenUrl to push this as a query parameter in the URL, but unfortunately this opens a new tab with the query parameter.
Is there any other way to achieve this? This is a sample JSON for the MS Teams webhook:
{
"type": "message",
"attachments": [
{
"contentType": "application/vnd.microsoft.card.adaptive",
"contentUrl": null,
"content": {
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"type": "AdaptiveCard",
"version": "1.5",
"msTeams": {
"width": "full"
},
"actions": [
{
"type": "Action.OpenUrl",
"title": "Approve",
"url": "https://<api_endpoint_url>?approved=true"
},
{
"type": "Action.OpenUrl",
"title": "Decline",
"url": "https://<api_endpoint_url>?approved=false"
}
]
}
}
]
}

This sample shows a feature where user can send task request to his manager and manager can approve/reject the request in group chat.You can try like below code:-
case "approved":
string[] approvedCard = { ".", "Cards", "ApprovedCard.json" };
var approvedAttachment = GetResponseAttachment(approvedCard, data, out cardJson);
Activity approvedActivity = new Activity();
approvedActivity.Type = "message";
approvedActivity.Id = turnContext.Activity.ReplyToId;
approvedActivity.Attachments = new List<Attachment> { approvedAttachment };
await turnContext.UpdateActivityAsync(approvedActivity);
response = JObject.Parse(cardJson);
adaptiveCardResponse = new AdaptiveCardInvokeResponse()
{
StatusCode = 200,
Type = "application/vnd.microsoft.card.adaptive",
Value = response
};
return CreateInvokeResponse(adaptiveCardResponse);
Ref Sample-https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/bot-request-approval/csharp

Related

How to mention the team-tag when sending message in channel

Currently, I have a chat-bot app that sends the message on the channel.
Also, it is capable of tagging a user. The below code is responsible for sending user mentioned message.
await turnContext.sendActivity(
{
text: `Hello <at>#${members[0].dispName}</at>`,
entities: [
{
type: 'mention',
mentioned: {
id: members[0].userName,
name: members[0].dispName,
},
text: `<at>#${members[0].dispName}</at>`,
}
],
});
Further, I am trying to mention the Team Tag. Is there a way I can pass the team-id or something else to mention the Tag
Note: Team tag means - tag in a team
Now you can create/Get teams tags using Beta Graph API.
Reference doc: Create teamworkTag - Microsoft Graph beta | Microsoft Docs
You can also get the created tags using below Beta Graph API:
GET /teams/{team-Id}/tags
List teamworkTags - Microsoft Graph beta | Microsoft Docs
You can also send the message with mentioning teams tag using below API
Post request: https://graph.microsoft.com/v1.0/teams/{team id}/channels/{channel id}/messages
Message body:
{
"subject": "This is very urgent!",
"importance": "urgent",
"body": {
"contentType": "html",
"content": "Programmatically mentioning of Tagged users <at id=\"0\">String_1234</at>"
},
"mentions": [
{
"id": 0,
"mentionText": "String_1234",
"mentioned": {
"tag": {
"#odata.type": "#microsoft.graph.teamworkTagIdentity",
"id": ""/*tag id*/,
"displayName": ""/* tag name*/
}
}
}
]
}

Teams is not displaying my unfurl response

I have a Teams integration with link unfurling set up. I have the messaging endpoint pointed to a public ngrok URL and ngrok proxying a local node.js server that returns the example payload Microsoft has in it's documentation.
This is my endpoint (express.js):
app.post('/bot-test', (req, res) => {
res.send({
"composeExtension": {
"type": "result",
"attachmentLayout": "list",
"attachments": [
{
"contentType": "application/vnd.microsoft.teams.card.o365connector",
"content": {
"sections": [
{
"activityTitle": "[85069]: Create a cool app",
"activityImage": "https://placekitten.com/200/200"
},
{
"title": "Details",
"facts": [
{
"name": "Assigned to:",
"value": "[Larry Brown](mailto:larryb#example.com)"
},
{
"name": "State:",
"value": "Active"
}
]
}
]
}
}
]
}
});
});
When I post a URL in a message in Teams, I see it POST to that endpoint and it responds without errors, but nothing shows up in Teams. What's going wrong? I can't find any logs on Microsoft's side either. I would expect that Teams renders a card with the response payload.
Office 365 Connector cards are not supported for link unfurls ("Message extension previews" in MS parlance). Changing the response to a supported card type worked. Unfortunately, MS doesn't surface this problem anywhere and it just silently discards the response. I was able to find a somewhat useful error description by inspecting the network request that went out from the Teams web client, however.
See this for supported card types: https://learn.microsoft.com/en-us/microsoftteams/platform/task-modules-and-cards/cards/cards-reference

Link AccessToken to a user in Loopback

I wanted to add a custom attribute (expireAt) to the access token for it to be used by MongoDB to automatically remove the expired access token when expired.
Adding the custom attribute while creating the access token using AccessToken model is working well:
const ttl = 600;
const expireAt = new Date();
expireAt.setSeconds(expireAt.getSeconds() + ttl);
const token = await AccessToken.create({ ttl, expireAt });
However, when I want to create an access token for a user, I can't add the custom attribute exprieAt when creating the token, so I have create first, and then update it:
const ttl = 600;
const expireAt = new Date();
expireAt.setSeconds(expireAt.getSeconds() + ttl);
// Create the access token for the user
const token = await user.createAccessToken(options);
// Update token to set the custom date and time to expire
token.expireAt = expireAt;
token.save();
// Return the token together with the user data
return Object.assign({}, token.toJSON(), { user });
Is there a way I can create the token for a user with the custom attribute (either using instance method or model method is fine), without doing two steps - create and update?
So it seems that AccessToken model has the relationship set up with the user via userId attribute (ref: https://github.com/strongloop/loopback/blob/master/common/models/access-token.json#L27).
{
"name": "AccessToken",
"properties": {
"id": {
"type": "string",
"id": true
},
"ttl": {
"type": "number",
"ttl": true,
"default": 1209600,
"description": "time to live in seconds (2 weeks by default)"
},
"scopes": {
"type": ["string"],
"description": "Array of scopes granted to this access token."
},
"created": {
"type": "Date",
"defaultFn": "now"
}
},
"relations": {
"user": {
"type": "belongsTo",
"model": "User",
"foreignKey": "userId"
}
},
"acls": [
{
"principalType": "ROLE",
"principalId": "$everyone",
"permission": "DENY"
}
]
}
To link the token to the user, we only need to pass in the value userId:
AccessToken.create({ ttl, expireAt, userId });

Microsoft Bot Framework and Microsoft Teams

I need help with handle of Actions.Submit (button) in MS Teams..
If we pass "data": "message", we will get a standard dialog. If you test it in the emulator, everything works fine.
Thanks.
My AdaptiveCard:
"actions": [
{
"type": "Action.Submit",
"title": "p3",
"data": {
"text": "p3"
}
},
{
"type": "Action.Submit",
"title": "Помощь",
"data": "p3"
}
I need when clicking on any button to send a specific message
It is MS Teams bug. I report this.
This is how I did it, to make it work for Microsoft teams. Else for the emulator, you simply pass a string in Data.
dynamic dataObject = new JObject();
dataObject.msteams = new JObject();
dataObject.msteams.type = "imBack";
dataObject.msteams.value = intent.Value;
var actionSubmit = new AdaptiveSubmitAction(){
Title = intent.Value,
Data = turnContext.Activity.ChannelId != "emulator" ? dataObject : intent.Value
};

Bot framework direct line using POST with JSON data

I now use bot framework with Azure functions.
it now works when the user sends his message its writes it to queue storage then picked up by Azure function and sends it back to the bot with direct line build in Azure function connector.
I want to change the functionality to LogicAppp and return the answer to the user with direct-line with http rest.
I have a key and have a json input that the function got like this:
{
"relatesTo": {
"user": {
"id": "default-user",
"name": "User"
},
"bot": {
"id": "b5023440-b1ce-11e8-9ad8-f5b615a4c6c3",
"name": "Bot"
},
"conversation": {
"id": "33cd0410-bf46-11e8-a228-a5c7cd21a798|livechat"
},
"channelId": "emulator",
"serviceUrl": "https://0a87dff1.ngrok.io"
},
"text": "example",
"isTrustedServiceUrl": true
}
I try to answer the chat using
https://directline.botframework.com/v3/directline/conversations/{conversationId}/activitie
I can't make it work, the conversation id looks different, it's like a guid instead of an id.
how can help me with the right POST syntax from the json provided?

Resources