Unable to send http post request from Microsoft Teams messagecard's potention action button - http-post

I'm sending a card to a Microsoft Teams channel with a button that contains a post request.
When I click the button I got the following error :
"Failed to send
Could not complete the requested action. Please try again later."
#type": "MessageCard",
"#context": "https://schema.org/extensions",
"summary": "{SUMMÁRIA}",
"themeColor": "0078D7",
"title": "{TÁJ} - {TÓÉ} ",
"sections": [
...sectionDescription],
"potentialAction": [
{
"name": "BUTTON LABEL",
"target": "https://<targetURL>",
/* I also tried this one "headers": [{
"name": "Authorization",
"value": "Basic base64",
}, {"name" : "Content-Type", "value": "application/json"}],*/
"headers": [{"Authorization": "Basic <BASE64STUFF>"}, {"Content-Type": "application/json"}, ],
"#type": "HttpPOST",
"url": "https://<TARGETURL>",
"bodyContentType": "application/json",
"body": JSON.stringify({
"buildType": {
"id": "hereisTheid"
},
"comment": {
"text": "message"
},
"properties": {
"property": [{
"name": "proprety",
"value": "valueofproperty"
},
{
"name": "properyt",
"value": "valueofProperty"
}
]
},
}),
},
{
"#type": "HttpPOST",
"name": "View Build",
"target": "https://....."
},
{
"#type": "HttpPOST",
"name": "Test results",
"target": "http://..."
}
]
How can I identify the button's response?

Try using Teams in the web client instead of the desktop client. It might give a better view on this because you have access to the browser F12 Developer tools.

Related

Update Teams Manifest - Object reference not set

We are currently build a MS Teams app, and we are in the POC phase.
When using the menu in Visual studio to update the Manifest with the latest changes from the manifest, I get the following error. Project -> TeamsFx -> Update Teams Manifest
System.NullReferenceException: Object reference not set to an instance of an object.
at TeamsFx.VisualStudio.Definitions.AppDefinitionBot.FromAppManifestBot(AppManifestBot appManifestBot)
at TeamsFx.VisualStudio.Commands.TeamsAppManifest.<>c.<MergeIntoTeamsAppDefinitionAsync>b__18_2(AppManifestBot bot)
at System.Linq.Enumerable.WhereSelectListIterator`2.MoveNext()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at TeamsFx.VisualStudio.Commands.TeamsAppManifest.<MergeIntoTeamsAppDefinitionAsync>d__18.MoveNext()
The bot is defined as follows :
"bots": [
{
"botId": "someId",
"needsChannelSelector": false,
"isNotificationOnly": false,
"scopes": [
"team",
"personal",
"groupchat"
]
}
],
And then we only have composeExtensions to show cards, with 2 simple examples to test and see how it works.
"composeExtensions": [
{
"botId": "someId",
"canUpdateConfiguration": true,
"commands": [
{
"id": "createCard",
"type": "action",
"context": [ "message" ],
"description": "Command to run action to create a Card from Compose Box",
"title": "Create Card",
"parameters": [
{
"name": "title",
"title": "Card title",
"description": "Title for the card",
"inputType": "text"
},
{
"name": "subTitle",
"title": "Subtitle",
"description": "Subtitle for the card",
"inputType": "text"
},
{
"name": "text",
"title": "Text",
"description": "Text for the card",
"inputType": "textarea"
}
]
},
{
"id": "createAdaptiveCard",
"type": "action",
"context": [ "message" ],
"description": "Command to run action to create a Card from Compose Box",
"title": "Adaptive Card",
"parameters": [
{
"name": "title",
"title": "Name",
"description": "Name of the User",
"inputType": "text"
},
{
"name": "subTitle",
"title": "Designation",
"description": "Designation of the User",
"inputType": "text"
},
{
"name": "text",
"title": "Description",
"description": "Description",
"inputType": "textarea"
}
]
}
]
}
],
The end result is the app in MS Teams when running it, doesn't pull in the latest changes.
The TeamFx Validation pass with no errors. My assumption is something is wrong in the manifest file, although I can't find anything that is standing out.
Can anyone please advise if they had this before and how to resolve it?
Thanks in advance.
I found the solution was to include the following in the bots section of the manifest file:
"commandLists": []"
If that is isn't defined, it was throwing an exception. Defined, but with just an empty list, resolved it.

Firefox webExtension - re-write "redirectURL" in HTTP POST response

I'm writing my first webExtension for Firefox. It targets a particular feature on one website, and essentially needs to rewrite the "redirectURL" value in the server response to a HTTP POST (I want it to stop refreshing the page after certain buttons are clicked).
I'm having trouble with this. So far, I've tried webRequest.onHeadersReceived, but the "redirectURL" value isn't in the headers. I've also tried a filterResponseData, but "redirectURL" value isn't in the content of the response either. I captured the full transaction using browser dev tools, and here is the relevant part:
"response": {
"status": 302,
"statusText": "Found",
"httpVersion": "HTTP/2.0",
"headers": [
{
"name": "date",
"value": "Fri, 05 Jul 2019 13:06:18 GMT"
},
{
"name": "content-type",
"value": "text/html; charset=utf-8"
},
{
"name": "location",
"value": "https://www.strava.com/clubs/2140/members"
},
{
"name": "cache-control",
"value": "no-cache, no-store"
},
{
"name": "via",
"value": "1.1 linkerd"
},
{
"name": "x-download-options",
"value": "noopen"
},
{
"name": "pragma",
"value": "no-cache"
},
{
"name": "status",
"value": "302 Found"
},
{
"name": "expires",
"value": "Sat, 01 Jan 2000 00:00:00 GMT"
},
{
"name": "x-request-id",
"value": "5ff9a2b9-e9b4-453e-9e4e-d42e1ffdd09c"
},
{
"name": "referrer-policy",
"value": "strict-origin-when-cross-origin"
},
{
"name": "x-frame-options",
"value": "SAMEORIGIN,DENY"
},
{
"name": "x-content-type-options",
"value": "nosniff"
},
{
"name": "x-permitted-cross-domain-policies",
"value": "none"
},
{
"name": "x-xss-protection",
"value": "1; mode=block"
},
{
"name": "content-encoding",
"value": "gzip"
},
{
"name": "X-Firefox-Spdy",
"value": "h2"
}
],
"cookies": [],
"content": {
"mimeType": "text/html; charset=utf-8",
"size": 119109,
"comment": "Response bodies are not included."
},
"redirectURL": "https://www.strava.com/clubs/1234/members", <-- I want to re-write this
"headersSize": 597,
"bodySize": 29832
},
Thanks in advance!
The redirect URL is in the location header. The line you marked in the HAR is merely an indication of the action the browser took.
So you can intercept the response and change said header:
function modifyRedir(details)
{
for (let header of details.responseHeaders) {
if (header.name.toLowerCase() == "location")
{
header.value = "<some URL>";
}
}
return {responseHeaders: details.responseHeaders};
}
browser.webRequest.onHeadersReceived.addListener(
modifyRedir,
{
urls: ["<URL this should be applied to>"]
},
["blocking", "responseHeaders"]
);
Alternatively, you could also just overwrite the redirect
function modifyRedir(details)
{
return {redirectUrl: "<some URL>"};
}

Bot Framework save user data in the database by UserID

I want to save data that the user has entered in my database.
I need an ID that will be unique for all conversations with the same user rather than for a single conversation.
According to the documentation, I need to use the From.ID field from the Channel Account data.
But when I use Bot Framework Emulator and click Restart with same User ID, the ID of the user changes and what remains is the bot ID.
What field should I use to identify a user across different calls (in the same channel, of course)?
In this example, I see that the the Recipient.id identifier that the bot sends does not change.
Is this the user's unique identifier? Why is it be different from the From.ID?
Conversation 1:
Message from the bot:
{
"channelId": "emulator",
"conversation": {
"id": "202d2d60-4c7f-11e9-b1fa-8b3537dcca45|livechat"
},
"from": {
"id": "2",
"name": "Bot",
"role": "bot"
},
"id": "208f2380-4c7f-11e9-98ea-9595460a8f6e",
"inputHint": "acceptingInput",
"localTimestamp": "2019-03-22T10:47:30+02:00",
"locale": "",
"recipient": {
"id": "d4d1b5a6-1797-4d2a-b78e-257de71d3a69",
"role": "user"
},
"replyToId": "20559cf0-4c7f-11e9-98ea-9595460a8f6e",
"serviceUrl": "http://localhost:53634",
"showInInspector": true,
"text": "conversationUpdate event detected",
"timestamp": "2019-03-22T08:47:30.232Z",
"type": "message"
}
Message from the user:
{
"channelData": {
"clientActivityID": "15532445742330.iqwrgb646rq",
"state": "sent"
},
"channelId": "emulator",
"conversation": {
"id": "202d2d60-4c7f-11e9-b1fa-8b3537dcca45|livechat"
},
"entities": [
{
"requiresBotState": true,
"supportsListening": true,
"supportsTts": true,
"type": "ClientCapabilities"
}
],
"from": {
"id": "r_wg30czmqjt",
"name": "User",
"role": "user"
},
"id": "6a791af0-4c7f-11e9-98ea-9595460a8f6e",
"localTimestamp": "2019-03-22T10:49:34+02:00",
"locale": "",
"recipient": {
"id": "2",
"name": "Bot",
"role": "bot"
},
"serviceUrl": "http://localhost:53634",
"showInInspector": true,
"text": "hi",
"textFormat": "plain",
"timestamp": "2019-03-22T08:49:34.239Z",
"type": "message"
}
Conversation 2 (After Restart with same user ID):
Message from the bot:
{
"channelId": "emulator",
"conversation": {
"id": "a10fba20-4c83-11e9-b1fa-8b3537dcca45|livechat"
},
"from": {
"id": "2",
"name": "Bot",
"role": "bot"
},
"id": "a15611f0-4c83-11e9-98ea-9595460a8f6e",
"inputHint": "acceptingInput",
"localTimestamp": "2019-03-22T11:19:44+02:00",
"locale": "",
"recipient": {
"id": "d4d1b5a6-1797-4d2a-b78e-257de71d3a69",
"role": "user"
},
"replyToId": "a116e610-4c83-11e9-98ea-9595460a8f6e",
"serviceUrl": "http://localhost:53634",
"showInInspector": true,
"text": "conversationUpdate event detected",
"timestamp": "2019-03-22T09:19:44.271Z",
"type": "message"
}
Message from the user:
{
"channelData": {
"clientActivityID": "15532464069120.36lccv6nsg3",
"state": "sent"
},
"channelId": "emulator",
"conversation": {
"id": "a10fba20-4c83-11e9-b1fa-8b3537dcca45|livechat"
},
"entities": [
{
"requiresBotState": true,
"supportsListening": true,
"supportsTts": true,
"type": "ClientCapabilities"
}
],
"from": {
"id": "r_xl9pb24o5o",
"name": "User",
"role": "user"
},
"id": "aed62f90-4c83-11e9-98ea-9595460a8f6e",
"localTimestamp": "2019-03-22T11:20:06+02:00",
"locale": "",
"recipient": {
"id": "2",
"name": "Bot",
"role": "bot"
},
"serviceUrl": "http://localhost:53634",
"showInInspector": true,
"text": "hi",
"textFormat": "plain",
"timestamp": "2019-03-22T09:20:06.921Z",
"type": "message"
}
This was a bug in the Emulator, and fixed with https://github.com/Microsoft/BotFramework-Emulator/pull/1348
Please make sure you are on version >= 4.3.3:
Also, the Recipient.Id is the bot id if the message is coming from the Emulator.
Being that the bots do not track or identify a user, that part is up to you.
You will need to:
Create a "back channel" that captures Authentication of user. Give the bot access to the userid/username of the user who is interacting or having a conversation.
When the user logs in and authenticates to the application, you identify the user - retrieve this.
When the user interacts with the bot you get the conversation ID - you already have this.
Tie them together in a JSON object and store back to cloud storage, or app storage or SQL db.

Accessing collections data from Google+ API

I'm using the Google Plus API, and there seems to be no information in the JSON response regarding the collection of the post. I was wondering if there was a way to access which collection a post belongs using the API data.
For example, could we use the URL given to parse the collection from the webpage? Does anyone have any idea how this could be done in a performant way?
The google+ api is a read only api and every limited it gives you access to people, activities and comments.
Activites list returns a list of all activities#resource posts by a user. try it
The only collection you can send is public. the response looks like this.
{
"kind": "plus#activity",
"etag": "\"RKS4-q7QGL10FxltAebpjqjKQR0/82jivrLU7ubQ-fwlLaXGSt3krb8\"",
"title": "",
"published": "2018-06-18T07:03:54.034Z",
"updated": "2018-06-18T07:03:54.034Z",
"id": "z13lu3vowpa5x3aws04chl2brzavs1rplos0k",
"url": "https://plus.google.com/+LindaLawton/posts/STgianNMQwU",
"actor": {
"id": "117200475532672775346",
"displayName": "Linda Lawton",
"url": "https://plus.google.com/117200475532672775346",
"image": {
"url": "https://lh5.googleusercontent.com/-a1CWlFnA5xE/AAAAAAAAAAI/AAAAAAAAl1I/UcwPajZOuN4/photo.jpg?sz=50"
},
"verification": {
"adHocVerified": "UNKNOWN_VERIFICATION_STATUS"
}
},
"verb": "post",
"object": {
"objectType": "note",
"actor": {
"verification": {
"adHocVerified": "UNKNOWN_VERIFICATION_STATUS"
}
},
"content": "",
"url": "https://plus.google.com/+LindaLawton/posts/STgianNMQwU",
"replies": {
"totalItems": 0,
"selfLink": "https://content.googleapis.com/plus/v1/activities/z13lu3vowpa5x3aws04chl2brzavs1rplos0k/comments"
},
"plusoners": {
"totalItems": 0,
"selfLink": "https://content.googleapis.com/plus/v1/activities/z13lu3vowpa5x3aws04chl2brzavs1rplos0k/people/plusoners"
},
"resharers": {
"totalItems": 0,
"selfLink": "https://content.googleapis.com/plus/v1/activities/z13lu3vowpa5x3aws04chl2brzavs1rplos0k/people/resharers"
},
"attachments": [
{
"objectType": "article",
"displayName": "leastprivilege/AspNetCoreSecuritySamples",
"content": "AspNetCoreSecuritySamples - Samples for various ASP.NET Core Security Features",
"url": "https://github.com/leastprivilege/AspNetCoreSecuritySamples",
"image": {
"url": "https://lh3.googleusercontent.com/proxy/1pdxjC-TsuF0-8yHOZKvfDOXG1pNWAIemDoW7OzrFy8pcckGqr0BTJj-TwgW9KgEuoGLJjfUKLWSCouJwTT7FjoOmZ_xURQwzz4=w506-h910",
"type": "image/jpeg",
"height": 910,
"width": 506
},
"fullImage": {
"url": "https://avatars0.githubusercontent.com/u/1454075?s=400&v=4",
"type": "image/jpeg"
}
}
]
},
"provider": {
"title": "Google+"
},
"access": {
"kind": "plus#acl",
"description": "Public",
"items": [
{
"type": "public"
}
]
}
},
the above post here is actually within one of my collections. But no were in the response does it mention the id of the collection that its in which is olLcVE
As i mentioned this is a very limited api and what you want to do is not available.

Bot Framework doesn't have username if telegram profile doesn't have full name or username

Messages delivered from Bot Framework don't have name property in from object if message was sent by user who doesn't have username and full name. For example if you delete first or last name from profile like that
Here's example of json that I get for messages sent from user that only has first name (look at from object):
{
"channelData": {
"message": {
"chat": {
"all_members_are_administrators": true,
"id": -219911672,
"title": "jlarky-dev",
"type": "group"
},
"date": 1493246056,
"from": {
"first_name": "Test",
"id": 107390199
},
"message_id": 100,
"text": "test"
},
"update_id": 66470785
},
"channelId": "telegram",
"conversation": {
"id": "-219911672",
"isGroup": true,
"name": "jlarky-dev"
},
"entities": [
{
"mentioned": {
"id": "JLarkyTestBot",
"name": "jlarky_test"
},
"text": "JLarkyTestBot",
"type": "mention"
}
],
"from": {
"id": "107390199"
},
"id": "KxBlE8JsLfg",
"recipient": {
"id": "JLarkyTestBot",
"name": "jlarky_test"
},
"serviceUrl": "https://telegram.botframework.com",
"text": "test",
"timestamp": "2017-04-26T22:34:17.4109674Z",
"type": "message"
}
Since #NilsW's comment I tested this again and it looks like from.name only exists when username of telegram profile was set (same can be looked up from channelData.message.from.username), so I guess it makes sense for it not to show username when username was not set :) and not having last_name part was not related here.

Resources