Bixby Developer Center

Guides
References

Setting Up Your Capsule

Before you can work on your capsule, you need to prepare your capsule.bxb file, as well as organize the capsule files appropriately.

Note

In order to create a capsule for the Bixby Marketplace, you need to be registered with a team and have your capsule registered under that team. For more information, read the Developer Console guide.

Create the capsule.bxb File

When you create a new capsule from scratch, one of the files that is automatically created is the capsule.bxb file in your capsule's root directory, which handles the metadata required by Bixby to ensure the capsule contents are rendered correctly.

This is what it looks like:

capsule {
id (playground.tester) // your ID will match your org and capsule name that you choose
version (0.1.0)
format (3)
targets {
target (bixby-mobile-en-US)
}
}

This section discusses the different settings you need in your capsule.bxb file in order to start working on your capsule.

You can always update your capsule.bxb if you decide to change the designs and plans for your capsule.

Set Device and Locale Targets

You must indicate the device types and languages your capsule supports within your capsule's capsule.bxb file. Use targets to specify each pair of device type and locale, such as bixby-mobile-en-US. This is important when you want your capsule to support multiple device types in multiple regions of the world.

Here's a sample capsule.bxb for reference:

capsule {
id (example.test)
// ensure that the version is unique with each submission
version(4.0.0)
format(3)
targets {
target (bixby-mobile-en-US) //supports US-English mobile devices
}
capsule-imports {
import (viv.measurement) {
as (measurement)
// indicate version for imported capsule
version (2.1.3)
}
}
}
Note

Each target must have at least a device and two-letter language code.

You can find the list of supported targets on the target reference page.

For more information on implementing translated versions of your capsule and organizing your localized text, see How to Localize Your Capsule.


Video Tutorial: Develop a Bixby Capsule for the Phone, Watch, TV, and Appliances


Import Library Capsules

We've provided several capsules that contain commonly used models. For example, viv.time has Date and Time concepts, with several actions to process those concepts. Instead of trying to model your own, you can import the viv.time capsule.

If you try to use one of these models without importing it, you won't be able to run your capsule.

For more information, you can read the Library Capsules topic and the individual library capsule topics.

Note

If you are declaring library permissions in an autocomplete component, you need to declare it both in the capsule.bxb file and in the permissions block in auto-complete.

Grant Capsule Permissions

Your capsule needs to be granted special permissions for certain situations. For a full list of what permissions you can request from users and additional information on implementation, see the permissions key and its child keys in the reference guide, as well as the Permissions sample capsule. If necessary, you can restrict the permissions needed using the restrictions key. This is similar to the visibility-constraints you can specify in store sections and hints. Library capsules and capsules that import these libraries must declare additional keys so that users can grant permissions. See Grant Permissions for Exported Capsules.

Depending on which permissions you request, you might have to do additional configuring in order to have access to the requested information. You can request from the user to provide your capsule this access with the permissions key in your capsule.bxb, like in this example from the Permissions sample capsule:

capsule {
id (example.permissions)
version (0.1.0)
format (3)
targets {
target (bixby-mobile-en-US)
target (bixby-watch-en-US)
}
runtime-version (8)
default-action (GetLocationAndProfile)
store-sections {
section (TravelAndTransportation)
}
capsule-imports {
import (viv.geo) {
as (geo)
version (9.27.15)
}
import (viv.self) {
as (self)
version (4.0.20)
}
}
permissions {
// This capsule uses device-location-access to get the user's location
// and self:profile to get the users name
device-location-access
library-permission (self:profile)
}
store-countries {
all
}
device-models {
all
}
}

View master on GitHub

Here is what the permissions prompt might look like for the Space Resorts example on mobile:

Permissions prompt on mobile

Note

If a user is adding the capsule for the first time, the prompt will look similar to the one below:

Permission prompt on capsule first open

Additionally, you need to provide a localized justification for why you are requesting any permissions in your capsule-info.bxb file using the requested-permissions key. This information is visible to the user, so you should add a reasonable business explanation of why you are requesting this permission in this justification:

capsule-info {
display-name (Permissions Example)
developer-name (Example Developer)
description ("Example capsule to show how to use the Bixby permissions model")
dispatch-name (Permissions Example)
icon-asset (images/icons/permissions-icon.png)
requested-permissions {
permission (device-location-access) {
justification ("This capsule needs your permission to get your device location")
}
permission (self:profile){
justification ("This capsule needs permission to get your name")
}
}
search-keywords {
keyword (sample capsule)
keyword (permissions)
}
privacy-policy-url (http://my-capsule.com/privacy-policy)
}

View master on GitHub

Where Users See Permissions Information

Users can find which permissions they granted in several locations:

  • Under the Manage > Privacy section on the capsule's home page within Bixby.

The Manage Privacy option on the capsule's home page

  • Under Bixby Voice Settings > All Devices > Privacy, after tapping on the chosen capsule.

The Privacy option under All devices on the Bixby Voice Settings screen

Each capsule that requests permissions is listed under this privacy page:

Bixby Voice Settings privacy tab

When users navigate to a specific capsule's privacy page, they can turn permissions on or off, as well as determine which devices have those specific permissions.

Permissions page for a specific capsule

If users tap on a specific permission, the permission page displays with a switch to turn that permission on or off, what the permission does, and the justification text. Here are some examples:

device-location-accessviv.self:profilebixby.contact:contacts
`device-location-access``viv.self:profile``bixby.contact:contacts`
Denied Permissions

If the user decides not to grant permissions to that capsule, it will continue to execute.

Note

When this happens, you should create a prompt so that the user can input the relevant information, such as a location or profile information. This is a better user experience and allows Bixby to continue to execute gracefully.

Alternatively, you can add a permission-link component in your view if you want users to be able to grant the permission later.

For example, consider a capsule called RestaurantFinder that declares permissions { device-location-access } in order to access a user's location. When a user asks Bixby "Find Italian restaurants nearby", Bixby checks for the device-location-access permission and prompts the user if no persisted value exists. If the user grants the permission, RestaurantFinder can access the user's location. However, if the RestaurantFinder never declares the device-location-access permission, Bixby does not check or prompt the user for the user's location and the RestaurantFinder capsule won't get that information either. You should add a prompt that allows users to input their location when it is not granted in this scenario.

If you want to check if the permission has been granted first, you can use the permissionGranted() EL function or the $vivContext.grantedPermissions variable in JavaScript.

If checking with EL:

output (Something) {
evaluate {
if("#{permissionGranted('device-location-access')}") {
...
} else {
...
}
}
}

If checking in JavaScript:

var permissions = $vivContext.grantedPermissions;
if ('device-location-access' in permissions) {
console.log("PERMISSION GRANTED");
} else {
console.log("PERMISSION DENIED");
}
Note

If you have the Deterministic Mode option enabled while testing permissions in the Simulator, you will be prompted for permissions every time in a conversation, even if you've previously granted permissions. Additional permissions settings are available in the Permissions tab of the User Pane in the Simulator.

Scope of Permission States

Permissions always depend on the currently executed end-user capsule, since users do not know about library capsules.

Some permissions are capsule-based permissions, such as device-location-access. This means that you would only need to declare them at the end-user capsule that needs the permission. These permissions are checked at execution, prompted for a value from the user, and the value the user gives (either granted or denied) persists for the entire execution of the request.

For example, consider an example end-user capsule RestaurantFinder that imports location, and location imports geo. During a user's request to RestaurantFinder, when location performs an action, it requests the user’s current location from geo. The current location will only be accessible if RestaurantFinder (the currently executed end-user capsule) requests the device-location-access permission and the user granted it.

Some permissions are system-level and are only available to internal-only developers.

How Library Capsules Define Permissions

A library capsule exports permissions by defining a permission and only allowing that action endpoint to execute if the permissions is granted by the user. For example, the bixby.contacts library capsule could declare a contacts permission that guards access to the user's address book. Another end-user capsule can import bixby.contacts and if it needs to use an action that requires the contacts permission, Bixby prompts the user, asking if the user grants the requested permission to the executed end-user capsule. If the user grants it, then the action will continue as usual. If the permissions are not properly requested in the end-user capsule, they are automatically denied and the function is not executed.

If you're developing a library capsule and need to guard certain sensitive information or functionality with permissions, you need to make sure that you've set up the library permissions correctly.

You might want to test that the permissions are being properly prompted-for and granted using on-device testing.

Declaring Exports

If your capsule is a library capsule (i.e., you intend to import it into other capsules within your organization, or make it available as a library capsule in the Marketplace), it must include a library block that specifies a scope controlling which capsules can import it.

  • A public scope allows all capsules to import a library capsule.
  • A restricted scope allows only specific organizations or individual capsules to import a library capsule:
    • When restricted is specified, capsules belonging to the same organization as the library capsule will always be allowed to import the library capsule.
    • Organizations can be specified with the organization namespace within the org (organization-namespace) key.
    • Capsules can be specified with the capsule name within the capsule (qualified.capsule.name) key.

For example, this capsule can be imported by capsules that belong to its own organization, plus capsules in the avengers and xmen organizations:

library {
scope {
restricted {
org (avengers)
org (xmen)
}
}
}

This capsule can be imported by capsules that belong to its own organization, plus the avengers.travel and avengers.cafeteria capsules:

library {
scope {
restricted {
capsule (avengers.travel)
capsule (avengers.cafeteria)
}
}
}

You can mix org and capsule restrictions. So a capsule can be imported by capsules that belong to its own organization, all capsules in the xmen organization, and the avengers.cafeteria capsule:

library {
scope {
restricted {
org (xmen)
capsule (avengers.cafeteria)
}
}
}

The default scope is restricted with no extra organizations specified. To indicate a library capsule can only be imported by its own organization, you can just use the library key alone:

capsule {
...
library
}

How Library Permissions Work End-to-End

There are several steps required to properly ensure that the library permission request is presented to users and they can grant Bixby access to the information they need. First, if you are writing the library capsule, you need to set up the library to export library permissions. Then, as described in How Library Capsules Define Permissions, if you are developing an end-user capsule that imports this library and requires those same permissions, you need to request those library permissions.

Note

You might not require both parts of this library permissions section. For example, if you are developing an end-user capsule and not developing a library capsule, then there is nothing for you to export on the library level.

Exporting Library Permissions

These steps set up the how to export the proper library permissions. Do this step while developing your library capsule.

  1. Define the permission in the library capsule's capsule.bxb file using the exports-permissions block.

    capsule {
    ...
    library {
    exports-permissions {
    permission (phone)
    permission (email)
    }
    }
    ...
    }
  2. In the *.endpoints.bxb file of that library capsule, make sure that any action that requires this permission has the required-permissions block set up, so that action is linked to the appropriate permission.

    ...
    action-endpoint (CallSomeone) {
    ...
    required-permissions {
    permission (phone)
    }
    }
    ...
  3. Provide localized descriptions in your capsule-info.bxb file, to describe what the permissions are for, so the user will be informed what an end-user capsule is requesting, with the exported-permissions block.

    ...
    exported-permissions {
    permission (phone) {
    label (Phone) // required
    detail (Permission to access your phone number) // optional
    }
    }
    ...
Requesting Library Permissions

These steps explain how to request the library permissions of an imported library capsule. Do this step while developing a top-level capsule and you're importing a library that requires permissions granted.

  1. Import the library you need. Check you're using the latest version.
    capsule-imports {
import (viv.core) {
as (core)
}
import (viv.self) {
as (self)
version (4.0.1)
}
import (viv.time) {
as (time)
version (3.1.102)
}
import (viv.money) {
as (money)
version (2.22.36)
}
}

View ddb50f8030305422a77ea0c4f39b16ad0ad6d2ad on GitHub

  1. Declare the various library-permission keys within the permissions block of your end-user capsule's capsule.bxb file.
    permissions {
library-permission (self:profile)

View ddb50f8030305422a77ea0c4f39b16ad0ad6d2ad on GitHub

  1. Add localized justifications of why you are requesting these permissions within the capsule-info.bxb file in the requested-permissions block.
  requested-permissions {
permission (self:profile){
justification (Your profile information is needed to book a space resort.)
}
}

View 31ffa0088f3751b6db396a1e9cc40c9c924db81b on GitHub

Organize Your Capsule Resources

Your capsule organization should also reflect the device types and languages (Targets) you want to support. For a full list of supported devices and languages, see the target reference doc.

Bixby sorts resources in the following order, from most to least specific:

  • spec-lang-country (ex: bixby-mobile-it-IT)
  • spec-lang (ex: bixby-mobile-it)
  • spec (ex: bixby-mobile)
  • lang-country (ex: it-IT)
  • lang (ex: it)
  • base

Note that your resources (such as your dialog, layout, training, and hint files) follow the hierarchy listed above within your resource folders. For example, bixby-mobile-it-IT is a more specific bucket than bixby-mobile. Bixby defaults to the base directory to look for your dialog, layout, and other similar files, unless you provide a more specific resource bucket with a file defined for that instance.

For example, if you want to support all devices in the US but only mobile devices in Korea, organize your capsule resources in two folders, as shown here:

/resources/en-us/
/resources/bixby-mobile-ko-KR/

Anything language-specific should be put in the corresponding language's resource folder. For example, each language should have their own training and vocab files.

The organization of your capsule resources offers fallback support, which lets you reuse parts of your capsule as needed. For example, you can organize your capsule to use the same English dialog (en-US), but different layouts depending on the device type.

Consider the following example with bixby-mobile-en-US and bixby-tv-en-US:

resources/en-US/Recipe_Results.dialog.bxb
resources/bixby-mobile-en-US/Recipe_Summary.layout.bxb
resources/bixby-tv-en-US/Recipe_Summary.layout.bxb
Note

You cannot have a macro with the same ID if the macro is defined in the same resource folder. For example, if you have a macro with the ID "this-test-macro" in the bixby-mobile-en-US target, you cannot have another different macro with the same name in that target.

However, if the macro's target is in a higher level resource folder, the more specific target will override the more general target. For example, say you have a macro in bixby-mobile-en and another macro in bixby-mobile-en-US, both with the ID "this-test-macro". The macro in the bixby-mobile-en-US target will render for the bixby-mobile-en-US target, but the bixby-mobile-en macro will render for the bixby-mobile-en-GB target.

Macros with the same ID but in different targets (for example, bixby-mobile-ko-KR and bixby-mobile-en-US) are allowed and are encouraged, especially when localizing or handling development for multiple devices.