I am writing a Bixby capsule and one of the inputs is street address.
One method that I have tried is creating the following structure:
structure (FullAddress) {
description (Address of a house)
property (addressNumber) {
type (geo.StreetNumber)
min (Required)
description (Address Number)
}
property (addressStreet) {
type (geo.StreetName)
min (Required)
description (Street Name)
}
property (addressSuffix) {
type (geo.StreetSuffix)
min (Required)
description (Street Name)
}
}
with a constructor action to put the 3 inputs together.
I have seen that given an address 19 Fake Fields Street the geo.StreetName typed input sometimes is able to understand Fake Fields and sometimes just Fake and drops Fields.
Also Bixby's speech to text sometimes hears app or have instead of ave for the geo.StreetSuffix value which makes it prompt the user for a suffix.
Is there a way to get Bixby to understand a street address with a little more accuracy?
Basically you need more training examples, which include 2 or 3 words as street names. Try to have at least 3 examples with xxx fakexxx fields street, and test in simulator the utterance yyy fakeyyy fields street to see if Bixby can capture fields as part of the address name. The goal here is to train Bixby to learn that there might be 2 or even 3 words ahead of addressSuffix. After that you can try utterance zzz fakezzz creek street without ever using creek in the training to confirm Bixby not just learned fields. Please read more in this article.
There is no easy way when come to speech recognition. You can include a vocab model to force "app" to be "ave", but what if user truly want say the word app or have? I would think the user can type ave or blvd, but need to say the word avenue instead of ave, and boulevard instead of blvd.
Another alternative is to use the viv.geo.SearchTerm in training and viv.geo.NamedPoint in your action. This let a user say something incomplete like "1 Market Street, California" and Bixby will use a HERE maps search to find this in San Francisco.
To use, setup a NamedPoint concept (after importing viv.geo)
structure (InputAddress) {
role-of (geo.NamedPoint)
}
Then in your action, you can do something like:
input (namedPoint) {
type (InputAddress)
min (Required) max (One)
default-select {
with-learning
with-rule {
select-first
}
}
}
In this example, using learning and select-first will automatically select the first address. Without this, Bixby will autosuggest addresses.
namedPoint will then be passed to your endpoint and you can parse as needed.
In training, use geo.SearchTerm - for example:
[g:GetAddressAction] My address is {[g:InputAddress] (665 Clyde Ave Mountain View California)[v:geo.SearchTerm]}
or for a prompt, you could use:
[g:GetAddressAction:continue:InputAddress] {[g:InputAddress] (60 S Market)[v:geo.SearchTerm]}
You can get a more fully formatted address by letting Bixby handle it by using the viv.geo.ResolveAddressByPlaceID goal. Here is a complete action using NamedPoint and ResolveAddressByPlaceID. Note the links to the relevant docs in comments
action (GetAddressAction) {
type(Search)
description (Get Address)
collect {
// See https://bixbydevelopers.com/dev/docs/dev-guide/developers/library.geo#using-searchterm - used in training
// and https://bixbydevelopers.com/dev/docs/dev-guide/developers/library.geo#namedpoint - used below and for computed-input
input (namedPoint) {
type (InputAddress)
min (Required) max (One)
default-select {
with-learning
with-rule {
select-first
}
}
// hidden - Hide if all you need is address
}
computed-input (address){
type (geo.Address)
min (Optional) max (One)
compute {
intent {
goal: viv.geo.ResolveAddressByPlaceID
value: $expr(namedPoint.placeID)
}
}
}
}
output (geo.Address)
}
Related
I'm trying to make a deserializer for the FullOrder struct from the CEX.IO exchange (https://cex.io/rest-api#/definitions/FullOrder). It unfortunately doesn't contain a consistent definition, and has fields as labelled below:
ta:{symbol2} string total amount in current currency (Maker)
tta:{symbol2} string total amount in current currency (Taker)
fa:{symbol2} string fee amount in current currency (Maker)
tfa:{symbol2} string fee amount in current currency (Taker)
a:{symbol1}:cds string credit, debit and saldo merged amount in current currency
So, for example, it could be tta:USD in one message or tta:EUR in another.
I've been following this guide (https://serde.rs/deserialize-struct.html) in creating my struct, and I've got all the way through it bar one thing - the final part requires specifying all the fields.
In the field visitor, I have the following to handle the fields in advance:
if value.starts_with("ta:") {
Ok(Field::TotalMakerAmount)
} else if value.starts_with("tta:") {
Ok(Field::TotalTakerAmount)
} else if value.starts_with("fa:") {
Ok(Field::FeeMakerAmount)
} else if value.starts_with("tfa:") {
Ok(Field::FeeTakerAmount)
} else if value.starts_with("a:") {
Ok(Field::CreditDebitSalvo)
But the deserialize_struct requires a list of all the fields to visit. Is there anyway I can get a hold of all fields dynamically to pass through here? Or have I reached the extreme of what a serde deserializer can do?
Thanks
Im setting up my Google Tag Manager and I want to grab the purchase value from my Data Layer. This works fine, but Facebook doesn't recognize this value as its a "String" and not a number.
Therefore my question is: How can I convert this String (Return Type) to a Number (Return Type) in order for Facebook to pick it up? If that helps, its a currency.
Create JavaScript Variable named "String2Number Convertor"
function(){
return function(s){
return +s;
}
}
Create another JavaScript Variable named "Facebook Purchase Value"
function(){
return {{String2Number Convertor}}({{DataLayer Conversion Value}})
}
I assume you have your purchase value in data layer variable I called in this example as DataLayer Conversion Value
With this approach you can convert any other variables into number.
I want to set two parameters in one capsule's inuput-view file. What should I do?
In my capsule, there has a function which need two parameters and these two parameters is required. When user say one case, if this case doesn't including these two parameters, bixby will hints user input these two parameters. In the previous version I created two input-view file and one input-view file including one parameter, but now I want to set these two parameters in one input-view file, so what should I do?
In action file:
input-group(ContactAndText){
requred(OneOrMoreOf)
collect{
input(contact){
type(Contact)
min(required)
max(one)
}
input(text){
type(Text)
min(required)
max(one)
}
}
}
In input-view file: I do not know what should I do?
In action file I set a input-group(ContactAndText), this input-group including these two parameters(contact and text), but I do not know what should I do in input-view file.
I don't think having an input view for two separate objects/structures will work, however having an input view for your input-group might work. I believe can use the match pattern match: [action name]~[input-group name] (match: action~ContactAndText) to match the input-group specifically.
If this doesn't work, I would recommend either using two separate input views, one for contact and one for text, or you could create a new structure ContactAndText: make it extend Contact and make it have a text property. Then, you can have the input view match the ContactAndText structure.
An easier solution:
Add a new structure
structure (ContactAndName) {
description (a structure to hold both)
property (contact) {
type (Contact)
min (Required) max (One)
}
property (text) {
type (Text)
min (Required) max (One)
}
}
In action model
input(contactAndText) {
type (ContactAndText)
min(Required) max(One)
}
You can then implement a view with match: ContactAndName
I don't understand the way Bixby retains data from previous NL Input. The following example uses the capsule capsule-sample-shirt.
I first use the NL input find 2 medium shirts to get a list of shirts.
I click on any of those (here i use the Collar Dress Shirt), and Bixby asks if I would want to buy it.
I click No and Bixby informs me with a Okay, I won't do that.
I now immediately run again the same NL input find 2 medium shirts and expect Bixby again to present me with the list of shirts, just like the first time. Instead of the expected list of shirts now, Bixby asks me again Are you sure you want to buy this? with the Collar Dress Shirt that I previously selected.
Why is Bixby not showing the list of shirts the second time find 2 medium shirts is given as NL input? What would need to happen to make Bixby show the list with this NL input after the first time?
List of shirts after NL Input:
Bixby waits for confirmation:
Bixby saying it canceled the prompt:
Bixby doesn't show the list but instead immediately asks for confirmation:
This is the AI part about Bixby.
Each conversation (utterance) without pressing the reset key is considered a continuation of last utterance (if any). Thus make the choice of Collar Dress and cancel it, but later ask to find 2 medium shirts again, Bixby will try to fill-in the blank with last choice user made.
One clear issue is that now has no way to change the type of shirt unless reset, but fix would be easy, make the image of shirt clickable and link actions in view model Confirmation.view.bxb
image-card {
aspect-ratio (4:3)
image-url ("[#{value(item.shirt.images[0].url)}]")
title-area {
halign (Start)
slot1 {
text {
value ("")
style (Title_M)
}
}
}
// Add on-click here
}
You can add on-click similar to change the size and quantity
input-cell {
label ("Quantity")
value ("#{value(item.quantity)}")
on-click {
//This intent relies on searchTerm matching the item which is not a good practice, a better approach
//was to allow an ID as input to SelectItem and use `this.id` in the intent
intent {
goal {
UpdateOrder
#context (Continuation) { Order }
}
value { SearchTerm$expr(item.shirt.title) }
route { GetQuantity }
}
}
}
You may need to add other models to properly promote user.
Hope this will help, and have fun with Bixby!
the utterance
the slot being used
the testing screen
the intent in my lambda function:
var phoneNumber;
"getPhoneNumberIntent": function() {
phoneNumber = this.event.request.intent.slots.phoneNumber.value;
if (getLength(phoneNumber) === 10) {
this.response.speak('I heard <say-as interpret-as="telephone"> ' + phoneNumber + '</say-as>. Is this the correct number?').listen();
this.emit(':responseReady');
} else {
console.log(phoneNumber);
this.response.speak('That is not a valid phone number. Please try again.').listen();
}
},
When I type in the incredibly specific utterance, The only thing in the output JSON is null. and in the input, the proper intent wasn't even being called. I have not seen a problem similar to mine on the website, I've looked high and low. Any help or feedback is appreciated.
Use predefined AMAZON.NUMBER as the slot type for phoneNumber.
While testing numbers in Alexa Test Simulator, represent them as words
Ex: the phone number is nine eight seven six five four three two one
zero
And for abbreviations use period "."
Ex: The code is a.w.e.