Actions.xml

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 as follows:

<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. All attributes are required unless marked "optional".

Tag Contained in Attributes
<actions> top-level
<action> <actions> intentName
<parameter> <action> name
<entity-set-reference> <parameter> entitySetId
<fulfillment> <action> urlTemplate

fulfillmentMode (optional)

<parameter-mapping> <fulfillment> urlParameter

intentParameter

required (optional)

entityMatchRequired (optional)

<entity-set> <actions> entitySetId
<entity> <entity-set> { name, alternateName (optional) } OR { sameAs }

{ identifier } OR { url }

Description

<action>

An App Action that the app supports.

Attributes:

  • intentName: Built-in intent for the App Action (for example, "actions.intent.CREATE_TAXI_RESERVATION"). For a list of built-in intents we support for deep linking into your app or launching your custom slices, see Implement built-in intents for App Actions.

<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 should be 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 just 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 should correspond to an entitySetId in an <entity-set> tag.

<fulfillment>

Information about how to fulfill the user intent using the Android app. Developers may provide multiple <fulfillment> elements in actions.xml, with different set 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 may be expanded with the parameters of the user intent if all required parameters for the template are available. For examples of the HTTP URL template, see this article. The template format follows the RFC6570 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.

The following are some examples of URL template values:

Template Values Expanded value
https://example.com/test{?foo,bar} "foo": "123"

"bar": "456"

https://example.com/test?foo=123&bar=456
https://example.com/test?referrer=assistant{&foo,bar} "foo": "123"

"bar": "456"

https://example.com/test?referrer=assistant&foo=123&bar=456
https://example.com/test?referrer=assistant{#foo} "foo": "123" https://example.com/test?referrer=assistant#foo=123
myapp://example/{foo} "foo": "123" myapp://example/123
intent://foo#Intent;scheme=my-scheme{;S.extra1,S.extra2};end "S.extra1": "123"

"S.extra2": "456"

intent://foo#Intent;scheme=my-scheme;S.extra1=123;S.extra2=456;end

For more about configuring URL templates, see Fulfillment with URL templates.

<parameter-mapping>

Maps from variables in the URL template to intent parameters. Keys in this map represent URL template parameters, or "variables" as decribed in RFC 6570.

If a parameter is not included in the intent, the corresponding variable will be 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 corresponding urlParameter in <parameter-mapping>. For example, if the uri_template is "http://spysatellite.com/show{?lat,long}", there must be a key in <parameter-mapping> for parameters "lat" and "long".
  • 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 parameter "taxiReservation" of type schema.org/TaxiReservation, you can use taxiReservation.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). It should point to a leaf-level field of the parameter (if the intent parameter has a complex type) or the parameter name itself (if the intent parameter has a primitive type).

  • required: (optional) Indicates that a value for the given intentParameter 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 given intentParameter.

  • entityMatchRequired: (optional) Indicates that the given urlParameter will only be included in the URL template if there is an inventory match for the intentParameter.

    If not specified, Google assumes that an inventory match is optional. That is, if inventory match does happen, the identifier from the matched inventory entity is passed to the URL template. If inventory match does not happen, the built-in intent parameter value (text) is omitted from the URL template.

<entity-set>

Set of inlined entities in actions.xml.

Attributes:

  • entitySetId: Required unique identifier for an <entity-set>in actions.xml (for example, "myInlineEntitySet1"). This value should correspond to the <entitySetId> value in the <entity-set-reference> tag.

<entity>

One 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 hard-coded or referenced via the APK’s string resources. In order to provide synonyms, string values for the alternateName field can be referenced via the APK’s string array resources.

Attributes:

  • name: Required name for the entity, unless you are specifying a sameAs field. Must be unique across entity name and alternativeName fields for the given <entity-set> (for example, "toothpaste").
  • alternateName: (optional) Alternate names for the entity. You must specify a name field before specifying an alternateName field. Must be unique across entity name and alternativeName 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 of Schema.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 be opened on an Android device. The URL may or may not be resolvable by an HTTP client. For example, on Android, the URL may be an app-linked "http://" URL or a device-specific URL, such as an "intent://" URL or a URL in a custom URL scheme.

    Either identifier or url must be provided. Also, all entities within a given entity set must have the same field (identifier or url) provided.

    You can the url field together with the urlTemplate in <fulfillment> in the following ways:

    • Provide URLs in the inline inventory and omit the URL template.
    • Provide a URL template and omit URLs in the inline inventory (provide identifiers instead).
    • Provide URLs in in the inline inventory, and use them in the URL template (for example, "{@url}&extra_param=foo").

Inline inventory for App Actions

You can optionally add inline inventory for your app through <entity> tags in your actions.xml file. This lets you provide identifiers that your app understands for entities in user queries. This simplifies your development because your app only needs to handle those identifiers from App Action invocations and does not have to recognize strings (or Google enum values).

If you specify inline inventory, you can use different URL templates for recognized and unrecognized parameter values. If you define a fulfillment URL template with parameter that has entityMatchRequired=true and required=true, Google will only use the template if there is an inline inventory match. This lets you fall back on a disambiguation or search activity if there is not an exact match.

You can specify up to 1,000 entities per app, across all entity sets.

Fulfillment with URL templates

For every <action> tag in your actions.xml file, you must provide a fulfillment mechanism. In the URL template model, you declare a URL template with placeholders for dynamic parameters. This template maps to one of your own Android activities, using an App Links URL, a custom scheme, or an Intent-based URL.

For example, for a ride hailing service, you can declare a URL template where Google would embed the origin and destination coordinates for a taxi ride.

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

The intentName attribute defines the App Action built-in intent.

The urlTemplate attribute contains the URL that will be called to trigger your Activity. Each urlTemplate you define can have any (or none) of the built-in intent parameters for each App Action.

The intentParameter attribute specifies which value (as provided by the user) you want substituted into your URL. In our example, we asked for the drop off location name (“taxiReservation.dropoffLocation.name”). For the built-in parameters, the possible values are provided in the built-in intent reference.

The urlParameter attribute is the name of the parameter in the URL that will be substituted. This value must be present in your urlTemplate and inside curly braces {}.

If you are specifying entity sets, you can combine the URL from an entity set with other URL parameters. This is accomplished by providing a <urlTemplate> that begins with an "{@url}" placeholder, such as "{@url}&autoplay=true&utm_source=assistant".

App Links URLs

If you are 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 needs to be enclosed in curly braces with a question mark (?) prefix. If the parameter is not set, the entire curly braces will be omitted.

As an example, if a user triggered the App Action by asking to order a taxi to “San Francisco”, the final Uri that is triggered (after parameter substitution) would be:

https://mydomain.com/order?action=com.example.myapp.MY_ACTION&dropoff=San+Francisco

Intent-based URLs

If you are using an intent-based URL, the urlTemplate value includes the package name, the Intent action, and one Intent extra, 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. The extra preceding semicolon is needed to separate the Intent action from the Intent extra (and will only be included if the parameter is set).

In our example, the urlParameter value is set to “S.dropoff”; you can see where this will appear in our URL by looking for this value in urlTemplate.

As an example, if a user triggered our Action by asking to order a ride to “San Francisco”, the final Uri that is triggered (after parameter substitution) would be:

intent:#Intent;package=com.example.myapp;action=com.example.myapp.MY_ACTION;S.dropoff=San+Francisco;end

Using URL values from entities in URL templates

By default, if an entity is matched to the user’s query, the identifier value is passed to the URL template. In order to reference the url field of an entity instead, do not create a <parameter-mapping> for the parameter. Instead, add "{@url}" to the URL template. Note that while identifier values are URL-escaped, url values are left unchanged.

For 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. For example:

<fulfillment urlTemplate="{@url}?referrer=actions_on_google{&amp;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 or alternateName value matches the user's query.

Examples

Finance - accounts and payments

The following example shows an example of an actions.xml that 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">
   <!-- Each parameter can reference an entity set using a custom ID. -->
   <parameter name="moneyTransfer.moneyTransferDestination.name">
       <entity-set-reference entitySetId="BankAccountTypeEntitySet"/>
   </parameter>
   <!-- Two parameters can reference the same entity set ID. -->
   <parameter name="moneyTransfer.moneyTransferOrigin.name">
       <entity-set-reference entitySetId="BankAccountTypeEntitySet"/>
   </parameter>
   <fulfillment urlTemplate="mybankapp://transfer{?amount,currency,recipientBankAccountType,senderBankAccountType}">
       <parameter-mapping intentParameter="moneyTransfer.amount.value" urlParameter="amount" />
       <parameter-mapping intentParameter="moneyTransfer.amount.currency" urlParameter="currency" />
       <parameter-mapping intentParameter="moneyTransfer.moneyTransferDestination.name" urlParameter="recipientBankAccountType" entityMatchRequired="true" />
       <parameter-mapping intentParameter="moneyTransfer.moneyTransferOrigin.name" urlParameter="senderBankAccountType" entityMatchRequired="true" />
   </fulfillment>
</action>
<entity-set entitySetId="BankAccountTypeEntitySet">
   <entity identifier="CHECKING" name="checking" alternateName="@array/checkingSynonyms" />
   <entity identifier="SAVINGS" name="savings" alternateName="@array/savingsSynonyms" />
</entity-set>
</actions>

Fitness - nutrition

The following example shows an example of an actions.xml that 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 example shows an example of an actions.xml that 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>