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 em
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> |
|
<parameter> |
<action> |
name |
<entity-set-reference> |
<parameter> |
|
<fulfillment> |
<action> |
|
<parameter-mapping> |
<fulfillment> |
|
<entity-set> |
<actions> |
entitySetId |
<entity> |
<entity-set> |
|
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 é 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 será o próprio 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 umentitySetId
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 conjuntos diferentes 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
.
- Especifique a atividade sem abreviações de classe usando o nome do
pacote do app,
seguido por uma barra (
Veja a seguir alguns exemplos de valores de modelo de URL:
Modelo | Valores | Valor ampliado |
---|---|---|
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 |
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 umurlParameter
correspondente na tag<parameter-mapping>
. Por exemplo, se o uri_template forhttp://spysatellite.com/show{?lat,long}
, será necessário usar chaves na<parameter-mapping>
para os parâmetroslat
elong
.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âmetrotaxiReservation
do tiposchema.org/TaxiReservation
, você pode usartaxiReservation.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 da intent tiver um tipo complexo, o valor vai corresponder à referência do objeto do parâmetro (por exemplo,
taxiReservation
). Se o parâmetro de intent tiver um tipo primitivo, o valor será o próprio nome do parâmetro.required
: (opcional) indica que é necessário ter um determinadointentParameter
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 ointentParameter
especificado.entityMatchRequired
(opcional): indica que precisa haver uma correspondência de inventário para ointentParameter
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>
noactions.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
fixados no código 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 camposameAs
. Precisa ser exclusivo nos camposname
ealternateName
da entidade para a tag<entity-set>
fornecida (por exemplo, "pasta de dente").alternateName
(opcional): nomes alternativos da entidade. Especifique um camponame
antes de umalternateName
. Precisa ser exclusivo nos camposname
ealternateName
da entidade para o<entity-set>
fornecido. 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 deschema.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 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 atributourlTemplate
de<fulfillment>
das seguintes maneiras:Forneça valores de
url
no inventário inline e omitaurlTemplate
no<fulfillment>
.Forneça valores de
url
no inventário inline e os use no valor deurlTemplate
(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 em 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>
. O inventário inline simplifica o desenvolvimento
ao permitir que seu app processe apenas identificadores ou URLs de invocações de Ações 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 app de exemplo.
Ok Google, peça um café gelado do app de exemplo.
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 anteriores, o Google Assistente
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
:
Na tag
<action>
em que você quer usar o inventário da Web, adicione uma tag<fulfillment>
e defina o atributourlTemplate
como{@url}
.Na mesma
<action>
, adicione uma tag<parameter>
e defina o atributoname
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 paraORDER_MENU_ITEM
, vincule as páginas do menu amenuItem.name
e as páginas de localização de restaurantes amenuItem.inMenuSection.inMenu.forRestaurant.name
.Na nova tag
<parameter>
, adicione uma tag<entity-set-reference>
e defina o atributourlFilter
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.
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 anteriores, 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 Activity
. 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, se um usuário acionar 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) será o seguinte:
https://mydomain.com/order?action=com.example.myapp.MY_ACTION&dropoff=San+Francisco
URLs baseados em intent
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 tem o prefixo "S." para indicar um extra de intent String
(conforme definido por
Intent.toUri()
) e está entre chaves para indicar a substituição por
um parâmetro.
Um 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.
No exemplo a seguir, o valor de urlParameter
está definido como S.dropoff
. Para ver
onde ele aparece no URL, procure esse valor no urlTemplate
.
Por exemplo, se um usuário acionar uma Ação no app pedindo uma viagem para São Francisco, o URI final acionado (após a substituição de parâmetro) será:
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.
Isso é mostrado neste 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:
<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>
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
oualternateName
corresponde à consulta do usuário.
Exemplos
Esta seção mostra exemplos de como usar intents integradas em
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>