Teams "refresh" adaptive card returns 209 error in group chat - botframework

Adaptive card "Refresh" action in Teams one to one chat doesn't work for companion
and for me after Teams cache clear but it works for any user in channel.
I'm posting an adaptive card with "refresh" action in Teams one to one chat from compose extension. "Refresh" action is triggered in compose box and I see result of refresh when push it out to the chat. "Refresh" action doesn't work for a user with whom I'm chatting, user sees
If I open the chat in browser, "refresh" doesn't happen for me anymore, instead I see an initial card like on attached sreenshot for the card I just posted.
In browser's developer tools -> "network" I see 403 code for the request is done to https://amer.ng.msg.teams.microsoft.com/v1/agents/28:{bot_ad_app_registration_id}/invoke with a responce
{
"errorCode": 0,
"message": "Invoke validation failed. User forbidden to perform action",
"standardizedError": {
"errorCode": 209,
"errorSubCode": 1,
"errorDescription": "Invoke validation failed. User forbidden to perform action"
}
}
My Teams compose extension is driven by Visual Studio through ngrok, in case of broken "refresh" described above request to ngrok doesn't happen.
Part of Teams App Extension Manifest:
{
"composeExtensions": [
{
"botId": "bot_id_is_here",
"commands": [
{
"id": "webView",
"description": "description_is_here",
"title": "title_is_here",
"type": "action",
"fetchTask": true,
"context": [ "compose" ]
}
]
}
],
"bots": [
{
"botId": "bot_id_is_here",
"needsChannelSelector": false,
"isNotificationOnly": true,
"scopes": [
"team",
"groupchat"
]
}
],
"permissions": [
"identity"
]
}
The solution perflectly works in channels: refresh happens both for me and all users, requests to the ngrok tunnel are routed properly.

Issue was because of missed bot. Bot isn't added to the "groupchat" automaticaly. Solved by adding a bot on the launch of messaging extension.
protected override async Task<MessagingExtensionActionResponse> OnTeamsMessagingExtensionFetchTaskAsync(
ITurnContext<IInvokeActivity> turnContext,
MessagingExtensionAction action,
CancellationToken cancellationToken)
{
try
{
// Check if your app is installed by fetching member information.
var member = await TeamsInfo.GetMemberAsync(turnContext, turnContext.Activity.From.Id, cancellationToken);
}
catch (ErrorResponseException ex)
{
if (ex.Body.Error.Code == "BotNotInConversationRoster")
{
return await Task.FromResult(this.CardsFabric.GetAddMissedBotCard());
}
throw; // It's a different error.
}
return await Task.FromResult(this.CardsFabric.GetSearchDialog());
}

Related

Adaptive card sends error message when using ToggleVisibility action in MS Teams desktop app

This morning we started getting the standard bot error message in MS teams desktop client when using a card with toggleVisbility actions. Selecting the button to toggle visbility on part of the card results in the below error, even though the toggle works as expected!
bot error message
The adaptive card code looks something like this:
{
"type": "ActionSet",
"actions": [
{
"type": "Action.ToggleVisibility",
"title": "Alerts",
"targetElements": [
"Incidents",
{
"elementId": "Metrics",
"isVisible": false
},
{
"elementId": "Admin",
"isVisible": false
}
]
},
{
"type": "Action.ToggleVisibility",
"title": "Actions",
"targetElements": [
"ActionButton"
]
}
]
}
This message would be expected if the bot app doesn't respond to a message/action, however the toggle action shouldn't be sending any data to the bot applicaiton. I confirmed this in the teams web client using the network tracing dev tool. When selecting the toggle action no new network calls are made.
We are not seeing this error in either the web client or the mobile client, only in Teams Desktop app.
This bot has been running for months without this issue and we didn't change the code, which makes me believe this is a MS teams side bug that was recently introduced.
Also: This same issue was independently identified in the Adaptive Cards Project.
https://github.com/microsoft/AdaptiveCards/issues/8145

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

Microsoft Teams HttpPost Action print http return status

We want to know what is the best way to do :
an alert is sent to the MS teams channel, the alert contains "Approve" and "Deny"
Both "Approve" or "Deny" has "HttpPost" to send the POST to target URL
After clicking "Approve" or "Deny", how do we get the http status and print the comment "Approved" if http status is "200" ?
After clicking either approve or deny, how do we print the comment with whoever clicked(for example logged in user) so that others will know.
This is below payload :
{
"#type":"MessageCard",
"#context":"http://schema.org/extensions",
"themeColor":"0076D7",
"text":"### Build [($BUILD_NUMBER)]($CONSOLE_LINK) of [($BUILD_LINK)]($BUILD_URL) failed on [($BM_NAME)]($JENKINS_URL)",
"potentialAction":[
{
"#type":"HttpPost",
"name":"Approve",
"body": "verification.approve",
"target":"https://learn.microsoft.com/outlook/actionable-messages"
},
{
"#type": "OpenUri",
"name": "Deny",
"targets": [{
"os": "default",
"uri": "https://learn.microsoft.com/outlook/actionable-messages"
}]
}
],
}
You need to implement a Bot or Client App and then while calling the Webhook Http/Https URL, you need to capture the response & based on response code, you can take action accordingly.

Why I can't save my connector on Microsoft Teams?

I made a custom connector for teams that display notifications on channels and add Tab on teams.
For the tab parts -> Everything is working well
But I have a problem for the connector parts, I get an error when I try to save my settings in the developer console:
Received error from connectors {"seq":1585127802210,"timestamp":1585127814174,"flightSettings":{"Name":"ConnectorFrontEndSettings","AriaSDKT....
-> registerOnSaveHandler is called
-> setSettings is correctly set with entityId, contentUrl (same configurationUrl as the connector configuration) and the configName.
getSettings -> is called to save to my app the webhook url -> it works
-> notifySuccess is then called and
I checked on the connector dashboard everything seems fine, on the App Studio everything is green also!
I don't know what is happening..
My manifest
{
"$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.5/MicrosoftTeams.schema.json",
"manifestVersion": "1.5",
"version": "1.0.0",
"id": "ca153ede-92f2-46e7-8695-3726b5343bf4",
"packageName": "com.kagilum.icescrum",
"developer": {
"name": "Kagilum SAS",
"websiteUrl": "https://www.icescrum.com",
"privacyUrl": "https://www.icescrum.com/privacy",
"termsOfUseUrl": "https://www.icescrum.com/termsofuser"
},
"icons": {
"color": "color.png",
"outline": "outline.png"
},
"name": {
"short": "iceScrum",
"full": "Connect with iceScrum"
},
"description": {
"short": "A true Agile project management tool",
"full": "iceScrum is a web application for using Scrum while keeping the spirit of a collaborative workspace. It also offers virtual boards with post-its for sprint backlog, product backlog and others."
},
"accentColor": "#FFFFFF",
"configurableTabs": [
{
"configurationUrl": "https://preview.icescrum.com/msTeams/setupTab/",
"canUpdateConfiguration": true,
"scopes": [
"team",
"groupchat"
],
"supportedSharePointHosts": [
"sharePointFullPage",
"sharePointWebPart"
]
}
],
"connectors": [
{
"connectorId": "f00d8890-daa8-4c87-89f5-83cbab0bccd4",
"configurationUrl": "https://preview.icescrum.com/msTeams/setup/",
"scopes": [
"team"
]
}
],
"permissions": [
"identity",
"messageTeamMembers"
],
"validDomains": [
"preview.icescrum.com"
]
}
Piece of code related to
microsoftTeams.settings.registerOnSaveHandler(function(saveEvent) {
microsoftTeams.settings.setSettings({
entityId: 'icescrum-pkey-' + $scope.settings.project.pkey,
contentUrl: isSettings.serverUrl + '/msTeams/setup/',
configName: $scope.settings.project.name
});
microsoftTeams.settings.getSettings(function(settings) {
$scope.settings.webhookUrl = settings.webhookUrl;
return FormService.httpPost('msTeams/save', $scope.settings, true).then(function() {
saveEvent.notifySuccess(); //wait that the settings are really saved on iceScrum side
});
});
});
microsoftTeams.settings.getSettings(function(settings) {
$scope.setup = !settings.configName;
var tokenData = JSON.parse(localStorage.getItem("msTeams-oauth"));
var userData = JSON.parse(localStorage.getItem("msTeams-user"));
if (tokenData) {
FormService.httpGet('ws/project/user/' + userData.id + '?light=true', {headers: {'Authorization': 'Bearer ' + tokenData['accessToken']}}, true).then(function(projects) {
$scope.projects = projects;
if (settings.entityId) {
$scope.settings.project = _.find($scope.projects, {pkey: settings.entityId.split('icescrum-pkey-')[1]});
}
$scope.ready = true;
});
}
});
Full error:
angular.min.js:113 2020-03-25T20:35:25.953Z Received error from connectors {"seq":1585168484680,"timestamp":1585168525943,"flightSettings":{"Name":"ConnectorFrontEndSettings","AriaSDKToken":"d127f72a3abd41c9b9dd94faca947689-d58285e6-3a68-4cab-a458-37b9d9761d35-7033","SPAEnabled":true,"ClassificationFilterEnabled":true,"ClientRoutingEnabled":true,"EnableYammerGroupOption":true,"EnableFadeMessage":false,"EnableDomainBasedOwaConnectorList":false,"EnableDomainBasedTeamsConnectorList":false,"DevPortalSPAEnabled":true,"ShowHomeNavigationButtonOnConfigurationPage":false,"DisableConnectToO365InlineDeleteFeedbackPage":true},"status":500,"clientType":"SkypeSpaces","connectorType":"f00d8890-daa8-4c87-89f5-83cbab0bccd4","name":"handleMessageError"}
In case this helps anyone else, I spent ages today trying to get to the bottom of this and couldn't find a solution. Until...as a last gasp show of desperation I decide to use App Studio to recreate the entire connector manifest from scratch, including creating a new connector in the portal.
For some reason, this then worked fine - even though I can see that the two manifest files are identical with the exception of the ID (and I already tried regenerating the ID for the original one).
Bit late to the story, but having followed multiple github issues like this and stack overflow posts, I'm pretty convinced that its the problem with Connectors dashboard. If you made any change to settings, they are not really propageted/saved correctly.
So for example, if you changed validDomains or configurationPage URL, they won't actually do anything. You can verify that with your devtools. For me, after changing the configurationPage the Teams is still making request to old URL as well as the new one, but the old request produces error that's listed in question.
The only workaround I was able to find is to recreate connector in dashboard. Reported problem to MS Teams dev team, waiting to hear back.
Also late here, but I ran into this problem and the below was the solution after 3 days of frustration.
Despite everything mentioned in the documentation, the following is required otherwise you'll get this error. This fixed things for me.
microsoftTeams.settings.registerOnSaveHandler(saveEvent => {
microsoftTeams.settings.setSettings({
contentUrl: "https://xxxxxx.ngrok.io/teams/connector"
});
saveEvent.notifySuccess();
});
The documentation states that registering a save handler is optional and Teams will handle notify success if it's not declared. WRONG. You must register a save handler.
The documentation does not state that setSettings is required. WRONG. You must set settings or else you will receive this error.
The documentation does not state that you must save a contentURL. WRONG. You must set content URL in the setSettings. You can apparently omit other things when setting your settings, but not content URL.
The documentation does not specifically mention it, but the contentURL must comply with your validURLs in your manifest. If it does not, you'll also see this error.
So in your case, you must ensure that isSettings.serverUrl (setSettings() contentURL) does match preview.icescrum.com (manifest validURLs). If they do not, you'll see this error.

How to send response to Slack with dynamically message options

I am trying to dynamically populate a message menu based on user selection. however, i am not sure how to send response to slack with the dynamic options. is it through chat.postMessage or chat.update? I tried both and it did not work. this is my code:
function usr_access (actionName,response_URL) {
var message = {
"text": "Choose the folder which you need access to",
"replace_original": false,
"attachments": [
{
"fallback": "Ooops... something went wrong..",
"callback_id": "DAaccess",
"attachment-type": "default",
"actions": [
{
"name": "fld_list",
"text": "Select",
"type": "select",
"data_source": "external"
}
]
}
]
}
sendMessageToSlackResponseURL(response_URL, message)
}
I am receiving below error:
request
="{\"name\":\"fld_list\",\"value\":\"\",\"callback_id\":\"DAaccess\",\"type\":\"interactive_message\",\"team\":{\"id\":\"xxxxxxxx\",\"domain\":\"xxxxxxxxx\"},\"channel\":{\"id\":\"XXXXXXXX\",\"name\":\"directmessage\"},\"user\":{\"id\":\"xxxxxxxx\",\"name\":\"xxxxxxxxxxxxxx\"},\"action_ts\":\"1545655305.281796\",\"message_ts\":\"1545654125.002700\",\"attachment_id\":\"1\",\"token\":\"xxxxxxxxxxxxxxxx\"}" request =interactive_message ReferenceError: res is not defined
at Request.request [as _callback] (SlackApp/events_slack.js:130:12)
at self.callback (SlackApp/node_modules/request/request.js:185:22)
at emitOne (events.js:115:13)
at Request.emit (events.js:210:7)
at Request.init (SlackApp/node_modules/request/request.js:231:17)
at new Request (SlackApp/node_modules/request/request.js:127:8)
at request (SlackApp/node_modules/request/index.js:53:10)
at sendDynamicList (SlackApp/events_slack.js:128:2)
at app.post (SlackApp/events_slack.js:651:7)
any help or direction would be really appreciated.
Issue is resolved now. I tried sending the options is JSON format through res.send() function.(didn't think we can send options that way).

Resources