Criar um arquivo actions.xml (descontinuado)

Mantenha tudo organizado com as coleções Salve e categorize o conteúdo com base nas suas preferências.

Depois de identificar a funcionalidade e a intent integrada (BII, na sigla em inglês) que você quer implementar, crie um recurso actions.xml no seu app Android que associe a BII à funcionalidade do app. As Ações no app definidas no actions.xml descrevem como cada BII resolve o fulfillment, além dos parâmetros extraídos e fornecidos ao app.

Visão geral

Para integrar seu app Android com Ações no app, é necessário ter um arquivo actions.xml no diretório res/xml do projeto do seu aplicativo.

Adicione uma referência ao actions.xml no arquivo AndroidManifest.xml usando uma tag <meta-data>. Por exemplo:

<application>
    <!-- ... -->
    <meta-data android:name="com.google.android.actions" android:resource="@xml/actions" />
</application>

Isso declara um recurso XML para o arquivo xml/actions.xml no APK. Para saber mais sobre como especificar recursos no Android, consulte a página Visão geral dos recursos de aplicativo na documentação para desenvolvedores Android.

Esquema

A tabela a seguir descreve o esquema para o actions.xml. Ao incluir uma tag, todos os atributos dela são obrigatórios, a menos que marcados como "opcionais".

Tag Contida em Atributos
<actions> nível superior
<action> <actions>

intentName

queryPatterns (aplicável somente para intents personalizadas)

<parameter> <action> name
<entity-set-reference> <parameter>

entitySetId OU

urlFilter

<fulfillment> <action>

urlTemplate

fulfillmentMode (opcional)

requiredForegroundActivity (opcional)

<parameter-mapping> <fulfillment>

urlParameter

intentParameter

required (opcional)

entityMatchRequired (opcional)

<entity-set> <actions> entitySetId
<entity> <entity-set>

name (e, opcionalmente, alternateName) OU

sameAs

identifier OU url

Descrições de tags

Esta seção descreve as diversas tags de esquema para o actions.xml.

<action>

Uma ação no app que pode ser usada com o aplicativo. Para cada tag <action> no arquivo actions.xml, é necessário fornecer pelo menos um <fulfillment>.

Atributos:

  • intentName: intent integrada para a ação no app (por exemplo, actions.intent.CREATE_TAXI_RESERVATION). Para ver uma lista de intents integradas com suporte, consulte a referência de intents integradas.

  • queryPatterns: um conjunto de consultas esperadas do usuário para essa intent. Esse atributo só é aplicável a intents personalizadas, porque as BIIs já incluem modelos das maneiras comuns em que os usuários expressam as tarefas que estão tentando fazer ou as informações que procuram.

<parameter>

Um parâmetro de uma ação no app com um nome e uma lista de entidades associadas.

Atributos:

  • name: nome a ser associado a esse parâmetro (por exemplo, "destino"). O nome precisa ser um campo no nível da folha do parâmetro (por exemplo, tradeOrder.assetOrdered.assetIssuedBy.name). Se o parâmetro for um tipo primitivo, como uma string, o nome vai ser apenas o nome do parâmetro.

<entity-set-reference>

Referência a um feed do schema.org (link em inglês) fornecido pelo desenvolvedor. Os feeds precisam ser fornecidos diretamente no arquivo actions.xml usando tags <entity-set>.

Atributos:

  • entitySetId: uma referência a uma coleção específica de entidades. Esse atributo precisa corresponder a um entitySetId em uma tag <entity-set>.

  • urlFilter: caminho do URL usado ao fornecer o inventário da Web para fulfillment. Esse atributo oferece suporte a dois caracteres curinga:

    • *: um asterisco corresponde a uma sequência de zero a várias ocorrências do caractere imediatamente anterior.

    • .*: um ponto seguido por um asterisco corresponde a qualquer sequência de zero a vários caracteres.

    • Os caracteres de escape são necessários apenas para * e \ literais, cujo escape pode ser feito usando \\* e \\\\, respectivamente.

<fulfillment>

Informações sobre como atender à intent do usuário utilizando o app Android. Os desenvolvedores podem fornecer várias tags <fulfillment> no actions.xml, com um conjunto diferente de parâmetros obrigatórios para cada intent.

O Google usa o primeiro <fulfillment> que tem todos os parâmetros necessários disponíveis para que ele atenda à consulta do usuário. Você precisa fornecer um <fulfillment> sem nenhum parâmetro obrigatório como fulfillment substituto.

Atributos:

  • urlTemplate: modelo para a criação do link direto ou de um URI do Slice a ser aberto no dispositivo. O modelo pode ser ampliado com os parâmetros da intent do usuário caso todos os parâmetros necessários para o modelo estejam disponíveis. Para ver exemplos do modelo de URL HTTP, consulte o artigo da Wikipédia sobre modelos de URL. O formato segue a especificação de modelo de URI RFC 6570 (links em inglês).

  • fulfillmentMode: (opcional) modo de fulfillment usado para disponibilização. Os valores válidos são estes:

    • actions.fulfillment.DEEPLINK: atender à ação do usuário abrindo o app Android com um link direto. Esse é o padrão.

    • actions.fulfillment.SLICE: atender à ação do usuário incorporando um Slice fornecido pelo app Android.

  • requiredForegroundActivity: (opcional) indica a atividade que precisa estar em primeiro plano para que a ação no app seja acionada com a invocação do app em primeiro plano.

    • Especifique a atividade sem abreviações de classe usando o nome do pacote do app, seguido por uma barra (/) e o nome da atividade: APP_PACKAGE_NAME/ACTIVITY_NAME

Veja a seguir alguns exemplos de valores de modelo de URL:

Modelo Valores Valor ampliado
https://example.com/test{?foo,bar} "foo": "123"

"bar": "456"

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

"bar": "456"

https://example.com/test?utm_campaign=appactions&foo=123&bar=456
https://example.com/test?utm_campaign=appactions{#foo} "foo": "123" https://example.com/test?utm_campaign=appactions#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

Para saber mais sobre como configurar modelos de URL, consulte os modelos de URL no fulfillment.

<parameter-mapping>

Associa desde parâmetros de intent a variáveis no modelo de URL. As chaves nesse mapa representam os parâmetros do modelo de URL, ou "variáveis", conforme descrito na RFC 6570 (link em inglês).

Se um parâmetro não for incluído na intent, a variável correspondente será deixada sem definição no momento da expansão do modelo de URL. Consulte a RFC 6570, seção 3.2.1 (link em inglês) para ver uma descrição de como as variáveis indefinidas são tratadas.

Observe que os valores required="true" e entityMatchRequired="true" são distintos.

Atributos:

  • urlParameter: todas as variáveis mencionadas no modelo de URL precisam ter um urlParameter correspondente na tag <parameter-mapping>. Por exemplo, se o uri_template for http://spysatellite.com/show{?lat,long}, será necessário usar chaves na <parameter-mapping> para os parâmetros lat e long.

  • intentParameter: os valores se referem a parâmetros de intent. Se o parâmetro da intent for de um tipo estruturado, use a notação de ponto para se referir a um campo aninhado. Por exemplo, caso haja um parâmetro taxiReservation do tipo schema.org/TaxiReservation, você pode usar taxiReservation.pickupLocation.geo.latitude para se referir ao valor de latitude.

    Se você fornecer um grupo de entidades para esse parâmetro, o intentParameter vai precisar corresponder exatamente ao nome da tag <parameter> (por exemplo, taxiReservation.pickupLocation.geo.latitude). Se o parâmetro de intent tiver um tipo complexo, o valor vai precisar corresponder à referência do objeto do parâmetro (por exemplo, taxiReservation). Se o parâmetro de intent tiver um tipo primitivo, o valor vai precisar ser o próprio nome do parâmetro.

  • required: (opcional) indica que é necessário ter um determinado intentParameter para que esse modelo de URL seja válido. O modelo de URL será descartado se a consulta do usuário não incluir um valor para o intentParameter especificado.

  • entityMatchRequired (opcional): indica que precisa haver uma correspondência de inventário para o intentParameter especificado. O valor padrão é false.

    Quando esse atributo for definido como true, se houver uma correspondência de inventário, o identificador dessa correspondência vai ser transmitido ao modelo de URL. Por outro lado, se não houver correspondência, o Google Assistente vai ignorar o fulfillment.

    Quando esse atributo for definido como false, se houver uma correspondência de inventário, o identificador dessa correspondência vai ser transmitido ao modelo de URL. Caso contrário, o Google Assistente vai fornecer o valor de parâmetro de BII conforme extraído da consulta do usuário.

<entity-set>

Conjunto de entidades inline no actions.xml.

Atributos:

  • entitySetId: identificador exclusivo obrigatório para uma tag <entity-set> no actions.xml (por exemplo, "myInlineEntitySet1"). Esse valor também precisa corresponder ao valor de <entitySetId> na tag <entity-set-reference>.

    Os valores de entitySetId precisam ter no máximo 30 caracteres alfanuméricos (sem caracteres especiais, como - ou _) e começar com uma letra.

<entity>

Um elemento entre um conjunto de entidades inline no actions.xml. Contém um subconjunto de campos schema.org/Thing (link em inglês).

Os valores de string dos campos url, identifier e sameAs podem ser codificados ou referenciados usando os recursos de string do APK. Ao fornecer sinônimos, use valores de string para o campo alternateName que fazem referência aos recursos de matriz de strings do APK.

Atributos:

  • name: nome obrigatório para a entidade, a menos que você esteja especificando um campo sameAs. Precisa ser exclusivo nos campos name e alternateName da entidade para a tag <entity-set> fornecida (por exemplo, "pasta de dente").

  • alternateName (opcional): nomes alternativos da entidade. Especifique um campo name antes de um alternateName. Precisa ser exclusivo nos campos name e alternateName da entidade para a <entity-set> fornecida. A entidade será selecionada se a consulta do usuário corresponder a qualquer uma dessas strings.

  • sameAs: é o URL de uma página da Web de referência que identifica claramente a entidade. Usado para especificar um valor de enumeração apenas se o tipo de parâmetro da intent for um subtipo de schema.org/Enumeration (link em inglês).

    Obrigatório para campos de parâmetro com tipos que são subtipos de schema.org/Enumeration. Por exemplo, MealTypeBreakfast (link em inglês).

  • identifier: identificador da entidade. Precisa ser exclusivo entre as entidades para a tag <entity-set> especificada (por exemplo, CAPPUCCINO_ID).

  • url: o URL RFC 3986 (link em inglês) a ser aberto em um dispositivo Android. O URL pode ou não ser resolvido por um cliente HTTP. Por exemplo, no Android, o URL pode ser um "http://" vinculado ao app ou um URL específico do dispositivo, como um "intent://" ou um esquema de URL personalizado.

    Você pode usar o campo url com o atributo urlTemplate de <fulfillment> das seguintes maneiras:

    • Forneça valores de url no inventário inline e omita urlTemplate no <fulfillment>.

    • Forneça valores de url no inventário inline e os use no valor de urlTemplate (por exemplo, {@url}?extra_param=ExampleValue).

É necessário fornecer identifier ou url. Todas as entidades dentro de um determinado conjunto de entidades precisam usar o mesmo atributo (identifier ou url).

Inventário inline para Ações no app

Para algumas intents integradas, você pode guiar a extração de entidade para um conjunto de entidades com suporte especificado no actions.xml, conhecido como inventário inline. Quando um usuário invoca a ação no app, o Google Assistente faz a correspondência de parâmetros de consulta com entidades especificadas como inventário inline. Depois, o Google Assistente pode usar identificadores que correspondam a itens de inventário ao gerar um link direto para fulfillment.

O inventário inline é definido principalmente usando os elementos <entity-set> e <entity>. Ele simplifica o desenvolvimento ao permitir que seu app processe apenas identificadores ou URLs de invocações de ação no app, em vez de reconhecer strings ou valores de enumeração do Google.

Por exemplo, seu app tem bebidas diferentes que os usuários podem pedir, e você espera que eles façam as seguintes solicitações para o mesmo tipo de bebida:

  • Ok Google, peça um café com leite gelado do ExampleApp.

  • Ok Google, peça um café gelado do ExampleApp.

No inventário inline, você especifica "Café com leite gelado" como uma entidade que corresponde ao identificador 12345a. Você também especifica "Café gelado" como uma entidade que corresponde ao mesmo identificador. Agora, quando um usuário acionar a ação no app com as consultas acima, o Google Assistente vai poder usar o identificador "12345a" ao gerar um link direto para o fulfillment.

É possível especificar até mil entidades por app em todos os conjuntos de entidades. Até 20 valores de sinônimos de alternateName podem ser definidos por <entity>.

Inventário da Web para Ações no app

Para algumas intents integradas, você pode usar o inventário da Web como um método de geração de URLs para fulfillment. O inventário da Web usa seu site para descobrir URLs de fulfillment de Ações no app. Esse recurso é mais útil quando você tem uma boa presença na Web e os links diretos no app são organizados em torno do conteúdo disponível publicamente na Web.

Para usar o inventário da Web, atualize o actions.xml:

  1. Na tag <action> em que você quer usar o inventário da Web, adicione uma tag <fulfillment> e defina o atributo urlTemplate como {@url}.

  2. Na mesma <action>, adicione uma tag <parameter> e defina o atributo name como o parâmetro de intent integrada que melhor corresponda à entidade descrita por suas páginas da Web. Por exemplo, ao fornecer o inventário da Web para ORDER_MENU_ITEM, vincule as páginas do menu a menuItem.name e as páginas de localização de restaurantes a menuItem.inMenuSection.inMenu.forRestaurant.name.

  3. Na nova tag <parameter>, adicione uma <entity-set-reference> e defina o atributo urlFilter como o caminho do URL que você quer usar para o inventário da Web.

Ao seguir as etapas acima, o Google Assistente pode fazer uma pesquisa na Web no caminho do URL fornecido no atributo urlFilter. Em seguida, ele fornece um valor de {@url} para o fulfillment usando os resultados. Seu gerenciador de links diretos pode então redirecionar um usuário com base no link direto retornado pelo Google Assistente para esse fulfillment.

Por exemplo, suponha que seu site contém informações do produto que usam um caminho começando com https://www.example.com/items/. Você usa o valor https://www.example.com/items/.* para o urlFilter, e o Google Assistente retorna um URL de fulfillment como https://www.example.com/items/item123. Consulte <entity-set-reference> para ver informações sobre o atributo urlFilter.

Modelos de URL no fulfillment

Em uma tag <fulfillment>, é possível declarar um modelo de URL com marcadores de posição para parâmetros dinâmicos. Esse modelo é associado a uma das suas atividades do Android usando um URL de links do app, um esquema personalizado ou um URL baseado em intent.

Como configurar o modelo de URL

Exemplo de um URL de links do app:

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

Exemplo de um esquema personalizado:

<action intentName="actions.intent.CREATE_TAXI_RESERVATION">
    <fulfillment urlTemplate="mytaxi://reserve{?dropoffLocation}">
        <parameter-mapping
                intentParameter="taxiReservation.dropoffLocation.name"
                urlParameter="dropoffLocation"/>
    </fulfillment>
</action>

Exemplo de um URL baseado em intent:

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

Ao especificar uma tag <parameter-mapping> para um fulfillment, o atributo intentParameter indica o parâmetro de intent integrado fornecido pelo usuário. Nos exemplos acima, esse parâmetro é o nome do local de desembarque (taxiReservation.dropoffLocation.name). É possível encontrar os parâmetros disponíveis para qualquer intent integrada na página de referência.

Para associar o parâmetro de intent integrada a uma posição no URL, use o atributo urlParameter da tag <parameter-mapping>. Esse atributo corresponde ao valor do marcador no modelo de URL que você quer substituir pelas informações do usuário. O valor do marcador precisa estar presente no urlTemplate e ser escrito entre chaves ({}).

URLs de links do app

Se você estiver usando um URL de links do app, o urlTemplate vai apontar para um URL HTTP normal que pode acionar sua atividade. Os parâmetros são transmitidos como parâmetros de URL para o URL de links do app. Os parâmetros no urlTemplate precisam estar entre chaves ({}) e ser prefixados com um ponto de interrogação (?). Se um parâmetro não for definido, ele e as chaves vão ser omitidos do resultado.

Por exemplo, caso um usuário acionasse a ação no app pedindo um táxi para São Francisco, o URI final acionado, após a substituição de parâmetro, seria o seguinte:

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

URLs baseados em intents

Se você estiver usando um URL baseado em intent, o valor de urlTemplate vai incluir o nome do pacote, a ação da intent e uma intent extra, chamada "dropoff" ("desembarque" em inglês). A extra é prefixada com "S". para indicar um extra de intent de string, conforme definido por Intent.toUri(), e está entre chaves para indicar a substituição por um parâmetro. O ponto e vírgula extra anterior é necessário para separar a ação do extra de intent, e só será incluído se o parâmetro estiver definido.

Em nosso exemplo, o valor de urlParameter é definido como S.dropoff. É possível ver onde ele aparece no URL procurando esse valor no urlTemplate.

Por exemplo, se um usuário acionasse nossa ação pedindo uma viagem para "São Francisco", o URI final acionado, após a substituição de parâmetro, seria:

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

Para ver mais informações sobre intents, consulte a documentação Intents do Android.

Como usar valores de URL de entidades em modelos de URL

Por padrão, se uma <entity> corresponder à consulta do usuário, o valor do atributo identifier vai ser transmitido para o modelo de URL. Para referenciar o atributo url de um <entity>, use {@url} no modelo de URL e não use uma tag <parameter-mapping>. Os valores de identificador têm escape de URL, mas os valores do atributo url não são modificados.

Se um fulfillment usar {@url} no modelo de URL, ele vai tentar derivar {@url} de fontes como o inventário inline e da Web. Quando esses inventários são possíveis fontes de derivação de {@url}, o inventário da Web tem preferência.

Por exemplo:

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

Os parâmetros {@url} podem ser combinados com outros parâmetros. Por exemplo:

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

Correspondência de parâmetros

A maneira como o Google faz a correspondência de parâmetros das falas do usuário com as entidades especificadas depende do tipo de parâmetro:

  • Tipo enumerado: o Google faz a correspondência da consulta do usuário ("monday", ou "segunda-feira" em inglês) com o URL de um tipo enumerado ("http://schema.org/Monday") e escolhe a entidade cujo valor de sameAs corresponde ao URL de enumeração.
  • String: o Google escolhe a entidade cujo valor de name ou alternateName corresponde à consulta do usuário.

Exemplos

A seção abaixo mostra exemplos de como usar intents integradas no actions.xml.

Finanças: contas e pagamentos

O exemplo de actions.xml a seguir usa a intent integrada actions.intent.CREATE_MONEY_TRANSFER:

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

Condicionamento físico: nutrição

O exemplo de actions.xml a seguir usa a intent integrada actions.intent.RECORD_FOOD_OBSERVATION:

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

Pedido de comida

O exemplo de actions.xml a seguir usa a intent integrada actions.intent.ORDER_MENU_ITEM:

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

Transporte

O arquivo actions.xml a seguir usa a intent integrada actions.intent.CREATE_TAXI_RESERVATION:

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

Outro

O exemplo de actions.xml a seguir usa a intent integrada actions.intent.OPEN_APP_FEATURE.

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