In botframework v3 I used to be able to pass any object in the entities of a message. In v4, I can pass only object with the "type" string member. At least as shown in the Bot emulator.
Why is this? Is there another way to pass custom objects? I have customers that are using the v3 way to pass objects as message metadata
While much has changed in V4, there is no significant difference between V3 and V4 when it comes to activities. You can still use entities to pass metadata in activities. Other ways to include metadata in activities are:
ChannelData
Properties
Value
Consider the following code:
private async Task TestEntitiesAsync(ITurnContext tc,
CancellationToken cancellationToken)
{
var reply = tc.Activity.CreateReply("reply");
var entity = new Entity("test")
{
Properties = JObject.FromObject(new { Foo = "Entity", Bar = 1 }),
};
reply.Entities = new[] { entity };
reply.ChannelData = new { Foo = "ChannelData", Bar = 2 };
reply.Properties = JObject.FromObject(new { Foo = "Properties", Bar = 3 });
reply.Value = new { Foo = "Value", Bar = 4 };
await tc.SendActivityAsync(reply);
}
The JSON of the activity it generates looks like this:
{
"Bar": 3,
"Foo": "Properties",
"attachments": [],
"channelData": {
"Bar": 2,
"Foo": "ChannelData"
},
"channelId": "emulator",
"conversation": {
"id": "xxxx|livechat"
},
"entities": [
{
"Bar": 1,
"Foo": "Entity",
"type": "test"
}
],
"from": {
"id": "3",
"name": "Bot",
"role": "bot"
},
"id": "xxxx",
"localTimestamp": "2018-12-26T15:33:36-08:00",
"locale": "en-us",
"recipient": {
"id": "xxxx",
"role": "user"
},
"replyToId": "xxxx",
"serviceUrl": "http://localhost:1234",
"text": "reply",
"timestamp": "2018-12-26T23:33:36.022Z",
"type": "message",
"value": {
"Bar": 4,
"Foo": "Value"
}
}
I recommend using Activity.Properties because ChannelData, Entities, and Value all have predefined uses, though they all should still serve your purposes in most cases. Remember that everything you write in C# (or whatever language you're using) is just going to be converted into JSON and sent through an HTTP message. The SDK is just providing an easy way of implementing the schema.
Related
Let's say below is the FHIR model I have in C# for Patient resource.
var pat = new Patient();
var name = new HumanName().WithGiven("Christopher").WithGiven("C.H.").AndFamily("Parks");
name.Prefix = new string[] { "Mr." };
name.Use = HumanName.NameUse.Official;
How do I convert this into FHIR JSON Schema? Basically I want to serialize it. I am expecting the output like below
{
"resourceType": "Patient",
"id": "xcda",
"text": {
"status": "generated",
"div": "<div xmlns=\"http://www.w3.org/1999/xhtml\"></div>"
},
"active": true,
"name": [
{
"family": "Levin",
"given": [
"Henry"
]
}
],
"gender": "male",
"birthDate": "1932-09-24",
"managingOrganization": {
"reference": "Organization/2.16.840.1.113883.19.5",
"display": "Good Health Clinic"
}
}
Also, I want to know is it possible to achieve this without using any FHIR external servers?
I am trying to retrieve data from the weather.gov API - it returns the format in geoJSON and I am not sure how to actually get the data I want from it.
If I am using the weatherbit.io API, I have no issues as it returns JSON format in which I can pull from rather easily.
I am using GuzzleHTTP to make the API call.
I am playing around with learning APIs and I have an interest in weather so I figured I would work on an application in which I could pull information from the local weather station and output it in to readable format for users in a table.
The code I am currently using is:
$api_call = https://api.weather.xxx/points/LAT,LON;
$client = new \GuzzleHttp\Client();
$request = $client->get($api_call);
if ($request->getStatusCode() == 200) {
$weatherRequest = $request->getBody();
$requestedWeather = json_decode($weatherRequest);
$currentweather = $requestedWeather; ** THIS IS WHERE I NEED HELP ***
}
return $currentweather;
});
return view('currentweather', ["currentweather" => $currentweather]);
When I am returning $currentweather and var_dump it to the view, it gives me all the geoJSON data but I don't know how to correctly iterate through the data to pull the information I need.
When I pull from another API it gives a different JSON format which I can just pull like so:
$api_call = https://api.weatherbit.xx/v2.0/current?
$client = new \GuzzleHttp\Client();
$request = $client->get($api_call);
if ($request->getStatusCode() == 200) {
$weatherRequest = $request->getBody();
$requestedWeather = json_decode($weatherRequest);
$currentweather = $requestedWeather->data;
}
return $currentweather;
});
return view('currentweather', ["currentweather" => $currentweather]);
}
And when I use $currentweather in my view I can pull any data I need with the object string name. I am not sure how to pull the data when it's leading off with the #Context tag.
The data I want lies in the "properties" part of the geoJSON array and I just can't seem to figure out how to get that in the way I am currently using.
This is my geoJSON array return:
{ "#context": [ "https://raw.githubusercontent.xxx/geojson/geojson-ld/master/contexts/geojson-base.jsonld", { "wx": "https://api.weather.xxx/ontology#", "s": "https://schema.org/", "geo": "http://www.opengis.xxx/ont/geosparql#", "unit": "http://codes.wmo.xxx/common/unit/", "#vocab": "https://api.weather.xxx/ontology#", "geometry":
{ "#id": "s:GeoCoordinates", "#type": "geo:wktLiteral" }, "city": "s:addressLocality", "state": "s:addressRegion", "distance": { "#id": "s:Distance", "#type": "s:QuantitativeValue" }, "bearing": { "#type": "s:QuantitativeValue" }, "value": { "#id": "s:value" }, "unitCode":
{ "#id": "s:unitCode", "#type": "#id" }, "forecastOffice": { "#type": "#id" }, "forecastGridData": { "#type": "#id" }, "publicZone": { "#type": "#id" }, "county": { "#type": "#id" } } ], "id": "https://api.weather.xxx/points/xxx,xxx", "type": "Feature", "geometry": { "type": "Point", "coordinates": [ xxx, xxx ] }, "properties":
{ "#id": "https://api.weather.xxx/points/xxx,xxx", "#type": "wx:Point", "cwa": "xxx", "forecastOffice": "https://api.weather.xxx/offices/xxx", "gridX": 86, "gridY": 77, "forecast": "https://api.weather.xxx/gridpoints/xxx/xx,xx/forecast", "forecastHourly": "https://api.weather.xxx/gridpoints/xxx/xx,xx/forecast/hourly", "forecastGridData": "https://api.weather.xxx/gridpoints/xxx/xx,xx", "observationStations": "https://api.weather.xxx/gridpoints/xxx/xx,xx/stations", "relativeLocation":
{ "type": "Feature", "geometry": { "type": "Point", "coordinates": [ xxx, xxx ] }, "properties": { "city": "xxx", "state": "xx", "distance": { "value": xxxx.xxxxxxxxx, "unitCode": "unit:m" }, "bearing": { "value": 150, "unitCode": "unit:degrees_true" } } }, "forecastZone": "https://api.weather.xxx/zones/forecast/xxxxxx", "county": "https://api.weather.xxx/zones/county/xxxxxx", "fireWeatherZone": "https://api.weather.xxx/zones/fire/SCZ050", "timeZone": "America/New_York", "radarStation": "xxxx" } }
Thanks for your help!
Any member of the JSON object can be accessed via the same name on the object returned by json_decode. Your weatherbit example $requestedWeather->data works because everything is in a member called data. So... $requestedWeather->properties will get you what you want from the weather.gov API.
You can also pass true as a second argument to json_decode to get back a plain PHP array instead.
$requestedWeather = json_decode($weatherRequest, true);
var_dump($requestedWeather['properties']);
This is often recommended because JSON allows member names that are not valid PHP object property names (e.g., names containing hyphens).
I have a skill, I'm trying to test it with the "test" function in alexa developer console. If I give the invocation name, it gets recognized to be the specific intent, but the response doesn't match. (It might be something glaringly obvious that I just can't notice anymore.)
I have a LaunchRequest type, it works with the invocation name.
const LaunchRequestHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'LaunchRequest';
},
handle(handlerInput) {
welcomeMessage = `updated welcome`;
return handlerInput.responseBuilder
.speak(welcomeMessage)
.reprompt(helpMessage)
.getResponse();
},
};
(welcomeMessage is declared outside, this was just testing if the issue was giving it new value)
However, when it comes to an intent based on user input (in this case TestIntent, the user input is "is the skill working"), it just doesn't work.
TestIntent's code is the same as LaunchRequest, except the intent type&name check
const request = handlerInput.requestEnvelope.request;
return (request.type === "IntentRequest" &&
request.intent.name === "TestIntent");
The alexa skill's json input recognizes the input as a TestIntent
"request": {
"type": "IntentRequest",
"requestId": "amzn1.echo-api.request.601d2e89-71c1-417e-b878-790afc6f79f4",
"timestamp": "2019-08-12T07:01:38Z",
"locale": "en-US",
"intent": {
"name": "TestIntent",
"confirmationStatus": "NONE"
},
"dialogState": "STARTED"
}
But the response is just "I am sorry, but I do not know that. Can you repeat that?"
You need to create your custom intent with utterances.
Login to https://developer.amazon.com
Create your skill and add your utterances which will map to specific intent.
Sample:
{
"interactionModel": {
"languageModel": {
"invocationName": "mySkill",
"intents": [
{
"name": "TestIntent",
"slots": [
{
"name": "name",
"type": ""
}
],
"samples": [
"test me", // This would be your utterance to identify intent
"testing you" // You can have multiple
]
},
{
"name": "AMAZON.FallbackIntent",
"samples": []
},
{
"name": "AMAZON.HelpIntent",
"samples": []
},
{
"name": "AMAZON.NoIntent",
"samples": []
}
]
}
}
}
Below is the walkthrough to the developer account
1) Create your intent
2) Create your utterances
And then just build your modal. Your Skill needs to be linked to your lambda function.
Hope this help!
======UPDATE=====
Need to return card response
response = {
outputSpeech: {
type: "PlainText",
text: output
},
card: {
type: "Simple",
title: title,
content: output
},
shouldEndSession: shouldEndSession
};
Using aw-sdk: (Sample)
return handlerInput.responseBuilder
.speak(speechText)
.reprompt(speechText)
.withSimpleCard('Hello World', speechText)
.getResponse();
}
I'm new to DynamoDB.
When I read data from the table with AWS.DynamoDB.DocumentClient class, the query works but I get the result in the wrong format.
Query:
{
TableName: "users",
ExpressionAttributeValues: {
":param": event.pathParameters.cityId,
":date": moment().tz("Europe/London").format()
},
FilterExpression: ":date <= endDate",
KeyConditionExpression: "cityId = :param"
}
Expected:
{
"user": "boris",
"phones": ["+23xxxxx999", "+23xxxxx777"]
}
Actual:
{
"user": "boris",
"phones": {
"type": "String",
"values": ["+23xxxxx999", "+23xxxxx777"],
"wrapperName": "Set"
}
}
Thanks!
The [unmarshall] function from the [AWS.DynamoDB.Converter] is one solution if your data comes as e.g:
{
"Attributes": {
"last_names": {
"S": "UPDATED last name"
},
"names": {
"S": "I am the name"
},
"vehicles": {
"NS": [
"877",
"9801",
"104"
]
},
"updatedAt": {
"S": "2018-10-19T01:55:15.240Z"
},
"createdAt": {
"S": "2018-10-17T11:49:34.822Z"
}
}
}
Please notice the object/map {} spec per attribute, holding the attr type.
Means you are using the [dynamodb]class and not the [DynamoDB.DocumentClient].
The [unmarshall] will Convert a DynamoDB record into a JavaScript object.
Stated and backed by AWS. Ref. https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB/Converter.html#unmarshall-property
Nonetheless, I faced the exact same use case, as yours. Having one only attribute, TYPE SET (NS) in my case, and I had to manually do it. Next a snippet:
// Please notice the <setName>, which represents your set attribute name
ddbTransHandler.update(params).promise().then((value) =>{
value.Attributes[<setName>] = value.Attributes[<setName>].values;
return value; // or value.Attributes
});
Cheers,
Hamlet
I took suggestions from here and tried to create a class with objects for the parts I need to parse from my json feed. I then tried to deserialize it before mapping the field contents to my objects but the deserialization returns nothing.
Here is the json feed content:
"data": [
{
"id": "17xxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxx",
"from": {
"name": "Lxxxxxx",
"category": "Sports league",
"id": "17xxxxxxxxxxxxx"
},
"picture": "http://external.ak.fbcdn.net/safe_image.php?d=AQB4GscSy-2RHY_0&w=130&h=130&url=http\u00253A\u00252F\u00252Fwww.ligabbva.com\u00252Fquiz\u00252Farchivos\u00252Fbenzema-quiz-facebook.png",
"link": "http://www.xxxxxva.com/quiz/index.php?qid=34",
"source": "http://www.lxxxxva.com/modulos/redirectQuiz.php?name=benzema&q=34&time=1312827103",
"name": "DEMUESTRA CU\u00c1NTO SABES SOBRE... BENZEMA",
"caption": "www.xxxxxva.com",
"description": "Demuestra cu\u00e1nto sabes sobre Karim Benzema, delantero del Real Madrid.",
"icon": "http://static.ak.fbcdn.net/rsrc.php/v1/yj/r/v2OnaTyTQZE.gif",
"type": "video",
"created_time": "2011-08-08T18:11:54+0000",
"updated_time": "2011-08-08T18:11:54+0000",
"likes": {
"data": [
{
"name": "Jhona Arancibia",
"id": "100000851276736"
},
{
"name": "Luis To\u00f1o",
"id": "100000735350531"
},
{
"name": "Manuel Raul Guerrero Cumbicos",
"id": "100001485973224"
},
{
"name": "Emmanuel Gutierrez",
"id": "100000995038988"
}
],
"count": 127
},
"comments": {
"count": 33
}
},
{
"id": "17xxxxxxxxxxxxxxxx_xxxxxxxxxxxxx",
"from": {
"name"
and here is the code I am trying. I tried to also use the jsontextreader and loop through each tokentype and check each one and then read the value but this looks like it will turn out to be tedious.
....
//fetch the content
responsedata = reader.readtoend()
......
dim pp as facedata = JsonConvert.DeserializeObject(of faceData)(responsedata)
console.writeline(pp.id.tostring)
and the class objects
Public Class faceData
Public Property id() as string
Get
Return f_id
End Get
Set(ByVal value as string)
f_id =value
End Set
End Property
Private f_id as string
......
any response appreciated.
Does anyone have links to full code where it actually works using vb.net.