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.

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.

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. 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.

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. 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 get the requested information. For example, you might want your capsule to be accessible at the lock screen. You can request from the user to provide your capsule this access with the permissions key in your capsule.bxb:

capsule {
id (example.spaceResorts)
version (1.0.0)
format (3)
targets {
target (bixby-mobile-en-US)
target (bixby-mobile-ko-KR)
}

runtime-version (3)
capsule-imports {
import (viv.core) {
as (core)
}
import (viv.self) {
as (self)
version (3.5.217)
}
import (viv.time) {
as (time)
version (3.1.102)
}
import (viv.money) {
as (money)
version (2.22.36)
}
}
store-sections{
section (TravelAndTransportation)
}
store-countries {
all
}
}

View on GitHub

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

Permission Prompt

Note

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

Initial Permission Prompt

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:

  requested-permissions {
permission (self:profile){
justification (Your profile information is needed to book a space resort.)
}
}

View on GitHub

Users can find which permissions they granted in several locations:

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

Capsule Home Page

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

Bixby Voice Settings

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

If you click 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`

If the user decides not to grant permissions to that capsule, it will continue to execute. For example, if the capsule asks for device-location-access location and the user denies, the capsule will still be executed, but not have access to the users location. 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");
}
How Capsules Inherit Permissions

Because users do not know about capsules that are imported, the way that permissions are inherited vary depending on the permission.

Some permissions are top-level capsule-based permissions, such as device-location-access. This means that you would only need to declare them at the top-level 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 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.

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 org (organization-name) key.
    • Capsules can be specified with 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.
        import (viv.self) {
as (self)
version (3.5.217)
}
import (viv.time) {
as (time)
version (3.1.102)
}
import (viv.money) {
as (money)
version (2.22.36)
}
}
store-sections{
section (TravelAndTransportation)
}
store-countries {

View on GitHub

  1. Declare the various library-permission keys within the permissions block of your end-user capsule's capsule.bxb file.

View 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 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:

  • 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

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

Note that your macros follow a certain hierarchy within your resource folders. Bixby defaults to the base directory for your dialog and layout files, unless you provide a more specific resource bucket with a file defined for that instance.

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.