Eventos in-app

Resumen General

Para ver una introducción a los eventos in-app para desarrolladores, consulta Eventos in-app.

Antes de comenzar

Debes integrar el SDK.

Registro de eventos in-app

El SDK te permite registrar las acciones de los usuarios que ocurren en el contexto de tu aplicación. Estos se conocen comúnmente como eventos in-app.

The logEvent method

The logEvent method lets you log in-app events and send them to AppsFlyer for processing.

To access the logEvent method, import AppsFlyerLib:

import com.appsflyer.AppsFlyerLib;
import com.appsflyer.AppsFlyerLib

To access predefined event constants, import AFInAppEventType and AFInAppEventParameterName:

import com.appsflyer.AFInAppEventType; // Predefined event names
import com.appsflyer.AFInAppEventParameterName; // Predefined parameter names
import com.appsflyer.AFInAppEventType // Predefined event names
import com.appsflyer.AFInAppEventParameterName // Predefined parameter names

logEvent toma 4 argumentos:

void logEvent(Context context,
              java.lang.String eventName,
              java.util.Map<java.lang.String,java.lang.Object> eventValues,
              AppsFlyerRequestListener listener)
  • The first argument (context) is the Application/Activity Context
  • The second argument (eventName) is the In-app event name
  • The third argument (eventValues) is the event parameters Map
  • The fourth argument (listener) is an optional AppsFlyerRequestListener (useful for Handling event submission success/failure)

Example: Send "add to wishlist" event

Por ejemplo, para registrar que un usuario agregó un artículo a su lista de deseos:

Map<String, Object> eventValues = new HashMap<String, Object>();
eventValues.put(AFInAppEventParameterName.PRICE, 1234.56);
eventValues.put(AFInAppEventParameterName.CONTENT_ID,"1234567");

AppsFlyerLib.getInstance().logEvent(getApplicationContext(),
                                    AFInAppEventType.ADD_TO_WISHLIST , eventValues);
val eventValues = HashMap<String, Any>() 
eventValues.put(AFInAppEventParameterName.PRICE, 1234.56)
eventValues.put(AFInAppEventParameterName.CONTENT_ID,"1234567")

AppsFlyerLib.getInstance().logEvent(getApplicationContext() ,
                                    AFInAppEventType.ADD_TO_WISHLIST , eventValues)

In the above logEvent invocation:

Implementing event structure definitions

Según la definición de ejemplo proporcionada en Comprender las definiciones de la estructura de eventos, el evento debe implementarse de la siguiente manera:

Map<String, Object> eventValues = new HashMap<String, Object>();
eventValues.put(AFInAppEventParameterName.PRICE, <ITEM_PRICE>);
eventValues.put(AFInAppEventParameterName.CONTENT_TYPE, <ITEM_TYPE>);
eventValues.put(AFInAppEventParameterName.CONTENT_ID, <ITEM_SKU>);

AppsFlyerLib.getInstance().logEvent(getApplicationContext(),
                                    AFInAppEventType.CONTENT_VIEW, eventValues);
val eventValues = HashMap<String, Any>() 
eventValues.put(AFInAppEventParameterName.PRICE, <ITEM_PRICE>)
eventValues.put(AFInAppEventParameterName.CONTENT_TYPE, <ITEM_TYPE>)
eventValues.put(AFInAppEventParameterName.CONTENT_ID, <ITEM_SKU>)

AppsFlyerLib.getInstance().logEvent(getApplicationContext(),
                                    AFInAppEventType.CONTENT_VIEW, eventValues)

Handling event submission success and failure

You can provide logEvent with a AppsFlyerRequestListener object when recording in-app events. The handler allows you to define logic for two scenarios:

  • Un evento in-app se registra correctamente.
  • Se produjo un error al registrar el evento in-app
AppsFlyerLib.getInstance().logEvent(getApplicationContext(),
                                    AFInAppEventType.PURCHASE,
                                    eventValues,
                                    new AppsFlyerRequestListener() {
                    @Override
                    public void onSuccess() {
                        Log.d(LOG_TAG, "Event sent successfully");
                    }
                    @Override
                    public void onError(int i, @NonNull String s) {
                        Log.d(LOG_TAG, "Event failed to be sent:\n" +
                                "Error code: " + i + "\n"
                                + "Error description: " + s);
                    }
                });
AppsFlyerLib.getInstance().logEvent(getApplicationContext(),
                                    AFInAppEventType.PURCHASE,
                                    eventValues,
                                    object : AppsFlyerRequestListener {
            override fun onSuccess() {
                Log.d(LOG_TAG, "Event sent successfully")
            }
            override fun onError(errorCode: Int, errorDesc: String) {
                Log.d(LOG_TAG, "Event failed to be sent:\n" +
                        "Error code: " + errorCode + "\n"
                        + "Error description: " + errorDesc)
            }
        })

En caso de que se produzca un error durante la grabación del evento in-app, se proporciona un código de error y una descripción de la cadena, como se indica en la tabla que figura a continuación.

Código del errorDescripción (NSError)
10"Event timeout. Check 'minTimeBetweenSessions' param" ("Tiempo de espera del evento agotado. Comprueba el parámetro 'minTimeBetweenSessions'")
11"Skipping event because 'isStopTracking' enabled" ("Se omite el evento porque 'isStopTracking' está activado")
40Network error: Error description comes from Android (Error de red: la descripción del error viene de Android)
41"No dev key" ("No hay clave de desarrollador")
50"Status code failure" + actual response code from the server ("Fallo del código de estado" + código de respuesta real del servidor)

Recording offline events

El SDK puede registrar los eventos que ocurren cuando no hay conexión a Internet disponible. Consulta Eventos in-app sin conexión para obtener más detalles.

Logging events before calling start

If you initialized the SDK but didn't call start, the SDK will cache in-app events until start is invoked.

Si hay varios eventos en el caché, se envían al servidor uno tras otro (sin lotes, una solicitud de red por evento).

Registro de ingresos

You can send revenue with any in-app event. Use the AFInAppEventParameterName.REVENUE event parameter to include revenue in the in-app event. You can populate it with any numeric value, positive or negative.

El valor de los ingresos no debe contener comas separadoras, signos de divisas ni texto. Por ejemplo, un evento generador de ingresos debería ser similar a 1234.56.

Example: Purchase event with revenue

Map<String, Object> eventValues = new HashMap<String, Object>();
eventValues.put(AFInAppEventParameterName.CONTENT_ID, <ITEM_SKU>);
eventValues.put(AFInAppEventParameterName.CONTENT_TYPE, <ITEM_TYPE>);
eventValues.put(AFInAppEventParameterName.REVENUE, 200);

AppsFlyerLib.getInstance().logEvent(getApplicationContext(), 
                                    AFInAppEventType.PURCHASE, eventValues);
val eventValues = HashMap<String, Any>() 
eventValues.put(AFInAppEventParameterName.CONTENT_ID, <ITEM_SKU>)
eventValues.put(AFInAppEventParameterName.CONTENT_TYPE, <ITEM_TYPE>)
eventValues.put(AFInAppEventParameterName.REVENUE, 200)

AppsFlyerLib.getInstance().logEvent(getApplicationContext(), 
                                    AFInAppEventType.PURCHASE, eventValues)

El evento de compra anterior contiene un ingreso de $200 que aparece como ingreso en el panel de control.

📘

Nota

No agregues símbolos de divisa al valor de los ingresos.

Configuring revenue currency

You can set the currency code for an event's revenue by using the af_currency predefined event parameter:

Map<String, Object> eventValues = new HashMap<String, Object>();
eventValues.put(AFInAppEventParameterName.CURRENCY, "USD");
eventValues.put(AFInAppEventParameterName.REVENUE, <TRANSACTION_REVENUE>);
AppsFlyerLib.getInstance().logEvent(getApplicationContext(), 
                                    AFInAppEventType.PURCHASE, eventValues);
val eventValues = HashMap<String, Any>() 
eventValues.put(AFInAppEventParameterName.REVENUE, <TRANSACTION_REVENUE>)
eventValues.put(AFInAppEventParameterName.CURRENCY,"USD")
AppsFlyerLib.getInstance().logEvent(getApplicationContext() , AFInAppEventType.PURCHASE , eventValues)
  • El código de divisa debe ser un código ISO 4217 de 3 caracteres.
  • La divisa predeterminada es USD

Para obtener información sobre la configuración, visualización y conversión de divisas, consulta nuestra guía sobre las divisas de los ingresos.

Logging negative revenue

Puede haber situaciones en las que quieras registrar ingresos negativos. Ejemplo: un usuario recibe un reembolso o cancela una suscripción.

Para registrar ingresos negativos:

Map<String, Object> eventValues = new HashMap<String, Object>();
eventValues.put(AFInAppEventParameterName.REVENUE, -1234.56);
eventValues.put(AFInAppEventParameterName.CONTENT_ID,"1234567");
AppsFlyerLib.getInstance().logEvent(getApplicationContext(),
                                    "cancel_purchase",
                                    eventValues);
val eventValues = HashMap<String, Any>() 
eventValues.put(AFInAppEventParameterName.REVENUE, -1234.56)
eventValues.put(AFInAppEventParameterName.CONTENT_ID,"1234567")
AppsFlyerLib.getInstance().logEvent(getApplicationContext(),
                                    "cancel_purchase",
                                    eventValues)

📘

Nota

Observe lo siguiente en el código anterior:

  • El valor de ingresos está precedido por un signo de menos
  • El nombre del evento es un nombre de evento personalizado llamado "cancel_purchase": te ayuda a identificar fácilmente los eventos generadores de ingresos negativos en el panel de control y en los reportes de raw data.

Validación de compras

AppsFlyer provides server verification for in-app purchases. The validateAndLogInAppPurchase method takes care of validating and logging the purchase event.

📘

Nota

La función heredada validateAndLogInAppPurchase se puede reemplazar por el conector del SDK de compra más nuevo y completamente automático. Para aprender a integrar el conector, consulta en Github sobre el conector del SDK de compra para Android.

The validateAndLogInAppPurchase method

validateAndLogInAppPurchase is exposed via AppsFlyerLib.

validateAndLognInAppPurchase toma estos argumentos:

validateAndLogInAppPurchase(Context context,
                            java.lang.String publicKey,
                            java.lang.String signature,
                            java.lang.String purchaseData,
                            java.lang.String price, java.lang.String currency,
                            java.util.Map<java.lang.String,java.lang.String> additionalParameters)
  • context: contexto de aplicación/actividad
  • publicKey: clave de licencia obtenida de Google Play Console
  • signature: data.INAPP_DATA_SIGNATURE from onActivityResult
  • purchaseData: data.INAPP_PURCHASE_DATA from onActivityResult
  • price: precio de compra, debe derivarse de skuDetails.getStringArrayList("DETAILS_LIST")
  • currency: divisa de compra, debe derivarse de skuDetails.getStringArrayList("DETAILS_LIST")
  • additionalParameters : parámetros del evento adicionales para registrar

If the validation is successful, an af_purchase event is logged with the values provided to validateAndLogInAppPurchase.

📘

Nota

validateAndLogInAppPurchase generates an af_purchase in-app event upon successful validation. Sending this event yourself will cause duplicate event reporting.

Example: Validate an in-app purchase

// Purchase object is returned by Google API in onPurchasesUpdated() callback
private void handlePurchase(Purchase purchase) {
    Log.d(LOG_TAG, "Purchase successful!");
    Map<String, String> eventValues = new HashMap<>();
    eventValues.put("some_parameter", "some_value");
    AppsFlyerLib.getInstance().validateAndLogInAppPurchase(getApplicationContext(),
                                                           PUBLIC_KEY,
                                                           purchase.getSignature(),
                                                           purchase.getOriginalJson(),
                                                           "10",
                                                           "USD",
                                                           eventValues);
}
// Purchase object is returned by Google API in onPurchasesUpdated() callback
private fun handlePurchase(Purchase purchase) {
   Log.d(LOG_TAG, "Purchase successful!")
   val eventValues = HashMap<String, String>()
   eventValues.put("some_parameter", "some_value")
   AppsFlyerLib.getInstance().validateAndLogInAppPurchase(this,
                                                          PUBLIC_KEY,
                                                          purchase.getSignature(),
                                                          purchase.getOriginalJson(),
                                                          "10",
                                                          "USD",
                                                          eventValues)
}

Handling purchase validation success/failure

use AppsFlyerInAppPurchaseValidatorListener to subscribe to purchase validation successes/failures and registerValidatorListener to register it in your Application class.

registerValidatorListener is exposed via AppsFlyerLib. To use AppsFlyerInAppPurchaseValidatorListener, import it:

import com.appsflyer.AppsFlyerInAppPurchaseValidatorListener;
import com.appsflyer.AppsFlyerInAppPurchaseValidatorListener

AppsFlyerInAppPurchaseValidatorListener tiene dos devoluciones de llamada:

registerValidatorListener toma 2 argumentos:

  • context: el contexto de la aplicación
  • validationListener: The AppsFlyerInAppPurchaseValidatorListener object you wish to register
AppsFlyerLib.getInstance().registerValidatorListener(this,new
   AppsFlyerInAppPurchaseValidatorListener() {
     public void onValidateInApp() {
       Log.d(TAG, "Purchase validated successfully");
     }
     public void onValidateInAppFailure(String error) {
       Log.d(TAG, "onValidateInAppFailure called: " + error);
     }
});
AppsFlyerLib.getInstance().registerValidatorListener(this, object : AppsFlyerInAppPurchaseValidatorListener {
    override fun onValidateInApp() {
       	Log.d(LOG_TAG, "Purchase validated successfully")
    }

    override fun onValidateInAppFailure(error: String) {
        Log.d(LOG_TAG, "onValidateInAppFailure called: $error")
   }
})

Al validar una compra in-app, se envía automáticamente un evento de compra in-app a AppsFlyer. Mira a continuación una muestra de los datos que se pasan en el parámetro event_value:

{
   "some_parameter": "some_value", // from additional_event_values
   "af_currency": "USD", // from currency
   "af_content_id" :"test_id", // from purchase
   "af_revenue": "10", // from revenue
   "af_quantity": "1", // from purchase
   "af_validated": true // flag that AF verified the purchase
}

Constantes de eventos

Predefined event names

Para usar las siguientes constantes, importa com.appsflyer.AFInAppEventType:

import com.appsflyer.AFInAppEventType;
import com.appsflyer.AFInAppEventType

Predefined event name constants follow a AFInAppEventType.EVENT_NAME naming convention. For example, AFInAppEventType.ADD_TO_CART

Nombre del eventoNombre de constante de Android
"af_level_achieved"
AFInAppEventType.LEVEL_ACHIEVED
"af_add_payment_info"
AFInAppEventType.ADD_PAYMENT_INFO
"af_add_to_cart"
AFInAppEventType.ADD_TO_CART
"af_add_to_wishlist"
AFInAppEventType.ADD_TO_WISHLIST
"af_complete_registration"
AFInAppEventType.COMPLETE_REGISTRATION
"af_tutorial_completion"
AFInAppEventType.TUTORIAL_COMPLETION
"af_initiated_checkout"
AFInAppEventType.INITIATED_CHECKOUT
"af_purchase"
AFInAppEventType.PURCHASE
"af_rate"
AFInAppEventType.RATE
"af_search"
"af_spent_credits"
AFInAppEventType.SPENT_CREDITS
"af_achievement_unlocked"
AFInAppEventType.ACHIEVEMENT_UNLOCKED
"af_content_view"
AFInAppEventType.CONTENT_VIEW
"af_list_view"
AFInAppEventType.LIST_VIEW
"af_travel_booking"
AFInAppEventType.TRAVEL_BOOKING
"af_share"
AFInAppEventType.SHARE
"af_invite"
AFInAppEventType.INVITE
"af_login"
AFInAppEventType.LOGIN
"af_re_engage"
AFInAppEventType.RE_ENGAGE
"af_update"
AFInAppEventType.UPDATE
"af_location_coordinates"
AFInAppEventType.LOCATION_COORDINATES
"af_customer_segment"
AFInAppEventType.CUSTOMER_SEGMENT
"af_subscribe"
AFInAppEventType.SUBSCRIBE
"af_start_trial"
AFInAppEventType.START_TRIAL
"af_ad_click"
AFInAppEventType.AD_CLICK
"af_ad_view"
AFInAppEventType.AD_VIEW
"af_opened_from_push_notification"
AFInAppEventType.OPENED_FROM_PUSH_NOTIFICATION

Predefined event parameters

To use the following constants, import AFInAppEventParameterName:

import com.appsflyer.AFInAppEventParameterName;
import com.appsflyer.AFInAppEventParameterName

Predefined event parameter constants follow a AFInAppEventParameterName.PARAMETER_NAME naming convention. For example, AFInAppEventParameterName.CURRENCY

Nombre del parámetro del eventoNombre de constante de AndroidTipo
"af_content"
CONTENT
String[]
"af_achievement_id"
ACHIEVEMENT_ID
String
"af_level"
LEVEL
String
"af_score"
SCORE
String
"af_success"
SUCCESS
String
"af_price"
PRICE
float
"af_content_type"
CONTENT_TYPE
String
"af_content_id"
CONTENT_ID
String
"af_content_list"
CONTENT_LIST
String[]
"af_currency"
CURRENCY
String
"af_quantity"
QUANTITY
int
"af_registration_method"
REGISTRATION_METHOD
String
"af_payment_info_available"
PAYMENT_INFO_AVAILABLE
String
"af_max_rating_value"
MAX_RATING_VALUE
String
"af_rating_value"
RATING_VALUE
String
"af_search_string"
SEARCH_STRING
String
"af_date_a"
DATE_A
String
"af_date_b"
DATE_B
String
"af_destination_a"
DESTINATION_A
String
"af_destination_b"
DESTINATION_B
String
"af_description"
DESCRIPTION
String
"af_class"
CLASS
String
"af_event_start"
EVENT_START
String
"af_event_end"
EVENT_END
String
"af_lat"
LAT
String
"af_long"
LONG
String
"af_customer_user_id"
CUSTOMER_USER_ID
String
"af_validated"
VALIDATED
boolean
"af_revenue"
REVENUE
float
"af_projected_revenue"
PROJECTED_REVENUE
float
"af_receipt_id"
RECEIPT_ID
String
"af_tutorial_id"
TUTORIAL_ID
String
"af_virtual_currency_name"
VIRTUAL_CURRENCY_NAME
String
"af_deep_link"String
"af_old_version"
OLD_VERSION
String
"af_new_version"
NEW_VERSION
String
"af_review_text"
REVIEW_TEXT
String
"af_coupon_code"
COUPON_CODE
String
"af_order_id"
ORDER_ID
String
"af_param_1"
PARAM_1
String
"af_param_2"
PARAM_2
String
"af_param_3"
PARAM_3
String
"af_param_4"
PARAM_4
String
"af_param_5"
PARAM_5
String
"af_param_6"
PARAM_6
String
"af_param_7"
PARAM_7
String
"af_param_8"
PARAM_8
String
"af_param_9"
PARAM_9
String
"af_param_10"
PARAM_10
String
"af_departing_departure_date"
DEPARTING_DEPARTURE_DATE
String
"af_returning_departure_date"
RETURNING_DEPARTURE_DATE
String
"af_destination_list"
DESTINATION_LIST
String[]
"af_city"
CITY
String
"af_region"
REGION
String
"af_country"
COUNTRY
String
"af_departing_arrival_date"
DEPARTING_ARRIVAL_DATE
String
"af_returning_arrival_date"
RETURNING_ARRIVAL_DATE
String
"af_suggested_destinations"
SUGGESTED_DESTINATIONS
String[]
"af_travel_start"
TRAVEL_START
String
"af_travel_end"
TRAVEL_END
String
"af_num_adults"
NUM_ADULTS
String
"af_num_children"
NUM_CHILDREN
String
"af_num_infants"
NUM_INFANTS
String
"af_suggested_hotels"
SUGGESTED_HOTELS
String[]
"af_user_score"
USER_SCORE
String
"af_hotel_score"
HOTEL_SCORE
String
"af_purchase_currency"
PURCHASE_CURRENCY
String
"af_preferred_neighborhoods"
PREFERRED_NEIGHBORHOODS
String[]
"af_preferred_num_stops"
PREFERRED_NUM_STOPS
String
"af_adrev_ad_type"
AD_REVENUE_AD_TYPE
String
"af_adrev_network_name"
AD_REVENUE_NETWORK_NAME
String
"af_adrev_placement_id"
AD_REVENUE_PLACEMENT_ID
String
"af_adrev_ad_size"
AD_REVENUE_AD_SIZE
String
"af_adrev_mediated_network_name"
AD_REVENUE_MEDIATED_NETWORK_NAME
String
"af_preferred_price_range"
PREFERRED_PRICE_RANGE
String, int tuple formateado como (min,max)
"af_preferred_star_ratings"
PREFERRED_STAR_RATINGS
String, int tuple formateado como (min,max)