Once you identify the in-app functionality and built-in intent (BII)
that you want to implement, create an actions.xml
resource in your Android app
that maps the BII to your app functionality. App Actions defined in
actions.xml
describe how each BII resolves its fulfillment as well as the
parameters that are extracted and provided to your app.
Overview
To integrate your Android app with App Actions, you must have an
actions.xml
file placed in your app project's res/xml
directory.
Add a reference to the actions.xml
file in the AndroidManifest.xml
file
using a <meta-data>
tag. For example:
<application> <!-- ... --> <meta-data android:name="com.google.android.actions" android:resource="@xml/actions" /> </application>
This declares an XML resource for the xml/actions.xml
file in the APK. To
learn more about specifying resources in Android, see the
App resources overview
in the Android developer documentation.
Schema
The following table describes the schema for actions.xml
. When including a
tag, all of its attributes are required unless marked as optional.
Tag | Contained in | Attributes |
---|---|---|
<actions> |
top-level | |
<action> |
<actions> |
|
<parameter> |
<action> |
name |
<entity-set-reference> |
<parameter> |
|
<fulfillment> |
<action> |
|
<parameter-mapping> |
<fulfillment> |
|
<entity-set> |
<actions> |
entitySetId |
<entity> |
<entity-set> |
|
Tag descriptions
This section describes the various schema tags for actions.xml
.
<action>
An App Action that the app supports. For every <action>
tag in your
actions.xml
file, you must provide at least one <fulfillment>
.
Attributes:
intentName
: Built-in intent for the App Action (for example,actions.intent.CREATE_TAXI_RESERVATION
). For a list of supported built-in intents, see the built-in intent reference.queryPatterns
: A set of queries expected from the user for this intent. This attribute is only applicable to custom intents, as BIIs already include models of the common ways users express the tasks they're trying to do or the information they seek.
<parameter>
A parameter of an App Action having a name and list of associated entities.
Attributes:
name
: Name to associate with this parameter (for example, "destination"). The name is a leaf-level field of the parameter (for example,tradeOrder.assetOrdered.assetIssuedBy.name
). If the parameter is a primitive type, such as a string, then the name is the parameter name itself.
<entity-set-reference>
Reference to a schema.org feed that the developer supplies.
Feeds must be provided directly in the actions.xml
file using <entity-set>
tags.
Attributes:
entitySetId
: A reference to a specific collection of entities. This attribute must correspond to anentitySetId
in an<entity-set>
tag.urlFilter
: URL path used when providing web inventory for fulfillment. This attribute supports two wildcards:*
: An asterisk matches a sequence of zero to many occurrences of the immediately preceding character..*
: A period followed by an asterisk matches any sequence of zero to many characters.Escape characters are only needed for literal
*
and\
, which you can escape as\\*
and\\\\
, respectively.
<fulfillment>
Information about how to fulfill the user intent using the Android app.
Developers can provide multiple <fulfillment>
tags in actions.xml
,
with different sets of required parameters for each intent.
Google uses the first <fulfillment>
for which all required parameters are
available to fulfill the user's query. You must provide one <fulfillment>
without any required parameters as a fallback fulfillment.
Attributes:
urlTemplate
: Template for constructing either the deep link or a Slice URI to be opened on the device. The template might expand with the parameters of the user intent if all required parameters for the template are available. For examples of the HTTP URL template, see the Wikipedia article on URL templates. The template format follows the RFC 6570 URI template specification.fulfillmentMode
: (optional) Fulfillment mode used for serving. The valid values are:actions.fulfillment.DEEPLINK
: Fulfill user action by opening the Android app using a deep link. This is the default.actions.fulfillment.SLICE
: Fulfill user action by embedding a Slice provided by Android app.
requiredForegroundActivity
: (optional) Indicates the activity that must be in the foreground for the App Action to be triggered with foreground app invocation.- Specify the activity without any class abbreviations using your app
package
name, followed by a forward slash (
/
), followed by the activity name:APP_PACKAGE_NAME/ACTIVITY_NAME
.
- Specify the activity without any class abbreviations using your app
package
name, followed by a forward slash (
The following are some examples of URL template values:
Template | Values | Expanded value |
---|---|---|
https://example.com/test{?someValue,anotherValue} |
"someValue": "123"
|
https://example.com/test?someValue=123&anotherValue=456 |
https://example.com/test?utm_campaign=appactions{&someValue,anotherValue} |
"someValue": "123"
|
https://example.com/test?utm_campaign=appactions&someValue=123&anotherValue=456 |
https://example.com/test?utm_campaign=appactions{#someValue} |
"someValue": "123" |
https://example.com/test?utm_campaign=appactions#someValue=123 |
myapp://example/{someValue} |
"someValue": "123" |
myapp://example/123 |
intent://example#Intent;scheme=my-scheme{;S.extra1,S.extra2};end |
"S.extra1": "123"
|
intent://example#Intent;scheme=my-scheme;S.extra1=123;S.extra2=456;end |
For more about configuring URL templates, see URL templates in fulfillment.
<parameter-mapping>
Maps from intent parameters to variables in the URL template. Keys in this map represent URL template parameters, or "variables" as described in RFC 6570.
If a parameter is not included in the intent, the corresponding variable is left undefined at the time of URL template expansion. See RFC 6570, Section 3.2.1 for a description of how undefined variables are treated.
Note that required="true"
and entityMatchRequired="true"
are distinct.
Attributes:
urlParameter
: Every variable mentioned in the URL template must have a correspondingurlParameter
in<parameter-mapping>
. For example, if the uri_template ishttp://spysatellite.com/show{?lat,long}
, there must be keys in<parameter-mapping>
for parameterslat
andlong
.intentParameter
: Values refer to intent parameters. If the intent parameter is of a structured type, use dot notation to refer to a nested field. For example, if there is a parametertaxiReservation
of typeschema.org/TaxiReservation
, you can usetaxiReservation.pickupLocation.geo.latitude
to refer to the latitude value.If providing an entity set for this parameter, the
intentParameter
must match exactly the name of the corresponding<parameter>
tag (for example,taxiReservation.pickupLocation.geo.latitude
).If the intent parameter has a complex type, the value corresponds to the object reference for the parameter (for example,
taxiReservation
). If the intent parameter has a primitive type, the value is the parameter name itself.required
: (optional) Indicates that a givenintentParameter
is required to be present for this URL template to be valid. The URL template is dropped if the user query does not include a value for the givenintentParameter
.entityMatchRequired
: (optional) Indicates that an inventory match for the givenintentParameter
must be present. Defaults tofalse
.When this attribute is set to
true
, if there is an inventory match, the identifier from that match is passed to the URL template. Otherwise, Assistant skips the fulfillment if there is no match.When this attribute is set to
false
, if there is an inventory match, the identifier from that match is passed to the URL template. Otherwise, Assistant provides the BII parameter value as extracted from the user query.
<entity-set>
Set of inlined entities in actions.xml
.
Attributes:
entitySetId
: Required unique identifier for an<entity-set>
inactions.xml
(for example,"myInlineEntitySet1"
). This value must also correspond to the<entitySetId>
value in the<entity-set-reference>
tag.Values for
entitySetId
must contain at most 30 alphanumeric characters (no special characters such as-
or_
), and begin with a letter.
<entity>
An element among a set of entities inlined in actions.xml
. Contains a subset
of schema.org/Thing
fields.
String values for the url
, identifier
, and sameAs
fields can either be
hardcoded or referenced using the APK's string resources. When providing
synonyms, use string values for the alternateName
field that reference the
APK's string array resources.
Attributes:
name
: Required name for the entity, unless you are specifying asameAs
field. Must be unique across entityname
andalternateName
fields for the given<entity-set>
(for example, "toothpaste").alternateName
: (optional) Alternate names for the entity. You must specify aname
field before specifying analternateName
field. Must be unique across entityname
andalternateName
fields for the given<entity-set>
. The entity is selected if the user's query matches any of these strings.sameAs
: URL of a reference web page that unambiguously identifies the entity. Used to specify an enum value if and only if the intent parameter type is a subtype ofschema.org/Enumeration
.Required for parameter fields whose types are subtypes of
schema.org/Enumeration
(for example:MealTypeBreakfast
).identifier
: Identifier for the entity. Must be unique across entities for the given<entity-set>
(for example,CAPPUCCINO_ID
).url
: RFC 3986 URL to open on an Android device. The URL might not be resolvable by an HTTP client. For example, on Android, the URL can be an app-linked "http://" URL or a device-specific URL, like an "intent://" URL or a URL in a custom URL scheme.You can use the
url
field together with theurlTemplate
attribute of<fulfillment>
in the following ways:Provide
url
values in inline inventory, and omiturlTemplate
in<fulfillment>
.Provide
url
values in inline inventory, and use those values in theurlTemplate
value (for example,{@url}?extra_param=ExampleValue
).
Either identifier
or url
must be provided. All entities within a given
entity set must use the same attribute (identifier
or url
).
Inline inventory for App Actions
For some built-in intents, you can optionally guide entity extraction to a set
of
supported entities specified in actions.xml
, known as inline inventory.
When a user invokes your App Action, Assistant matches user query parameters
with entities specified as inline inventory. Google Assistant can then use
identifiers that correspond to inventory items when generating a deep link for
fulfillment.
You define inline inventory primarily using the <entity-set>
and <entity>
elements. Inline inventory simplifies development by
letting your app handle only identifiers or URLs from App Action invocations
instead of needing to recognize strings or Google enumeration values.
For example, your app offers different beverages that users can order, and you expect users to make the following requests for the same type of beverage:
Hey Google, order a Blueberry Crisp Iced Signature Latte from Example App.
Hey Google, order a Blueberry Iced Coffee from Example App.
In your inline inventory, you specify "Blueberry Crisp Iced Signature Latte"
as an entity that corresponds to the identifier 12345a
. You also specify
"Blueberry Iced Coffee" as an entity that corresponds to the same identifier.
Now, when a user triggers your App Action with the preceding queries, Assistant
can use the identifier 12345a
when generating a deep link for fulfillment.
You can specify up to 1,000 entities per app across all entity sets. Up to 20
alternateName
synonym values can be defined per <entity>
.
Web inventory for App Actions
For some built-in intents, you can use web inventory as a method of generating URLs for fulfillment. Web inventory uses your website to discover URLs for App Action fulfillment. This feature is most useful when you have a strong web presence and your in-app deep links are organized around publicly available web content.
To use web inventory, update your actions.xml
:
In the
<action>
tag where you want to use web inventory, add a<fulfillment>
tag and set itsurlTemplate
attribute to{@url}
.In the same
<action>
tag, add a<parameter>
tag and set itsname
attribute to the built-in intent parameter that most closely corresponds to the entity described by your web pages. For example, when providing web inventory forORDER_MENU_ITEM
, you link menu pages tomenuItem.name
and link restaurant location pages tomenuItem.inMenuSection.inMenu.forRestaurant.name
.In the new
<parameter>
tag, add an<entity-set-reference>
tag and set itsurlFilter
attribute to the URL path you want to use for web inventory.
By performing the preceding steps, Assistant can perform a web search in the URL
path you provide in the urlFilter
attribute. Google Assistant then supplies a
{@url}
value to your fulfillment using the results. Your deep link handler can
then route a user based on the deep link returned by Assistant for that
fulfillment.
For example, suppose your website contains product listings that use a path
beginning with https://www.example.com/items/
. You use the urlFilter
value
https://www.example.com/items/.*
, and Assistant later returns a
fulfillment URL like https://www.example.com/items/item123
. See
<entity-set-reference>
for information about
the urlFilter
attribute.
URL templates in fulfillment
In a <fulfillment>
tag, you can declare a URL template with
placeholders for dynamic parameters. This template maps to one of your Android
activities, using an App Links URL, a custom scheme, or an
intent-based URL.
Configure the URL template
Example of an App Links URL:
<action intentName="actions.intent.CREATE_TAXI_RESERVATION"> <fulfillment urlTemplate="http://my-taxi.com/order{?dropoffLocation}"> <parameter-mapping intentParameter="taxiReservation.dropoffLocation.name" urlParameter="dropoffLocation"/> </fulfillment> </action>
Example of a custom scheme:
<action intentName="actions.intent.CREATE_TAXI_RESERVATION"> <fulfillment urlTemplate="mytaxi://reserve{?dropoffLocation}"> <parameter-mapping intentParameter="taxiReservation.dropoffLocation.name" urlParameter="dropoffLocation"/> </fulfillment> </action>
Example of an intent-based URL:
<action intentName="actions.intent.CREATE_TAXI_RESERVATION"> <fulfillment urlTemplate="intent:#Intent;package=com.example.myapp;action=com.example.myapp.MY_ACTION{;S.dropoff};end"> <parameter-mapping intentParameter="taxiReservation.dropoffLocation.name" urlParameter="S.dropoff"/> </fulfillment> </action>
When specifying a <parameter-mapping>
tag for a
fulfillment, the intentParameter
attribute denotes the built-in intent
parameter provided by the user. In the preceding examples, that parameter is the
drop-off location name (taxiReservation.dropoffLocation.name
). You can find
the available parameters for any given built-in intent in the built-in intent reference.
To map the built-in intent parameter to a position in your URL, you use the
urlParameter
attribute of the <parameter-mapping>
tag. This attribute
corresponds to the placeholder value in the URL template that you want to
substitute with information from the user. The placeholder value must be present
in your urlTemplate
and enclosed by curly braces ({}
).
App Links URLs
If you're using an App Links URL, the urlTemplate
points to a regular HTTP
URL that can trigger your Activity
. Parameters are passed as URL parameters
to the App Links URL. The parameters in urlTemplate
must be enclosed
in curly braces ({}
) and prefixed with a question mark (?
). If a parameter
is not set, the parameter (curly braces included) is omitted from the result.
For example, if a user triggered the App Action by asking to order a taxi to San Francisco, the final URI triggered (after parameter substitution) is the following:
https://mydomain.com/order?action=com.example.myapp.MY_ACTION&dropoff=San+Francisco
Intent-based URLs
If you're using an intent-based URL, the urlTemplate
value includes the
package name, the intent action, and one extra intent, called the dropoff.
The extra is prefixed by "S." to denote a String
intent extra (as defined by
Intent.toUri()
) and is surrounded by curly braces to denote a substitution by
a parameter.
An extra preceding semicolon is needed to separate the intent action from the intent extra (and is only included if the parameter is set).
In the following example, the urlParameter
value is set to S.dropoff
; you can see
where this appears in the URL by looking for this value in urlTemplate
.
As an example, if a user triggers an App Action by asking to order a ride to San Francisco, the final URI triggered (after parameter substitution) is:
intent:#Intent;package=com.example.myapp;action=com.example.myapp.MY_ACTION;S.dropoff=San+Francisco;end
For more information about intents, see the Android intents documentation.
Use URL values from entities in URL templates
By default, if an <entity>
is matched to the user's query, the value of the
identifier
attribute is passed to the URL template. To reference the url
attribute of an <entity>
instead, use {@url}
in the URL template and don't
use a <parameter-mapping>
tag. Note that identifier values are URL-escaped,
but url
attribute values are left unchanged.
If a fulfillment uses {@url}
in the URL template, the fulfillment attempts
to derive {@url}
from sources such as web and inline inventory. When both
web and inline inventories are potential sources of deriving {@url}
, web
inventory takes preference.
This is shown in the following example:
<fulfillment urlTemplate="{@url}"> <!-- No parameter-mapping is needed --> </fulfillment> <entity-set entitySetId="..."> <entity name="..." url="https://my.url.fulfillment/1"/> <entity name="..." url="https://my.url.fulfillment/2"/> </entity-set>
The {@url}
parameters can be combined with other parameters:
<fulfillment urlTemplate="{@url}?referrer=actions_on_google{&other_param}"> <parameter-mapping intentParameter="otherParam.name" urlParameter="other_param"/> </fulfillment> <entity-set entitySetId="..."> <entity name="..." url="https://my.url.fulfillment/1"/> <entity name="..." url="https://my.url.fulfillment/2"/> </entity-set>
Parameter matching
The way Google matches parameters from the user utterances to the entities you specified depends on the type of the parameter:
- Enum: Google matches the user's query ("Monday") to an associated enum
URL ("http://schema.org/Monday"), then picks the entity whose
sameAs
value matches the enum URL. - String: Google picks the entity whose
name
oralternateName
value matches the user's query.
Examples
This section shows examples of how to utilize built-in intents in
actions.xml
.
Finance - accounts and payments
The following actions.xml
example uses the
actions.intent.CREATE_MONEY_TRANSFER
built-in intent:
<?xml version="1.0" encoding="utf-8"?> <actions> <action intentName="actions.intent.CREATE_MONEY_TRANSFER"> <fulfillment urlTemplate="mybankapp://transfer{?amount,currency,recipientBankAccountType,senderBankAccountType,mode}"> <parameter-mapping intentParameter="moneyTransfer.amount.value" urlParameter="amount" /> <parameter-mapping intentParameter="moneyTransfer.amount.currency" urlParameter="currency" /> <parameter-mapping intentParameter="moneyTransfer.moneyTransferDestination.name" urlParameter="recipientBankAccountType" /> <parameter-mapping intentParameter="moneyTransfer.moneyTransferOrigin.name" urlParameter="senderBankAccountType" /> <parameter-mapping intentParameter="moneyTransfer.transferMode" urlParameter="mode" /> </fulfillment> </action> </actions>
Fitness - nutrition
The following actions.xml
example uses the
actions.intent.RECORD_FOOD_OBSERVATION
built-in intent:
<?xml version="1.0" encoding="utf-8"?> <actions> <action intentName="actions.intent.RECORD_FOOD_OBSERVATION"> <parameter name="foodObservation.forMeal"> <entity-set-reference entitySetId="MealEntitySet"/> </parameter> <fulfillment urlTemplate="myfoodapp://record{?food,meal}"> <parameter-mapping intentParameter="foodObservation.forMeal" urlParameter="meal" entityMatchRequired="true" /> <parameter-mapping intentParameter="foodObservation.aboutFood.name" urlParameter="food" /> </fulfillment> </action> <entity-set entitySetId="MealEntitySet"> <entity sameAs="http://schema.googleapis.com/MealTypeBreakfast" identifier="1" /> <entity sameAs="http://schema.googleapis.com/MealTypeLunch" identifier="2" /> <entity sameAs="http://schema.googleapis.com/MealTypeDinner" identifier="3" /> </entity-set> </actions>
Food ordering
The following actions.xml
example uses the
actions.intent.ORDER_MENU_ITEM
built-in intent:
<?xml version="1.0" encoding="utf-8"?> <actions> <action intentName="actions.intent.ORDER_MENU_ITEM"> <parameter name="menuItem.inMenuSection.inMenu.forRestaurant.servesCuisine"> <entity-set-reference entitySetId="CuisineEntitySet"/> </parameter> <fulfillment urlTemplate="myfoodapp://order{?restaurant}"> <parameter-mapping intentParameter="menuItem.inMenuSection.inMenu.forRestaurant.name" urlParameter="restaurant" required="true" /> </fulfillment> <!-- URL values are derived from a matched entity from the CuisineEntity Set. This is not a fallback fulfillment because {@url} is a required parameter. --> <fulfillment urlTemplate="{@url}" /> <!-- Fallback fulfillment with no required parameters --> <fulfillment urlTemplate="myfoodapp://browse{?food}"> <parameter-mapping intentParameter="menuItem.name" urlParameter="food" /> </fulfillment> </action> <entity-set entitySetId="CuisineEntitySet"> <entity url="myfoodapp://browse/italian/pizza" name="@string/pizza" alternateName="@array/pizzaSynonyms" /> <entity url="myfoodapp://browse/american/hamburger" name="@string/hamburger" alternateName="@array/hamburgerSynonyms" /> <entity url="myfoodapp://browse/mediterranean" name="@string/mediterranean" alternateName="@array/mediterraneanSynonyms" /> </entity-set> </actions>
Transportation
The following actions.xml
file uses the
actions.intent.CREATE_TAXI_RESERVATION
built-in intent:
<actions> <action intentName="actions.intent.CREATE_TAXI_RESERVATION"> <fulfillment urlTemplate="https://taxi-actions.firebaseapp.com/order{?dropoffAddress}"> <!-- Dropoff location as an address --> <parameter-mapping intentParameter="taxiReservation.dropoffLocation.name" urlParameter="dropoffAddress"/> </fulfillment> </action> </actions>
Other
The following actions.xml
example uses the
actions.intent.OPEN_APP_FEATURE
built-in intent.
<?xml version="1.0" encoding="utf-8"?> <actions> <action intentName="actions.intent.OPEN_APP_FEATURE"> <!-- Each parameter can reference an entity set using a custom ID. --> <parameter name="feature"> <entity-set-reference entitySetId="FeatureEntitySet"/> </parameter> <fulfillment urlTemplate="myexampleapp://pathto{?appFeature}"> <parameter-mapping intentParameter="feature" urlParameter="appFeature" /> </fulfillment> </action> <entity-set entitySetId="FeatureEntitySet"> <entity identifier="FEATUREONE" name="first feature" /> <entity identifier="FEATURETWO" name="second feature" /> </entity-set> </actions>