Bixby Developer Center

Guides
References

Text Message (bixby.textMessage)

The bixby.textMessage library capsule provides a way for your capsule to send text messages. It takes a recipient and phone number as input, and can either take the text of the message from your capsule, asking the user to confirm before sending and change the message if they wish, or prompt the user to enter the message text.

The library can run on devices that are capable of sending SMS messages, and can use the user's Bixby-enabled phone to send the message on some but not all other devices. Devices with mobile and watch targets can send messages; fridge and tv targets cannot.

Import the capsule in your capsule-imports block.

bixby.textMessage vs. viv.shareVia

The bixby.textMessage and viv.shareVia library capsules both allow you to share from your capsule, but have different uses.

The bixby.textMessage library capsule allows your capsule to send a text message to a phone number. For example, if you want to use a hard-coded phone number, such as a customer service number or one for delivery, you can use bixby.textMessage.

However, if you want users to be able to share things, such as an image or video, you should instead use viv.shareVia, which allows users to choose an app and recipient when sharing.

Models

The Phone Call library provides structure concepts, MessageInfo and MessageText, that contain the information necessary to send the message. MessageInfo also contains a named-consumer link to the SendMessage action. A named-consumer explicitly links a concept to an action, letting capsules refer to the action with notation similar to property projection.

Your capsule should extend both of these concepts:

structure (MessageInfo) {
extends (message.MessageInfo)
}
text (MessageText) {
extends (message.MessageText)
}

Then, define a constructor action that takes a model with a phone number property, an optional recipient name, and optional message text. The action should output a MessageInfo model.

Here's an example ComposeMessage action; you should adjust this for your capsule's specific use case. (For instance, if your capsule has a Business concept with properties for name and phone number, this action should take that as an input rather than the phoneNumber and recipientName.)

action (ComposeMessage) {
type (Constructor)
collect {
// phoneNumber and recipientName should be text primitives
input (phoneNumber) {
type (PhoneNumber)
min (Required) max (One)
}
input (recipientName) {
type (BusinessName)
min (Optional) max (One)
}
// if the message text is not provided as an input, the user will be
// prompted to enter the text; if it is provided, the user will be
// asked to confirm sending the message
input (messageText) {
type (MessageText)
min (Optional) max (One)
}

computed-input (message) {
type (message.MessageInfo)
min (Required) max (One)
compute {
intent {
goal: message.ComposeMessage
// if phoneNumber and RecipientName don't extend message.PhoneNumber
// and message.RecipientName, use cast() here
value: $expr(phoneNumber.cast('message.PhoneNumber'))
value: $expr(recipientName.cast('message.RecipientName'))
value: $expr(messageText)
}
}
}
}
output (MessageInfo) {
evaluate {
$expr(message)
}
}
}

Your capsule also needs a SendMessage action. Assuming your capsule has the proper MessageInfo concept, you can use this implementation directly.

action (SendMessage) {
type (Search)
collect {
input (messageInfo) {
type (MessageInfo)
min (Required) max (One)
hidden
}

computed-input (actionResult) {
type(message.ActionResult)
min(Optional) max(One)
compute {
intent {
goal: message.SendMessage
value: $expr(messageInfo)
}
}
}
}

output (message.ActionResult) {
evaluate {
$expr(actionResult)
}
}
}

This action sends the message and returns a message.ActionResult concept. To see whether sending the message was successful, check the result property of ActionResult, which is an enum set to one of these values:

  • success
  • failure
  • cancelled

ActionResult also has a description property, which contains more information about the failure condition if the result was not success, and a timeStampInfo property (of viv.time.DateTime type).

Intents

From anywhere in your capsule, you can use an intent to send a message. If you don't provide message text, the user will be prompted to enter it.

intent {
goal: SendMessage
route: ComposeMessage
value: PhoneNumber (1-555-666-1212)
// optional
value: RecipientName (Super Burrito)
value: MessageText (I want to sign up for your mailing list)
}

The value keys should match the input of your ComposeMessage action. If it takes a structure like a business or a contact as input, the intent could look like this:

intent {
goal: SendMessage
route: ComposeMessage
// where "this" is a contact or a business model
value: $expr(this)
// optional
value: MessageText (I want to sign up for your mailing list)
}

Training

Training entries should use the SendMessage action as their goal, routing through your capsule's ComposeMessage action. For instance, your capsule could find a contact using a search term. The aligned NL for that training entry might be:

[g:SendMessage,r:ComposeMessage] Text (Fred)[v:contact.SearchTerm] the
message (Are you feeling ok?)[v:MessageText]

Your capsule could also implement its own SearchTerm model to find businesses:

[g:SendMessage,r:ComposeMessage] Send feedback to (Super Burrito)[v:SearchTerm]

If that capsule was displaying a result view for a business, you could add a continuation that lets the user send feedback via text:

[g:SendMessage:continue:Business,r:ComposeMessage] Leave feedback