Bixby Developer Center

Guides

Profile (viv.self)

The viv.self capsule provides access to information in the user's profile, such as given names, phone numbers, and addresses. In certain respects, it functions as a special case of viv.contact.

Usage

Import this capsule in your capsule.bxb file:

capsule-imports {
import (viv.self) {
as (self)
version (3.5.167)
}
}

Use the current version of viv.self.

You must have the user-profile-access permission set in the capsule.bxb file as well:

permissions {
user-profile-access
}

Models

Types are always in the viv.* namespace, and in the viv.self.* namespace unless another namespace is specified (e.g., viv.geo.*). All properties have a cardinality of min (Optional), max (One) unless otherwise specified.

Profile

The Profile structure is a snapshot of the Self structure, and is the recommended way to interact with viv.profile. Use the GetProfile action to retrieve a user profile.

The following types all exist in the viv.contact.* namespace, not viv.self.*. (Note that viv.self imports viv.contact as contact, so your capsule does not need to import viv.contact.)

PropertyTypeKindNotes
structuredNamecontact.StructuredNamestructure(1)
firstNamecontact.FirstNametext
lastNamecontact.LastNametext
emailInfocontact.EmailInfostructure
phoneInfocontact.PhoneInfostructure
addressInfocontact.AddressInfostructure
  1. The structuredName is the contact's full name, incorporating all the filled-in fields for Prefix, FirstName, MiddleName, LastName, and Suffix. See contact.NameInfo.

Self

The Self structure concept simply extends viv.contact.ContactInfo. You can use Self any place ContactInfo is required.

The following types all exist in the viv.contact.* namespace, not viv.self.*. (Note that viv.self imports viv.contact as contact, so your capsule does not need to import viv.contact.)

PropertyTypeKindNotes
contactIdcontact.ContactIdintegerIdentifier from device
nameInfocontact.NameInfostructure
addressInfoscontact.AddressInfostructuremax (Many)
phoneInfoscontact.PhoneInfostructuremax (Many)
emailInfoscontact.EmailInfostructuremax (Many)
relationshipInfoscontact.RelationshipInfostructuremax (Many)
photoInfocontact.PhotoInfostructure
isFavoritecontact.IsFavoriteboolean
workInfocontact.WorkInfostructure
birthdayInfocontact.BirthdayInfostructure 

AddressType

This is a primitive that extends contact.AddressType, primarily intended for training use.

The possible symbols for AddressType are Home, Work, and Other.

EmailType

This is a primitive that extends contact.EmailType, primarily intended for training use.

The possible symbols for EmailType are Home, Work, Other, and Custom.

PhoneType

This is a primitive that extends contact.PhoneType, primarily intended for training use.

The possible symbols for PhoneType are Mobile, Home, Work, WorkFax, HomeFax, Pager, Callback, CustomType, and Other.

Field

This is a primitive used for training. It enumerates symbols in the Profile model. The viv.self library includes vocabulary terms to refer to individual fields.

enum (Field) {
symbol (firstName)
symbol (lastName)
symbol (structuredName)
symbol (firstAndLastName)
symbol (phoneInfo)
symbol (emailInfo)
symbol (addressInfo)
}

These symbols have defined vocabulary terms:

vocab (Field) {
"FirstName" { "first name" "given name" }
"LastName" { "last name" "family name" }
"EmailInfo" { "email" "email address" }
"PhoneInfo" { "phone number" "number" "phone" }
"AddressInfo" { "address" }
}

StructuredName and FirstAndLastName have no set vocabulary; capsules that import viv.self can add their own vocabulary to cover those cases, as those might be domain-specific. For details, read about Adding Enum Vocabulary.

Actions

As with other library capsules, most actions are selected by Bixby when it builds the execution graph, rather than needing to be chosen explicitly.

The GetProfile Action

The recommended way to retrieve profile information is to use the GetProfile action. This action prompts the user for any required profile fields you need in your capsule. The profile elicitation views are defined in the profile capsule and can handle hands-free mode.

It is recommended you rely on the views in the profile capsule for profile input prompts instead of customizing the views in your capsule.

action (WhoAmI) {
type (Constructor)
collect {
input (profile) {
min (Required)
type (self.Profile)
default-init {
intent {
goal: self.GetProfile
value-set: self.RequiredField {
self.RequiredField (structuredName)
self.RequiredField (addressInfo)
self.RequiredField (emailInfo)
self.RequiredField (phoneInfo)
}
}
}
}
}
output (MyInfo) {
evaluate {
MyInfo$expr(profile)
}
}
}

In this example, MyInfo has the role-of self.Profile:

structure (MyInfo) {
role-of (self.Profile)
}

Passing Profile to Your Action

To use Profile as an input to one of your capsule's actions, define a constructor action that returns a capsule-specific concept that extends Profile. For a example, a shopping capsule might have a Buyer structure concept:

structure (Buyer) {
role-of (self.Profile)
}

Your capsule can then use Buyer in an input action and initialize it with the fields you require:

action (CreateOrder) {
type (BeginTransaction)

collect {
input (buyer) {
type (Buyer) // buyer is fetched from profile
min (Required)
default-init {
intent {
goal: self.GetProfile
value-set: self.RequiredField {
self.RequiredField (firstName)
self.RequiredField (lastName)
self.RequiredField (addressInfo)
self.RequiredField (emailInfo)
self.RequiredField (phoneInfo)
}
}
}
}
input (product) {
type (Product)
min (Required)
}
}
// Order is a structure with transaction feature that has buyer and
// product properties
output (Order)
}

Updating Information

To update information drawn from the Profile object in your capsule-specific object, you can pass in the current information and a list of fields that need to be updated.

Note

This example updates the information being used in your capsule, but does not modify the user's actual saved contact information.

action (UpdateBuyer) {
description (Prompt user to enter personal data)
type (Constructor)
collect {
// Order is a structure with transaction feature that has the current
// buyer and product properties
input (order) {
type (Order)
min (Required)
}
//T his is the list of the fields the user wants to update
input (fieldsToUpdate) {
type (self.Field)
min (Required) max (Many)
default-init {
intent {
goal-set: self.Field {
self.Field(firstName)
self.Field(lastName)
self.Field(emailInfo)
self.Field(phoneInfo)
}
}
}
}
// new values for fields
input (firstName) {
type (contact.FirstName)
min (Optional) max (One)
}
input (lastName) {
type (contact.LastName)
min (Optional) max (One)
}
input (emailAddress) {
type (contact.EmailAddress)
min (Optional) max (One)
}
input (phoneNumber) {
type (contact.PhoneNumber)
min (Optional) max (One)
}
input (forcePrompt) {
type (self.ForcePrompt)
min (Optional) max (One)
}
// compute the new buyer information by calling self library
computed-input (buyer) {
type (Buyer)
min (Required)
compute {
intent {
goal: self.GetProfile
value: self.Profile$expr(order.buyer)
value: $expr(firstName)
value: $expr(lastName)
value: $expr(emailAddress)
value: $expr(phoneNumber)
value: $expr(forcePrompt)
subplan {
goal: self.RequiredField
value: $expr(fieldsToUpdate)
}
}
}
}
}
output (Buyer) {
evaluate { $expr(buyer) }
}
}

To make this work you also need an action such as UpdateOrder:

action (UpdateOrder) {
type (UpdateTransaction)
collect {
input (order) {
type (Order)
min (Required)
}
input (buyer) {
type (Buyer)
}
// other order properties that can be updated can be listed as
// inputs here as well
}
output (Order)
}

Constructing a NamedPoint

A useful provided action is ConstructNamedPointFromSelf, which converts a physical address in the user's profile to a Named Point. This action might be used, for example, by a ride sharing app to find a destination in the user's profile.

action (FindProfileDestination) {
type (Search)
collect {
// addressType is passed in from training
input (addressType) {
type (self.AddressType)
min (Required) max (One)
}
// self can be computed rather than explicitly passed
computed-input (self) {
type (self.Self)
min (Optional) max (One)
compute {
intent {
goal: self.Self
route: self.GetSelf
}
}
}
// DestinationPoint is a capsule-specific extension of geo.NamedPoint.
// We compute it with a subplan that uses ConstructNamedPointFromSelf
computed-input (namedPoint) {
type (DestinationPoint)
min (Optional) max (One)
compute {
intent {
goal: DestinationPoint
subplan {
goal: self.ConstructNamedPointFromSelf
subplan {
goal: self.FindAddress
value: $expr(addressType)
value: $expr($self)
}
}
}
}
}
}

output (DestinationPoint) {
...
}
}

This uses several actions within viv.Self. Both ConstructNamedPointFromSelf and FindAddress have the same inputs:

InputTypeNotes
addressTypeAddressType
selfSelf 

The GetSelf action has no inputs, and simply returns the Self concept.

Training

Most commonly, your capsules will need to be trained on the AddressType, EmailType, and PhoneType enums, to handle utterances such as "call my office" or "book me a car to go home". A ride sharing capsule might have training such as:

[g:viv.rideshare.RideShare#book] I want a car to go (home)[v:viv.self.AddressType:home]

[g:viv.rideshare.RideShare#book] Book a ride to the (office)[v:viv.self.AddressType:work]