so I send an adaptive card with submitting action on my bot framework, that submit action have invoked action. When the TaskModuleContinueResponse is set to card the task module is working fine, but when I Used my NRGROK URL for the TaskModuleContinueResponse it will only show blank. I already add my NGROK URL in the valid domains, when I see the NGROK inspect I don't see my page being called.
Here is my manifest
{
"$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.9/MicrosoftTeams.schema.json",
"manifestVersion": "1.9",
"version": "1.0.0",
"id": "1c07cd26-a088-4db8-8928-ace382fa219f",
"packageName": "Some.microsoft.teams.companycommunicator.authors",
"developer": {
"name": "Some",
"websiteUrl": "https://somewebsite.com",
"privacyUrl": "https://somewebsite.com",
"termsOfUseUrl": "https://somewebsite.com"
},
"icons": {
"color": "color.png",
"outline": "outline.png"
},
"name": {
"short": "Announce (Authors)",
"full": "Company Announce (Authors)"
},
"description": {
"short": "Broadcast messages to multiple teams and people in one go",
"full": "Broadcasts messages to multiple teams and individuals through channel posts and chat messages"
},
"accentColor": "#64A2CC",
"configurableTabs": [
{
"configurationUrl": "https://b0837b7151f7.ngrok.io/configtab",
"canUpdateConfiguration": true,
"scopes": [
"team"
],
"context": [
"channelTab"
]
}
],
"bots": [
{
"botId": "eae687a6-936c-4fd7-ade7-1f01b388ac16",
"scopes": [
"team"
],
"commandLists": [
{
"scopes": [
"team"
],
"commands": [
{
"title": "Test",
"description": "Test bot trigger"
}
]
}
],
"supportsFiles": true,
"isNotificationOnly": false
}
],
"permissions": [
"identity",
"messageTeamMembers"
],
"validDomains": [
"b0837b7151f7.ngrok.io",
],
"webApplicationInfo": {
"id": "eae687a6-936c-4fd7-ade7-1f01b388ac16",
"resource": "api://b0837b7151f7.ngrok.io"
}
}
and here is my code for the task module I using ASP Net core
protected override async Task<TaskModuleResponse> OnTeamsTaskModuleFetchAsync(ITurnContext<IInvokeActivity> turnContext, TaskModuleRequest taskModuleRequest, CancellationToken cancellationToken)
{
var reply = MessageFactory.Text("OnTeamsTaskModuleFetchAsync TaskModuleRequest: " + JsonConvert.SerializeObject(taskModuleRequest));
await turnContext.SendActivityAsync(reply);
return new TaskModuleResponse
{
Task = new TaskModuleContinueResponse
{
Value = new Microsoft.Bot.Schema.Teams.TaskModuleTaskInfo()
{
//Card = CreateAdaptiveCardAttachment(),
Url = "https://b0837b7151f7.ngrok.io/details",
FallbackUrl = "https://b0837b7151f7.ngrok.io/details",
Height = 800,
Width = 1000,
Title = "Details",
},
},
};
}
And for my page is just simple hello world.
import React, { Component } from 'react'
import * as microsoftTeams from "#microsoft/teams-js";
export default class SeeDetail extends Component {
componentDidMount() {
microsoftTeams.initialize();
}
render() {
return (
<div>
<center>
<h1>Hello World</h1>
</center>
</div>
)
}
}
I don't know why like its been blocked or something because I don't see any request to my page on the NGROK Inspect. Is there something missing here
I have tried with your code it's working.
Please check in browser is your react page rendering correctly in browser when you call using https://b0837b7151f7.ngrok.io/details and try to render a page by generating a new ngrok Url.
Also check by adding your react page url in task module working sample.
If the issue still persists then try by deleting the existing app and upload your manifest again in teams App studio.
I believe for adaptive cards that you have to register any submit urls with the actionable messages dashboard here https://outlook.office.com/connectors/oam/publish
Related
I'm trying to create a Microsoft Teams bot that can be called. Especially, we plan to use it as a destination for incoming calls on a Call Queue.
It seems that the call buttons
we usually get with contacts are nowhere to be seen on this bot:
So far, I have managed to create a bot according to the samples.
In https://dev.botframework.com/, the bot appears and I have the Enable Calling flag set (which - interestingly, seems to get disabled almost every time I run the project in Visual Studio).
My permissions.json looks like this:
[
{
"resource": "Microsoft Graph",
"delegated": [
"User.Read"
],
"application": [
"Calls.Initiate.All",
"Calls.InitiateGroupCall.All",
"Calls.JoinGroupCall.All",
"Calls.AccessMedia.All"
]
}
]
My manifest.template.json looks like this:
{
"$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.13/MicrosoftTeams.schema.json",
"manifestVersion": "1.13",
"version": "1.0.0",
"id": "{{state.fx-resource-appstudio.teamsAppId}}",
"packageName": "com.microsoft.teams.extension",
"developer": {
"name": "Teams App, Inc.",
"websiteUrl": "{{state.fx-resource-frontend-hosting.endpoint}}",
"privacyUrl": "{{state.fx-resource-frontend-hosting.endpoint}}{{state.fx-resource-frontend-hosting.indexPath}}/privacy",
"termsOfUseUrl": "{{state.fx-resource-frontend-hosting.endpoint}}{{state.fx-resource-frontend-hosting.indexPath}}/termsofuse"
},
"icons": {
"color": "resources/color.png",
"outline": "resources/outline.png"
},
"name": {
"short": "{{config.manifest.appName.short}}",
"full": "{{config.manifest.appName.full}}"
},
"description": {
"short": "Short description of {{config.manifest.appName.short}}",
"full": "Full description of {{config.manifest.appName.short}}"
},
"accentColor": "#FFFFFF",
"bots": [
{
"botId": "{{state.fx-resource-bot.botId}}",
"scopes": [
"personal",
"team",
"groupchat"
],
"supportsFiles": false,
"supportsCalling": true,
"supportsVideo": true,
"isNotificationOnly": false
}
],
"composeExtensions": [],
"configurableTabs": [],
"staticTabs": [],
"permissions": [
"identity",
"messageTeamMembers"
],
"validDomains": [],
"webApplicationInfo": {
"id": "{{state.fx-resource-aad-app-for-teams.clientId}}",
"resource": "{{state.fx-resource-aad-app-for-teams.applicationIdUris}}"
}
}
I also believe to have configured the correct permissions on the App Registration in Azure:
Any idea where to look next? What do I need to do to make the bot directly callable as I would be able to with any other user?
I have the following problem. When I turn on/off my bulb in Google Home app it sends me EXECUTE request and then QUERY request for state check. That behaviour is okay, but the problem is that Actions on Google project can't parse my QUERY response.
For clarification: I don't have problems with C# JSON parsing and any of similar topics. I have problem with that the Actions on Google can't understand my QUERY response. I reponse in correct format according to Google's docs but in the web console I see that error occurs and I don't know what is wrong.
It shows following error in the Google Cloud Console:
{
"insertId": "166g06lg15lgekt",
"jsonPayload": {
"executionLog": {
"executionResults": [
{
"actionResults": [
{
"action": {
"actionType": "STATE_QUERY"
},
"device": {
"deviceType": "OUTLET"
},
"status": {
"externalDebugString": "JSON payload not an object.",
"isSuccess": false,
"statusType": "PARTNER_RESPONSE_INVALID_PAYLOAD"
}
}
],
"executionType": "PARTNER_CLOUD",
"latencyMsec": "191",
"requestId": "4734217757620110233"
}
]
},
"locale": "en-US"
},
"logName": "projects/smartlightproject-f47f4/logs/assistant_smarthome%2Fassistant_smarthome_logs",
"receiveTimestamp": "2022-07-13T13:23:04.088211105Z",
"resource": {
"labels": {
"project_id": "smartlightproject-f47f4"
},
"type": "assistant_action_project"
},
"severity": "ERROR",
"timestamp": "2022-07-13T13:23:04.088211105Z"
}
QUERY request which I receive is
{
"inputs": [
{
"intent": "action.devices.QUERY",
"payload": {
"devices": [
{
"customData": {
"barValue": true,
"bazValue": "foo",
"fooValue": 74
},
"id": "123"
}
]
}
}
],
"requestId": "5460596871498683621"
}
And my response to that QUERY request is
{
"requestId": "5460596871498683621",
"payload": {
"devices": {
"123": {
"on": true,
"online": true
}
}
}
}
I think that everything is as Google wants to in documentation but I can't find the solution nor cause of that issue. I appreciate your help, really.
If it matters I write my local fulfillment in ASP.NET.
That's how I send the QUERY response
var queryObj = JsonConvert.DeserializeObject<dynamic>("{\"requestId\":\"" + requestId + "\",\"payload\":{\"devices\":{\"123\":{\"on\":true,\"online\":true}}}}");
_logger.LogInformation("Odpowiedź na żądanie QUERY." + originalRequest + "\n\n" + JsonConvert.SerializeObject((object)queryObj));
return Ok((object)queryObj);
I have loaded the drop in UI, my auth works, the UI loads correctly, but when I click on Paypal Checkout, a new window pops up, it remains on about:blank for 5-10s and then it closes. The UI then states: ⚠ Something went wrong on our end.
In the console I get:
{
country: "US"
env: "sandbox"
errtype: "[object Error]"
host: "www.sandbox.paypal.com"
lang: "en"
pageID: "cd1b0e1c50"
path: "/smart/button"
prev_corr_ids: ""
referer: "https://localhost:7244"
stack: "Error: No ack for postMessage postrobot_method in https://www.sandbox.paypal.com in 10000ms\n at o (https://www.paypalobjects.com/api/checkout.min.js:2:134213)"
timestamp: 1649373277263
uid: {{uId}}
ver: "4.0.334"
windowID: "3a6eb34307"
}
Here is the initialization config for the drop-in UI:
{
authorization: "*********"
container: "#braintree_container"
paypal:{
amount: "$487.88"
currency: "USD"
flow: "checkout"
}
}
I have used known working credentials to no avail, and it still does not work, despite them being known good credentials. In digging into the requests, it seems like somewhere after the web.paypal-checkout.createPayment POST call. it sets up the billing agreement seemingly successfully, gets the ectoken, makes the UpdateClientConfig graphql call, but never makes the call out to the sandbox.paypal.com/smart/api/checkout/{{ectoken}}/appData? endpoint.
In the internal application, it seems to fail after the updateClientConfig call. It never populates the popup window, nor places the overlay. Attached are the HAR files for the internal app and the working codepen for comparison. These HAR files comprise all calls made after the Paypal gold button was clicked. I am inlining the relevant responses for redundancy.
INTERNAL—NON-WORKING SOLUTION
Analytics payload:
{
"analytics": [
{
"kind": "web.dropin.selected.paypal",
"timestamp": 1649854187
}
],
"_meta": {
"merchantAppId": "localhost:7244",
"platform": "web",
"sdkVersion": "3.80.0",
"source": "client",
"integration": "dropin2",
"integrationType": "dropin2",
"sessionId": {{sId}},
"dropinVersion": "1.31.2"
},
"braintreeLibraryVersion": "3.80.0",
"authorizationFingerprint": {{token}}
}
Setup billing agreement response:
{
"agreementSetup": {
"tokenId": {{paymentToken}},
"approvalUrl": "https://www.sandbox.paypal.com/agreements/approve?nolegacy=1\u0026ba_token={{paymentToken}}"
}
}
ectoken response:
{
"ack": "success",
"data": {
"type": "ba-token",
"token": {{paymentToken}}
},
"meta": {
"calc": "6496f6f13b1bb",
"rlog": "rZJvnqaaQhLn%2FnmWT8cSUueWscmrtUHe5Y1Bd%2FeqyvyOTq66rSXAciiXRg7dClMl1o2iporwJbYz7mI0k8X%2B5ryRC%2FRgCX6v_18022f916a7"
},
"server": {{serverId}}
}
UpdateClientConfig graphql:
Request:
mutation UpdateClientConfig(
$paymentToken : String!,
$fundingSource : ButtonFundingSourceType!,
$integrationArtifact : IntegrationArtifactType!,
$userExperienceFlow : UserExperienceFlowType!,
$productFlow : ProductFlowType!,
$buttonSessionID : String
) {
updateClientConfig(
token: $paymentToken,
fundingSource: $fundingSource,
integrationArtifact: $integrationArtifact,
userExperienceFlow: $userExperienceFlow,
productFlow: $productFlow,
buttonSessionID: $buttonSessionID
)
}
{
"paymentToken": {{paymentToken}},
"fundingSource": "paypal",
"integrationArtifact": "JS_V4",
"userExperienceFlow": "INCONTEXT",
"productFlow": "SMART_PAYMENT_BUTTONS",
"buttonSessionID": null
}
Response:
{
"data": {
"updateClientConfig": null
},
"extensions": {
"tracing": {
"version": 1,
"startTime": "2022-04-13T12:49:51.854Z",
"endTime": "2022-04-13T12:49:51.938Z",
"duration": 84116563,
"execution": {
"resolvers": [
{
"path": [
"updateClientConfig"
],
"parentType": "Mutation",
"fieldName": "updateClientConfig",
"returnType": "Boolean",
"startOffset": 1044862,
"duration": 83027846
}
]
}
},
"correlationId": "3535ba30e2627"
}
}
WORKING CODEPEN SOLUTION
Analytics payload:
{
"analytics": [
{
"kind": "web.paypal-checkout.createPayment",
"isAsync": false,
"timestamp": 1649854795783
}
],
"braintreeLibraryVersion": "braintree/web/3.85.3",
"_meta": {
"merchantAppId": "cdpn.io",
"platform": "web",
"sdkVersion": "3.85.3",
"source": "client",
"integration": "dropin2",
"integrationType": "dropin2",
"sessionId": {{sId}},
"dropinVersion": "1.33.1"
},
"authorizationFingerprint": {{token}}
}
Setup billing agreement response:
{
"agreementSetup": {
"tokenId": {{paymentToken}},
"approvalUrl": "https://www.sandbox.paypal.com/agreements/approve?nolegacy=1\u0026ba_token={{paymentToken}}"
}
}
ectoken response:
{
"ack": "success",
"data": {
"type": "ba-token",
"token": {{paymentToken}}
},
"meta": {
"calc": "3f508c09dd431",
"rlog": "rZJvnqaaQhLn%2FnmWT8cSUueWscmrtUHe5Y1Bd%2FeqyvyOTq66rSXAciiXRg7dClMl1o2iporwJbYz7mI0k8X%2B5vvp6t7dnU%2B%2B_180230253f6"
},
"server": {{serverId}}
}
UpdateClientConfig graphql:
Request:
mutation UpdateClientConfig(
$paymentToken : String!,
$fundingSource : ButtonFundingSourceType!,
$integrationArtifact : IntegrationArtifactType!,
$userExperienceFlow : UserExperienceFlowType!,
$productFlow : ProductFlowType!,
$buttonSessionID : String
) {
updateClientConfig(
token: $paymentToken,
fundingSource: $fundingSource,
integrationArtifact: $integrationArtifact,
userExperienceFlow: $userExperienceFlow,
productFlow: $productFlow,
buttonSessionID: $buttonSessionID
)
}
{
"paymentToken": {{paymentToken}},
"fundingSource": "paypal",
"integrationArtifact": "JS_V4",
"userExperienceFlow": "INCONTEXT",
"productFlow": "SMART_PAYMENT_BUTTONS",
"buttonSessionID": null
}
Response:
{
"data": {
"updateClientConfig": null
},
"extensions": {
"tracing": {
"version": 1,
"startTime": "2022-04-13T12:59:57.407Z",
"endTime": "2022-04-13T12:59:57.491Z",
"duration": 84834935,
"execution": {
"resolvers": [
{
"path": [
"updateClientConfig"
],
"parentType": "Mutation",
"fieldName": "updateClientConfig",
"returnType": "Boolean",
"startOffset": 1231858,
"duration": 83540568
}
]
}
},
"correlationId": "f6e5896873a1"
}
}
For my specific issue, VS2022 opens a chrome window with default debug switches that interfere with the functionality of the Braintree Paypal integration. specifically, it seems to be the --disable-background-networking switch. Once I disabled this switch, Paypal worked fine. Opening a new window and navigating to the path or using a different browser will also solve the issue.
as in title, I am trying to use Google API Explorer to run vm instance. I am using instances.insert for this, but I can't get it to work. After successfuly executing the call I can not see any newly creted vm instance in https://console.cloud.google.com/compute/instances
The request I am trying to execute is copied from Equivalent REST request in Google Cloud Console Create an instance web page :
{
"name": "some-name",
"machineType": "projects/my-project-id/zones/europe-west3-c/machineTypes/f1-micro",
"displayDevice": {
"enableDisplay": false
},
"metadata": {
"items": [
{
"key": "startup-script",
"value": "#! /bin/bash\necho hello\nEOF"
}
]
},
"tags": {
"items": []
},
"disks": [
{
"type": "PERSISTENT",
"boot": true,
"mode": "READ_WRITE",
"autoDelete": true,
"deviceName": "some-name",
"initializeParams": {
"sourceImage": "projects/debian-cloud/global/images/debian-10-buster-v20200910",
"diskType": "projects/my-project-id/zones/europe-west3-c/diskTypes/pd-standard",
"diskSizeGb": "10",
"labels": {}
},
"diskEncryptionKey": {}
}
],
"canIpForward": false,
"networkInterfaces": [
{
"subnetwork": "projects/my-project-id/regions/europe-west3/subnetworks/default",
"accessConfigs": [
{
"name": "External NAT",
"type": "ONE_TO_ONE_NAT",
"networkTier": "PREMIUM"
}
],
"aliasIpRanges": []
}
],
"description": "",
"labels": {},
"scheduling": {
"preemptible": false,
"onHostMaintenance": "MIGRATE",
"automaticRestart": true,
"nodeAffinities": []
},
"deletionProtection": false,
"reservationAffinity": {
"consumeReservationType": "ANY_RESERVATION"
},
"serviceAccounts": [
{
"email": "some-number-compute#developer.gserviceaccount.com",
"scopes": [
"https://www.googleapis.com/auth/cloud-platform"
]
}
],
"shieldedInstanceConfig": {
"enableSecureBoot": false,
"enableVtpm": true,
"enableIntegrityMonitoring": true
},
"confidentialInstanceConfig": {
"enableConfidentialCompute": false
}
}
Here is the response with status 200
{
"id": "2981010757915612255",
"name": "operation-1602235056020-5b1396b5c5cee-e0e30499-4d06ce75",
"zone": "https://www.googleapis.com/compute/v1/projects/my-project-id/zones/europe-west3-c",
"operationType": "insert",
"targetLink": "https://www.googleapis.com/compute/v1/projects/my-project-id/zones/europe-west3-c/instances/ams2-linux-race-1",
"targetId": "1541614827291382879",
"status": "RUNNING",
"user": "email#gmail.com",
"progress": 0,
"insertTime": "2020-10-09T02:17:36.818-07:00",
"startTime": "2020-10-09T02:17:36.821-07:00",
"selfLink": "https://www.googleapis.com/compute/v1/projects/my-project-id/zones/europe-west3-c/operations/operation-1602235056020-5b1396b5c5cee-e0e30499-4d06ce75",
"kind": "compute#operation"
}
I have the same issue with C# code example from https://cloud.google.com/compute/docs/reference/rest/v1/instances/insert#examples
I can execute the same request without errors and in response I am getting this
{
"clientOperationId":null,
"creationTimestamp":null,
"description":null,
"endTime":null,
"error":null,
"httpErrorMessage":null,
"httpErrorStatusCode":null,
"id":3283200477858999168,
"insertTime":"2020-10-09T00:46:55.187-07:00",
"kind":"compute#operation",
"name":"operation-1602229614262-5b1382701b989-381126a6-cc145485",
"operationType":"insert",
"progress":0,
"region":null,
"selfLink":"https://www.googleapis.com/compute/v1/projects/my-project-id/zones/europe-west3-c/operations/operation-1602229614262-5b1382701b989-381126a6-cc145485",
"startTime":"2020-10-09T00:46:55.189-07:00",
"status":"RUNNING",
"statusMessage":null,
"targetId":2365846324436118401,
"targetLink":"https://www.googleapis.com/compute/v1/projects/my-project-id/zones/europe-west3-c/instances/some-name",
"user":"email#gmail.com",
"warnings":null,
"zone":"https://www.googleapis.com/compute/v1/projects/my-project-id/zones/europe-west3-c",
"ETag":null
}
but I can't see any new instance beeing created...
Does any one know what is the issue here?
The Compute Engine API is enabled. Result of gcloud services list:
NAME TITLE
...
compute.googleapis.com Compute Engine API
...
Can you please double check if Compute Engine Api is enabled and post the result in your question.
gcloud services list
I believe your Compute Engine Api is not enabled.
I followed this guide in order to create account linking in my app
https://developers.google.com/actions/identity/google-sign-in#json
I'm able to verify the user's jwt decoder and send back a response that the user is authorised. Then, according to the guide, in the next request, I should get the user's profile payload (user.profile.payload in the json structure) but It's missing from the next request. More than that, I get the tokenId for jwt verification again.
I think that what i miss here is in the possibleIntent object but I'm not sure, as I didn't see any documentation for that, because I work with asp.net server. There are SDKs with documentation for java and nodeJS only
this is the request provided for the sign in the contain the tokenId
{
"user": {
"locale": "en-US",
"lastSeen": "2019-07-11T14:18:10Z",
"idToken": "<tokenId>",
"userVerificationStatus": "VERIFIED"
},
"conversation": {
"conversationId": "ABwppHH9uZfcKj6pS6A6wItKC1dOXuZJ5oFYt2Og7cqrElSQYC9bv-aV7iQ5FDYaJPp-fa7tQNhc2yS0fw3QBu-M",
"type": "ACTIVE",
"conversationToken": "e0e78f40-a207-49c2-9050-50c6ed526c24"
},
"inputs": [
{
"intent": "actions.intent.SIGN_IN",
"rawInputs": [
{
"inputType": "KEYBOARD"
}
],
"arguments": [
{
"name": "SIGN_IN",
"extension": {
"#type": "type.googleapis.com/google.actions.v2.SignInValue",
"status": "OK"
}
},
{
"name": "text"
}
]
}
],
"surface": {
"capabilities": [
{
"name": "actions.capability.SCREEN_OUTPUT"
},
{
"name": "actions.capability.ACCOUNT_LINKING"
},
{
"name": "actions.capability.AUDIO_OUTPUT"
},
{
"name": "actions.capability.MEDIA_RESPONSE_AUDIO"
},
{
"name": "actions.capability.WEB_BROWSER"
}
]
},
"isInSandbox": true,
"requestType": "SIMULATOR"
}
this is the response that i provide after verifying the user.
I tried it with both intents actions.intent.TEXT and actions.intent.SIGN_IN but with no success. the next request is provided with the user.idToken property again instead of the user.profile (that should contain the payload)
{
"conversationToken": "b09d915e-6df9-496d-acde-b76858cd95b4",
"expectUserResponse": true,
"expectedInputs": [
{
"inputPrompt": {
"richInitialPrompt": {
"items": [
{
"simpleResponse": {
"textToSpeech": "Hi",
"displayText": "Hi"
}
}
],
"suggestions": []
}
},
"possibleIntents": [
{
"intent": "actions.intent.TEXT",
"inputValueData": {
"#type": "type.googleapis.com/google.actions.v2.SignInValue",
"status": "OK"
}
}
]
}
]
}
The user.profile attribute you're talking about is something that is provided via the actions-on-google library for JavaScript. It isn't in the JSON that you will receive. But...
You don't need it because the basic profile information (name, email, and Google ID) is encoded in the user.idToken. That string, which will be sent to you for every request, is just a JWT token which you can verify and decode. The profile will be in the "payload" section.
I don't know c#, but https://jwt.io/ contains a list of libraries which can decode the JWT string for you so you can read the "payload".
Keep in mind that you don't need to verify the token each time (although if you do it right, this shouldn't be expensive), but that you can decode it to get the information that you're looking for.
If you don't want to decode it, you can decode it when you first verify it, get the information you need, and store that information in the userStorage string (assuming you don't expect it to change).