App Actions deployment requirements

To ensure that users enjoy a seamless experience when using App Actions, you must meet these requirements before activating App Actions for your app:

  • Log contextual content: To create a better experience when users invoke App Actions from the Assistant while in the app, your Activity should call the onProvideAssistContent() method.
  • Report App Action interaction results: To help Google proactively suggest your App Actions to users, use the Firebase App Indexing API to let the Assistant know whether your app has successfully handled a built-in request.
  • Handle the SEARCH_ACTION Android intent: If your app has a search function, you must support the SEARCH_ACTION common intent. This lets Google provide a fallback mechanism if we are unable to resolve the user’s query to a built-in intent.

These requirements are described in more detail below.

Log contextual content

By implementing onProvideAssistContent(), you provide the Assistant with structured information about the current foreground content. This contextual information enables the Assistant to continue being helpful after the user enters your app.

You only need to implement onProvideAssistContent() for the final app activity in the user's task flow after invoking the App Action. For example, in a CREATE_MONEY_TRANSFER flow, you would implement the method in the final screen showing the receipt; you would not need to implement it for any in-progress or preview screens.

You must provide this data as a JSON-LD object in the structuredData field. The following code snippet shows how you might implement the contextual content logging:

Java

@Override
public void onProvideAssistContent(AssistantContent outContent) {
  super.onProvideAssistContent(outContent);

  // JSON-LD object based on Schema.org structured data
  outContent.structuredData = new JSONObject()
    .put("@type", "MenuItem")
    .put("name", "Blueberry Crisp Iced Signature Latte")
    .put("url", "https://mysite.com/menuitems/12345a")
    .toString();
}

Kotlin

override fun onProvideAssistContent(outContent: AssistContent) {
 super.onProvideAssistContent(outContent)

 // JSON-LD object based on Schema.org structured data
 outContent.structuredData = JSONObject()
         .put("@type", "MenuItem")
         .put("name", "Blueberry Crisp Iced Signature Latte")
         .put("url", "https://mysite.com/menuitems/12345a")
         .toString()
}

We recommend that you implement onProvideAssistContent() for any sharable entity in your app. However, onProvideAssistContent() is required in the activities that are triggered by the following built-in intents for App Actions:

Category Built-in intent Required entity type
Finance CREATE_MONEY_TRANSFER @MoneyTransfer
Fitness STOP_EXERCISE @Exercise
GET_EXERCISE_OBSERVATION @ExerciseObservation
GET_FOOD_OBSERVATION @FoodObservation
Food ordering ORDER_MENU_ITEM @MenuItem, @Restaurant
GET_ORDER @Order
Ride sharing CREATE_TAXI_RESERVATION @TaxiReservation
GET_TAXI_RESERVATION @TaxiReservation

Similarly, while we recommend providing as much data as possible about each entity, we require the following fields:

  • @type
  • .name
  • .url (only required if the content is URL-addressable)

To learn more about using onProvideAssistContent(), see the Optimizing Contextual Content for the Assistant guide in the Android developer documentation.

Report interaction results

If your app supports App Actions to deep link into activities, follow the Log User Actions instructions in the Firebase documentation to let Google know whether your app has successfully handled a built-in request. This is critical for us to ensure and monitor the health of your App Actions.

To satisfy this requirement, you only need to report success or failure based on whether the App Action was successful or not within the app. You are not required to implement indexing of your app content using Firebase App Indexing in order to deploy your App Actions.

Make sure to add Firebase and the App Indexing library to your Android Studio project.

The following code snippet shows how to use the FirebaseUserActions class to report status when users invoke your App Actions:

Java

private static final String ACTION_TOKEN_EXTRA =
        "actions.fulfillment.extra.ACTION_TOKEN";

void notifyActionStatus(String status) {
    String actionToken = getIntent().getStringExtra(ACTION_TOKEN_EXTRA);
    final Action action = new AssistActionBuilder()
            .setActionToken(actionToken)
            .setActionStatus(status)
            .build();
    FirebaseUserActions.getInstance().end(action);
}

// On Action success
notifyActionStatus(Action.Builder.STATUS_TYPE_COMPLETED);

// On Action failed
notifyActionStatus(Action.Builder.STATUS_TYPE_FAILED);

Kotlin

private val actionTokenExtra = "actions.fulfillment.extra.ACTION_TOKEN"

fun notifyActionStatus(status: String) {
     val actionToken = intent.getStringExtra(actionTokenExtra)
     val action = AssistActionBuilder()
             .setActionToken(actionToken)
             .setActionStatus(status)
             .build()
     FirebaseUserActions.getInstance().end(action)
 }

 // On Action success
 notifyActionStatus(Action.Builder.STATUS_TYPE_COMPLETED)

 // On Action failed
 notifyActionStatus(Action.Builder.STATUS_TYPE_FAILED)

Make sure that you're uploading the action data to Google servers (default behavior) by not setting setUpload(false).

To learn more about logging actions with the App Indexing API, see the Log User Actions guide in the Firebase documentation.

In the event where the Assistant is confident that the user wishes to access your app via the Assistant, but is unable to resolve the query to a built-in intent, it’s important to provide a fallback mechanism. If your app already has a search function, you must handle the SEARCH_ACTION Android intent, so that Google can pass the user query into your app, if needed.

The following snippet shows how to add an intent filter to an Activity with the SEARCH_ACTION common intent in the AndroidManifest.xml file:

<activity android:name=".SearchActivity">
   <intent-filter>
      <action android:name="com.google.android.gms.actions.SEARCH_ACTION"/>
      <category android:name="android.intent.category.DEFAULT"/>
   </intent-filter>
</activity>

In your search activity, you should check the for the SEARCH_ACTION intent and extract the query. Then, do something with the query like running a search and displaying the results in the UI. For example, you could make a query to the Assistant like this: "Hey Google, show me cats on myvideoapp".

The following code snippet shows an example implementation.

Java

@Override
protected void onCreate(Bundle savedInstanceState) {
  ...
  Intent intent = getIntent();
  if (intent.getAction().equals(SearchIntents.ACTION_SEARCH)) {
    String query = intent.getStringExtra(SearchIntents.EXTRA_QUERY);
    //TODO: user query value to run search
  }
}

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
  ...
  if (intent?.action == SearchIntents.ACTION_SEARCH) {
    val query = intent?.getStringExtra(SearchIntents.EXTRA_QUERY)
    // TODO: use query value to run search
  }
  ...
}

To learn more about handling this common intent, see the Search using a specific app guide in the Android documentation.