diff --git a/.github/workflows/action.yml b/.github/workflows/action.yml new file mode 100644 index 000000000..b1111378e --- /dev/null +++ b/.github/workflows/action.yml @@ -0,0 +1,14 @@ +on: [pull_request] +name: Check links for modified files +jobs: + markdown-link-check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + - uses: gaurav-nelson/github-action-markdown-link-check@v1 + with: + folder-path: 'docs' + use-quiet-mode: 'yes' + use-verbose-mode: 'yes' + check-modified-files-only: 'yes' + base-branch: 'main' \ No newline at end of file diff --git a/docs/analytics/batch-event-upload.md b/docs/analytics/batch-event-upload.md deleted file mode 100644 index 712c6362c..000000000 --- a/docs/analytics/batch-event-upload.md +++ /dev/null @@ -1,505 +0,0 @@ ---- -title: Batch Event Upload ---- - -`POST /batch` -*Bulk upload events* - -Bulk upload events to Amplitude via the batch event upload endpoint. - -If you have used our HTTP API before, note that there are two minor but important differences in your POST request to /batch. First, your Content-type must be `application/json`. Second, your key for the `events` payload is `events` plural, NOT `event` singular. Take a look at the code sample to the right for more details. - -## Body parameter - -```json -{ - "api_key": "my_amplitude_api_key", - "events": [ - { - "user_id": "datamonster@gmail.com", - "device_id": "C8F9E604-F01A-4BD9-95C6-8E5357DF265D", - "event_type": "watch_tutorial", - "time": 1396381378123, - "event_properties": { - "load_time": 0.8371, - "source": "notification", - "dates": [ - "monday", - "tuesday" - ] - }, - "user_properties": { - "age": 25, - "gender": "female", - "interests": [ - "chess", - "football", - "music" - ] - }, - "groups": { - "team_id": "1", - "company_name": [ - "Amplitude", - "DataMonster" - ] - }, - "app_version": "2.1.3", - "platform": "iOS", - "os_name": "Android", - "os_version": "4.2.2", - "device_brand": "Verizon", - "device_manufacturer": "Apple", - "device_model": "iPhone 9,1", - "carrier": "Verizon", - "country": "United States", - "region": "California", - "city": "San Francisco", - "dma": "San Francisco-Oakland-San Jose, CA", - "language": "English", - "price": 4.99, - "quantity": 3, - "revenue": -1.99, - "productId": "Google Pay Store Product Id", - "revenueType": "Refund", - "location_lat": 37.77, - "location_lng": -122.39, - "ip": "127.0.0.1", - "idfa": "AEBE52E7-03EE-455A-B3C4-E57283966239", - "idfv": "BCCE52E7-03EE-321A-B3D4-E57123966239", - "adid": "AEBE52E7-03EE-455A-B3C4-E57283966239", - "android_id": "BCCE52E7-03EE-321A-B3D4-E57123966239", - "event_id": 23, - "session_id": 1396381378123, - "insert_id": "5f0adeff-6668-4427-8d02-57d803a2b841" - } - ] -} -``` - -## Parameters - -|Parameter|In|Type|Required|Description| -|---|---|---|---|---| -|body|body|[UploadRequestBody](#schemauploadrequestbody)|true|A JSON object containing your api_key and an array of events| - -## Responses - -|Status|Meaning|Description|Schema| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|Successful batch event upload|[SuccessSummary](#schemasuccesssummary)| -|400|[Bad Request](https://tools.ietf.org/html/rfc7231#section-6.5.1)|A 400 indicates invalid upload request. Possible reasons for invalid request:
The request body isn't valid JSON. The `error` will say "Invalid JSON request body".
The request body is missing at least one of: required api_key and events array of at least one event. The `error` will say "Request missing required field". The `missing_field` will indicate which is missing.
At least one of the events in the request is missing a required field. The `error` will say "Request missing required field". The `events_missing_required_fields` will be a map from field names to an array of indexes indicating the events missing those required fields.
At least one of the events in the request has an invalid value for one of the fields (for example setting a string for the `time` field). The `error` will say "Invalid field values on some events". The `events_with_invalid_fields` will be a map from field names to an array of indexes indicating the events with invalid values for those fields.|[InvalidRequestError](#schemainvalidrequesterror)| -|413|[Payload Too Large](https://tools.ietf.org/html/rfc7231#section-6.5.11)|Payload size is too big (request size exceeds 20MB). You should split your events array payload in half and try again.|[PayloadTooLargeError](#schemapayloadtoolargeerror)| -|429|[Too Many Requests](https://tools.ietf.org/html/rfc6585#section-4)|Too many requests for a user / device. Amplitude will throttle requests for users and devices that exceed 1000 events per second (measured as an average over a recent time window) or 500,000 events per 24 hours rolling period (measured as a rolling window of 1-hour interval). If you encountered the "per seconds" throttling, you should pause sending events for that user / device for a period of 30 seconds before retrying and continue retrying until you no longer receive a 429 response. If you encountered the "daily limit" throttling, you should try again in the next hour and contact us for further support. Note: the daily limit (24-hours rolling limit) only applies if we've determined that your user/device is spammy.|[TooManyRequestsForDeviceError](#schematoomanyrequestsfordeviceerror)| -*This operation does not require authentication* - -# UploadRequestBody - - -```json -{ - "api_key": "my_amplitude_api_key", - "events": [ - { - "user_id": "datamonster@gmail.com", - "device_id": "C8F9E604-F01A-4BD9-95C6-8E5357DF265D", - "event_type": "watch_tutorial", - "time": 1396381378123, - "event_properties": { - "load_time": 0.8371, - "source": "notification", - "dates": [ - "monday", - "tuesday" - ] - }, - "user_properties": { - "age": 25, - "gender": "female", - "interests": [ - "chess", - "football", - "music" - ] - }, - "groups": { - "team_id": "1", - "company_name": [ - "Amplitude", - "DataMonster" - ] - }, - "app_version": "2.1.3", - "platform": "iOS", - "os_name": "Android", - "os_version": "4.2.2", - "device_brand": "Verizon", - "device_manufacturer": "Apple", - "device_model": "iPhone 9,1", - "carrier": "Verizon", - "country": "United States", - "region": "California", - "city": "San Francisco", - "dma": "San Francisco-Oakland-San Jose, CA", - "language": "English", - "price": 4.99, - "quantity": 3, - "revenue": -1.99, - "productId": "Google Pay Store Product Id", - "revenueType": "Refund", - "location_lat": 37.77, - "location_lng": -122.39, - "ip": "127.0.0.1", - "idfa": "AEBE52E7-03EE-455A-B3C4-E57283966239", - "idfv": "BCCE52E7-03EE-321A-B3D4-E57123966239", - "adid": "AEBE52E7-03EE-455A-B3C4-E57283966239", - "android_id": "BCCE52E7-03EE-321A-B3D4-E57123966239", - "event_id": 23, - "session_id": 1396381378123, - "insert_id": "5f0adeff-6668-4427-8d02-57d803a2b841" - } - ] -} - -``` - -## Properties - -|Name|Type|Required|Restrictions|Description| -|---|---|---|---|---| -|api_key|string|true|none|Amplitude project API key| -|events|[[Event](#schemaevent)]|true|none|Array of [Events](#definition-Event) to upload| -|options|[[options](#schemaRequestOptions)]|false|none|Object| - -# Event - - -```json -{ - "user_id": "datamonster@gmail.com", - "device_id": "C8F9E604-F01A-4BD9-95C6-8E5357DF265D", - "event_type": "watch_tutorial", - "time": 1396381378123, - "event_properties": { - "load_time": 0.8371, - "source": "notification", - "dates": [ - "monday", - "tuesday" - ] - }, - "user_properties": { - "age": 25, - "gender": "female", - "interests": [ - "chess", - "football", - "music" - ] - }, - "groups": { - "team_id": "1", - "company_name": [ - "Amplitude", - "DataMonster" - ] - }, - "app_version": "2.1.3", - "platform": "iOS", - "os_name": "Android", - "os_version": "4.2.2", - "device_brand": "Verizon", - "device_manufacturer": "Apple", - "device_model": "iPhone 9,1", - "carrier": "Verizon", - "country": "United States", - "region": "California", - "city": "San Francisco", - "dma": "San Francisco-Oakland-San Jose, CA", - "language": "English", - "price": 4.99, - "quantity": 3, - "revenue": -1.99, - "productId": "Google Pay Store Product Id", - "revenueType": "Refund", - "location_lat": 37.77, - "location_lng": -122.39, - "ip": "127.0.0.1", - "idfa": "AEBE52E7-03EE-455A-B3C4-E57283966239", - "idfv": "BCCE52E7-03EE-321A-B3D4-E57123966239", - "adid": "AEBE52E7-03EE-455A-B3C4-E57283966239", - "android_id": "BCCE52E7-03EE-321A-B3D4-E57123966239", - "event_id": 23, - "session_id": 1396381378123, - "insert_id": "5f0adeff-6668-4427-8d02-57d803a2b841" -} -``` -```json -{ - "user_id": "datamonster@gmail.com", - "device_id": "C8F9E604-F01A-4BD9-95C6-8E5357DF265D", - "event_type": "$identify", - "time": 1396381378123, - "user_properties": { - "$set": { - "age": 25, - "gender": "female", - "interests": [ - "chess", - "football", - "music" - ]} - }, - "event_id": 23, - "session_id": 1396381378123, - "insert_id": "5f0adeff-6668-4427-8d02-57d803a2b841" -} -``` -```json -{ - "user_id": "datamonster@gmail.com", - "device_id": "C8F9E604-F01A-4BD9-95C6-8E5357DF265D", - "event_type": "$groupidentify", - "time": 1396381378123, - "groups": { - "team_id": "1", - "company_name": [ - "Amplitude", - "DataMonster" - ] - }, - "group_properties": { - "$set": { - "start_date": "01/01/2017" - } - }, - "event_id": 23, - "session_id": 1396381378123, - "insert_id": "5f0adeff-6668-4427-8d02-57d803a2b841" -} -``` - -## Properties - -|Name|Type|Required|Restrictions|Description| -|---|---|---|---|---| -|user_id|string|true|none|A readable ID specified by you. Must have a minimum length of 5 characters. Required unless device_id is present.| -|device_id|string|true|none|A device-specific identifier, such as the Identifier for Vendor on iOS. Required unless user_id is present. If a device_id is not sent with the event, it will be set to a hashed version of the user_id.| -|event_type|string|true|none|A unique identifier for your event. Note: "$identify" and "$groupidentify" are predefined for identification and group identification. More information about the two operations can be found in the descriptions of "user_properties" and "group_properties".| -|time|long|false|none|The timestamp of the event in milliseconds since epoch. If time is not sent with the event, it will be set to the request upload time.| -|event_properties|object|false|none|A dictionary of key-value pairs that represent additional data to be sent along with the event. You can store property values in an array. Date values are transformed into string values. Object depth may not exceed 40 layers.| -|user_properties|object|false|none|A dictionary of key-value pairs that represent additional data tied to the user. You can store property values in an array. Date values are transformed into string values. In addition, user property operations ($set, $setOnce, $add, $append, $unset) are supported when "event_type" is "$identify". Object depth may not exceed 40 layers.| -|groups|object|false|none|This feature is only available to Enterprise customers who have purchased the [Accounts add-on](https://amplitude.zendesk.com/hc/en-us/articles/115001765532). This field adds a dictionary of key-value pairs that represent groups of users to the event as an event-level group. *Note: You can only track up to 5 unique group types and 10 total groups. Any groups past that threshold will not be tracked.*| -|group_properties|object|false|none|This feature is only available to Enterprise customers who have purchased the [Accounts add-on](https://amplitude.zendesk.com/hc/en-us/articles/115001765532). When "event_type" is "$groupidentify", the field is a dictionary of key-value pairs that represent properties tied to the groups listed in the "groups" field. The field is ignored for other event types. Group property operations ($set, $setOnce, $add, $append, $unset) are also supported.| -|app_version|string|false|none|The current version of your application.| -|platform|string|false|none|Platform of the device.| -|os_name|string|false|none|The name of the mobile operating system or browser that the user is using.| -|os_version|string|false|none|The version of the mobile operating system or browser the user is using.| -|device_brand|string|false|none|The device brand that the user is using.| -|device_manufacturer|string|false|none|The device manufacturer that the user is using.| -|device_model|string|false|none|The device model that the user is using.| -|carrier|string|false|none|The carrier that the user is using.| -|country|string|false|none|The current country of the user.| -|region|string|false|none|The current region of the user.| -|city|string|false|none|The current city of the user.| -|dma|string|false|none|The current Designated Market Area of the user.| -|language|string|false|none|The language set by the user.| -|price|float|false|none|The price of the item purchased. Required for revenue data if the revenue field is not sent. You can use negative values to indicate refunds.| -|quantity|integer|false|none|The quantity of the item purchased. Defaults to 1 if not specified.| -|revenue|float|false|none|revneue = price * quantity. If you send all 3 fields of price, quantity, and revenue, then (price * quantity) will be used as the revenue value. You can use negative values to indicate refunds.| -|productId|string|false|none|An identifier for the item purchased. You must send a price and quantity or revenue with this field.| -|revenueType|string|false|none|The type of revenue for the item purchased. You must send a price and quantity or revenue with this field.| -|location_lat|float|false|none|The current Latitude of the user.| -|location_lng|float|false|none|The current Longitude of the user.| -|ip|string|false|none|The IP address of the user. Use "$remote" to use the IP address on the upload request. We will use the IP address to reverse lookup a user's location (city, country, region, and DMA). Amplitude has the ability to drop the location and IP address from events once it reaches our servers. You can submit a request to our platform specialist team [here](https://amplitude.zendesk.com/hc/en-us/requests/new) to configure this for you.| -|idfa|string|false|none|(iOS) Identifier for Advertiser.| -|idfv|string|false|none|(iOS) Identifier for Vendor.| -|adid|string|false|none|(Android) Google Play Services advertising ID| -|android_id|string|false|none|(Android) Android ID (not the advertising ID)| -|event_id|int|false|none|(Optional) An incrementing counter to distinguish events with the same user_id and timestamp from each other. We recommend you send an event_id, increasing over time, especially if you expect events to occur simultanenously.| -|session_id|long|false|none|(Optional) The start time of the session in milliseconds since epoch (Unix Timestamp), necessary if you want to associate events with a particular system. A session_id of -1 is the same as no session_id specified.| -|insert_id|string|false|none|(Optional) A unique identifier for the event. We will deduplicate subsequent events sent with an insert_id we have already seen before within the past 7 days. We recommend generation a UUID or using some combination of device_id, user_id, event_type, event_id, and time.| -|plan|object|false|Only branch, source, version properties are accepted|(Optional) Tracking plan properties.| -|plan.branch|string|false|none|(Optional) The tracking plan branch name e.g. "main"| -|plan.source|string|false|none|(Optional) The tracking plan source e.g. "web"| -|plan.version|string|false|none|(Optional) The tracking plan version e.g. "1", "15"| - -# Options - - -## Properties - -|Name|Type|Required|Restrictions|Description| -|---|---|---|---|---| -|min_id_length|integer|false|none|Minimum permitted length for user_id & device_id fields| - -```json -"options": { - "min_id_length": 5, -} -``` - -# SuccessSummary - - -```json -{ - "code": 200, - "events_ingested": 50, - "payload_size_bytes": 50, - "server_upload_time": 1396381378123 -} - -``` - -## Properties - -|Name|Type|Required|Restrictions|Description| -|---|---|---|---|---| -|code|integer|false|none|200 success code| -|events_ingested|integer|false|none|The number of events ingested from the upload request.| -|payload_size_bytes|integer|false|none|The size of the upload request payload in bytes.| -|server_upload_time|long|false|none|The time in milliseconds since epoch (Unix Timestamp) that our event servers accepted the upload request.| - -# InvalidRequestError - - -```json -{ - "code": 400, - "error": "Request missing required field", - "missing_field": "api_key", - "events_with_invalid_fields": { - "time": [ - 3, - 4, - 7 - ] - }, - "events_with_missing_fields": { - "event_type": [ - 3, - 4, - 7 - ] - } -} - -``` - -## Properties - -|Name|Type|Required|Restrictions|Description| -|---|---|---|---|---| -|code|integer|false|none|400 error code| -|error|string|false|none|Error description| -|missing_field|string|false|none|Indicates which request-level required field is missing.| -|events_with_invalid_fields|object|false|none|A map from field names to an array of indexes into the events array indicating which events have invalid values for those fields| -|events_with_missing_fields|object|false|none|A map from field names to an array of indexes into the events array indicating which events are missing those required fields| - -# SilencedDeviceID - - -```json -{ - "code": 400, - "eps_threshold": 100, - "error": "Events silenced for device_id", - "exceeded_daily_quota_devices": - {}, - "silenced_devices": - [ - "silenced_device_id_1", - "silenced_device_id_2" - ], - "silenced_events": - [ - 5, - 6 - ], - "throttled_devices": - { - "throttled_device_id_1": 0, - "throttled_device_id_2": 100 - }, - "throttled_events": - [ - 3, - 4 - ] -} -``` - -## Properties - -|Name|Type|Required|Restrictions|Description| -|---|---|---|---|---| -|code|integer|false|none|400 error code| -|error|string|false|none|Error description.| -|eps_threshold|integer|false|none|Your app's current events per second threshold. If you exceed this rate your requests will be throttled.| -|exceeded_daily_quota_devices|object|false|none|A map from device_id to its current number of daily events, for all devices that exceed the app's daily event quota.| -|silenced_devices|[string]|false|none|Array of device_ids that have been silenced by Amplitude.| -|silenced_events|[integer]|false|none|Array of indexes in the events array indicating events whose device_id got silenced.| -|throttled_devices|object|false|none|A map from device_id to its current events per second rate, for all devices that exceed the app's current threshold.| -|throttled_events|[integer]|false|none|Array of indexes in the events array indicating events whose user_id and/or device_id got throttled| - -# PayloadTooLargeError - - -```json -{ - "code": 413, - "error": "Payload too large" -} - -``` - -## Properties - -|Name|Type|Required|Restrictions|Description| -|---|---|---|---|---| -|code|integer|false|none|413 error code| -|error|string|false|none|Error description.| - -# TooManyRequestsForDeviceError - - - -```json -{ - "code": 429, - "error": "Too many requests for some devices and users", - "eps_threshold": 1000, - "throttled_devices": { - "C8F9E604-F01A-4BD9-95C6-8E5357DF265D": 4000 - }, - "throttled_users": { - "datamonster@amplitude.com": 4000 - }, - "exceeded_daily_quota_users": { - "datanom@amplitude.com": 500200 - }, - "exceeded_daily_quota_devices": { - "A1A1A000-F01A-4BD9-95C6-8E5357DF265D": 500900 - }, - "throttled_events": [ - 3, - 4, - 7 - ] -} - -``` - -## Properties - -|Name|Type|Required|Restrictions|Description| -|---|---|---|---|---| -|code|integer|false|none|429 error code| -|error|string|false|none|Error description.| -|eps_threshold|integer|false|none|Your app's current events per second threshold. If you exceed this rate your requests will be throttled.| -|throttled_devices|object|false|none|A map from device_id to its current events per second rate, for all devices that exceed the app's current threshold.| -|throttled_users|object|false|none|A map from user_id to their current events per second rate, for all users that exceed the app's current threshold| -|throttled_events|[integer]|false|none|Array of indexes in the events array indicating events whose user_id and/or device_id got throttled| - -#Status Codes \ No newline at end of file diff --git a/docs/analytics/index.md b/docs/analytics/index.md index 82c6d3daf..bb1ee8804 100644 --- a/docs/analytics/index.md +++ b/docs/analytics/index.md @@ -14,78 +14,4 @@ hide: } -# Heading 1 - -Paragraph text. Here's a paragraph of nonsense text so you can understand what it looks like. Look at me! Wow, what a bunch of text!Paragraph text. Here's a paragraph of nonsense text so you can understand what it looks like. Look at me! Wow, what a bunch of text!Paragraph text. Here's a paragraph of nonsense text so you can understand what it looks like. Look at me! Wow, what a bunch of text!Paragraph text. Here's a paragraph of nonsense text so you can understand what it looks like. Look at me! Wow, what a bunch of text!Paragraph text. Here's a paragraph of nonsense text so you can understand what it looks like. Look at me! Wow, what a bunch of text! - -## Heading 2 - -!!! note - - I'm a note box - -!!! example - - I'm an example box - -!!! tip - - I'm a tip box - -!!! warning - - I'm a warning box - -!!! info - - I'm an info box - -!!! success - - I'm an success box - -!!! question - - I'm an question box - -### Heading 3: Tab and Code Examples - -=== "Tab 1" - - ```json - { - "user_id": "datamonster@gmail.com", - "device_id": "C8F9E604-F01A-4BD9-95C6-8E5357DF265D", - "event_type": "$groupidentify", - "time": 1396381378123, - "groups": { - "team_id": "1", - "company_name": [ - "Amplitude", - "DataMonster" - ] - }, - "group_properties": { - "$set": { - "start_date": "01/01/2017" - } - }, - "event_id": 23, - "session_id": 1396381378123, - "insert_id": "5f0adeff-6668-4427-8d02-57d803a2b841" - } - - - ``` - -=== "Tab 2" - - Tab content - -## Table Example - -| Method | Description | -| ----------- | ------------------------------------ | -| `GET` | :material-check: Fetch resource | -| `PUT` | :material-check-all: Update resource | -| `DELETE` | :material-close: Delete resource | \ No newline at end of file +Welcome to Amplitude Analytics. Use all these resources to do stuff. \ No newline at end of file diff --git a/docs/apis/attribution-api.md b/docs/apis/attribution-api.md new file mode 100644 index 000000000..5b96913d7 --- /dev/null +++ b/docs/apis/attribution-api.md @@ -0,0 +1,85 @@ +--- +title: Attribution API +--- + +## Attribution API + +--8<-- "includes/postman.md" + +The Attribution API is for sending attribution campaign events (identified by `idfa`, `idfv`, or `adid`) that contain attribution information. + +## Before you begin + +- This API doesn't use authorization, but uses your API key. If you're using Postman, set your API key in Amplitude API Environment variables. +- Before you send a request, make sure you're using the correct endpoint. + +| Region | Endpoint | +| --- | --- | +| Standard Server | | +| EU Residency Server | | + +## Considerations + + +- If attribution events can't be matched to an existing user, then they are held for up to 72 hours for potential user matching. If an event isn't logged for a matching user within 72 hours of receiving the attribution data, then the **attribution data is dropped**. +- For most of our partners, attribution is matched to Amplitude users/events via the Advertising ID (IDFA/IDFV or ADID). Therefore, you must send the Advertising ID for attribution requests and you must set the idfa, idfv, and adid fields in Amplitude as the Advertising ID. +- If you are using the iOS SDK or Android SDK, you can enable tracking of the Advertising ID by following the instructions [here](https://developers.amplitude.com/docs/ios#advertising-id). If you are using JS SDK or React Native, these do not have the functionality to collect Advertising ID automatically due to Google's and Apple's privacy rules around advertising ID and web tracking. You will have to send the Advertising ID through our HTTP API endpoint so that Amplitude can match attribution data/events. See keys in our [HTTP API V2](https://developers.amplitude.com/docs/http-api-v2) doc. + + + +### POST + +https://api.amplitude.com/attribution + +!!! example "Attribution Examples" + + === "iOS Attribution" + + ``` bash + POST /attribution HTTP/1.1 + Host: api.amplitude.com + Content-Length: 365 + + api_key={{api_key}}&event=%7B%22event_type%22%3A%22%5BYOUR%20COMPANY%5D%20Install%22%2C%20%22idfa%22%3A%20%22AEBE52E7-03EE-455A-B3C4-E57283966239%22%2C%20%22user_properties%22%3A%20%7B%22%5BYOUR%20COMPANY%5D%20media%20source%22%3A%20%22facebook%22%2C%20%22%5BYOUR%20COMPANY%5D%20campaign%22%3A%20%22refer-a-friend%22%7D%2C%20%22platform%22%3A%20%22ios%22%7D + + ``` + + === "Android Attribution" + + ```bash + + POST /attribution?api_key={{api_key}}&event={"event_type":"[YOUR COMPANY] Install","adid": "AEBE52E7-03EE-455A-B3C4-E57283966239", "user_properties": {"[YOUR COMPANY] media source": "facebook", "[YOUR COMPANY] campaign": "refer-a-friend"}, "platform": "android"} HTTP/1.1 + Host: api2.amplitude.com + ``` + + + +##### Required Event Argument Keys + +You must include the following keys within the event argument: + +| Required Key | Type | Description | Example | +| --- | --- | --- | --- | +| event_type | string | Prefix with brackets "[YOUR COMPANY]". | "[YOUR COMPANY] Install" | +| platform | string | Either "ios" or "android". | "ios" | +| idfa or idfv | string | (*required for iOS*) The Identifier for Advertiser or the Identifier for Vendor. | AEBE52E7-03EE-455A-B3C4-E57283966239 | +| adid | string | *(required for Android)* The Google AdID, or Amazon Advertising ID for Amazon devices. | AEBE52E7-03EE-455A-B3C4-E57283966239 | + +*Note: For iOS devices, you can send either the IDFA or the IDFV but you must send at least one.* + +##### Optional Event Argument Keys + +These optional keys are available. + +| Additional Key | Type | Description | Example | +| --- | --- | --- | --- | +| android_id | string | (Android) The Android ID | AEBE52E7-03EE-455A-B3C4-E57283966239 | +| user_properties | dictionary | A dictionary of attribution properties prefixed with brackets "[YOUR COMPANY]". | {"[YOUR COMPANY] media source": "Facebook"} | +| time | long | Timestamp of the event in milliseconds since epoch. | 1396381378123, will be set to the upload time by default | + +### Body (urlencoded) + +|Name| | Description| +|---|---|---| +|api_key| INSERT API KEY| Required. Your API key.| +|event| {"event_type":"[YOUR COMPANY] Install", "idfa": "AEBE52E7-03EE-455A-B3C4-E57283966239", "user_properties": {"[YOUR COMPANY] media source": "facebook", "[YOUR COMPANY] campaign": "refer-a-friend"}, "platform": "ios"}|Required. A request parameter representing the event, in JSON format.| \ No newline at end of file diff --git a/docs/apis/identify-api.md b/docs/apis/identify-api.md new file mode 100644 index 000000000..8fdcdc67c --- /dev/null +++ b/docs/apis/identify-api.md @@ -0,0 +1,3 @@ +--- +title: Identify API +--- \ No newline at end of file diff --git a/docs/apis/index.md b/docs/apis/index.md new file mode 100644 index 000000000..86925df3c --- /dev/null +++ b/docs/apis/index.md @@ -0,0 +1,5 @@ +--- +title: API References +--- + +Go see this stuff in Postman diff --git a/docs/data/ampli-sdk-overview.md b/docs/data/ampli-sdk-overview.md new file mode 100644 index 000000000..21d1a40ef --- /dev/null +++ b/docs/data/ampli-sdk-overview.md @@ -0,0 +1,70 @@ +--- +title: Ampli SDK Overview +description: An introduction to the Ampli SDK and CLI, and how they work with the Amplitude SDK. +--- + +The Ampli CLI, Ampli SDK, and Amplitude SDK work together to bring a tracking library into your project. + +Iteratively can generate a tracking library for many platforms and programming languages. The autogenerated +library, the Ampli SDK, is a lightweight wrapper over the Amplitude SDK that provides type-safety, supports linting, +and enables features like input validation. The code replicates the spec in the Tracking Plan and enforces its rules +and requirements. + +!!! tip + Visit the [ampli-examples GitHub repo](https://github.com/amplitude/ampli-examples) for example applications + that use the Ampli SDK. + +## Ampli CLI + +The Ampli CLI connects your codebase to your tracking plan. Each Source in your tracking plan represents a runtime +in which you wish to generate a strongly typed SDK. + +`ampli pull` will login and download the Ampli SDK for your current tracking plan. + +`ampli status` will verify implementation status of event tracking in your project. + +## Ampli SDK + +The Ampli SDK is a dynamic, code-generated SDK. It contains strong types for the events in your tracking plan, and +provides autocomplete and static type checking. + + ```js + ampli.songPlayed({ title: ‘Song #1’ }) + ``` + + The Ampli SDK is a light wrapper for untyped Amplitude SDKs. + + +## Amplitude SDK + +The Amplitude SDK is a static, open source SDK with untyped events. + + ```js + amplitude.logEvent({ event_type: ‘Song Played’, event_properties: { title: ‘Song #1’ }}) + ``` + +The Ampli SDK runs on top of the Amplitude SDK. The `client.instance` is the Amplitude SDK client that makes the underlying calls to Amplitude. If you don't specify a `client.instance`, Ampli uses a default instance. + +```js +class Ampli { + var client: AmplitudeClient; + + load(options) { + // use provided AmplitudeCLient if available, default otherwise + this.client = options.client.instance || Amplitude.getInstance().init(...); + } + + // track method wraps Amplitude SDK's logEvent() + track(event: Event) { + // use the Amplitude client to logEvents to the server + this.client.logEvent(event.eventType, event.eventProperties); + } + + // strongly typed event method wraps "generic" track + myEvent(properties: EventProperties) { + this.track(new MyEvent(properties)); + } +} +``` + +You can override the default client configuration with `client.config`. diff --git a/docs/data/android-ampli.md b/docs/data/android-ampli.md index 1bffbf7a5..d5c3ceae7 100644 --- a/docs/data/android-ampli.md +++ b/docs/data/android-ampli.md @@ -1,15 +1,371 @@ --- title: Android +description: Learn how to install and use the Ampli SDK for the Android Java and Kotlin runtimes. icon: material/android --- -# Android Ampli -```js -var http = require('http'); +!!! note + This page covers the Android Java and Kotlin runtimes. All (Itly) runtimes are deprecated. If you are still using an (Itly) runtime, see the **[migration guide](#migrating-from-an-itly-android-runtime)** to upgrade to the newest runtime. Docs for the Itly version are available **[here](browser.md)**. -http.createServer(function (req, res) { - res.writeHead(200, {'Content-Type': 'text/plain'}); - res.end('Hello World!'); -}).listen(8080); -``` \ No newline at end of file +Iteratively supports tracking analytics events from Android apps (API 22 and above) written in Kotlin and Java. + +In Kotlin and Java, the tracking library exposes a type-safe function for every event in your team’s tracking plan. The function’s arguments correspond to the event’s properties and are strongly typed to allow for code completion and compile-time checks. + +!!! tip + See example apps that use the Android Java and Kotlin runtimes on [GitHub](https://github.com/amplitude/ampli-examples/tree/main/android). + +## Installation + +These instructions are also available from the **Implementation** page of your Iteratively workspace. + +### Install the Ampli CLI + +If you haven't installed the Ampli CLI, [install it now](using-the-ampli-cli.md). + +### Install dependencies + +If you haven't already, install the core Amplitude SDK dependencies. + +=== "Java" + + ```bash + implementation 'com.amplitude:android-sdk:2.35.2' + implementation 'com.squareup.okhttp3:okhttp:4.9.3' + ``` + +=== "Kotlin" + + ```bash + implementation 'com.amplitude:android-sdk:2.35.2' + implementation 'com.squareup.okhttp3:okhttp:4.9.3' + ``` + +!!! note + If you're not already requesting the [INTERNET permission](https://developer.android.com/reference/android/Manifest.permission#INTERNET), add `` to your AndroidManifest.xml. + + +### Pull the SDK into your project + +At the project root, run `pull` command. + +```bash +ampli pull +``` + +This prompts you to log in to your workspace and select a source. + +=== "Java" + + ```bash + ➜ ampli pull sourcename + Ampli project is not initialized. No existing `ampli.json` configuration found. + ? Create a new Ampli project here? Yes + Organization: Amplitude + Workspace: My Workspace + Source: sourcename + Runtime: Android - Java + Branch: main + Pulling latest version (1.0.0)... + Tracking library generated successfully. + Path: ./src/itly + ``` + +=== "Kotlin" + + ```bash + ➜ ampli pull sourcename + Ampli project is not initialized. No existing `ampli.json` configuration found. + ? Create a new Ampli project here? Yes + Organization: Amplitude + Workspace: My Workspace + Source: sourcename + Runtime: Android - Kotlin + Branch: main + Pulling latest version (1.0.0)... + Tracking library generated successfully. + Path: ./src/itly + ``` + +## API + +### Load + +Initialize Ampli in your code. The `load()` method accepts configuration option arguments: + +=== "Java" + + ```java + import com.amplitude.ampli.*; + + Ampli.getInstance().load(appContext, new LoadOptions() + .setEnvironment(Ampli.Environment.PRODUCTION) + ); + ``` + +=== "Kotlin" + + ```java + import com.amplitude.ampli.* + + ampli.load(appContext, LoadOptions( + environment = Ampli.Environment.PRODUCTION + )); + ``` + +| Arg | Description | +|-|-| +| `appContext`| An object with a set of properties to add to every event sent by the Ampli SDK.

This option is available when there is at least one source template associated with your team's tracking plan.| +| `LoadOptions` | Optional. Specifies configuration options for the Ampli SDK.| +|`disabled`|Optional. Specifies whether the Ampli SDK does any work. When true, all calls to the Ampli SDK are no-ops. Useful in local or development environments.| +|`environment`|Optional. Defaults to `development`. Specifies the environment the Ampli SDK runs in: either `production` or `development`. Environment determines which Access Token is used to load the underlying analytics provider libraries. The option also determines safe defaults for handling event validation errors. In production, when the SDK detects an invalid event, it logs an error but stills let the event through. In development, the SDK throws an exception to alert you that something is wrong.| +|`client.instance`| Optional. Specifies an Amplitude instance. By default Ampli creates an instance for you.| +|`client.apiKey`|Optional. Specifies an API Key. This option overrides the default, which is the API Key configured in your tracking plan.| + +### Identify + +Call `identify()` to identify a user in your app and associate all future events with their identity, or to set their properties. + +Just as Ampli creates types for events and their properties, it creates types for user properties. + +The `identify()` function accepts an optional `userId`, optional user properties, and optional `options`. + +For example your tracking plan contains a user property called `userProp`. The property's type is a string. + +=== "Java" + + ```java + Ampli.getInstance().identify(userId, Identify.builder() + .userProp("A trait associated with this user") + .build() + ); + ``` + +=== "Kotlin" + + ```kotlin + ampli.identify(userId, Identify( + userProp = "A trait associated with this user" + )) + ``` + +The options argument allows you to pass [Amplitude fields](https://developers.amplitude.com/docs/http-api-v2#keys-for-the-event-argument) for this call, such as `deviceId`. + +=== "Java" + + ```java + Ampli.getInstance().identify( + userId, + Identify.builder() .userProp("A trait associated with this user").build(), + new EventOptions().setDeviceId(deviceId), + extra + ); + ``` + +=== "Kotlin" + + ```kotlin + ampli.identify( + userId, + Identify( + userProp = "A trait associated with this user", + ) + EventOptions(deviceId = "device-id"), + extra + ) + ``` + +### Group + +!!! note + This feature is available for Growth customers who have purchased the [Accounts add-on](https://help.amplitude.com/hc/en-us/articles/115001765532). + +Call `setGroup()` to associate a user with their group (for example, their department or company). The `setGroup()` function accepts a required `groupType`, and `groupName`. + +=== "Java" + + ```java + Ampli.getInstance().setGroup("groupType", "groupName"); + ``` + +=== "Kotlin" + + ```kotlin + ampli.setGroup("groupType", "groupName"); + ``` + +Amplitude supports assigning users to groups and performing queries, such as Count by Distinct, on those groups. If at least one member of the group has performed the specific event, then the count includes the group. + +For example, you want to group your users based on what organization they're in by using an 'orgId'. Joe is in 'orgId' '10', and Sue is in 'orgId' '15'. Sue and Joe both perform a certain event. You can query their organizations in the Event Segmentation Chart. + +When setting groups, define a `groupType` and `groupName`. In the previous example, 'orgId' is the `groupType` and '10' and '15' are the values for `groupName`. Another example of a `groupType` could be 'sport' with `groupName` values like 'tennis' and 'baseball'. + + Setting a group also sets the 'groupType:groupName' as a user property, and overwrites any existing groupName value set for that user's groupType, and the corresponding user property value. groupType is a string, and groupName can be either a string or an array of strings to indicate that a user is in multiple groups. For example, if Joe is in 'orgId' '10' and '20', then the `groupName` is '[10, 20]'). + + Your code might look like this: + +=== "Java" + + ```java + Ampli.getInstance().setGroup("orgID", ["10", "20"]); + ``` + +=== "Kotlin" + + ```kotlin + ampli.setGroup("orgId", ["10", "20"]); + ``` + +### Track + +To track an event, call the event's corresponding function. Every event in your tracking plan gets its own function in the Ampli SDK. The call is structured like this: + +=== "Java" + + ```java + Ampli.getInstance().eventName(EventName event, EventOptions options, MiddlewareExtra extra) + ``` + +=== "Kotlin" + + ```kotlin + ampli.eventName(...eventNameProperties) + ``` + +The `options` argument allows you to pass to pass [Amplitude fields](https://developers.amplitude.com/docs/http-api-v2#properties-1), like `deviceID`. The `extra` argument lets you pass data to middleware. + +For example, in the code snippet below, your tracking plan contains an event called `songPlayed`. The event is defined with two required properties: `songId` and `songFavorited.` The property type for `songId` is string, and `songFavorited` is a boolean. + + The event has one MiddlewareExtra defined: `extra`. Learn more about [middleware](middleware-overview.md). + +=== "Java" + + ```java + Ampli.getInstance().songPlayed(SongPlayed.builder() + .songId('songId') // String + .songFavorited(true) // Boolean + .build() + ); + ``` + +=== "Kotlin" + + ```kotlin + ampli.songPlayed( + songId = 'songId', // String, + songFavorited = true, // Boolean + ) + ``` + +Ampli also generates a class for each event. + +=== "Java" + + ```java + SongPlayed event = SongPlayed.builder() + .songId('songId') // String + .songFavorited(true) // Boolean + .build() + ``` + +=== "Kotlin" + + ```kotlin + val myEventObject = SongPlayed( + songId = 'songId', // String, + songFavorited = true, // Boolean + ); + ``` + +Send event objects using the generic track method. + +=== "Java" + + ```java + Ampli.getInstance().track(SongPlayed.builder() + .songId('songId') // String + .songFavorited(true) // Boolean + .build()) + ``` + +=== "Kotlin" + + ```kotlin + ampli.track(SongPlayed( + songId = 'songId', // String, + songFavorited = true, // Boolean + ); + ``` + +## Verify implementation status + +Verify that events are implemented in your code with the status command: + +```bash +ampli status +``` + +To update the implementation status in your tracking plan use the `--update` flag or `-u`: + +```bash +ampli status -u +``` +The output displays status and indicates what events are missing. + +```bash +➜ ampli status +✘ Verifying event tracking implementation in source code + ✔ Song Played (1 location) + ✘ Song Stopped Called when a user stops playing a song. +Events Tracked: 2 missed, 3 total +``` +Learn more about [`ampli status`](using-the-ampli-cli.md#ampli-status). + +## Migrating from an Itly Android runtime + +Migrate from an Itly Android runtime to Ampli by following these steps. + +1. Remove legacy Itly dependencies from your project. This includes anything with a `ly.iterative.itly`. + + ```bash + implementation "ly.iterative.itly:sdk-android:$itlySdkVersion" + implementation "ly.iterative.itly:plugin-iteratively:$itlySdkVersion" + implementation "ly.iterative.itly:plugin-schema-validator:$itlySdkVersion" + implementation "ly.iterative.itly:plugin-amplitude-android:$itlySdkVersion" + implementation "ly.iterative.itly:plugin-mixpanel-android:$itlySdkVersion" + implementation "ly.iterative.itly:plugin-mparticle-android:$itlySdkVersion" + implementation "ly.iterative.itly:plugin-segment-android:$itlySdkVersion" + ``` + +2. Add Amplitude dependencies. + + ```bash + implementation 'com.amplitude:android-sdk:2.35.2' + // https://github.com/amplitude/Amplitude-Android/issues/309 + implementation 'com.squareup.okhttp3:okhttp:4.9.3' + ``` + +3. Pull the latest Ampli SDK. + + ```bash + ampli pull + ``` + +4. Find and replace: + + **Kotlin and Java:** + - `import ly.iterative.itly.* => import com.amplitude.ampli.*` + - `itly.` => `ampli.` + - `itly.group(groupId)` => `ampli.setGroup(groupType, groupValue)` + + **Kotlin only:** + + - `Itly.load()` => `ampli.load()` + - `Itly.` => `ampli.` + + **Java only:** + + - `Itly.getInstance().load()` => `Ampli.getInstance().load()` + - `Itly.` => `Ampli.` + +5. See updated Event tracking details on your Implementation page in the web app. diff --git a/docs/data/android-legacy.md b/docs/data/android-legacy.md new file mode 100644 index 000000000..7bdf824fc --- /dev/null +++ b/docs/data/android-legacy.md @@ -0,0 +1,177 @@ +--- +title: Android (Legacy) +--- + +Iteratively supports tracking analytics events from Android apps (API 22 and above) written in Kotlin and Java. + +In Kotlin and Java, the tracking library exposes a type-safe function for every event in your team’s tracking plan. The function’s arguments correspond to the event’s properties and are strongly typed to allow for code completion and compile-time checks. + +## Installation + +### Generate the SDK + +If you have not yet installed the Ampli CLI, [install it now](/using-the-ampli-cli). + +To generate the Itly SDK, run `ampli pull {source}` in the top-most folder of your project. By default, the SDK will be generated in `./app/src/main/java/io/itly/`. + +:::note Tip +`{source}` is the name of the source you created in your tracking plan (e.g. `android`). +::: + +### Install dependencies + +To validate your analytics events, the Android SDK depends on [everit-org/json-schema](https://github.com/everit-org/json-schema) (Apache License 2.0). To install this dependency with Gradle: + +- Edit the project-level `build.gradle` file and add the following to `allprojects.repositories` (the JSON Schema validation package from Everit is published to JitPack): + +```bash +maven { url 'https://jitpack.io/' } +``` + +- Edit the app-level `build.gradle` file and add the following to `dependencies`: + +```bash +implementation 'com.github.everit-org.json-schema:org.everit.json.schema:1.12.0' +``` + +If you've configured Itly with Amplitude or Segment, you'll also install each configured provider's SDK. Edit the app-level `build.gradle` file and add the following to `dependencies`: + +```bash +implementation 'com.amplitude:android-sdk:2.14.1' +implementation 'com.segment.analytics.android:analytics:4.+' +``` + +### Import into your app + +To use the library, you'll need to import it first: + + + + +```java +import io.itly.*; +``` + + + + +```java +import io.itly.*; +``` + + + + +## API + +### Load + +Load the Itly SDK once when your application starts. The `load()` (`init()` in Java) method accepts an options object that lets you configure how the Itly SDK works: + +| Options | Description | +|-|-| +| `context`| An object with a set of properties to add to every event sent by the Itly SDK.

Only available if there is at least one [source template](/working-with-templates#adding-a-template-to-a-source) associated with your your team's tracking plan.| +| `disabled`| Specifies whether the Itly SDK does any work. When true, all calls to the Itly SDK will be no-ops. Useful in local or development environments.

Optional. Defaults to `false`.| +| `environment` | Specifies the environment the Itly SDK is running in: either `production` or `development`. Environment determines which Access Token is used to load the underlying analytics provider libraries.

The option also determines safe defaults for handling event validation errors. In production, when the SDK detects an invalid event, it will log an error but still let the event through. In development, the SDK will throw an exception to alert you that something is wrong.

Optional. Defaults to `development`.| +| `destinations` | Specifies any analytics provider-specific configuration. The Itly SDK passes these objects in when loading the underlying analytics provider libraries.

Optional.| +| `logger` | To log Itly's logs to a custom logger, implement the `ItlyLogger` protocol and set `logger` to an instance of your class. The Itly SDK will call into your class with all debug, info, warn, and error-level messages.

[Click here](https://bitbucket.org/seasyd/examples/src/master/android-kotlin/app/src/main/java/io/itly/ItlyBase.kt) to see an example written in Kotlin.

[Click here](https://bitbucket.org/seasyd/examples/src/master/android-java/app/src/main/java/io/itly/Itly.java) to see an example written in Java.

Optional. Defaults to standard out. | + +For example: + + + + +```java +Itly.load( + Options( + Context(version = "1.0"), + DestinationsOptions( + CustomOptions(MyCustomDestination()) + ) + ) +); +``` + + + + +```java +Itly.getInstance().init(ItlyOptions.builder() + .destinations(ItlyDestinations.builder() + .amplitude(new ItlyAmplitudeOptions(getApplicationContext())) + .build()) + .context(Context.builder() + .version("1.0") + .build()) + .logger(new Logger()) + .disabled(false) + .environment(ItlyOptions.Environment.DEVELOPMENT) + .build()); +``` + + + + +### Track + +To track an event, call the event’s corresponding function. Every event in your tracking plan gets its own function in the Itly SDK. + +For example, in the code snippet below, our tracking plan contains an event called `Activity Created`. The event was defined with one required property called `title`. The property's type is an enum. + + + + +```java +Itly.activityCreated( + title = ActivityCreated.Title.MAINACTIVITY +) +``` + + + + +```java +Itly.getInstance().trackActivityCreated(ActivityCreated.builder() + .title(ActivityCreated.Title.MAINACTIVITY) + .build()); +``` + + + + + + + + + diff --git a/docs/data/android.md b/docs/data/android.md new file mode 100644 index 000000000..38f9a3c2d --- /dev/null +++ b/docs/data/android.md @@ -0,0 +1,290 @@ +--- +id: android +title: Android (Itly) +--- + + + +:::note Previous Version +Still using the **Android (Legacy)** runtime? Docs for the previous version are available [here](android-legacy). +::: +:::note Migrating +Migrating from **Android (Legacy)** to the new **Android** runtime? A migration guide is available [here](#migrating-from-previous-version). +::: + +Iteratively supports tracking analytics events from Android apps (API 22 and above) written in Kotlin and Java. + +In Kotlin and Java, the tracking library exposes a type-safe function for every event in your team’s tracking plan. The function’s arguments correspond to the event’s properties and are strongly typed to allow for code completion and compile-time checks. + +## Installation + +### Generate the SDK + +If you have not yet installed the Ampli CLI, [install it now](/using-the-ampli-cli). + +To generate the Itly SDK, run `ampli pull {source}` in the top-most folder of your project. By default, the SDK will be generated in `./app/src/main/java/ly/iterative/itly/`. + +:::note Tip +`{source}` is the name of the source you created in your tracking plan (e.g. `android`). +::: + +### Install dependencies + +Edit the app-level build.gradle and add the following to `dependencies`: +- `implementation 'ly.iterative.itly:sdk-android:1.2+'` +- `implementation 'ly.iterative.itly:plugin-schema-validator:1.2+'` + +For Amplitude: +- `implementation 'ly.iterative.itly:plugin-amplitude-android:1.2+'` + +For Segment: +- `implementation 'ly.iterative.itly:plugin-segment-android:1.2+'` + +Note: if you're not already requesting the [INTERNET permission](https://developer.android.com/reference/android/Manifest.permission#INTERNET), add `` to your AndroidManifest.xml. + +### Import into your app + +To use the library, you'll need to import it first: + + + + +```java +import ly.iterative.itly.* +``` + + + + +```java +import ly.iterative.itly.* +``` + + + + +## API + +### Load + +Load the Itly SDK once when your application starts. The `load()` method accepts a few configuration option arguments: + + + + +```java +Itly.load( + Context(version = "1.0"), + DestinationsOptions( + AmplitudeOptions(applicationContext), + SegmentOptions(applicationContext) + ), + Options( + plugins = listOf(MyCustomDestination()) + ) +); +``` + + + + +```java +Itly.getInstance().load(Options.builder() + .destinations(Destinations.builder() + .custom(new CustomOptions(new MyCustomDestination())) + .build()) + .context(Context.builder() + .version("1.0") + .build()) + .logger(new Logger()) + .disabled(false) + .environment(ItlyOptions.Environment.DEVELOPMENT) + .build() +); +``` + + + + +In our example above, we defined a tracking plan in the Itly web application to: + - Include a property called *version* on every event + - Send events to Amplitude, Segment, and a custom destination + +As a result, our SDK will be initialized to: + - Set the required *version* property to 1.0 + - Send events to a custom destination implemented in the `MyCustomDestination` class + +

+ +| Arg | Description | +|-|-| +| `context`| An object with a set of properties to add to every event sent by the Itly SDK.

Only available if there is at least one [source template](/working-with-templates#adding-a-template-to-a-source) associated with your your team's tracking plan.| +| `destinations` | Specifies any analytics provider-specific configuration. The Itly SDK passes these objects in when loading the underlying analytics provider libraries.

Optional.| +| `options` | Specifies additional configuration options for the Itly SDK. Optional.

`disabled`
Specifies whether the Itly SDK does any work. When true, all calls to the Itly SDK will be no-ops. Useful in local or development environments.

Optional. Defaults to `false`.

`environment`
Specifies the environment the Itly SDK is running in: either `production` or `development`. Environment determines which Access Token is used to load the underlying analytics provider libraries.

The option also determines safe defaults for handling event validation errors. In production, when the SDK detects an invalid event, it will log an error but still let the event through. In development, the SDK will throw an exception to alert you that something is wrong.

Optional. Defaults to `development`.

`plugins`
An array of additional plugins to load into the Itly SDK. Plugins allow you to extend the Itly SDK's event validation and event tracking functionality with your own. For example, a plugin can be used to implement a custom destination or a custom event validator.

[Click here](#custom-destination) to learn about writing a custom destination plugin.

[Click here](https://bitbucket.org/seasyd/examples/src/master/android-kotlin-v3/app/src/main/java/ly/iterative/examples/kotlin/MyCustomDestination.kt) to see a sample custom destination plugin.

`logger`
To log Itly's logs to a custom logger, implement the `ItlyLogger` protocol and set `logger` to an instance of your class. The Itly SDK will call into your class with all debug, info, warn, and error-level messages.

[Click here](https://bitbucket.org/seasyd/examples/src/master/android-kotlin/app/src/main/java/io/itly/ItlyBase.kt) to see an example written in Kotlin.

[Click here](https://bitbucket.org/seasyd/examples/src/master/android-java/app/src/main/java/io/itly/Itly.java) to see an example written in Java.

Optional. Defaults to standard out. | + +:::note Note +The Itly SDK will automatically load and initialize your analytics providers' libraries using your each library's official installation instructions. +::: + +### Track + +To track an event, call the event’s corresponding function. Every event in your tracking plan gets its own function in the Itly SDK. + +For example, in the code snippet below, our tracking plan contains an event called `Activity Created`. The event was defined with one required property called `title`. The property's type is an enum. + + + + +```java +Itly.activityCreated( + title = ActivityCreated.Title.MAIN_ACTIVITY +) +``` + + + + +```java +Itly.getInstance().activityCreated(ActivityCreated.builder() + .title(ActivityCreated.Title.MAIN_ACTIVITY) + .build()); +``` + + + + +## Example + +Browse over to https://bitbucket.org/seasyd/examples/src/master/android-kotlin-v3/ to see an example of an instrumented Kotlin app, along with a sample implementation of the `MyCustomDestination` plugin. + +## Migrating from Previous Version + +The new Android SDK enjoys a simpler deployment model and introduces several new features to help developers implement product analytics: + +- Previously, the entire SDK was codegen'd into your source tree. In the new SDK, the SDK is split into two, allowing developers to call `ampli pull` freely without worrying about pulling down changes that may affect their application's behavior: + - The static, core SDK — open source and hosted on GitHub, and usable standalone, it contains all the logic needed to validate, track, and test analytics events. It is now semantically versioned and published to popular package repos, incl. Maven Central. + - The dynamic, codegen'd API — generated by `ampli pull` and placed into your source tree, the codegen'd API contains event classes and a corresponding strongly-typed API only. It delegates all work to the core SDK and contains no logic. +- The core SDK is now extensible via plugins. 5 plugins are currently available out of the box: a JSON Schema validation plugin, and 4 destination plugins: Segment, Amplitude, and Iteratively. +- When environment is set to `development`, the SDK will stream events to Amplitude's [User Lookup](https://help.amplitude.com/hc/en-us/articles/229313067-User-Look-Up) dashboard. The live debugger allows developers to watch tracked events, inspect their payloads, and detect validation problems. + +### Tracking Plan Changes + +- Update your source's runtime from **Android — Kotlin (Legacy)** to **Android — Kotlin** + +### Android Studio Changes + +- Open existing project +- Remove from app module's build.gradle (if applicable): + +```java +implementation 'com.networknt:json-schema-validator:1.0.29' +// If using Amplitude +implementation 'com.amplitude:android-sdk:2.14.1' +// If using Segment +implementation 'com.segment.analytics.android:analytics:4.+' +``` + +- Add to app module's build.gradle: + +```java +implementation 'ly.iterative.itly:sdk-android:1.2+' +implementation 'ly.iterative.itly:plugin-schema-validator:1.2+' +// If using Amplitude +implementation 'ly.iterative.itly:plugin-amplitude-android:1.2+' +// If using Segment +implementation 'ly.iterative.itly:plugin-segment-android:1.2+' +``` +- Pull down the new SDK inside your Android project's root folder + +```bash +ampli pull +``` + +- **Note**: the new SDK's package name is **ly.iterative.itly** instead of **io.itly**. The `ampli` CLI will display a one-time warning that the location of the SDK on the file system has changed. +- Delete the old SDK: + +```bash +rm -rf ./app/src/main/java/io/itly +rmdir ./app/src/main/java/io # in case it is now empty +``` + +- Global search and replace `import io.itly.*` with `import ly.iterative.itly.*` +- Custom destination adapters are now passed in as plugins rather than as part of `DestinationOptions`. If you are using a custom destination: + - Remove e.g. `CustomOptions(MyCustomDestination())` from `DestinationOptions` + - Add `arrayListOf(MyCustomDestination())` to `Options`: + + ```java + Itly.load( + DestinationsOptions( + AmplitudeOptions(applicationContext), + SegmentOptions(applicationContext) + ), + Options( + plugins = listOf(MyCustomDestination()) + ) + ); + ``` + +- Enum names are now properly snake cased. E.g. an enum value of "MainActivity" or "Main Activity" will be codegen'd as `MAIN_ACTIVITY` rather than `MAINACTIVITY`. If you've instrumented any events with multi-word enum properties, please update them. + +### Custom Destination Changes + +In the new SDK, custom destinations no longer implement an `IDestination` interface. They are now considered plugins and extend the `PluginBase` class. + +For example, the following custom destination: + +```java +package ly.iterative.examples.kotlin + +import io.itly.* + +class MyCustomDestination : IDestination { + override fun init() {} + override fun alias(userId: String, previousId: String?) {} + override fun identify(userId: String?, properties: ConvertibleProperties?) {} + override fun group(groupId: String, properties: ConvertibleProperties?) {} + override fun reset() {} + override fun track(userId: String?, eventName: String, properties: ConvertibleProperties?) {} +} +``` + +Now looks like this: + +```java +package ly.iterative.examples.kotlin + +import ly.iterative.itly.* +import ly.iterative.itly.core.Options + +class MyCustomDestination : Plugin("my-custom-destination") { + override fun load(options: Options) {} + override fun alias(userId: String, previousId: String?) {} + override fun identify(userId: String?, properties: Properties?) {} + override fun group(userId: String?, groupId: String, properties: Properties?) {} + override fun reset() {} + override fun track(userId: String?, event: Event) {} +} +``` + +`Properties` is a simple `Map`. `Event` exposes the event's `id`, `name`, and `properties`. \ No newline at end of file diff --git a/docs/data/browser-ampli.md b/docs/data/browser-ampli.md index 1d584439c..b8de175ae 100644 --- a/docs/data/browser-ampli.md +++ b/docs/data/browser-ampli.md @@ -1,58 +1,42 @@ --- -id: browser-ampli -title: Browser -tags: - - Data - - Kerfluffle +title: Browser +description: Learn how to install and use the Ampli SDK for the browser JavaScript and Typescript runtimes. icon: material/language-javascript --- ---8<-- "includes/growth.md" -!!!note - This doc covers the Ampli Browser runtime. The **Browser (Itly)** runtime is deprecated. See the [migration guide](#migrating-from-previous-version) to ugrade to the newest runtime. Docs for the Itly version are available [here](browser). - -Iteratively supports tracking analytics events from browser apps written in JavaScript (ES6 and above) and TypeScript (2.1 and above). The generated tracking library is packaged as an ES module. - -In TypeScript, the tracking library exposes a type-safe function for every event in your team’s tracking plan. The function’s arguments correspond to the event’s properties, and they are strongly typed to allow for code completion and compile-time checks. -!!! info inline end - Lorem ipsum dolor sit amet, consectetur - adipiscing elit. Nulla et euismod nulla. - Curabitur feugiat, tortor non consequat - finibus, justo purus auctor massa, nec - semper lorem quam in massa. - -Because JavaScript is not a type-safe language, the library doesn't expose type-safe functions for the events in your team’s tracking plan. Instead, the auto-generated library performs those checks at runtime. - -``` mermaid -stateDiagram-v2 - state fork_state <> - [*] --> fork_state - fork_state --> State2 - fork_state --> State3 - - state join_state <> - State2 --> join_state - State3 --> join_state - join_state --> State4 - State4 --> [*] -``` +!!! note + This page covers Browser JavaScript and TypeScript runtimes. All (Itly) runtimes are deprecated. If you are still using an (Itly) runtime, see the **[migration guide](#migrating-from-an-itly-browser-runtime)** to ugrade to the newest runtime. Docs for the Itly version are available **[here](browser.md)**. -## Installation -These instructions are also available from the **Implementation** page of your Iteratively workspace. +Iteratively supports tracking analytics events from Node.js apps written in JavaScript (ES6 and above) and TypeScript (2.1 and above). The generated tracking library is packaged as a CJS module. + +The tracking library exposes a function for every event in your team’s tracking plan. The function’s arguments correspond to the event’s properties and are strongly typed to allow for code completion and compile-time checks. + +??? tip "Enable real-time type checking for JavaScript" + Because JavaScript isn't a type-safe language, static type checking isn't built in like TypeScript. Some common IDEs allow for real-time type checks in JavaScript based on JSDoc. For a better development experience Ampli generates JSDocs for all methods and classes. + + To enable real-time type checking in VSCode for JavaScript: + + 1. Go to **Preferences > Settings** then search for **checkJs**. + 2. Select **JS/TS > Implicit Project Config: Check JS**. -??? note annotate "Note with a Custom Title" + After it's activated, type errors appear directly in the IDE. - Lorem ipsum dolor sit amet, (1) consectetur adipiscing elit. Nulla et - euismod nulla. Curabitur feugiat, tortor non consequat finibus, justo - purus auctor massa, nec semper lorem quam in massa. + Jetbrains provides similar support: - 1. :man_raising_hand: I'm an annotation! + 1. Go to **Preferences > Editor > Inspections > JavaScript and TypeScript > General**. + 2. In **Signature mismatch** and **Type mismatch**, set the **Severity** to Warning or Error based on your desired level of strictness. + + + +## Installation + +These instructions are also available from the **Implementation** page of your Iteratively workspace. ### Install the Ampli CLI -If you have not yet installed the Ampli CLI, [install it now](using-the-ampli-cli). +If you haven't installed the Ampli CLI, [install it now](using-the-ampli-cli.md). ### Install dependencies @@ -62,18 +46,16 @@ If you haven't already, install the core Amplitude SDK dependencies. ```bash npm install amplitude-js - ``` -=== "yarn" + ``` + +=== "Yarn" ```bash yarn add amplitude-js ``` - !!!note - - When using Ampli in the browser we recommend loading amplitude-js as a module rather than as a JS snippet. - + Note: when using Ampli in the browser, we recommend loading amplitude-js as a module rather than as a JS snippet. ### Pull the SDK into your project @@ -85,29 +67,23 @@ ampli pull This prompts you to log in to your workspace and select a source. -=== "JavaScript" +=== "TypeScript" - ```bash linenums="1" hl_lines="2 3" + ```bash ➜ ampli pull sourcename Ampli project is not initialized. No existing `ampli.json` configuration found. ? Create a new Ampli project here? Yes Organization: Amplitude Workspace: My Workspace Source: sourcename - Runtime: Browser - JavaScript + Runtime: Browser - TypeScript Branch: main Pulling latest version (1.0.0)... Tracking library generated successfully. - Path: ./src/itly #(1)! - ``` - - 1. This is a code annotation - ```bash - More Code I guess + Path: ./src/itly ``` - -=== "TypeScript" +=== "JavaScript" ```bash ➜ ampli pull sourcename @@ -116,17 +92,13 @@ This prompts you to log in to your workspace and select a source. Organization: Amplitude Workspace: My Workspace Source: sourcename - Runtime: Browser - TypeScript + Runtime: Browser - JavaScript Branch: main Pulling latest version (1.0.0)... Tracking library generated successfully. Path: ./src/itly ``` -#### This is a 4th level heading? - -Would we do this? Maybe? - ## API ### Load @@ -134,21 +106,25 @@ Would we do this? Maybe? Initialize Ampli in your code. The `load()` function accepts an options object to configure the SDK's behavior: -| Option | Type | Required | Description | -| -------------- | --------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `disabled` | Boolean | optional | Specifies whether the Itly SDK does any work. When `true`, all calls to the Itly SDK will be no-ops. Useful in local or development environments.

Defaults to `false`. | -| `environment` | String | optional | Specifies the environment the Itly SDK is running in: `production` or `development`.

Environment determines which Access Token is used to load the underlying analytics provider libraries.

The option also determines safe defaults for handling event validation errors. In production, when the SDK detects an invalid event, it will log an error but still let the event through. In development, the SDK will throw an exception to alert you that something is wrong.

Defaults to `development`. | +| Option | Type | Required | Description | +| --------------- | --------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `disabled` | Boolean | optional | Specifies whether the Ampli SDK does any work. When `true`, all calls to the Ampli SDK will be no-ops. Useful in local or development environments.

Defaults to `false`. | +| `environment` | String | optional | Specifies the environment the Ampli SDK is running in: `production` or `development`.

Environment determines which Access Token is used to load the underlying analytics provider libraries.

Defaults to `development`. | +| `client.apiKey` | String | optional |Specifies an API Key. This option overrides the default, which is the API Key configured in your tracking plan.| +|`client.instance`| AmplitudeClient | optional | Specifies an Amplitude instance. By default Ampli creates an instance for you.| +| `client.config` | Amplitude.Config | optional | Overrides the default configuration for the AmplitudeClient.| + ### Identify -Call `identify()` to identify a user in your application and associate all future events with their identity, or to set their traits. +Call `identify()` to identify a user in your app and associate all future events with their identity, or to set their properties. -Just as Iteratively creates types for events and their properties (and validates them at runtime), Iteratively creates types for user traits (and validates them at runtime). +Just as the Ampli SDK creates types for events and their properties, it creates types for user properties. -The `identify()` function accepts an optional `userId`, optional `traits`, and optional `options`. +The `identify()` function accepts an optional `userId`, optional user properties, and optional `options`. -For example, in the code snippet below, our tracking plan contains a user trait called `role`. The trait's type is a string. +For example, your tracking plan contains a user property called `role`. The property's type is a string. === "TypeScript" @@ -166,414 +142,212 @@ For example, in the code snippet below, our tracking plan contains a user trait }); ``` +The options argument allows you to pass [Amplitude fields](https://developers.amplitude.com/docs/http-api-v2#keys-for-the-event-argument) for this call, such as `deviceId`. -The `options` argument allows you to pass additional metadata about this call, such as a callback function or custom configuration, to the SDK's destinations. For example, to specify that Segment should only send data to Intercom and Google Analytics: - - - - -```js -ampli.identify( - 'user-id', - { - role: 'admin', - }, - { - segment: { - options: { - integrations: { - All: false, - Intercom: true, - 'Google Analytics': true, - }, - }, - }, - } -); -``` +=== "TypeScript" + + ```js + ampli.identify('user-id', { + role: 'admin' + }, { + deviceId: 'my-device-id' + }); + ``` - - - -```js -ampli.identify( - 'user-id', - { - role: 'admin', - }, - { - segment: { - options: { - integrations: { - All: false, - Intercom: true, - 'Google Analytics': true, - }, - }, - }, - } -); -``` - - +=== "JavaScript" + + ```js + ampli.identify('user-id', { + role: 'admin' + }, { + deviceId: 'my-device-id' + }); + ``` ### Group -!!!note +!!! note This feature is available for Growth customers who have purchased the [Accounts add-on](https://help.amplitude.com/hc/en-us/articles/115001765532). - Call `setGroup()` to associate a user with their group (for example, their department or company). The `setGroup()` function accepts a required `groupType`, and `groupName`. +=== "TypeScript" - - - -```js -ampli.setGroup('groupType', 'groupName'); -``` - - - + ```js + ampli.setGroup('groupType', 'groupName'); + ``` -```js -ampli.setGroup('groupType', 'groupName'); -``` +=== "JavaScript" - - + ```js + ampli.setGroup('groupType', 'groupName'); + ``` -Amplitude supports assigning users to groups and performing queries, such as Count by Distinct, on those groups. If at least one member of the group has performed the specific event, that group will be included in the count. +Amplitude supports assigning users to groups and performing queries, such as Count by Distinct, on those groups. If at least one member of the group has performed the specific event, then the count includes the group. -For example, you want to group your users based on what organization they are in by using an 'orgId'. Joe is in 'orgId' '10', and Sue is in 'orgId' '15'. Sue and Joe both perform a certain event. You can query their organizations in the Event Segmentation Chart. +For example, you want to group your users based on what organization they're in by using an 'orgId'. Joe is in 'orgId' '10', and Sue is in 'orgId' '15'. Sue and Joe both perform a certain event. You can query their organizations in the Event Segmentation Chart. When setting groups, define a `groupType` and `groupName`. In the previous example, 'orgId' is the `groupType` and '10' and '15' are the values for `groupName`. Another example of a `groupType` could be 'sport' with `groupName` values like 'tennis' and 'baseball'. - Setting a group also sets the 'groupType:groupName' as a user property, and overwrites any existing groupName value set for that user's groupType, and the corresponding user property value. groupType is a string, and groupName can be either a string or an array of strings to indicate a user being in multiple groups. For example, if Joe is in 'orgId' '10' and '16', then the `groupName` is '[10, 16]'). - - Your code might look like this: + Setting a group also sets the 'groupType:groupName' as a user property, and overwrites any existing groupName value set for that user's groupType, and the corresponding user property value. groupType is a string, and groupName can be either a string or an array of strings to indicate that a user is in multiple groups. For example, if Joe is in 'orgId' '10' and '20', then the `groupName` is '[10, 20]'). + Your code might look like this: - - - -```js -ampli.setGroup('orgId', '[10,16]'); -``` - - - - -```js -ampli.setGroup('orgId', '[10,16]'); -``` +=== "TypeScript" - - - --- need help with the group options stuff. Could use a good example. - -The `options` argument lets you pass Amplitude field options. For example, to specify that Segment should invoke a callback function when it's done calling `group()`: - - - - -```js -itly.group( - 'group-id', - { name: 'Iteratively, Inc.' }, - { - segment: { - callback: () => console.log('Segment is done!'), - }, - } -); -``` + ```js + ampli.setGroup('orgId', ['10', '20']); + ``` - - - -```js -itly.group( - 'group-id', - { name: 'Iteratively, Inc.' }, - { - segment: { - callback: () => console.log('Segment is done!'), - }, - } -); -``` +=== "JavaScript" - - + ```js + ampli.setGroup('orgId', ['10', '20']); + ``` ### Track -To track an event, call the event’s corresponding function. Every event in your tracking plan gets its own function in the Ampli SDK. The call is structured like this: - - - - -```js -ampli.eventName(userId: string, properties: eventProperties, options: AmplitudeEventFields, extra: MiddlewareExtra) -``` +To track an event, call the event's corresponding function. Every event in your tracking plan gets its own function in the Ampli SDK. The call is structured like this: - - +=== "TypeScript" -```js -ampli.eventName(userId: string, properties: eventProperties, options: AmplitudeEventFields, extra: MiddlewareExtra) -``` + ```js + ampli.eventName(properties: EventNameProperties, options: EventOptions, extra: MiddlewareExtra) + ``` - - +=== "JavaScript" -For example, in the code snippet below, our tracking plan contains an event called `songPlayed`. The event was defined with two required properties: `songId` and `songFavorited.` The property type for `songId` is string, and `songFavorited` is a boolean. + ```js + ampli.eventName(properties: EventNameProperties, options: EventOptions, extra: MiddlewareExtra) + ``` -The event also has two AmplitudeEventFields defined: `price`, and `quantity`. Learn more about AmplitudeEventFields [here](https://developers.amplitude.com/docs/http-api-v2#properties-1). --- need to add bit about middleware. +The `properties` argument passes event properties. +The `options` argument allows you to pass to pass [Amplitude fields](https://developers.amplitude.com/docs/http-api-v2#properties-1), like `price`, `quanity` and `revenue`. - - +The `extra` argument lets you pass data to middleware. -```js -ampli.songPlayed( { - songId: 'songId', // string, - songFavorited: true, // boolean -}, { - price: 1.23, - quantity: 2 -}, { - myMiddleware: "a value to send to middleware" -}) -``` +For example, in the code snippet below, your tracking plan contains an event called `songPlayed`. The event is defined with two required properties: `songId` and `songFavorited.` The property type for `songId` is string, and `songFavorited` is a boolean. - - - -```js -ampli.songPlayed( { - songId: 'songId', // string, - songFavorited: true, // boolean -}, { - price: 1.23, - quantity: 2 -}, { - myMiddleware: "a value to send to middleware" -}) -``` +The event has an Amplitude field defined: `deviceId`. Learn more about Amplitude fields [here](https://developers.amplitude.com/docs/http-api-v2#properties-1). The event has one MiddlewareExtra defined: `myMiddleware`. Learn more about [Middleware](#middleware). - - +=== "TypeScript" + ```js + ampli.songPlayed( { + songId: 'songId', // string, + songFavorited: true, // boolean + }, { + deviceId: 'a-device-id', + }, { + myMiddleware: { myMiddlewareProp: "value to send to middleware" } + }); + ``` -Ampli also generates a class for each event. +=== "JavaScript" - - - -```js -const myEventObject = new Ampli.SongPlayed({ - songId: 'songId', // string, - songFavorited: true, // boolean -}); -``` + ```js + ampli.songPlayed( { + songId: 'songId', // string, + songFavorited: true, // boolean + }, { + deviceId: 'a-device-id', + }, { + myMiddleware: { myMiddlewareProp: "value to send to middleware" } + }); + ``` - - -```js -const myEventObject = new Ampli.SongPlayed({ - songId: 'songId', // string, - songFavorited: true, // boolean -}); -``` - - - -Event objects can be tracked using the Ampli `track`: - - - - -```js -ampli.track(new Ampli.SongPlayed({ - songId: 'songId', // string, - songFavorited: true, // boolean -})); -``` +Ampli also generates a class for each event. - - +=== "TypeScript" -```js -ampli.track(new Ampli.SongPlayed({ - songId: 'songId', // string, - songFavorited: true, // boolean -})); -``` + ```js + const myEventObject = new SongPlayed({ + songId: 'songId', // string, + songFavorited: true, // boolean + }); + ``` - - - -
- - -- all of this stuff has changed. See slack for info from justin. Options AmplitudeFields are all the fields listed in HTTP V2 Api. Add the 3rd Param: Middlewareextra it's unstructured data that you can send to middleware. - -The `options` argument allows you to pass additional metadata about this call, such as a callback function or custom configuration, to the SDK's destinations. For example, to specify that Segment should only track the event to Intercom and Google Analytics: - - - - -```js -itly.userSignedIn( - { platform: 'web' }, - { - segment: { - options: { - integrations: { - All: false, - Intercom: true, - 'Google Analytics': true, - }, - }, - }, - } -); -``` +=== "JavaScript" - - - -```js -itly.userSignedIn( - { platform: 'web' }, - { - segment: { - options: { - integrations: { - All: false, - Intercom: true, - 'Google Analytics': true, - }, - }, - }, - } -); -``` + ```js + const myEventObject = new SongPlayed({ + songId: 'songId', // string, + songFavorited: true, // boolean + }); + ``` - - -## Middleware +Track Event objects using Ampli `track`: --- Placeholder! Get the rest of the info from chat with Justin. +=== "TypeScript" -## Migrating from Previous Version + ```js + ampli.track(new SongPlayed({ + songId: 'songId', // string, + songFavorited: true, // boolean + })); + ``` -### Introduction +=== "JavaScript" -The new Browser SDK introduces several new features to help developers implement product analytics. + ```js + ampli.track(new SongPlayed({ + songId: 'songId', // string, + songFavorited: true, // boolean + })); + ``` -### Tracking Plan Changes +## Verify implementation status -- Update your source's runtime to **Browser — JavaScript** or **Browser — TypeScript** (from **Browser — JavaScript (Legacy)** or **Browser — TypeScript (Legacy)**, respectively) +Verify that events are implemented in your code with the status command: -### CLI & Code Changes +```bash +ampli status +``` -- Make sure you have downloaded the [Ampli CLI](/using-the-ampli-cli) +To update the implementation status in your tracking plan use the `--update` flag or `-u`: -- Pull down the new SDK inside your project's folder (the one with the .itlyrc file): +```bash +ampli status -u +``` +The output displays status and indicates what events are missing. ```bash -ampli pull +➜ ampli status +✘ Verifying event tracking implementation in source code + ✔ Song Played (1 location) + ✘ Song Stopped Called when a user stops playing a song. +Events Tracked: 2 missed, 3 total ``` +Learn more about [`ampli status`](using-the-ampli-cli.md#ampli-status). + +## Migrating from an Itly Browser runtime + +Migrate from an Itly Browser runtime to Ampli by following these steps. -- Validation options are now an enum rather than an object with three boolean fields: +1. Update Source runtime. In the web app open the **Connections > Source** modal. From the dropdown, update the source to a non-`(Itly)` runtime. +2. Go to the **Implementation** page, then select the new Source for detailed setup and usage instructions. +3. Remove legacy Itly dependencies from your project. This includes anything that contains `@itly`: - - Remove e.g. `validation: { disabled: true }` from `options` passed to `load()` - - Add `validation: Validation.Disabled` instead, e.g.: + `yarn remove @itly/sdk @itly/plugin-schema-validator @itly/plugin-amplitude ...` - ```js - itly.load({ - validation: Validation.Disabled, - }); - ``` +4. Add Amplitude dependencies: + + `yarn add amplitude-js` -- The SDK's plugins no longer initialize analytics provider libraries if they're detected on `window`. In version 1.0, if the SDK's plugin detected that a library has already loaded, it would skip loading it, but would still initialize it using the access key provided in the tracking plan. In the 2.0 version of the SDK, this is no longer the case, and Iteratively simply reuses the instance from `window` as is. +5. Pull the latest Ampli SDK: -### Custom Destination + `ampli pull` -In the new SDK, custom destinations look almost identical. The following changes were made: +6. Find and replace: + - `import { itly } from '../itly'` => `import { ampli } from '../ampli'` + - `itly.group(userId, groupId) => ampli.setGroup(userId, groupType, groupName)` + - `itly.load()` => `ampli.load()` + - All `itly.` with `ampli.` -- The `PluginBase` class your plugin extends was renamed to `Plugin` -- The `id()` method was removed. To set a plugin's ID, implement a constructor and call `super('your-plugin-id')` instead -- All plugin methods (except for `load()`, `reset()`, and `flush()`) now accept a new optional argument called `options`. The argument carries additional metadata that the plugin can use to further customize its behavior for a particular identify, track, group, etc. call. The values in this additional metadata object are provided by the analytics tracking developer when making the original call and are passed all the way through to your plugin. +7. See updated Event tracking details on your Implementation page in the web app. diff --git a/docs/data/browser-legacy.md b/docs/data/browser-legacy.md new file mode 100644 index 000000000..73b6a3ece --- /dev/null +++ b/docs/data/browser-legacy.md @@ -0,0 +1,386 @@ +--- +id: browser-legacy +title: Browser (Legacy) +--- + + + +Iteratively supports tracking analytics events from browser apps written in JavaScript (ES6 and above) and TypeScript (2.1 and above). The generated tracking library is packaged as an ES module. + +In TypeScript, the tracking library exposes a type-safe function for every event in your team’s tracking plan. The function’s arguments correspond to the event’s properties and are strongly typed to allow for code completion and compile-time checks. + +Since JavaScript is not a type-safe language, the library won't expose type-safe functions for the events in your team’s tracking plan. Instead, the auto-generated library performs those checks at runtime. + +## Installation + +### Generate the SDK + +If you have not yet installed the Ampli CLI, [install it now](using-the-ampli-cli). + +To generate the Itly SDK, run `ampli pull {source}` in the folder with your package.json file. By default, the SDK will be generated in `./src/itly/`. + +:::note Tip +`{source}` is the name of the source you created in your tracking plan (e.g. `browser`). +::: + +### Install dependencies + +The generated Itly SDK has several dependencies. To install them, run: + + + + +```bash +npm install @itly/sdk \ + @itly/plugin-schema-validator +``` + + + + +```bash +yarn add @itly/sdk \ + @itly/plugin-schema-validator +``` + + + + +If you're using Amplitude or Segment, the SDK will also depend on a few additional plugins that must be installed before your project will compile: + + + + +```bash +# if you're using Segment +npm install @itly/plugin-segment +# if you're using Amplitude +npm install @itly/plugin-amplitude +``` + + + + +```bash +# if you're using Segment +yarn add @itly/plugin-segment +# if you're using Amplitude +yarn add @itly/plugin-amplitude +``` + + + + +:::note Note +- To validate your analytics events, the SDK depends on [ajv](https://github.com/ajv-validator/ajv) (MIT). +::: + +### Import into your app + +To use the library, you'll need to import it first: + + + + +```js +import itly from './itly'; +``` + + + + +```js +import itly from './itly'; +``` + + + + +You can now call functions on `itly` directly. + +:::note Note +Adjust the relative import path to the location where `ampli pull` generated your SDK. By default, this path is `./src/itly`. +::: + +## API + +### Load + +Load the Itly SDK once when your application starts. The `load()` function accepts an options object to configure the SDK's behavior: + + + + +```js +itly.load({ environment: 'development' }); +``` + + + + +```js +itly.load({ environment: 'development' }); +``` + + + + +| Option |||| +|-|-|-|-| +| `context` | Object
`Context` | required | An object with a set of properties to add to every event sent by the Itly SDK.

Only available if there is at least one [source template](working-with-templates#adding-a-template-to-a-source) associated with your your team's tracking plan.| +| `disabled` | Boolean | optional | Specifies whether the Itly SDK does any work. When `true`, all calls to the Itly SDK will be no-ops. Useful in local or development environments.

Defaults to `false`.| +| `environment` | String | optional | Specifies the environment the Itly SDK is running in: `production` or `development`.

Environment determines which Access Token is used to load the underlying analytics provider libraries.

The option also determines safe defaults for handling event validation errors. In production, when the SDK detects an invalid event, it will log an error but still let the event through. In development, the SDK will throw an exception to alert you that something is wrong.

Defaults to `development`.| +| `destinations` | Object
`DestinationsOptions` | optional | Specifies any analytics provider-specific configuration. The Itly SDK passes these objects in when loading the underlying analytics provider libraries.| +| `validation` | Object
`ValidationOptions` | optional | Configures the Itly SDK's behavior when events or traits fail validation against your tracking plan. Supports the following properties:

`disabled`
Disables validation altogether. Defaults to `false`.

`trackInvalid`
Secifies whether events that failed validation should still be tracked. Defaults to `false` in development, `true` in production.

`errorOnInvalid`
Specifies whether the SDK should throw an exception when validation fails. Defaults to `true` in development, `false` in production.| +| `plugins` | Array | optional | An array of additional plugins to load into the Itly SDK. Plugins allow you to extend the Itly SDK's event validation and event tracking functionality with your own. For example, a plugin can be used to implement a custom destination or a custom event validator.

[Click here](#custom-destination) to learn about writing a custom destination plugin.

[Click here](https://bitbucket.org/seasyd/examples/src/master/browser-javascript/src/CustomDestination.js) to see a sample custom destination plugin written in JavaScript.

[Click here](https://bitbucket.org/seasyd/examples/src/master/browser-typescript/src/CustomDestination.ts) to see a sample custom destination plugin written in TypeScript.| + +:::note Note +The Itly SDK will automatically load and initialize your analytics providers' libraries using your each library's official installation instructions. +::: + +### Identify + +Call `identify()` to identify a user in your application and associate all future events with their identity, or to set their traits. + +Just as Iteratively creates types for events and their properties (and validates them at runtime), Iteratively creates types for user traits (and validates them at runtime). + +The `identify()` function accepts an optional `userId` and optional `traits`. + +For example, in the code snippet below, our tracking plan contains a user trait called `role`. The trait's type is a string. + + + + +```js +itly.identify('user-id', { role: 'admin' }); +``` + + + + +```js +itly.identify('user-id', { role: 'admin' }); +``` + + + + +### Group + +Call `group()` to associate a user with their group (for example, their department or company), or to set the group's traits. + +Just as Iteratively creates types for events and their properties (and validates them at runtime), Iteratively creates types for group traits (and validates them at runtime). + +The `group()` function accepts a required `groupId` and optional `traits`. + +For example, in the code snippet below, our tracking plan contains a group trait called `name`. The trait's type is a string. + + + + +```js +itly.group('group-id', { name: 'Iteratively, Inc.' }); +``` + + + + +```js +itly.group('group-id', { name: 'Iteratively, Inc.' }); +``` + + + + +### Track + +To track an event, call the event’s corresponding function. Every event in your tracking plan gets its own function in the Itly SDK. + +For example, in the code snippet below, our tracking plan contains an event called `User Signed In`. The event was defined with one required property called `platform`. The property's type is a string. + + + + +```js +itly.userSignedIn({ platform: 'web' }); +``` + + + + +```js +itly.userSignedIn({ platform: 'web' }); +``` + + + + + + +## Custom Destination + +:::note Advanced +If you're using Iteratively with Amplitude or Segment, you can safely skip this section! +::: + +To send clean, valid events to custom analytics destinations, or those not yet supported by the Itly SDK natively, the SDK is extensible via plugins. Writing a plugin is easy! Extend the `PluginBase` class, override `track()`, and include your new plugin in the `plugins` array when calling `itly.load()`. + +Plugins allow you to implement your own processing logic for analytics tracking. When you call a function on the Itly SDK, the SDK will first validate your event (or user, group, and page properties) against your tracking plan, then call into your plugin's implementation. + +The following functions are available to override when developing your plugin. Only override those functions that matter to your custom destination. + +:::note Examples +A sample custom destination plugin is available [here](https://bitbucket.org/seasyd/examples/src/master/browser-javascript/src/CustomDestination.js) in JavaScript and [here](https://bitbucket.org/seasyd/examples/src/master/browser-typescript/src/CustomDestination.ts) in TypeScript. +::: + +#### ID +Every plugin has a unique ID. To set one, override `id()` and return your plugin's ID. The function has the following signature: + +```javascript +id(): string; +``` +
+ +#### Load +Called when the Itly SDK is being loaded and is ready to load your plugin. The function has the following signature: + +```javascript +load(options: Options): void; +``` + +| Argument |||| +|-|-|-|-| +| `options` | Object
`Options` | required | The [same](#load) configuration object passed to `itly.load()` when the SDK was being initialized. | +
+ +#### Alias +Called when Itly SDK's `alias()` function is called to associate one user ID with another (typically a known user ID with an anonymous one). The `alias()` function has the following signature: + +```javascript +alias(userId: string, previousId: string | undefined): void; +``` + +| Argument | Type || Description | +|-|-|-|-| +| `userId` | String | required | The ID that the user will be identified by going forward. This is typically the user's database ID (as opposed to an anonymous ID), or their updated ID (for example, if the ID is an email address which the user just updated). | +| `previousId` | String | optional | The ID the user has been identified by so far. | +
+ +#### Identify +Called when Itly SDK's `identify()` function is called to identify a user with a specific ID or set the user's traits. The `identify()` function has the following signature: + +```javascript +identify(userId: string | undefined, properties: Properties | undefined): void; +``` + +| Argument | Type || Description | +|-|-|-|-| +| `userId` | String | optional | The user's ID, if it was provided to `itly.identify()`. The ID may not be provided if `identify()` was called only to update the user's traits. | +| `properties` | Object
`Properties` | optional | The user's traits. | +
+ +#### Track +Called when an event is tracked. The function receives a validated event with its complete set of properties (a combination of the event's own properties any any other properties associated with the source via a [source template](working-with-templates#adding-a-template-to-a-source)) The `track()` function has the following signature: + +```javascript +track(userId: string | undefined, event: Event): void; +``` + +| Argument | Type || Description | +|-|-|-|-| +| `userId` | String | optional | Always undefined in the Browser SDK. | +| `event` | Object
`Event` | required | The event that was tracked by the Itly SDK. The event object contains the following properties:

`name`
The event's name.

`properties`
The event's properties.

`id`
The event's unique ID in Iteratively.

`version`
The event's version, e.g. 2.0.1.

| +
+ +#### Group +Called when Itly SDK's `group()` function is called to associate the user with a specific account (for example, their department or company) or set the group's properties. The `group()` function has the following signature: + +```javascript +group(userId: string | undefined, groupId: string, properties?: Properties | undefined): void; +``` + +| Argument | Type || Description | +|-|-|-|-| +| `userId` | String | optional | Always undefined in the Browser SDK. | +| `groupId` | String | required | The ID of the group (for example, the user's department or company) to associate the user with. | +| `properties` | Object
`Properties` | optional | The group's traits. | +
+ +#### Page +Called when Itly SDK's `page()` function is called to track a page view in a web application. The `page()` function has the following signature: + +```javascript +page(userId: string | undefined, category: string | undefined, name: string | undefined, properties: Properties | undefined): void; +``` + +| Argument | Type || Description | +|-|-|-|-| +| `userId` | String | optional | Always undefined in the Browser SDK. | +| `category` | String | optional | The page's category. Useful when many pages might live under a single category. | +| `name` | String | optional | The page's name. | +| `properties` | Object
`Properties` | optional | The page's traits. | +
+ +#### Reset +Called when Itly SDK's `reset()` function is called to reset the SDK's (and all plugins') state. This method is usually called when a user logs out. The `reset()` function has the following signature: + +```javascript +reset(): void; +``` + + diff --git a/docs/data/browser.md b/docs/data/browser.md new file mode 100644 index 000000000..6d54b365e --- /dev/null +++ b/docs/data/browser.md @@ -0,0 +1,678 @@ +--- +id: browser +title: Browser (Itly) +--- + + + + +:::note Upgrade to the [Browser (Ampli)](/browser-ampli.mdx) runtime. The Browser (Itly) runtime is deprecated.::: + +:::note Previous Version +Still using the **Browser (Legacy)** runtime? Docs for the previous version are available [here](browser-legacy). +::: +:::note Migrating +Migrating from **Browser (Legacy)** to the new **Browser** runtime? A migration guide is available [here](#migrating-from-previous-version). +::: + +Iteratively supports tracking analytics events from browser apps written in JavaScript (ES6 and above) and TypeScript (2.1 and above). The generated tracking library is packaged as an ES module. + +In TypeScript, the tracking library exposes a type-safe function for every event in your team’s tracking plan. The function’s arguments correspond to the event’s properties and are strongly typed to allow for code completion and compile-time checks. + +Since JavaScript is not a type-safe language, the library won't expose type-safe functions for the events in your team’s tracking plan. Instead, the auto-generated library performs those checks at runtime. + +## Installation + +### Generate the SDK + +If you have not yet installed the Ampli CLI, [install it now](using-the-ampli-cli). + +To generate the Itly SDK, run `ampli pull {source}` in the folder with your package.json file. By default, the SDK will be generated in `./src/itly/`. + +:::note Tip +`{source}` is the name of the source you created in your tracking plan (e.g. `browser`). +::: + +### Install dependencies + +:::note Tip +When you run `ampli pull {source}` for the first time, the Ampli CLI will provide an npm/yarn install command specific to your tracking plan that will include all required dependencies. +::: + +The generated Itly SDK has several dependencies. To install them, run: + + + + +```bash +npm install @itly/sdk \ + @itly/plugin-schema-validator +``` + + + + +```bash +yarn add @itly/sdk \ + @itly/plugin-schema-validator +``` + + + + +If you're using Amplitude or Segment the SDK will also depend on a few additional plugins that must be installed before your project will compile: + + + + +```bash +# if you're using Segment +npm install @itly/plugin-segment +# if you're using Amplitude +npm install @itly/plugin-amplitude +``` + + + + +```bash +# if you're using Segment +yarn add @itly/plugin-segment +# if you're using Amplitude +yarn add @itly/plugin-amplitude +``` + + + + +:::note Note +- To validate your analytics events, the SDK depends on [ajv](https://github.com/ajv-validator/ajv) (MIT). +::: + +### Import into your app + +To use the library, you'll need to import it first: + + + + +```js +import itly from './itly'; +``` + + + + +```js +import itly from './itly'; +``` + + + + +You can now call functions on `itly` directly. + +:::note Note +Adjust the relative import path to the location where `ampli pull` generated your SDK. By default, this path is `./src/itly`. +::: + +## API + +### Load + +Load the Itly SDK once when your application starts. The `load()` function accepts an options object to configure the SDK's behavior: + + + + +```js +itly.load({ environment: 'development' }); +``` + + + + +```js +itly.load({ environment: 'development' }); +``` + + + + +| Option |||| +|-|-|-|-| +| `context` | Object
`Context` | required | An object with a set of properties to add to every event sent by the Itly SDK.

Only available if there is at least one [source template](working-with-templates#adding-a-template-to-a-source) associated with your your team's tracking plan.| +| `disabled` | Boolean | optional | Specifies whether the Itly SDK does any work. When `true`, all calls to the Itly SDK will be no-ops. Useful in local or development environments.

Defaults to `false`.| +| `environment` | String | optional | Specifies the environment the Itly SDK is running in: `production` or `development`.

Environment determines which Access Token is used to load the underlying analytics provider libraries.

The option also determines safe defaults for handling event validation errors. In production, when the SDK detects an invalid event, it will log an error but still let the event through. In development, the SDK will throw an exception to alert you that something is wrong.

Defaults to `development`.| +| `destinations` | Object
`DestinationsOptions` | optional | Specifies any analytics provider-specific configuration. The Itly SDK passes these objects in when loading the underlying analytics provider libraries.| +| `validation` | Enum
`Validation` | optional | Configures the Itly SDK's behavior when events or traits fail validation against your tracking plan. Supports the following options:

`Disabled`
Disables validation altogether.

`TrackOnInvalid`
Specifies whether events that failed validation should still be tracked.

`ErrorOnInvalid`
Specifies whether the SDK should throw an exception when validation fails.

Defaults to `ErrorOnInvalid` in development, `TrackOnInvalid` in production.| +| `plugins` | Array | optional | An array of additional plugins to load into the Itly SDK. Plugins allow you to extend the Itly SDK's event validation and event tracking functionality with your own. For example, a plugin can be used to implement a custom destination or a custom event validator.

[Click here](#custom-destination) to learn about writing a custom destination plugin.

[Click here](https://bitbucket.org/seasyd/examples/src/master/browser-javascript-v3/src/CustomDestination.js) to see a sample custom destination plugin written in JavaScript.

[Click here](https://bitbucket.org/seasyd/examples/src/master/browser-typescript-v3/src/CustomDestination.ts) to see a sample custom destination plugin written in TypeScript.| + +:::note Note +By default, the Itly SDK will automatically load and initialize your analytics providers' libraries using each library's official installation instructions. + +However, if the Itly SDK detects that your analytics provider's library has already been loaded (typically by checking whether it's available on `window`), it will skip loading and initializing it and will simply reuse it. This means your can easily and safely add Iteratively to your existing codebase without any other changes; Iteratively will run side-by-side with your existing instrumentation. +::: + +### Identify + +Call `identify()` to identify a user in your application and associate all future events with their identity, or to set their traits. + +Just as Iteratively creates types for events and their properties (and validates them at runtime), Iteratively creates types for user traits (and validates them at runtime). + +The `identify()` function accepts an optional `userId`, optional `traits`, and optional `options`. + +For example, in the code snippet below, our tracking plan contains a user trait called `role`. The trait's type is a string. + + + + +```js +itly.identify('user-id', { role: 'admin' }); +``` + + + + +```js +itly.identify('user-id', { role: 'admin' }); +``` + + + + +
+ +The `options` argument allows you to pass additional metadata about this call, such as a callback function or custom configuration, to the SDK's destinations. For example, to specify that Segment should only send data to Intercom and Google Analytics: + + + + +```js +itly.identify( + 'user-id', + { + role: 'admin', + }, + { + segment: { + options: { + integrations: { + 'All': false, + 'Intercom': true, + 'Google Analytics': true + } + } + } + } +); +``` + + + + +```js +itly.identify( + 'user-id', + { + role: 'admin', + }, + { + segment: { + options: { + integrations: { + 'All': false, + 'Intercom': true, + 'Google Analytics': true + } + } + } + } +); +``` + + + + +### Group + +Call `group()` to associate a user with their group (for example, their department or company), or to set the group's traits. + +Just as Iteratively creates types for events and their properties (and validates them at runtime), Iteratively creates types for group traits (and validates them at runtime). + +The `group()` function accepts a required `groupId`, optional `traits`, and optional `options`. + +For example, in the code snippet below, our tracking plan contains a group trait called `name`. The trait's type is a string. + + + + +```js +itly.group('group-id', { name: 'Iteratively, Inc.' }); +``` + + + + +```js +itly.group('group-id', { name: 'Iteratively, Inc.' }); +``` + + + + +
+ +The `options` argument allows you to pass additional metadata about this call, such as a callback function or custom configuration, to the SDK's destinations. For example, to specify that Segment should invoke a callback function when it's done calling `group()`: + + + + +```js +itly.group('group-id', { name: 'Iteratively, Inc.' }, { + segment: { + callback: () => console.log('Segment is done!'), + } +}); +``` + + + + +```js +itly.group('group-id', { name: 'Iteratively, Inc.' }, { + segment: { + callback: () => console.log('Segment is done!'), + } +}); +``` + + + + +### Track + +To track an event, call the event’s corresponding function. Every event in your tracking plan gets its own function in the Itly SDK. + +For example, in the code snippet below, our tracking plan contains an event called `User Signed In`. The event was defined with one required property called `platform`. The property's type is a string. + + + + +```js +itly.userSignedIn({ platform: 'web' }); +``` + + + + +```js +itly.userSignedIn({ platform: 'web' }); +``` + + + + +
+ +The `options` argument allows you to pass additional metadata about this call, such as a callback function or custom configuration, to the SDK's destinations. For example, to specify that Segment should only track the event to Intercom and Google Analytics: + + + + +```js +itly.userSignedIn({ platform: 'web' }, + { + segment: { + options: { + integrations: { + 'All': false, + 'Intercom': true, + 'Google Analytics': true + } + } + } + } +); +``` + + + + +```js +itly.userSignedIn({ platform: 'web' }, + { + segment: { + options: { + integrations: { + 'All': false, + 'Intercom': true, + 'Google Analytics': true + } + } + } + } +); +``` + + + + +## Custom Destination + +:::note Advanced +If you're using Iteratively with Amplitude or Segment you can safely skip this section! +::: + +To send clean, valid events to custom analytics destinations, or those not yet supported by the Itly SDK natively, the SDK is extensible via plugins. Writing a plugin is easy! Extend the `Plugin` class, call the base constructors with your plugin's ID, override `track()`, and include your new plugin in the `plugins` array when calling `itly.load()`. + +Plugins allow you to implement your own processing logic for analytics tracking. When you call a function on the Itly SDK, the SDK will first validate your event (or user, group, and page properties) against your tracking plan, then call into your plugin's implementation. + +The following functions are available to override when developing your plugin. Only override those functions that matter to your custom destination. + +:::note Examples +A sample custom destination plugin is available [here](https://bitbucket.org/seasyd/examples/src/master/browser-javascript-v3/src/CustomDestination.js) in JavaScript and [here](https://bitbucket.org/seasyd/examples/src/master/browser-typescript-v3/src/CustomDestination.ts) in TypeScript. +::: + +#### Constructor +Every plugin needs a unique ID. To provide one, add a constructor to your plugin and call the base constructor with your plugin's ID. This might look something like this: + +```javascript + constructor() { + super('custom-destination'); + } +``` +
+ +#### Load +Called when the Itly SDK is being loaded and is ready to load your plugin. The function has the following signature: + +```javascript +load(options: Options): void; +``` + +| Argument |||| +|-|-|-|-| +| `options` | Object
`Options` | required | The [same](#load) configuration object passed to `itly.load()` when the SDK was being initialized. | +
+ +#### Alias +Called when Itly SDK's `alias()` function is called to associate one user ID with another (typically a known user ID with an anonymous one). The `alias()` function has the following signature: + +```javascript +alias(userId: string, previousId: string | undefined, options: AliasOptions | undefined): void; +``` + +| Argument | Type || Description | +|-|-|-|-| +| `userId` | String | required | The ID that the user will be identified by going forward. This is typically the user's database ID (as opposed to an anonymous ID), or their updated ID (for example, if the ID is an email address which the user just updated). | +| `previousId` | String | optional | The ID the user has been identified by so far. | +| `options` | AliasOptions | optional | See [Call Options](#call-options). | +
+ +#### Identify +Called when Itly SDK's `identify()` function is called to identify a user with a specific ID or set the user's traits. The `identify()` function has the following signature: + +```javascript +identify(userId: string | undefined, properties: Properties | undefined, options: IdentifyOptions | undefined): void; +``` + +| Argument | Type || Description | +|-|-|-|-| +| `userId` | String | optional | The user's ID, if it was provided to `itly.identify()`. The ID may not be provided if `identify()` was called only to update the user's traits. | +| `properties` | Object
`Properties` | optional | The user's traits. | +| `options` | IdentifyOptions | optional | See [Call Options](#call-options). | +
+ +#### Track +Called when an event is tracked. The function receives a validated event with its complete set of properties (a combination of the event's own properties any any other properties associated with the source via a [source template](working-with-templates#adding-a-template-to-a-source)) The `track()` function has the following signature: + +```javascript +track(userId: string | undefined, event: Event, options: TrackOptions | undefined): void; +``` + +| Argument | Type || Description | +|-|-|-|-| +| `userId` | String | optional | Always undefined in the Browser SDK. | +| `event` | Object
`Event` | required | The event that was tracked by the Itly SDK. The event object contains the following properties:

`name`
The event's name.

`properties`
The event's properties.

`id`
The event's unique ID in Iteratively.

`version`
The event's version, e.g. 2.0.1.

| +| `options` | TrackOptions | optional | See [Call Options](#call-options). | +
+ +#### Group +Called when Itly SDK's `group()` function is called to associate the user with a specific account (for example, their department or company) or set the group's properties. The `group()` function has the following signature: + +```javascript +group(userId: string | undefined, groupId: string, properties?: Properties | undefined, options: GroupOptions | undefined): void; +``` + +| Argument | Type || Description | +|-|-|-|-| +| `userId` | String | optional | Always undefined in the Browser SDK. | +| `groupId` | String | required | The ID of the group (for example, the user's department or company) to associate the user with. | +| `properties` | Object
`Properties` | optional | The group's traits. | +| `options` | GroupOptions | optional | See [Call Options](#call-options). | +
+ +#### Page +Called when Itly SDK's `page()` function is called to track a page view in a web application. The `page()` function has the following signature: + +```javascript +page(userId: string | undefined, category: string | undefined, name: string | undefined, properties: Properties | undefined, options: PageOptions | undefined): void; +``` + +| Argument | Type || Description | +|-|-|-|-| +| `userId` | String | optional | Always undefined in the Browser SDK. | +| `category` | String | optional | The page's category. Useful when many pages might live under a single category. | +| `name` | String | optional | The page's name. | +| `properties` | Object
`Properties` | optional | The page's traits. | +| `options` | PageOptions | optional | See [Call Options](#call-options). | +
+ +#### Reset +Called when Itly SDK's `reset()` function is called to reset the SDK's (and all plugins') state. This method is usually called when a user logs out. The `reset()` function has the following signature: + +```javascript +reset(): void; +``` +
+ +#### Call Options + +Call Options are a powerful feature that allows your plugin's users to pass additional per-call metadata, such as a callback function or custom configuration, to your plugin. You can use this metadata to customize your plugin's behavior when processing individual alias, identify, group, page, and track calls. Your plugin's users will provide the metadata intended for your plugin under a field named after the plugin's ID, and your plugin will receive them via the `options` argument. + +For example, let's assume you'd like your plugin's users to tell your plugin whether a particular event they're tracking is awesome. Your instrumention engineers would track the event like this: + + + + +```js +itly.buttonClicked( + /* event's properties */ + { label: 'Send Event' }, + /* event's metadata for the custom destination plugin */ + { 'custom-destination': { awesome: true } as CustomTrackOptions }, +) +``` + + + + +```js +itly.buttonClicked( + /* event's properties */ + { label: 'Send Event' }, + /* event's metadata for the custom destination plugin */ + { 'custom-destination': { awesome: true } }, +) +``` + + + + +
+And your plugin would read the call option metadata like this: + + + + +```js +import { Plugin, Options, Event, PluginCallOptions } from './itly'; + +export interface CustomTrackOptions extends PluginCallOptions { + awesome: boolean; +} + +export default class extends Plugin { + constructor() { + super('custom-destination'); + } + + track(_: string, event: Event, options?: CustomTrackOptions) { + console.log(options?.awesome); + } +} +``` + + + + +```js +import { Plugin } from './itly'; + +export default class extends Plugin { + constructor() { + super('custom-destination'); + } + + track(_, event, options) { + console.log(options?.awesome); + } +} +``` + + + + +## Migrating from Previous Version + +### Introduction + +The new Browser SDK introduces several new features to help developers implement product analytics. + +### Tracking Plan Changes + +- Update your source's runtime to **Browser — JavaScript** or **Browser — TypeScript** (from **Browser — JavaScript (Legacy)** or **Browser — TypeScript (Legacy)**, respectively) + +### CLI & Code Changes + +- Make sure you have downloaded the [Ampli CLI](/using-the-ampli-cli) + +- Pull down the new SDK inside your project's folder (the one with the .itlyrc file): + +```bash +ampli pull +``` + +- Validation options are now an enum rather than an object with three boolean fields: + - Remove e.g. `validation: { disabled: true }` from `options` passed to `load()` + - Add `validation: Validation.Disabled` instead, e.g.: + + ```js + itly.load({ + validation: Validation.Disabled, + }); + ``` + - The SDK's plugins no longer initialize analytics provider libraries if they're detected on `window`. In version 1.0, if the SDK's plugin detected that a library has already loaded, it would skip loading it, but would still initialize it using the access key provided in the tracking plan. In the 2.0 version of the SDK, this is no longer the case, and Iteratively simply reuses the instance from `window` as is. + +### Custom Destination + +In the new SDK, custom destinations look almost identical. The following changes were made: + +- The `PluginBase` class your plugin extends was renamed to `Plugin` +- The `id()` method was removed. To set a plugin's ID, implement a constructor and call `super('your-plugin-id')` instead +- All plugin methods (except for `load()`, `reset()`, and `flush()`) now accept a new optional argument called `options`. The argument carries additional metadata that the plugin can use to further customize its behavior for a particular identify, track, group, etc. call. The values in this additional metadata object are provided by the analytics tracking developer when making the original call and are passed all the way through to your plugin. \ No newline at end of file diff --git a/docs/data/creating-your-tracking-plan.md b/docs/data/creating-your-tracking-plan.md index e0b43905b..ab2dbeed5 100644 --- a/docs/data/creating-your-tracking-plan.md +++ b/docs/data/creating-your-tracking-plan.md @@ -7,11 +7,11 @@ import useBaseUrl from '@docusaurus/useBaseUrl'; Now that we know what a [Tracking Plan](/what-is-a-tracking-plan) is and how it can benefit your company, let's get started. -The Iteratively web app allows alxAl stakeholders to collaborate on a single source of truth for analytics definitions. It keeps everyone in sync on what data to track, when, and why, and maintains a consistent schema across engineering, product management, data science, and other consumers of analytics data. +The Iteratively web app allows all stakeholders to collaborate on a single source of truth for analytics definitions. It keeps everyone in sync on what data to track, when, and why, and maintains a consistent schema across engineering, product management, data science, and other consumers of analytics data. ### Step 1: Add your Sources -Sources represent the masin parts of your product, e.g. your `iOS`, `Android`, `Web`, and `Backend`. Create a new Source for every standalone part that will send events to your analytics backends. +Sources represent the main parts of your product, e.g. your `iOS`, `Android`, `Web`, and `Backend`. Create a new Source for every standalone part that will send events to your analytics backends. From [Connections](//data.amplitude.com/connections) select `Add source` to create a new source. diff --git a/docs/data/dotnet.md b/docs/data/dotnet.md index c66f577d8..8f4e0a2b5 100644 --- a/docs/data/dotnet.md +++ b/docs/data/dotnet.md @@ -1,11 +1,9 @@ --- id: dotnet -title: .NET -icon: material/dot-net +title: .NET (Itly) --- -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; + Iteratively supports tracking analytics events from .NET (Standard 1.3 and Standard 2.0) apps written in C# (6 and above). diff --git a/docs/data/getting-started.md b/docs/data/getting-started.md index 9713fd057..ec69eb30e 100644 --- a/docs/data/getting-started.md +++ b/docs/data/getting-started.md @@ -1,12 +1,14 @@ --- -title: Getting Started with Data +id: getting-started +slug: / +title: Getting Started --- Welcome to Iteratively's documentation! This will get you up to speed on the product and show you how to start instrumenting your application.
-![Iteratively Tracking Plan](../assets/images/diagram.png) +![Iteratively Tracking Plan](/img/diagram.png) ## Iteratively Overview diff --git a/docs/data/index.md b/docs/data/index.md index cc7c35367..e09d39e15 100644 --- a/docs/data/index.md +++ b/docs/data/index.md @@ -1,20 +1,3 @@ --- -title: Data Docs -hide: - - tags - - feedback ---- - - - -# Data Overview - -This is where I'd add a bunch of introductory content to make it clear what Data is, and what you need to know before you proceed. - -We can also make splashy, flashy landing page templates for each doc set's home page. \ No newline at end of file +title: Data Home +--- \ No newline at end of file diff --git a/docs/data/integrating-with-ci.md b/docs/data/integrating-with-ci.md index 29d42bea8..24a85bd48 100644 --- a/docs/data/integrating-with-ci.md +++ b/docs/data/integrating-with-ci.md @@ -59,8 +59,7 @@ To integrate Ampli with your CI system, modify your CI configuration to run [`am The following examples are for Bitbucket Pipelines but you can use the same images in any CI system that supports containers. -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; + 8.6.0" + end + ``` + === "Objective-C" + + ```objectivec + platform :ios, '10.0' + + target '{Project-Name}' do + use_frameworks! + + pod 'Amplitude', "~> 8.6.0" + end + ``` + +4. Run `pod install` +5. Open Xcode. Don't open the .xcodeproj file, instead open the .xcodeworkspace file. + +### Pull the SDK into your project + +At the project root, run `pull` command. + +```bash +ampli pull +``` + +This prompts you to log in to your workspace and select a source. + +=== "Swift" + ```bash + ➜ ampli pull sourcename + Ampli project is not initialized. No existing `ampli.json` configuration found. + ? Create a new Ampli project here? Yes + Organization: Amplitude + Workspace: My Workspace + Source: sourcename + Runtime: iOS - Swift + Branch: main + Pulling latest version (1.0.0)... + Tracking library generated successfully. + Path: ./src/itly + ``` + +=== "Objective-C" + + ```bash + ➜ ampli pull sourcename + Ampli project is not initialized. No existing `ampli.json` configuration found. + ? Create a new Ampli project here? Yes + Organization: Amplitude + Workspace: My Workspace + Source: sourcename + Runtime: iOS - Obj-C + Branch: main + Pulling latest version (1.0.0)... + Tracking library generated successfully. + Path: ./src/itly + ``` + +## API + +### Load + +Initialize Ampli in your code. The `load()` method accepts configuration option arguments: + +=== "Swift" + + ```swift + Ampli.instance.load(LoadOptions( + environment: AmpliEnvironment.Production + )); + ``` +=== "Objective-C" + + ```objectivec + #import "Ampli.h" + [Ampli.instance load:[LoadOptions builderBlock:^(LoadOptionsBuilder *b) { + b.environment = development; + }]]; + ``` + +| Arg | Description | +|-|-| +| `LoadOptions` | Optional. Defaults to `false`. Specifies configuration options for the Ampli SDK.| +|`disabled`|Optional. Specifies whether the Ampli SDK does any work. When true, all calls to the Ampli SDK are no-ops. Useful in local or development environments.| +|`environment`|Optional. Defaults to `development`. Specifies the environment the Ampli SDK runs in: either `production` or `development`. Environment determines which Access Token is used to load the underlying analytics provider libraries. The option also determines safe defaults for handling event validation errors. In production, when the SDK detects an invalid event, it logs an error but stills let the event through. In development, the SDK throws an exception to alert you that something is wrong.| +|`instance`|Optional. Specifies an Amplitude instance. By default Ampli creates an instance for you.| +|`apiKey`|Optional. Specifies an API Key. This option overrides the default, which is the API Key configured in your tracking plan.| + +### Identify + +Call `identify()` to identify a user in your app and associate all future events with their identity, or to set their properties. + +Just as the Ampli SDK creates types for events and their properties, it creates types for user properties. + +The `identify()` function accepts an optional `userId`, optional user properties, and optional `options`. + +For example your tracking plan contains a user property called `userProp`. The property's type is a string. + +=== "Swift" + + ```swift + Ampli.instance.identify("userID", Identify( + userProp: "A trait associated with this user" + )); + ``` + +=== "Objective-C" + + ```objectivec + [Ampli.instance identify:@"userID" event:[Identify userProp:@"A trait associated with this user"]]; + ``` + +The options argument allows you to pass [Amplitude fields](https://developers.amplitude.com/docs/http-api-v2#keys-for-the-event-argument) for this call, such as `deviceId`. + +=== "Swift" + + ```swift + Ampli.instance.identify("userID", Identify(deviceID: "my_device_id") + ``` + +=== "Objective-C" + + ```objectivec + [Ampli.instance identify:@"userID" event:[Identify deviceID: "my_device_id"]; + ``` + +### Group + +!!! note + This feature is available for Growth customers who have purchased the [Accounts add-on](https://help.amplitude.com/hc/en-us/articles/115001765532). + +Call `setGroup()` to associate a user with their group (for example, their department or company). The `setGroup()` function accepts a required `groupType`, and `groupName`. + +=== "Swift" + + ```swift + Ampli.instance.setGroup("groupType", "groupName") + ``` + +=== "Objective-C" + + ```objectivec + [Ampli.instance setGroup:"groupType" value:"groupName"] + ``` + +Amplitude supports assigning users to groups and performing queries, such as Count by Distinct, on those groups. If at least one member of the group has performed the specific event, then the count includes the group. + +For example, you want to group your users based on what organization they're in by using an 'orgId'. Joe is in 'orgId' '10', and Sue is in 'orgId' '15'. Sue and Joe both perform a certain event. You can query their organizations in the Event Segmentation Chart. + +When setting groups, define a `groupType` and `groupName`. In the previous example, 'orgId' is the `groupType` and '10' and '15' are the values for `groupName`. Another example of a `groupType` could be 'sport' with `groupName` values like 'tennis' and 'baseball'. + + Setting a group also sets the 'groupType:groupName' as a user property, and overwrites any existing groupName value set for that user's groupType, and the corresponding user property value. groupType is a string, and groupName can be either a string or an array of strings to indicate that a user is in multiple groups. For example, if Joe is in 'orgId' '10' and '20', then the `groupName` is '[10, 20]'). + + Your code might look like this: + +=== "Swift" + + ```swift + Ampli.instance.setGroup("orgID", ["10", "20"]) + ``` + +=== "Objective-C" + + ```objc + [Ampli.instance setGroup:"orgID" value:["10", "20"]] + ``` + +### Track + +To track an event, call the event's corresponding function. Every event in your tracking plan gets its own function in the Ampli SDK. The call is structured like this: + +=== "Swift" + + ```swift + Ampli.instance.track(_ event: Event, options: EventOptions, extra: MiddlewareExtra) + ``` + +=== "Objective-C" + + ```objectivec + [Ampli.instance track:(Event *)event + options:(EventOptions *_Nullable)options + extra:(MiddlewareExtra *_Nullable)extra + ]; + `` + +The `options` argument allows you to pass to pass [Amplitude fields](https://developers.amplitude.com/docs/http-api-v2#properties-1), like `deviceID`. The `extra` argument lets you pass data to middleware. + +!!! note + EventOptions are set via generic track and aren't exposed on the strongly typed event methods such as `Ampli.instance.songPlayed(songId: 'id', songFavorited: true)`. + +For example, in the code snippet below, your tracking plan contains an event called `songPlayed`. The event is defined with two required properties: `songId` and `songFavorited.` The property type for `songId` is string, and `songFavorited` is a boolean. + +The event has two Amplitude fields defined: `price`, and `quantity`. Learn more about Amplitude fields [here](https://developers.amplitude.com/docs/http-api-v2#properties-1). The event has one MiddlewareExtra defined: `myMiddleware`. Learn more about [middleware](#middleware-overview.md). + +=== "Swift" + + ```swift + Ampli.instance.track(SongPlayed(songId: 'songId', songFavorited: true), options: EventOptions(deviceId: 'deviceId')) + ); + ``` + +=== "Objective-C" + + ```objectivec + SongPlayed* event = [SongPlayed + songId:'songId', // NSString * + songFavorited:true, // NSNumber * + ]]; + + EventOptions* options = [EventOptions builderBlock:^(EventOptionsBuilder *builder) { + builder.deviceId = deviceId; + builder.userId = userId; + }]; + + [Ampli.instance track:event options:options] + ``` + +Ampli also generates a class for each event. + +=== "Swift" + + ```swift + let myEventObject = SongPlayed( + songId: 'songId', // String, + songFavorited: true, // Bool + ); + ``` + +=== "Objective-C" + + ```objectivec + SongPlayed *songPlayed = [SongPlayed + songId:'songId', // NSString * + songFavorited:true, // NSNumber * + ]; + ``` + +All event objects can be sent using the generic track method. + +=== "Swift" + + ```swift + Ampli.instance.track(SongPlayed( + songId: 'songId', // String, + songFavorited: true, // Bool + ); + ``` + +=== "Objective-C" + + ```objectivec + [Ampli.instance track:[SongPlayed + songId:'songId', // NSString * + songFavorited:true, // NSNumber * + ]]; + ``` + +## Verify implementation status + +Verify events are implemented in your code with the status command: + +```bash +ampli status +``` + +To update the implementation status in your tracking plan use the `--update` flag or `-u`: + +```bash +ampli status -u +``` +The output displays status and indicates which events are missing. + +```bash +➜ ampli status +✘ Verifying event tracking implementation in source code + ✔ Song Played (1 location) + ✘ Song Stopped Called when a user stops playing a song. +Events Tracked: 2 missed, 3 total +``` + +Learn more about [`ampli status`](using-the-ampli-cli.md#ampli-status). + +## Migrating from an Itly iOS runtime + +Migrate from an Itly iOS runtime to Ampli by following these steps. + +1. Remove legacy Itly dependencies from your project. This includes anything with a `ly.iterative.itly`. + ```bash + pod "ItlySdk", '~> 1.X' + pod "ItlyAmplitudePlugin", '~> 1.X' + pod "ItlyIterativelyPlugin", '~> 1.X' + pod "ItlySchemaValidatorPlugin", '~> 1.X' + pod "ItlyMixpanelPlugin", '~> 1.X' + pod "ItlySegmentPlugin", '~> 1.X' + ``` +2. Add Amplitude dependencies. + ```bash + platform :ios, '10.0' + + target '{Project-Name}' do + use_frameworks! + + pod 'Amplitude', "~> 8.6" + end + ``` +3. Install pods. + ```bash + pod install + ``` +4. Pull the latest Ampli SDK. + ```bash + ampli pull + ``` +5. Find and replace: + + **Swift and Objective-C:** + - `Itly => Ampli` + + **Swift only:** + + - `Itly.instance.load() => Ampli.instance.load()` + - `Itly.instance.group(groupId) => Ampli.instance.setGroup(groupType, groupValue)` + - `Itly. => Ampli.` + + **Objective-C only:** + + - `[Itly.instance load] => [Ampli.instance load]` + - `[Itly.group:groupId] => [Ampli.setGroup:groupType groupValue:groupValue)` + - `[Itly instance] => [Ampli instance]` + +6. See updated Event tracking details on your Implementation page in the web app. diff --git a/docs/data/ios-legacy.md b/docs/data/ios-legacy.md new file mode 100644 index 000000000..35daee253 --- /dev/null +++ b/docs/data/ios-legacy.md @@ -0,0 +1,197 @@ +--- +id: ios-legacy +title: iOS (Legacy) +--- + + + +Iteratively supports tracking analytics events from iOS apps written in Swift and Objective-C. + +In Swift and Objective-C, the tracking library exposes a type-safe function for every event in your team’s tracking plan. The function’s arguments correspond to the event’s properties and are strongly typed to allow for code completion and compile-time checks. + +## Installation + +### Generate the SDK + +If you have not yet installed the Ampli CLI, [install it now](/using-the-ampli-cli). + +To generate the Itly SDK, run `ampli pull {source}` in the folder with your Info.plist file. By default, the SDK will be generated in `./Itly/`. + +:::note Tip +`{source}` is the name of the source you created in your tracking plan (e.g. `ios`). +::: + +After calling `ampli pull` for the first time, add the generated tracking library to your project: + +- Right click on the yellow project folder and click **Add Files to "{Project}"** +- Select the Itly folder +- Select **Create groups** +- Make sure **{Project}** is checked in **Add to targets** +- Click **Add** + +### Install dependencies + +To validate your analytics events, the iOS SDK depends on [DSJSONSchemaValidation](https://github.com/dashevo/JSONSchemaValidation) (MIT). To install this dependency with CocoaPods: + +- Close Xcode +- If you haven't already, install CocoaPods with `sudo gem install cocoapods` +- If you haven't already, create a file called `Podfile` in the project root folder (the one with your `.xcodeproj`) and edit it to contain: + +```bash +platform :ios, '9.0' + +target '{Project-Name}' do + use_frameworks! + + pod 'DSJSONSchemaValidation' +end +``` +- If you already had a `Podfile`, simply add `pod 'DSJSONSchemaValidation'` to your target +- Run `pod install` +- Open Xcode but don't open the `.xcodeproj` file, instead open the `.xcodeworkspace` file + +If you've configured Itly with Amplitude, or Segment, you'll also install each configured provider's SDK. Edit your `Podfile` and add the relevant pods. + +```bash +pod 'Amplitude-iOS', '~> 4.5' +pod 'Analytics', '3.7.0' +``` + +### Import into your app + +If you are using Swift, no import is needed to use the library. If you are using Objective-C, you'll need to import it first: + + + +N/A + + + +```c +#import "Itly/Itly.h" +``` + + + + +## API + +### Load + +Initialize the Itly SDK once when your application starts. The `setup()` (`init` in Objective-C) method accepts an options object that lets you configure how the Itly SDK works: + +| Options | Description | +|-|-| +| `context`| An object with a set of properties to add to every event sent by the Itly SDK.

Only available if there is at least one [source template](/working-with-templates#adding-a-template-to-a-source) associated with your your team's tracking plan.| +| `isDisabled`
(`disabled` in Objective-C)| Specifies whether the Itly SDK does any work. When true, all calls to the Itly SDK will be no-ops. Useful in local or development environments.

Optional. Defaults to `false`.| +| `environment` | Specifies the environment the Itly SDK is running in: either `production` or `development`. Environment determines which Access Token is used to load the underlying analytics provider libraries.

The option also determines safe defaults for handling event validation errors. In production, when the SDK detects an invalid event, it will log an error but still let the event through. In development, the SDK will throw an exception to alert you that something is wrong.

Optional. Defaults to `development`.| +| `logger` | To log Itly's logs to a custom logger, implement the `ItlyLogger` protocol and set `logger` to an instance of your class. The Itly SDK will call into your class with all debug, info, warn, and error-level messages.

[Click here](https://bitbucket.org/seasyd/examples/src/master/ios-swift/IterativelySwift/CustomLogger.swift) to see a sample logger implemented in Swift.

Optional. Defaults to standard out. | +| `destinations` | Configuration options object to customize the analytics providers used by the Itly SDK.

[Click here](https://bitbucket.org/seasyd/examples/src/master/ios-swift/IterativelySwift/CustomDestination.swift) to see a sample custom destination implemented in Swift, and [click here](https://bitbucket.org/seasyd/examples/src/1c87c96354b146448f0a0eb5d4b868ffb13d3c5a/ios-swift/IterativelySwift/AppDelegate.swift#lines-20) to see how to load a custom destination in the Itly SDK.

Required if a custom destination is connected to your iOS source.| + +For example: + + + + +```c +// With no context properties +Itly.setup(ItlyOptions()) + +// With context properties (e.g. a string property called version) +Itly.setup(ItlyOptions(context: Context(version: "1.0"))) +``` + + + + +```c +// With no context properties or custom destinations +[Itly init]; + +// With context properties (e.g. a string property called version) +[Itly init:[ItlyOptions context:[Context version:@"1.0"]]]; +``` + + + + + + + +### Track + +To track an event, call the event’s corresponding function. Every event in your tracking plan gets its own function in the Itly SDK. + +For example, in the code snippet below, our tracking plan contains an event called `View Loaded`. The event was defined with one required property called `name` and one optional property called `description`. The `name` property's type is an enum. The `description` property's type is a string. + + + + +```c +Itly.instance.trackViewLoaded(ViewLoaded(name: .firstView)) +``` + + + + +```c +// Track a View Loaded event with a required enum property called name +[[Itly instance] trackViewLoaded:[ViewLoaded name:ViewLoadedNameFirstView]]; + +// Track the same event with an optional string property called description +[[Itly instance] trackViewLoaded:[ViewLoaded + name:ViewLoadedNameFirstView + builderBlock:^(ViewLoadedBuilder *builder) { + builder.description = @"First View"; + } +]]; +``` +> In Objective-C, the builder pattern is used to set optional properties. + + + + + + + + + + + diff --git a/docs/data/ios.md b/docs/data/ios.md new file mode 100644 index 000000000..bb00bbbc9 --- /dev/null +++ b/docs/data/ios.md @@ -0,0 +1,413 @@ +--- +id: ios +title: iOS (Itly) +--- + + + +:::note Previous Version +Still using the **iOS (Legacy)** runtime? Docs for the previous version are available [here](ios-legacy). +::: +:::note Migrating +Migrating from **iOS (Legacy)** to the new **iOS** runtime? A migration guide is available [here](#migrating-from-previous-version). +::: + +Iteratively supports tracking analytics events from iOS apps written in Swift and Objective-C. + +In Swift and Objective-C, the tracking library exposes a type-safe function for every event in your team’s tracking plan. The function’s arguments correspond to the event’s properties and are strongly typed to allow for code completion and compile-time checks. + +## Installation + +### Generate the SDK + +If you have not yet installed the Ampli CLI, [install it now](/using-the-ampli-cli). + +To generate the Itly SDK, run `ampli pull {source}` in the folder with your Info.plist file. By default, the SDK will be generated in `./Itly/`. + +:::note Tip +`{source}` is the name of the source you created in your tracking plan (e.g. `ios`). +::: + +After calling `ampli pull` for the first time, add the generated tracking library to your project: + +- Right click on the yellow project folder and click **Add Files to "{Project}"** +- Select the Itly folder +- Select **Create groups** +- Make sure **{Project}** is checked in **Add to targets** +- Click **Add** + +### Install dependencies + +The generated Itly SDK will automatically reference its dependencies based on the destinations you've configured in your tracking plan. By default, the SDK depends on [ItlySdk](https://github.com/iterativelyhq/itly-sdk-ios) (the base Itly library), [SchemaValidatorPlugin](https://github.com/iterativelyhq/itly-sdk-ios/tree/master/SchemaValidatorPlugin) (the event validation plugin). Optionally, it also depends on provider-specific plugins like [AmplitudePlugin](https://github.com/iterativelyhq/itly-sdk-ios/tree/master/AmplitudePlugin) and [SegmentPlugin](https://github.com/iterativelyhq/itly-sdk-ios/tree/master/SegmentPlugin). + +To install these dependencies with CocoaPods: + +- Close Xcode +- If you haven't already, install CocoaPods with `sudo gem install cocoapods` +- If you haven't already, create a file called `Podfile` in the project root folder (the one with your `.xcodeproj`) and edit it to contain: + +```bash +platform :ios, '10.0' + +target '{Project-Name}' do + use_frameworks! + + pod 'ItlySdk', '~> 1.0' + pod 'ItlySchemaValidatorPlugin', '~> 1.0' +end +``` +- Run `pod install` +- Open Xcode but don't open the `.xcodeproj` file, instead open the `.xcodeworkspace` file + +If you've configured Itly with Amplitude or Segment, you'll also install each configured provider's SDK. Edit your `Podfile` and add the relevant pods. + +```bash + pod 'ItlyAmplitudePlugin', '~> 1.0' + pod 'ItlySegmentPlugin', '~> 1.0' +``` + +To install these dependencies with Carthage: + +- Close Xcode +- If you haven't already, install Carthage with `brew install carthage` +- If you haven't already, create a file called `Cartfile` in the project root folder (the one with your `.xcodeproj`) and edit it to contain: + +```bash +github "iterativelyhq/itly-sdk-ios" +``` +- Run `carthage update --platform iOS` +- Run `carthage build --platform iOS` to build nested dependencies +- Open Xcode +- Select the top-level app in the Project Navigator +- Make sure the main project's target (in the TARGETS section) is selected +- Select the General tab +- Drag and drop ItlySdk.framework, ItlySchemaValidatorPlugin.framework, and DSJSONSchemaValidation.framework from the `Carthage/Build` folder to the Frameworks, Libraries, and Embedded Content section +- Select the Build Phases tab + - Click the Plus icon in the top left corner of that tab, click New Run Script Phase + - Create a new run script: + - Shell: `/bin/sh` + - Script: `/usr/local/bin/carthage copy-frameworks` + +If you've configured Itly with Amplitude or Segment, you'll drag and drop each configured provider's SDK: + - ItlyAmplitudePlugin.framework and Amplitude.framework for Amplitude + - ItlySegmentPlugin.framework and Analytics.framework for Segment + +### Import into your app + +If you are using Swift, no import is needed to use the library. If you are using Objective-C, you'll need to import it first: + + + +N/A + + + +```c +#import "Itly/Itly.h" +``` + + + + +## API + +### Load + +Initialize the Itly SDK once when your application starts. The `load` method accepts an options object that lets you configure how the Itly SDK works: + +| Options | Description | +|-|-| +| `context`| An object with a set of properties to add to every event sent by the Itly SDK.

Only available if there is at least one [source template](/working-with-templates#adding-a-template-to-a-source) associated with your your team's tracking plan.| +| `destinations` | Specifies any analytics provider-specific configuration. The Itly SDK passes these objects in when loading the underlying analytics provider libraries.

Note: only the Iteratively destination is currently supported.

Optional.| +| `options` | Specifies additional configuration options for the Itly SDK. Optional.

`disabled`
Specifies whether the Itly SDK does any work. When true, all calls to the Itly SDK will be no-ops. Useful in local or development environments.

Optional. Defaults to `false`.

`environment`
Specifies the environment the Itly SDK is running in: either `ItlySdk.Environment.production` (`ITLEnvironmentProduction` in Obj-C) or `ItlySdk.Environment.development` (`ITLEnvironmentDevelopment` in Obj-C). Environment determines which Access Token is used to load the underlying analytics provider libraries.

The option also determines safe defaults for handling event validation errors. In production, when the SDK detects an invalid event, it will log an error but still let the event through. In development, the SDK will terminate the application to alert you that something is wrong.

Optional. Defaults to `development`.

`plugins`
An array of additional plugins to load into the Itly SDK. Plugins allow you to extend the Itly SDK's event validation and event tracking functionality with your own. For example, a plugin can be used to implement a custom destination or a custom event validator.

[Click here](https://bitbucket.org/seasyd/examples/src/master/ios-swift-v2/ItlySwiftCarthageExample/CustomPlugin.swift) to see a sample custom destination plugin written in Swift.

[Click here](https://bitbucket.org/seasyd/examples/src/master/ios-objc-v2/ItlyObjCCarthageExample/CustomPlugin.m) to see a sample custom destination plugin written in Objective-C.

Optional.

`logger`
To log Itly's logs to a custom logger, extend the `Logger` class (`ITLLogger` in Objective-C) and set `logger` to an instance of your class. The Itly SDK will call into your class with all debug, info, warn, and error-level messages.

[Click here](https://bitbucket.org/seasyd/examples/src/master/ios-swift-v2/ItlySwiftCarthageExample/CustomLogger.swift) to see a a sample custom logger written in Swift.

[Click here](https://bitbucket.org/seasyd/examples/src/master/ios-objc-v2/ItlyObjCCarthageExample/CustomLogger.m) to see a a sample custom logger written in Objective-C.

Optional. | + +For example: + + + + +```c +// Load Itly with no custom plugins or logger +Itly.instance.load() + +// Or, load Itly with a custom plugin and logger +Itly.instance.load( + options: Options( + environment: Environment.development, + plugins: [CustomPlugin()], + logger: CustomLogger() + ) +) +``` + + + + +```c +// Load Itly with no custom plugins or logger +// [Itly.instance load]; + +// Or, load Itly with a custom plugin and logger +[Itly.instance load:nil options:[ITLItlyOptions builderBlock:^(ITLItlyOptionsBuilder *b) { + b.environment = ITLEnvironmentDevelopment; + b.plugins = @[[CustomPlugin new]]; + b.logger = [CustomLogger new]; +}]]; +``` + + + + +### Track + +To track an event, call the event’s corresponding function. Every event in your tracking plan gets its own function in the Itly SDK. + +For example, in the code snippet below, our tracking plan contains an event called `View Loaded`. The event was defined with one required property called `name` and one optional property called `description`. The `name` property's type is an enum. The `description` property's type is a string. + + + + +```c +Itly.instance.viewLoaded(name: ViewLoaded.Name.firstView) +``` + + + + +```c +// Track a View Loaded event with a required enum property called name +[Itly.instance viewLoadedWithName:ViewLoadedNameFirstView]; +``` +> In Objective-C, the builder pattern is used to set optional properties. + + + + +## Migrating from Previous Version + +### Introduction + +The new Iteratively Swift & Objective-C SDK enjoys a simpler deployment model and introduces several new features to help developers implement product analytics: + +- Previously, the entire SDK was codegen'd into your source tree. In the new version, the SDK is split into two, allowing developers to call `ampli pull` freely without worrying about pulling down changes that may affect their application's behavior: + - The static, core SDK — open source, hosted on GitHub, and usable standalone, the static SDK contains all the logic needed to validate, track, and test analytics events. It is now semantically versioned and published to popular package repos, incl. Carthage and CocoaPods. + - The dynamic, codegen'd API — generated by `ampli pull` and placed into your source tree, the codegen'd API contains event classes and a corresponding strongly-typed API only. It delegates all work to the core SDK and contains no logic. +- The core SDK is now extensible via plugins. 5 plugins are currently available out of the box: a JSON Schema validation plugin, and 4 destination plugins: Segment, Amplitude, and Iteratively. +- When environment is set to `development`, the SDK will stream events to Amplitude's [User Lookup](https://help.amplitude.com/hc/en-us/articles/229313067-User-Look-Up) dashboard. The live debugger allows developers to watch tracked events, inspect their payloads, and detect validation problems. + +### Tracking Plan Changes + +- Update your source's runtime to **iOS — Swift (2.0)** or **iOS — Obj-C (2.0)** + +### Xcode Changes (Carthage) + +- Remove from Cartfile: + +```java +github "dashevo/JSONSchemaValidation" +// If using Amplitude +github "amplitude/Amplitude-iOS" +// If using Segment +github "segmentio/analytics-ios" +``` + +- Add to Cartfile: + +```java +github "iterativelyhq/itly-sdk-ios" +``` + +### Xcode Changes (CocoaPods) + +- Remove from Podfile: + +```java +pod 'DSJSONSchemaValidation' +// If using Amplitude +pod 'Amplitude-iOS', '~> 4.5' +// If using Segment +pod 'Analytics', '3.7.0' +``` + +- Add to Podfile: + +```java +pod 'ItlySdk', '~> 1.0' +pod 'ItlySchemaValidatorPlugin', '~> 1.0' +// If using Amplitude +pod 'ItlyAmplitudePlugin', '~> 1.0' +// If using Segment +pod 'ItlySegmentPlugin', '~> 1.0' +``` + +### CLI Changes + +- Pull down the new SDK inside your iOS project's folder (the one with Info.plist): + +```bash +ampli pull +``` + +- Custom destination adapters are now passed in as plugins rather than as part of `ItlyDestinations`. If you are using a custom destination: + - Remove e.g. `custom: ItlyCustomOptions(adapter: CustomDestination())` from `destinations` + - Add `plugins: [CustomPlugin()]` to `Options`: + + ```java + Itly.instance.load( + options: Options( + environment: Environment.development, + plugins: [CustomPlugin()], + logger: CustomLogger() + ) + ) + ``` + + - Or in Objective-C: + + ```objectivec + [Itly.instance load:nil options:[ITLItlyOptions builderBlock:^(ITLItlyOptionsBuilder *b) { + b.environment = ITLEnvironmentDevelopment; + b.plugins = @[[CustomPlugin new]]; + b.logger = [CustomLogger new]; + }]]; + ``` + +### Custom Destination + +In the new SDK, custom destinations no longer implement an `ItlyDestination` interface. They are now considered plugins and extend the `Plugin` class (`ITLPlugin` in Objective-C). + +For example, the following custom destination: + +```java +final class MyCustomAdapter: ItlyDestination { + func identify(_ userId: String?, properties: [String: Any]?) { + } + + func alias(_ userId: String, previousId: String?) { + } + + func group(_ groupId: String, properties: [String: Any]?) { + } + + func track(_ userId: String?, eventName: String, properties: [String: Any]) { + } + + func reset() { + } +} +``` + +```objectivec +@interface MyCustomAdapter: NSObject +@end + +@implementation MyCustomAdapter +- (instancetype)init { + if (self = [super init]) { + } + return self; +} + +- (void)track:(NSString *)userId eventName:(NSString *)eventName properties:(NSDictionary *)properties { +} + +- (void)alias:(NSString *)userId previousId:(NSString *)previousId { +} + +- (void)group:(NSString *)groupId properties:(NSDictionary *)properties { +} + +- (void)identify:(NSString *)userId properties:(NSDictionary *)properties { +} + +- (void)reset { +} +@end +``` + +Now looks like this: + +```java +class CustomPlugin: Plugin { + override init() { + super.init(id: "custom-plugin") + } + + public override func load(_ options: Options) { + super.load(options) + } + + override func alias(_ userId: String, previousId: String?) { + } + + override func identify(_ userId: String?, properties: Properties?) { + } + + override func group(_ userId: String?, groupId: String, properties: Properties?) { + } + + override func track(_ userId: String?, event: Event) { + } + + override func reset() { + } + + override func flush() { + } + + override func shutdown() { + } +} +``` + +```objectivec +@interface CustomPlugin : ITLPlugin +@property id _Nullable logger; +@end + +@implementation CustomPlugin: ITLPlugin +- (instancetype)init { + if (self = [super initWithId:@"custom-plugin"]) { + } + return self; +} + +- (void)load:(ITLItlyOptions *)options { +} + +- (void)alias:(NSString *)userId previousId:(NSString *)previousId { +} + +- (void)identify:(NSString *)userId properties:(ITLProperties *)properties { +} + +- (void)group:(NSString *)userId groupId:(NSString *)groupId properties:(ITLProperties *)properties { +} + +- (void)track:(NSString *)userId event:(ITLEvent *)event { +} +@end +``` + +`Properties` exposes a dictionary of properties as `NSDictionary* properties`. `Event` exposes the event's `id`, `name`, `version`, and `properties`. \ No newline at end of file diff --git a/docs/data/jre-ampli.md b/docs/data/jre-ampli.md new file mode 100644 index 000000000..28b3b219e --- /dev/null +++ b/docs/data/jre-ampli.md @@ -0,0 +1,527 @@ +--- +id: jre-ampli +title: JRE +--- + + + + +:::note +This page covers the JRE Java and Kotlin runtimes. All (Itly) runtimes have been deprecated. If you are still using an (Itly) runtime, see the **[migration guide](#migrating-from-previous-version)** to ugrade to the newest runtime. Docs for the Itly version are available **[here](browser)**. +::: + + +Iteratively supports tracking analytics events from JRE programs written in Java (6 and above). + +In Java, the tracking library exposes a type-safe function for every event in your team’s tracking plan. The function’s arguments correspond to the event’s properties and are strongly typed to allow for code completion and compile-time checks. + +:::tip +See example apps that use the JRE Java and Kotlin runtimes on [GitHub](https://github.com/amplitude/ampli-examples/tree/main/jre). +::: + +## Installation + +These instructions are also available from the **Implementation** page of your Iteratively workspace. + +### Install the Ampli CLI + +If you haven't installed the Ampli CLI, [install it now](using-the-ampli-cli). + +### Install dependencies + +If you haven't already, install the core Amplitude SDK dependencies. + + + + +- Inside ``, add: + +```xml + + com.amplitude + java-sdk + 1.6.0 + + + org.json + json + 20201115 + +``` + + + + +```bash +implementation 'com.amplitude:java-sdk:1.6.0' +implementation 'org.json:json:20201115' +``` + + + + + + + +### Pull the SDK into your project + +At the project root, run `pull` command. + +```bash +ampli pull +``` + +This prompts you to log in to your workspace and select a source. + + + + +```bash +➜ ampli pull sourcename +Ampli project is not initialized. No existing `ampli.json` configuration found. +? Create a new Ampli project here? Yes +Organization: Amplitude +Workspace: My Workspace +Source: sourcename +Runtime: JRE - Java +Branch: main +Pulling latest version (1.0.0)... +Tracking library generated successfully. +Path: ./src/itly +``` + + + + +```bash +➜ ampli pull sourcename +Ampli project is not initialized. No existing `ampli.json` configuration found. +? Create a new Ampli project here? Yes +Organization: Amplitude +Workspace: My Workspace +Source: sourcename +Runtime: JRE - Kotlin +Branch: main +Pulling latest version (1.0.0)... +Tracking library generated successfully. +Path: ./src/itly +``` + + + + + +## API + +### Load + +Initialize Ampli in your code. The `load()` method accepts configuration option arguments: + + + + +```java +import com.amplitude.ampli.*; + +Ampli.getInstance().load(new LoadOptions() + .setEnvironment(Ampli.Environment.PRODUCTION) +); +``` + + + + +```java +import com.amplitude.ampli.* + +ampli.load(LoadOptions( + environment = Ampli.Environment.PRODUCTION +)); +``` + + + + + +| Arg | Description | +|-|-| +| `LoadOptions` | Optional. Defaults to `false`. Specifies configuration options for the Ampli SDK.| +|`disabled`|Optional. Specifies whether the Ampli SDK does any work. When true, all calls to the Ampli SDK are no-ops. Useful in local or development environments.| +|`environment`|Optional. Defaults to `development`. Specifies the environment the Ampli SDK runs in: either `production` or `development`. Environment determines which Access Token is used to load the underlying analytics provider libraries. The option also determines safe defaults for handling event validation errors. In production, when the SDK detects an invalid event, it logs an error but stills let the event through. In development, the SDK throws an exception to alert you that something is wrong.| +|`client`|Optional. Specifies an Amplitude instance. By default Ampli creates an instance for you.| +|`apiKey`|Optional. Specifies an API Key. This option overrides the default, which is the API Key configured in your tracking plan.| + +### Identify + +Call `identify()` to set user properties. + +Just as Ampli creates types for events and their properties, it creates types for user properties. + +The `identify()` function accepts an optional `userId`, optional user properties, and optional `options`. + +For example your tracking plan contains a user property called `userProp`. The property's type is a string. + + + + +```java +Ampli.getInstance().identify("user-id", Identify.builder() + .userProp("A user property") + .build() +); +``` + + + + +```kotlin +ampli.identify("user-id", Identify( + userProp = "A trait associated with this user" +)) +``` + + + + +
+ +The options argument allows you to pass [Amplitude fields](https://developers.amplitude.com/docs/http-api-v2#keys-for-the-event-argument) for this call, such as `deviceId`. + + + + + + +```java +Ampli.getInstance().identify( + userId, + Identify.builder().userProp("A trait associated with this user"),.build(), + new EventOptions().setDeviceId(deviceId).setUserId("some-user"), +); +``` + + + + +```kotlin +ampli.identify(userId, Identify( + userProp = "A trait associated with this user", + ) + EventOptions(deviceId = "device-id"), +) +``` + + + + +### Group + +:::note +This feature is available for Growth customers who have purchased the [Accounts add-on](https://help.amplitude.com/hc/en-us/articles/115001765532). +::: + +Call `setGroup()` to associate a user with their group (for example, their department or company). The `setGroup()` function accepts a required `groupType`, and `groupName`. + + + + +```java +Ampli.getInstance().setGroup("user-id", "GroupType", "GroupName"); +``` + + + + +```kotlin +ampli.setGroup("user-id", "GroupType", "GroupName"); +``` + + + + +Amplitude supports assigning users to groups and performing queries, such as Count by Distinct, on those groups. If at least one member of the group has performed the specific event, then the count includes the group. + +For example, you want to group your users based on what organization they're in by using an 'orgId'. Joe is in 'orgId' '10', and Sue is in 'orgId' '15'. Sue and Joe both perform a certain event. You can query their organizations in the Event Segmentation Chart. + +When setting groups, define a `groupType` and `groupName`. In the previous example, 'orgId' is the `groupType` and '10' and '15' are the values for `groupName`. Another example of a `groupType` could be 'sport' with `groupName` values like 'tennis' and 'baseball'. + + Setting a group also sets the 'groupType:groupName' as a user property, and overwrites any existing groupName value set for that user's groupType, and the corresponding user property value. groupType is a string, and groupName can be either a string or an array of strings to indicate that a user is in multiple groups. For example, if Joe is in 'orgId' '10' and '20', then the `groupName` is '[10, 20]'). + + Your code might look like this: + + + + +```java +Ampli.getInstance().setGroup("user-id", "orgID", ["10", "20"]); +``` + + + + +```kotlin +ampli.setGroup("user-id", "orgId", ["10", "20"]); +``` + + + + + + +### Track + +To track an event, call the event's corresponding function. Every event in your tracking plan gets its own function in the Ampli SDK. The call is structured like this: + + + + +```java +Ampli.getInstance().track(String userId, Event event, EventOptions options, MiddlewareExtra extra) +``` + + + + +```kotlin +ampli.track(userId: String, event: Event, options: EventOptions, extra: MiddlewareExtra) +``` + + + + +The `options` argument allows you to pass to pass [Amplitude fields](https://developers.amplitude.com/docs/http-api-v2#properties-1), like `price`, `quantity` and `revenue`. The `extra` argument lets you pass data to middleware. + +For example, in the code snippet below, your tracking plan contains an event called `songPlayed`. The event is defined with two required properties: `songId` and `songFavorited.` The property type for `songId` is string, and `songFavorited` is a boolean. + +The event has an Amplitude field defined: `deviceId`. Learn more about Amplitude fields [here](https://developers.amplitude.com/docs/http-api-v2#properties-1). The event has one MiddlewareExtra defined: `extra`. Learn more about [Middleware](#middleware). + + + + + +```java +MiddlewareExtra extra = new MiddlewareExtra(); +extra.put("extra-key", "extra-value"); + +Ampli.getInstance().songPlayed("user-id", + SongPlayed.builder() + .songId('songId') // String + .songFavorited(true) // Boolean + .build(), + new EventOptions().setDeviceId(deviceId), + extra +); +``` + + + + +```kotlin +ampli.songPlayed("user-id", + SongPlayed( + songId = 'songId', // String, + songFavorited = true, // Boolean + ), + options = EventOptions(deviceId = "device-id"), + extra = MiddlewareExtra(mapOf("extra-key" to "extra-value") +); +``` + + + + +Ampli also generates a class for each event. + + + + +```java +SongPlayed event = SongPlayed.builder() + .songId('songId') // String + .songFavorited(true) // Boolean + .build() +``` + + + + +```kotlin +val myEventObject = SongPlayed( + songId = 'songId', // String, + songFavorited = true, // Boolean +); +``` + + + + +Send Event objects using the generic track method. + + + + +```java +Ampli.getInstance().track("user-id", SongPlayed.builder() + .songId('songId') // String + .songFavorited(true) // Boolean + .build() +); +``` + + + + +```kotlin +ampli.track("user-id", SongPlayed( + songId = 'songId', // String, + songFavorited = true, // Boolean +); +``` + + + + +## Verify implementation status + +Verify that events are implemented in your code with the status command: + +```bash +ampli status +``` + +To update the implementation status in your tracking plan use the `--update` flag or `-u`: + +```bash +ampli status -u +``` +The output displays status and indicates what events are missing. + +```bash +➜ ampli status +✘ Verifying event tracking implementation in source code + ✔ Song Played (1 location) + ✘ Song Stopped Called when a user stops playing a song. +Events Tracked: 2 missed, 3 total +``` +Learn more about [`ampli status`](https://developers.data.amplitude.com/using-the-ampli-cli/#ampli-status). + + +## Migrating from an Itly JRE Runtime + +Migrate from an Itly JRE runtime to Ampli by following these steps. + +1. Remove legacy Itly dependencies from your project. This includes anything with a `ly.iterative.itly`. + +```bash +implementation "ly.iterative.itly:sdk-jvm:$itlySdkVersion" +implementation "ly.iterative.itly:plugin-iteratively:$itlySdkVersion" +implementation "ly.iterative.itly:plugin-schema-validator:$itlySdkVersion" +implementation "ly.iterative.itly:plugin-segment-jvm:$itlySdkVersion" +``` +2. Add Amplitude dependencies. + +```bash +implementation 'com.amplitude:java-sdk:1.6.0' +implementation 'org.json:json:20201115' +``` +3. Pull the latest Ampli SDK. + +```bash +ampli pull +``` + +4. Find and replace: + + **Kotlin and Java:** + - `import ly.iterative.itly.* => import com.amplitude.ampli.*` + - `itly.` => `ampli.` + - `itly.group(groupId)` => `ampli.setGroup(groupType, groupValue)` + + **Kotlin only:** + + - `Itly.load()` => `ampli.load()` + - `Itly.` => `ampli.` + + **Java only:** + + - `Itly.getInstance().load()` => `Ampli.getInstance().load()` + - `Itly.` => `Ampli.` + +5. See updated Event tracking details on your Implementation page in the web app. diff --git a/docs/data/jre-v3.md b/docs/data/jre-v3.md index a3a90b7f1..9be79751d 100644 --- a/docs/data/jre-v3.md +++ b/docs/data/jre-v3.md @@ -1,11 +1,9 @@ --- id: jre-v3 title: JRE (v3) -icon: material/language-java --- -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; + Iteratively supports tracking analytics events from JRE programs written in Java (6 and above). diff --git a/docs/data/jre.md b/docs/data/jre.md index c20e48a26..2624d8749 100644 --- a/docs/data/jre.md +++ b/docs/data/jre.md @@ -1,11 +1,9 @@ --- id: jre -title: JRE -icon: material/language-java +title: JRE (Itly) --- -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; + Iteratively supports tracking analytics events from JRE programs written in Java (6 and above). diff --git a/docs/data/middleware-overview.md b/docs/data/middleware-overview.md new file mode 100644 index 000000000..d431079c6 --- /dev/null +++ b/docs/data/middleware-overview.md @@ -0,0 +1,112 @@ +--- +id: middleware +title: Using Middleware +--- + + + + +## Overview + +Middleware allows you to extend Amplitude by running a sequence of custom code on every event. This pattern is flexible and you can use it to support event enrichment, transformation, filtering, routing to third-party destinations, and more. + +Each Middleware is a simple function with this signature: + +```js +function (payload: MiddlewarePayload: next: MiddlewareNext): void; +``` + +The `payload` contains the `event` to send and an optional `extra` that lets you pass custom data to your own Middleware implementations. + +To invoke the next Middleware in the queue, use the `next` function. You must call `next(payload)` to continue the Middleware chain. If a Middleware doesn't call `next`, then the event processing stop executing after the current Middleware completes. + +Add middleware to Ampli via `ampli.client.addEventMiddleware()`. You can add as many Middleware as you like. Each Middleware runs in the order in which it's added. + +```js +const loggingMiddleware: Middleware = (payload, next) => { + console.log(`[ampli] event=${payload.event} extra=${payload.extra}`); + // continue to next middleware in chain + next(payload); +} + +const filteringMiddleware: Middleware = (payload, next) => { + const {eventType} = payload.event; + if (shouldSendEvent(eventType)) { + next(payload) + } else { + // event will not continue to following middleware or be sent to Amplitude + console.log(`Filtered event: ${eventType}`); + } +} + +ampli.client.addEventMiddleware(loggingMiddleware) +ampli.client.addEventMiddleware(filteringMiddleware) +``` +## Middleware examples + +**Modifying events** + +```js +ampli.client.addEventMiddleware((payload, next) => { + const { event } = payload; + if (hasPii(event.properties)) { + obfuscate(payload.event.properties); + } + next(payload); +}); +``` +**Enriching events** + +```js +ampli.client.addEventMiddleware((payload, next) => { + const { event } = payload; + if (needsDeviceId(event)) { + payload.event.deviceId = getDeviceId(); + } + next(payload) +}); +``` +**Basic filtering** + +```js +ampli.client.addEventMiddleware((payload, next) => { + const { event } = payload; + if (event.name !== 'Event to Skip') { + next(payload); + } +}); +``` + +**Forwarding data to other services, but not Amplitude** + +```js +import amplitude from 'amplitude/sdk' +import ampli = './ampli'; +import adroll from 'adroll'; +import segment from 'segment'; +import snowplow from 'snowplow'; + +ampli.client.addEventMiddleware((payload, next) => { + const { event, extra } = payload; + segment.track(event.name, event.properties, { extra.anonymousId }) + adroll.track(); + snowplow.track(event.name, event.properties, extra.snowplow.context); + // next(); +}); +``` +**Using client-side validation** + +```js +ampli.client.addEventMiddleware((payload, next) => { + if (isDevelopment && !SchemaValidator.isValid(payload.event)) { + throw Error(`Invalid event ${event.name}`); + } + next(payload); +}); + +ampli.client.addEventMiddleware((payload, next) => { + const { event, extra } = payload; + segment.track(event.name, event.properties, { extra.segment.anonymousId }) + next(payload); +}); +``` \ No newline at end of file diff --git a/docs/data/nodejs-ampli.md b/docs/data/nodejs-ampli.md index b039038a9..924e5773c 100644 --- a/docs/data/nodejs-ampli.md +++ b/docs/data/nodejs-ampli.md @@ -1,6 +1,495 @@ --- id: nodejs-ampli title: Node.js -icon: material/nodejs --- -# Node.js \ No newline at end of file + + + + +:::note +This page covers Node.js JavaScript and TypeScript runtimes. All (Itly) runtimes are deprecated. If you are still using an (Itly) runtime, see the **[migration guide](#migrating-from-previous-version)** to ugrade to the newest runtime. Docs for the Itly version are available **[here](browser)**. +::: + + +Iteratively supports tracking analytics events from Node.js apps written in JavaScript (ES6 and above) and TypeScript (2.1 and above). The generated tracking library is packaged as a CJS module. + +The tracking library exposes a function for every event in your team’s tracking plan. The function’s arguments correspond to the event’s properties and are strongly typed to allow for code completion and compile-time checks. + +:::tip +Because JavaScript is not a type-safe language, static type checking isn't built in like TypeScript. Some common IDEs allow for real-time type checks in JavaScript based on JSDoc. For a better development experience Ampli generates JSDocs for all methods and classes. + +To enable real-time type checking in VSCode for JavaScript: + +1. Go to **Preferences > Settings** then search for **checkJs**. +2. Select **JS/TS > Implicit Project Config: Check JS**. + +After it's activated, type errors appear directly in the IDE. + +Jetbrains provides similar support: + +1. Go to **Preferences > Editor > Inspections > JavaScript and TypeScript > General**. +2. In **Signature mismatch** and **Type mismatch**, set the **Severity** to Warning or Error based on your desired level of strictness. + +::: + +## Installation + +These instructions are also available from the **Implementation** page of your Iteratively workspace. + +### Install the Ampli CLI + +If you haven't installed the Ampli CLI, [install it now](using-the-ampli-cli). + +### Install dependencies + +If you haven't already, install the core Amplitude SDK dependencies. + +```bash +npm install @amplitude/node @amplitude/identify @amplitude/types +``` + + +### Pull the SDK into your project + +At the project root, run `pull` command. + +```bash +ampli pull +``` + +This prompts you to log in to your workspace and select a source. + + + + +```bash +➜ ampli pull sourcename +Ampli project is not initialized. No existing `ampli.json` configuration found. +? Create a new Ampli project here? Yes +Organization: Amplitude +Workspace: My Workspace +Source: sourcename +Runtime: Node.js - JavaScript +Branch: main +Pulling latest version (1.0.0)... +Tracking library generated successfully. +Path: ./src/itly +``` + + + + +```bash +➜ ampli pull sourcename +Ampli project is not initialized. No existing `ampli.json` configuration found. +? Create a new Ampli project here? Yes +Organization: Amplitude +Workspace: My Workspace +Source: sourcename +Runtime: Node.js - TypeScript +Branch: main +Pulling latest version (1.0.0)... +Tracking library generated successfully. +Path: ./src/itly +``` + + + + +## API + +### Load + +Initialize Ampli in your code. + + + + +```js +const { ampli } = require('./ampli'); +ampli.load({ environment: 'production' }); +``` + + + + +```js +import { ampli } from './ampli'; +ampli.load({ environment: 'production' }); +``` + + + + +The `load()` function accepts an options object to configure the SDK's behavior: + + + +| Option | Type | Required | Description | +| --------------- | --------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `disabled` | Boolean | optional | Specifies whether the Ampli SDK does any work. When `true`, all calls to the Ampli SDK will be no-ops. Useful in local or development environments.

Defaults to `false`. | +| `environment` | String | optional | Specifies the environment the Ampli SDK is running in: `production` or `development`.

Environment determines which Access Token is used to load the underlying analytics provider libraries.

Defaults to `development`. | +| `client.apiKey` | String | optional |Specifies an API Key. This option overrides the default, which is the API Key configured in your tracking plan.| +|`client.instance`| AmplitudeClient | optional | Specifies an Amplitude instance. By default Ampli creates an instance for you.| +| `client.config` | Amplitude.Config | optional | Overrides the default configuration for the AmplitudeClient.| + +### Identify + +Call `identify()` to set user properties. + +Just as Ampli creates types for events and their properties, it creates types for user properties. + +The `identify()` function accepts an optional `userId`, optional user `properties`, and optional `options`. + +For example, your tracking plan contains a user property called `role`. The property's type is a string. + + + + +```js +ampli.identify('user-id', { + role: 'Admin' +}); +``` + + + + +```js +ampli.identify('user-id', { + role: 'Admin' +}); +``` + + + + +
+ +The options argument allows you to pass [Amplitude fields](https://developers.amplitude.com/docs/http-api-v2#keys-for-the-event-argument) for this call, such as `deviceId`. + + + + + +```js +ampli.identify('user-id', { + role: 'admin' +}, { + deviceId: 'my-device-id' +}); +``` + + + + +```js +ampli.identify('user-id', { + role: 'admin' +}, { + deviceId: 'my-device-id' +}); +``` + + + + +### Group + +:::note +This feature is available for Growth customers who have purchased the [Accounts add-on](https://help.amplitude.com/hc/en-us/articles/115001765532). +::: + +Call `setGroup()` to associate a user with their group (for example, their department or company). The `setGroup()` function accepts a required `groupType`, and `groupName`. + + + + +```js +ampli.setGroup('user-id', 'Group name', 'Group Value'); +``` + + + + +```js +ampli.setGroup('user-id', 'Group name', 'Group Value'); +``` + + + + +Amplitude supports assigning users to groups and performing queries, such as Count by Distinct, on those groups. If at least one member of the group has performed the specific event, then the count includes the group. + +For example, you want to group your users based on what organization they're in by using an 'orgId'. Joe is in 'orgId' '10', and Sue is in 'orgId' '15'. Sue and Joe both perform a certain event. You can query their organizations in the Event Segmentation Chart. + +When setting groups, define a `groupType` and `groupName`. In the previous example, 'orgId' is the `groupType` and '10' and '15' are the values for `groupName`. Another example of a `groupType` could be 'sport' with `groupName` values like 'tennis' and 'baseball'. + + Setting a group also sets the 'groupType:groupName' as a user property, and overwrites any existing groupName value set for that user's groupType, and the corresponding user property value. groupType is a string, and groupName can be either a string or an array of strings to indicate a user being in multiple groups. For example, if Joe is in 'orgId' '10' and '20', then the `groupName` is '[10, 20]'). + + Your code might look like this: + + + + +```js +ampli.setGroup('user-id', 'orgId', ['10', '20']); +``` + + + + +```js +ampli.setGroup('user-id', 'orgId', ['10', '20']); +``` + + + + + +### Track + +To track an event, call the event's corresponding function. Every event in your tracking plan gets its own function in the Ampli SDK. The call is structured like this: + + + + +```js +ampli.eventName( + userId: string | undefined, + properties: EventProperties, + options: EventOptions, + extra: MiddlewareExtra +) +``` + + + + +```js +ampli.eventName( + userId: string | undefined, + properties: EventNameProperties, + options: EventOptions, + extra: MiddlewareExtra +) +``` + + + +`userId` in multi-tenant, server environments a `userId` must be provided for each tracking call to associate it to a + +`properties` passes in event properties specific to this event in the tracking plan. + +The `options` argument allows you to pass to pass [Amplitude fields](https://developers.amplitude.com/docs/http-api-v2#properties-1), like `price`, `quanity` and `revenue`. + +The `extra` argument lets you pass data to middleware. + +For example, your tracking plan contains an event called Song Played. The SDK generates the `songPlayed` function for the event, using camelcase to make it valid JavaScript. The event is defined with two required properties: `songId` and `songFavorited.` The property type for `songId` is string, and `songFavorited` is a boolean. + +The event has two Amplitude fields defined: `price`, and `quantity`. Learn more about Amplitude fields [here](https://developers.amplitude.com/docs/http-api-v2#properties-1). The event has one MiddlewareExtra defined: `myMiddleware`. Learn more about [Middleware](#middleware). + + + + + +```js +ampli.songPlayed('ampli-user-id', { + songId: 'songId', // string, + songFavorited: true, // boolean +}, { + price: 1.23, + quantity: 2 +}, { + myMiddleware: { myMiddlewareProp: "value to send to middleware" } +}); +``` + + + + +```js +ampli.songPlayed('ampli-user-id', { + songId: 'songId', // string, + songFavorited: true, // boolean +}, { + price: 1.23, + quantity: 2 +}, { + myMiddleware: { myMiddlewareProp: "value to send to middleware" } +}); +``` + + + + + +Ampli also generates a class for each event. + + + + +```js +const myEventObject = new SongPlayed({ + songId: 'songId', // string, + songFavorited: true, // boolean +}); +``` + + + + +```js +const myEventObject = new SongPlayed({ + songId: 'songId', // string, + songFavorited: true, // boolean +}); +``` + + + + +Track Event objects using Ampli `track`: + + + + +```js +ampli.track('ampli-user-id', new SongPlayed({ + songId: 'songId', // string, + songFavorited: true, // boolean +})); +``` + + + + +```js +ampli.track('ampli-user-id', new SongPlayed({ + songId: 'songId', // string, + songFavorited: true, // boolean +})); +``` + + + + +
+ +## Verify implementation status + +Verify events are implemented in your code with the status command: + +```bash +ampli status +``` + +To update the implementation status in your tracking plan use the `--update` flag or `-u`: + +```bash +ampli status -u +``` +The output displays status and indicates what events are missing. + +```bash +➜ ampli status +✘ Verifying event tracking implementation in source code + ✔ Song Played (1 location) + ✘ Song Stopped Called when a user stops playing a song. +Events Tracked: 2 missed, 3 total +``` +Learn more about [`ampli status`](https://developers.data.amplitude.com/using-the-ampli-cli/#ampli-status). + +## Migrating from an Itly Browser runtime + +Migrate from an Itly Browser runtime to Ampli by following these steps. + +1. Update Source runtime. In the web app open the **Connections > Source** modal. From the dropdown, update the source to a non-`(Itly)` runtime. +2. Go to the **Implementation** page, then select the new Source for detailed setup and usage instructions. +3. Remove legacy Itly dependencies from your project. This includes anything that contains `@itly`: + + `yarn remove @itly/sdk @itly/plugin-schema-validator @itly/plugin-amplitude-node ...` +4. Add Amplitude dependencies: + + `yarn add @amplitude/node` + +5. Pull the latest Ampli SDK: + + `ampli pull` + +6. Find and replace: + - `import { itly } from '../itly'` => `import { ampli } from '../ampli'` + - `itly.group(userId, groupId) => ampli.setGroup(userId, groupType, groupName)` + - `itly.load()` => `ampli.load()` + - All `itly.` with `ampli.` +7. See updated Event tracking details on your Implementation page in the web app. diff --git a/docs/data/nodejs-legacy.md b/docs/data/nodejs-legacy.md new file mode 100644 index 000000000..6f675ae38 --- /dev/null +++ b/docs/data/nodejs-legacy.md @@ -0,0 +1,386 @@ +--- +id: nodejs-legacy +title: Node.js (Legacy) +--- + + + +Iteratively supports tracking analytics events from Node.js apps written in JavaScript (ES6 and above) and TypeScript (2.1 and above). The generated tracking library is packaged as a CJS module. + +In TypeScript, the tracking library exposes a type-safe function for every event in your team’s tracking plan. The function’s arguments correspond to the event’s properties and are strongly typed to allow for code completion and compile-time checks. + +Since JavaScript is not a type-safe language, the library won't expose type-safe functions for the events in your team’s tracking plan. Instead, the auto-generated library performs those checks at runtime. + +## Installation + +### Generate the SDK + +If you have not yet installed the Ampli CLI, [install it now](using-the-ampli-cli). + +To generate the Itly SDK, run `ampli pull {source}` in the folder with your package.json file. By default, the SDK will be generated in `./src/itly/`. + +:::note Tip +`{source}` is the name of the source you created in your tracking plan (e.g. `backend`). +::: + +### Install dependencies + +The generated Itly SDK has several dependencies. To install them, run: + + + + +```bash +npm install @itly/sdk \ + @itly/plugin-schema-validator +``` + + + + +```bash +yarn add @itly/sdk \ + @itly/plugin-schema-validator +``` + + + + +If you're using Segment or Amplitude, the SDK will also depend on a few additional plugins that must be installed before your project will compile: + + + + +```bash +# if you're using Segment +npm install @itly/plugin-segment-node +# if you're using Amplitude +npm install @itly/plugin-amplitude-node +``` + + + + +```bash +# if you're using Segment +yarn add @itly/plugin-segment-node +# if you're using Amplitude +yarn add @itly/plugin-amplitude-node +``` + + + + +:::note Note +- To validate your analytics events, the SDK depends on [ajv](https://github.com/ajv-validator/ajv) (MIT). + +- To send events to Segment, the SDK depends on [analytics-node](https://github.com/segmentio/analytics-node) (MIT). + +- To send events to Amplitude, the SDK depends on [amplitude](https://github.com/geoffdutton/amplitude). +::: + +### Import into your app + +To use the library, you'll need to import it first: + + + + +```js +import itly from './itly'; +``` + + + + +```js +const itly = require('./itly'); +``` + + + + +You can now call functions on `itly` directly. + +:::note Note +Adjust the relative import path to the location where `ampli pull` generated your SDK. By default, this path is `./src/itly`. +::: + +## API + +### Load + +Load the Itly SDK once when your application starts. The `load()` function accepts an options object to configure the SDK's behavior: + + + + +```js +itly.load({ environment: 'development' }); +``` + + + + +```js +itly.load({ environment: 'development' }); +``` + + + + +| Option |||| +|-|-|-|-| +| `context`| Object
`Context` | required | An object with a set of properties to add to every event sent by the Itly SDK.

Only available if there is at least one [source template](working-with-templates#adding-a-template-to-a-source) associated with your your team's tracking plan.| +| `disabled`| Boolean | optional | Specifies whether the Itly SDK does any work. When `true`, all calls to the Itly SDK will be no-ops. Useful in local or development environments.

Defaults to `false`.| +| `environment` | String | optional | Specifies the environment the Itly SDK is running in: `production` or `development`.

Environment determines which Access Token is used to load the underlying analytics provider libraries.

The option also determines safe defaults for handling event validation errors. In production, when the SDK detects an invalid event, it will log an error but still let the event through. In development, the SDK will throw an exception to alert you that something is wrong.

Defaults to `development`.| +| `destinations` | Object
`DestinationsOptions` | optional | Specifies any analytics provider-specific configuration. The Itly SDK passes these objects in when loading the underlying analytics provider libraries.| +| `validation` | Object
`ValidationOptions` | optional | Configures the Itly SDK's behavior when events or traits fail validation against your tracking plan. Supports the following properties:

`disabled`
Disables validation altogether. Defaults to `false`.

`trackInvalid`
Secifies whether events that failed validation should still be tracked. Defaults to `false` in development, `true` in production.

`errorOnInvalid`
Specifies whether the SDK should throw an exception when validation fails. Defaults to `true` in development, `false` in production.| +| `plugins` | Array | optional | An array of additional plugins to load into the Itly SDK. Plugins allow you to extend the Itly SDK's event validation and event tracking functionality with your own. For example, a plugin can be used to implement a custom destination or a custom event validator.

[Click here](#custom-destination) to learn about writing a custom destination plugin.

[Click here](https://bitbucket.org/seasyd/examples/src/master/browser-javascript/src/CustomDestination.js) to see a sample custom destination plugin written in JavaScript.

[Click here](https://bitbucket.org/seasyd/examples/src/master/browser-typescript/src/CustomDestination.ts) to see a sample custom destination plugin written in TypeScript.| + +### Identify + +Call `identify()` to set a particular user's traits. + +Just as Iteratively creates types for events and their properties (and validates them at runtime), Iteratively creates types for user traits (and validates them at runtime). + +The `identify()` function accepts a required `userId` and required `traits`. + +For example, in the code snippet below, our tracking plan contains a user trait called `role`. The trait's type is a string. + + + + +```js +itly.identify('user-id', { role: 'admin' }); +``` + + + + +```js +itly.identify('user-id', { role: 'admin' }); +``` + + + + +### Group + +Call `group()` to associate a user with their group (for example, their department or company), or to set the group's traits. + +Just as Iteratively creates types for events and their properties (and validates them at runtime), Iteratively creates types for group traits (and validates them at runtime). + +The `group()` function accepts a required `userId`, `groupId`, and optional `traits`. + +For example, in the code snippet below, our tracking plan contains a group trait called `name`. The trait's type is a string. + + + + +```js +itly.group('user-id', 'group-id', { name: 'Iteratively, Inc.' }); +``` + + + + +```js +itly.group('user-id', 'group-id', { name: 'Iteratively, Inc.' }); +``` + + + + +### Track + +To track an event, call the event’s corresponding function. Every event in your tracking plan gets its own function in the Itly SDK. + +For example, in the code snippet below, our tracking plan contains an event called `Process Started`. The event was defined with one required property called `availableProcessors`. The property's type is an integer. + + + + +```js +itly.processStarted({ availableProcessors: os.cpus().length }); +``` + + + + +```js +itly.processStarted({ availableProcessors: os.cpus().length }); +``` + + + + + + +## Custom Destination + +:::note Advanced +If you're using Iteratively with Amplitude or Segment, you can safely skip this section! +::: + +To send clean, valid events to custom analytics destinations, or those not yet supported by the Itly SDK natively, the SDK is extensible via plugins. Writing a plugin is easy! Extend the `PluginBase` class, override `track()`, and include your new plugin in the `plugins` array when calling `itly.load()`. + +Plugins allow you to implement your own processing logic for analytics tracking. When you call a function on the Itly SDK, the SDK will first validate your event (or user, group, and page properties) against your tracking plan, then call into your plugin's implementation. + +The following functions are available to override when developing your plugin. Only override those functions that matter to your custom destination. + +:::note Examples +A sample custom destination plugin is available [here](https://bitbucket.org/seasyd/examples/src/master/browser-javascript/src/CustomDestination.js) in JavaScript and [here](https://bitbucket.org/seasyd/examples/src/master/browser-typescript/src/CustomDestination.ts) in TypeScript. +::: + +#### ID +Every plugin has a unique ID. To set one, override `id()` and return your plugin's ID. The function has the following signature: + +```javascript +id(): string; +``` +
+ +#### Load +Called when the Itly SDK is being loaded and is ready to load your plugin. The function has the following signature: + +```javascript +load(options: Options): void; +``` + +| Argument |||| +|-|-|-|-| +| `options` | Object
`Options` | required | The [same](#load) configuration object passed to `itly.load()` when the SDK was being initialized. | +
+ +#### Alias +Called when Itly SDK's `alias()` function is called to associate one user ID with another (typically a known user ID with an anonymous one). The `alias()` function has the following signature: + +```javascript +alias(userId: string, previousId: string): void; +``` + +| Argument | Type || Description | +|-|-|-|-| +| `userId` | String | required | The ID that the user will be identified by going forward. This is typically the user's database ID (as opposed to an anonymous ID), or their updated ID (for example, if the ID is an email address which the user just updated). | +| `previousId` | String | required | The ID the user has been identified by so far. | +
+ +#### Identify +Called when Itly SDK's `identify()` function is called to identify a user with a specific ID or set the user's traits. The `identify()` function has the following signature: + +```javascript +identify(userId: string, properties: Properties): void; +``` + +| Argument | Type || Description | +|-|-|-|-| +| `userId` | String | required | The user's ID, if it was provided to `itly.identify()`. The ID may not be provided if `identify()` was called only to update the user's traits. | +| `properties` | Object
`Properties` | required | The user's traits. | +
+ +#### Track +Called when an event is tracked. The function receives a validated event with its complete set of properties (a combination of the event's own properties any any other properties associated with the source via a [source template](working-with-templates#adding-a-template-to-a-source)) The `track()` function has the following signature: + +```javascript +track(userId: string, event: Event): void; +``` + +| Argument | Type || Description | +|-|-|-|-| +| `userId` | String | required | Always undefined in the Browser SDK. | +| `event` | Object
`Event` | required | The event that was tracked by the Itly SDK. The event object contains the following properties:

`name`
The event's name.

`properties`
The event's properties.

`id`
The event's unique ID in Iteratively.

`version`
The event's version, e.g. 2.0.1.

| +
+ +#### Group +Called when Itly SDK's `group()` function is called to associate the user with a specific account (for example, their department or company) or set the group's properties. The `group()` function has the following signature: + +```javascript +group(userId: string, groupId: string, properties?: Properties | undefined): void; +``` + +| Argument | Type || Description | +|-|-|-|-| +| `userId` | String | required | Always undefined in the Browser SDK. | +| `groupId` | String | required | The ID of the group (for example, the user's department or company) to associate the user with. | +| `properties` | Object
`Properties` | optional | The group's traits. | +
+ +#### Page +Called when Itly SDK's `page()` function is called to track a page view in a web application. The `page()` function has the following signature: + +```javascript +page(userId: string, category: string | undefined, name: string | undefined, properties: Properties | undefined): void; +``` + +| Argument | Type || Description | +|-|-|-|-| +| `userId` | String | required | Always undefined in the Browser SDK. | +| `category` | String | optional | The page's category. Useful when many pages might live under a single category. | +| `name` | String | optional | The page's name. | +| `properties` | Object
`Properties` | optional | The page's traits. | +
+ +#### Reset +Called when Itly SDK's `reset()` function is called to reset the SDK's (and all plugins') state. This method is usually called when a user logs out. The `reset()` function has the following signature: + +```javascript +reset(): void; +``` + + diff --git a/docs/data/nodejs.md b/docs/data/nodejs.md new file mode 100644 index 000000000..9ea2bf939 --- /dev/null +++ b/docs/data/nodejs.md @@ -0,0 +1,669 @@ +--- +id: nodejs +title: Node.js (Itly) +--- + + + +:::note Previous Version +Still using the **Node.js (Legacy)** runtime? Docs for the previous version are available [here](nodejs-legacy). +::: +:::note Migrating +Migrating from **Node.js (Legacy)** to the new **Node.js** runtime? A migration guide is available [here](#migrating-from-previous-version). +::: + +Iteratively supports tracking analytics events from Node.js apps written in JavaScript (ES6 and above) and TypeScript (2.1 and above). The generated tracking library is packaged as a CJS module. + +In TypeScript, the tracking library exposes a type-safe function for every event in your team’s tracking plan. The function’s arguments correspond to the event’s properties and are strongly typed to allow for code completion and compile-time checks. + +Since JavaScript is not a type-safe language, the library won't expose type-safe functions for the events in your team’s tracking plan. Instead, the auto-generated library performs those checks at runtime. + +## Installation + +### Generate the SDK + +If you have not yet installed the Ampli CLI, [install it now](using-the-ampli-cli). + +To generate the Itly SDK, run `ampli pull {source}` in the folder with your package.json file. By default, the SDK will be generated in `./src/itly/`. + +:::note Tip +`{source}` is the name of the source you created in your tracking plan (e.g. `backend`). +::: + +### Install dependencies + +:::note Tip +When you run `ampli pull {source}` for the first time, the Ampli CLI will provide an npm/yarn install command specific to your tracking plan that will include all required dependencies. +::: + +The generated Itly SDK has several dependencies. To install them, run: + + + + +```bash +npm install @itly/sdk \ + @itly/plugin-schema-validator +``` + + + + +```bash +yarn add @itly/sdk \ + @itly/plugin-schema-validator +``` + + + + +If you're using Segment or Amplitude, the SDK will also depend on a few additional plugins that must be installed before your project will compile: + + + + +```bash +# if you're using Segment +npm install @itly/plugin-segment-node +# if you're using Amplitude +npm install @itly/plugin-amplitude-node +``` + + + + +```bash +# if you're using Segment +yarn add @itly/plugin-segment-node +# if you're using Amplitude +yarn add @itly/plugin-amplitude-node +``` + + + + +:::note Note +- To validate your analytics events, the SDK depends on [ajv](https://github.com/ajv-validator/ajv) (MIT). + +- To send events to Segment, the SDK depends on [analytics-node](https://github.com/segmentio/analytics-node) (MIT). + +- To send events to Amplitude, the SDK depends on [amplitude](https://github.com/geoffdutton/amplitude) (ISC). +::: + +### Import into your app + +To use the library, you'll need to import it first: + + + + +```js +import itly from './itly'; +``` + + + + +```js +const itly = require('./itly'); +``` + + + + +You can now call functions on `itly` directly. + +:::note Note +Adjust the relative import path to the location where `ampli pull` generated your SDK. By default, this path is `./src/itly`. +::: + +## API + +### Load + +Load the Itly SDK once when your application starts. The `load()` function accepts an options object to configure the SDK's behavior: + + + + +```js +itly.load({ environment: 'development' }); +``` + + + + +```js +itly.load({ environment: 'development' }); +``` + + + + +| Option |||| +|-|-|-|-| +| `context`| Object
`Context` | required | An object with a set of properties to add to every event sent by the Itly SDK.

Only available if there is at least one [source template](working-with-templates#adding-a-template-to-a-source) associated with your your team's tracking plan.| +| `disabled`| Boolean | optional | Specifies whether the Itly SDK does any work. When `true`, all calls to the Itly SDK will be no-ops. Useful in local or development environments.

Defaults to `false`.| +| `environment` | String | optional | Specifies the environment the Itly SDK is running in: `production` or `development`.

Environment determines which Access Token is used to load the underlying analytics provider libraries.

The option also determines safe defaults for handling event validation errors. In production, when the SDK detects an invalid event, it will log an error but still let the event through. In development, the SDK will throw an exception to alert you that something is wrong.

Defaults to `development`.| +| `destinations` | Object
`DestinationsOptions` | optional | Specifies any analytics provider-specific configuration. The Itly SDK passes these objects in when loading the underlying analytics provider libraries.| +| `validation` | Enum
`Validation` | optional | Configures the Itly SDK's behavior when events or traits fail validation against your tracking plan. Supports the following options:

`Disabled`
Disables validation altogether.

`TrackOnInvalid`
Specifies whether events that failed validation should still be tracked.

`ErrorOnInvalid`
Specifies whether the SDK should throw an exception when validation fails.

Defaults to `ErrorOnInvalid` in development, `TrackOnInvalid` in production.| +| `plugins` | Array | optional | An array of additional plugins to load into the Itly SDK. Plugins allow you to extend the Itly SDK's event validation and event tracking functionality with your own. For example, a plugin can be used to implement a custom destination or a custom event validator.

[Click here](#custom-destination) to learn about writing a custom destination plugin.

[Click here](https://bitbucket.org/seasyd/examples/src/master/browser-javascript-v3/src/CustomDestination.js) to see a sample custom destination plugin written in JavaScript.

[Click here](https://bitbucket.org/seasyd/examples/src/master/browser-typescript-v3/src/CustomDestination.ts) to see a sample custom destination plugin written in TypeScript.| + +### Identify + +Call `identify()` to set a particular user's traits. + +Just as Iteratively creates types for events and their properties (and validates them at runtime), Iteratively creates types for user traits (and validates them at runtime). + +The `identify()` function accepts a required `userId`, required `traits`, and optional `options`. + +For example, in the code snippet below, our tracking plan contains a user trait called `role`. The trait's type is a string. + + + + +```js +itly.identify('user-id', { role: 'admin' }); +``` + + + + +```js +itly.identify('user-id', { role: 'admin' }); +``` + + + + +The `options` argument allows you to pass additional metadata about this call, such as a callback function or custom configuration, to the SDK's destinations. For example, to specify that Segment should only send data to Intercom and Google Analytics: + + + + +```js +itly.identify( + 'user-id', + { + role: 'admin', + }, + { + segment: { + options: { + integrations: { + 'All': false, + 'Intercom': true, + 'Google Analytics': true + } + } + } + } +); +``` + + + + +```js +itly.identify( + 'user-id', + { + role: 'admin', + }, + { + segment: { + options: { + integrations: { + 'All': false, + 'Intercom': true, + 'Google Analytics': true + } + } + } + } +); +``` + + + + +### Group + +Call `group()` to associate a user with their group (for example, their department or company), or to set the group's traits. + +Just as Iteratively creates types for events and their properties (and validates them at runtime), Iteratively creates types for group traits (and validates them at runtime). + +The `group()` function accepts a required `userId`, `groupId`, optional `traits`, and optional `options`. + +For example, in the code snippet below, our tracking plan contains a group trait called `name`. The trait's type is a string. + + + + +```js +itly.group('user-id', 'group-id', { name: 'Iteratively, Inc.' }); +``` + + + + +```js +itly.group('user-id', 'group-id', { name: 'Iteratively, Inc.' }); +``` + + + + +
+ +The `options` argument allows you to pass additional metadata about this call, such as a callback function or custom configuration, to the SDK's destinations. For example, to specify that Segment should invoke a callback function when it's done calling `group()`: + + + + +```js +itly.group('user-id', 'group-id', { name: 'Iteratively, Inc.' }, { + segment: { + callback: () => console.log('Segment is done!'), + } +}); +``` + + + + +```js +itly.group('user-id', 'group-id', { name: 'Iteratively, Inc.' }, { + segment: { + callback: () => console.log('Segment is done!'), + } +}); +``` + + + + +### Track + +To track an event, call the event’s corresponding function. Every event in your tracking plan gets its own function in the Itly SDK. + +For example, in the code snippet below, our tracking plan contains an event called `Process Started`. The event was defined with one required property called `availableProcessors`. The property's type is an integer. + + + + +```js +itly.processStarted('user-id', { availableProcessors: os.cpus().length }); +``` + + + + +```js +itly.processStarted('user-id', { availableProcessors: os.cpus().length }); +``` + + + + +
+ +The `options` argument allows you to pass additional metadata about this call, such as a callback function or custom configuration, to the SDK's destinations. For example, to specify that Segment should only track the event to Intercom and Google Analytics: + + + + +```js +itly.processStarted('user-id', { availableProcessors: os.cpus().length }, + { + segment: { + options: { + integrations: { + 'All': false, + 'Intercom': true, + 'Google Analytics': true + } + } + } + } +); +``` + + + + +```js +itly.processStarted('user-id', { availableProcessors: os.cpus().length }, + { + segment: { + options: { + integrations: { + 'All': false, + 'Intercom': true, + 'Google Analytics': true + } + } + } + } +); +``` + + + + +## Custom Destination + +:::note Advanced +If you're using Iteratively with Amplitude or Segment, you can safely skip this section! +::: + +To send clean, valid events to custom analytics destinations, or those not yet supported by the Itly SDK natively, the SDK is extensible via plugins. Writing a plugin is easy! Extend the `Plugin` class, call the base constructors with your plugin's ID, override `track()`, and include your new plugin in the `plugins` array when calling `itly.load()`. + +Plugins allow you to implement your own processing logic for analytics tracking. When you call a function on the Itly SDK, the SDK will first validate your event (or user, group, and page properties) against your tracking plan, then call into your plugin's implementation. + +The following functions are available to override when developing your plugin. Only override those functions that matter to your custom destination. + +:::note Examples +A sample custom destination plugin is available [here](https://bitbucket.org/seasyd/examples/src/master/browser-javascript-v3/src/CustomDestination.js) in JavaScript and [here](https://bitbucket.org/seasyd/examples/src/master/browser-typescript-v3/src/CustomDestination.ts) in TypeScript. +::: + +#### Constructor +Every plugin needs a unique ID. To provide one, add a constructor to your plugin and call the base constructor with your plugin's ID. This might look something like this: + +```javascript + constructor() { + super('custom-destination'); + } +``` +
+ +#### Load +Called when the Itly SDK is being loaded and is ready to load your plugin. The function has the following signature: + +```javascript +load(options: Options): void; +``` + +| Argument |||| +|-|-|-|-| +| `options` | Object
`Options` | required | The [same](#load) configuration object passed to `itly.load()` when the SDK was being initialized. | +
+ +#### Alias +Called when Itly SDK's `alias()` function is called to associate one user ID with another (typically a known user ID with an anonymous one). The `alias()` function has the following signature: + +```javascript +alias(userId: string, previousId: string, options: AliasOptions | undefined): void; +``` + +| Argument | Type || Description | +|-|-|-|-| +| `userId` | String | required | The ID that the user will be identified by going forward. This is typically the user's database ID (as opposed to an anonymous ID), or their updated ID (for example, if the ID is an email address which the user just updated). | +| `previousId` | String | required | The ID the user has been identified by so far. | +| `options` | AliasOptions | optional | See [Call Options](#call-options). | +
+ +#### Identify +Called when Itly SDK's `identify()` function is called to identify a user with a specific ID or set the user's traits. The `identify()` function has the following signature: + +```javascript +identify(userId: string, properties: Properties, options: IdentifyOptions | undefined): void; +``` + +| Argument | Type || Description | +|-|-|-|-| +| `userId` | String | required | The user's ID, if it was provided to `itly.identify()`. The ID may not be provided if `identify()` was called only to update the user's traits. | +| `properties` | Object
`Properties` | required | The user's traits. | +| `options` | IdentifyOptions | optional | See [Call Options](#call-options). | +
+ +#### Track +Called when an event is tracked. The function receives a validated event with its complete set of properties (a combination of the event's own properties any any other properties associated with the source via a [source template](working-with-templates#adding-a-template-to-a-source)) The `track()` function has the following signature: + +```javascript +track(userId: string, event: Event, options: TrackOptions | undefined): void; +``` + +| Argument | Type || Description | +|-|-|-|-| +| `userId` | String | required | Always undefined in the Browser SDK. | +| `event` | Object
`Event` | required | The event that was tracked by the Itly SDK. The event object contains the following properties:

`name`
The event's name.

`properties`
The event's properties.

`id`
The event's unique ID in Iteratively.

`version`
The event's version, e.g. 2.0.1.

| +| `options` | TrackOptions | optional | See [Call Options](#call-options). | +
+ +#### Group +Called when Itly SDK's `group()` function is called to associate the user with a specific account (for example, their department or company) or set the group's properties. The `group()` function has the following signature: + +```javascript +group(userId: string, groupId: string, properties?: Properties | undefined, options: GroupOptions | undefined): void; +``` + +| Argument | Type || Description | +|-|-|-|-| +| `userId` | String | required | Always undefined in the Browser SDK. | +| `groupId` | String | required | The ID of the group (for example, the user's department or company) to associate the user with. | +| `properties` | Object
`Properties` | optional | The group's traits. | +| `options` | GroupOptions | optional | See [Call Options](#call-options). | +
+ +#### Page +Called when Itly SDK's `page()` function is called to track a page view in a web application. The `page()` function has the following signature: + +```javascript +page(userId: string, category: string | undefined, name: string | undefined, properties: Properties | undefined, options: PageOptions | undefined): void; +``` + +| Argument | Type || Description | +|-|-|-|-| +| `userId` | String | required | Always undefined in the Browser SDK. | +| `category` | String | optional | The page's category. Useful when many pages might live under a single category. | +| `name` | String | optional | The page's name. | +| `properties` | Object
`Properties` | optional | The page's traits. | +| `options` | PageOptions | optional | See [Call Options](#call-options). | +
+ +#### Reset +Called when Itly SDK's `reset()` function is called to reset the SDK's (and all plugins') state. This method is usually called when a user logs out. The `reset()` function has the following signature: + +```javascript +reset(): void; +``` + +#### Call Options + +Call Options are a powerful feature that allows your plugin's users to pass additional per-call metadata, such as a callback function or custom configuration, to your plugin. You can use this metadata to customize your plugin's behavior when processing individual alias, identify, group, page, and track calls. Your plugin's users will provide the metadata intended for your plugin under a field named after the plugin's ID, and your plugin will receive them via the `options` argument. + +For example, let's assume you'd like your plugin's users to tell your plugin whether a particular event they're tracking is awesome. Your instrumention engineers would track the event like this: + + + + +```js +itly.buttonClicked( + /* event's properties */ + { label: 'Send Event' }, + /* event's metadata for the custom destination plugin */ + { 'custom-destination': { awesome: true } as CustomTrackOptions }, +) +``` + + + + +```js +itly.buttonClicked( + /* event's properties */ + { label: 'Send Event' }, + /* event's metadata for the custom destination plugin */ + { 'custom-destination': { awesome: true } }, +) +``` + + + + +
+And your plugin would read the call option metadata like this: + + + + +```js +import { Plugin, Options, Event, PluginCallOptions } from './itly'; + +export interface CustomTrackOptions extends PluginCallOptions { + awesome: boolean; +} + +export default class extends Plugin { + constructor() { + super('custom-destination'); + } + + track(_: string, event: Event, options?: CustomTrackOptions) { + console.log(options?.awesome); + } +} +``` + + + + +```js +import { Plugin } from './itly'; + +export default class extends Plugin { + constructor() { + super('custom-destination'); + } + + track(_, event, options) { + console.log(options?.awesome); + } +} +``` + + + + +## Migrating from Previous Version + +### Introduction + +The new Node.js SDK introduces several new features to help developers implement product analytics. + +### Tracking Plan Changes + +- Update your source's runtime to **Node.js — JavaScript** or **Node.js — TypeScript** (from **Node.js — JavaScript (Legacy)** or **Node.js — TypeScript (Legacy)**, respectively) + +### CLI & Code Changes + +- Make sure you have downloaded the [Ampli CLI](/using-the-ampli-cli) + +- Pull down the new SDK inside your project's folder (the one with the .itlyrc file): + +```bash +ampli pull +``` + +- Validation options are now an enum rather than an object with three boolean fields: + - Remove e.g. `validation: { disabled: true }` from `options` passed to `load()` + - Add `validation: Validation.Disabled` instead, e.g.: + + ```js + itly.load({ + validation: Validation.Disabled, + }); + ``` + +### Custom Destination + +In the new SDK, custom destinations look almost identical. The following changes were made: + +- The `PluginBase` class your plugin extends was renamed to `Plugin` +- The `id()` method was removed. To set a plugin's ID, implement a constructor and call `super('your-plugin-id')` instead +- All plugin methods (except for `load()`, `reset()`, and `flush()`) now accept a new optional argument called `options`. The argument carries additional metadata that the plugin can use to further customize its behavior for a particular identify, track, group, etc. call. The values in this additional metadata object are provided by the analytics tracking developer when making the original call and are passed all the way through to your plugin. \ No newline at end of file diff --git a/docs/data/python-legacy.md b/docs/data/python-legacy.md new file mode 100644 index 000000000..7d1380fb4 --- /dev/null +++ b/docs/data/python-legacy.md @@ -0,0 +1,104 @@ +--- +id: python-legacy +title: Python (Legacy) +--- + + + +Iteratively supports tracking analytics events from Python 3 apps. + +Since Python is not a type-safe language, the library won't expose type-safe functions for the events in your team’s tracking plan. Instead, the auto-generated library performs those checks at runtime. + +## Installation + +### Generate the SDK + +If you have not yet installed the Ampli CLI, [install it now](/using-the-ampli-cli). + +To generate the Itly SDK, run `ampli pull {source}` in the top-most folder of your project. By default, the SDK will be generated in `./itly/`. + +:::note Tip +`{source}` is the name of the source you created in your tracking plan (e.g. `python`). +::: + +### Install dependencies + +To validate your analytics events, the Python SDK depends on [jsonschema](https://github.com/Julian/jsonschema) (MIT). And to work well on both Python 2 and Python 3, it depends on [six](https://pypi.org/project/six/) (MIT), [future](https://pypi.org/project/future/) (MIT), [enum34](https://pypi.org/project/enum34/) (BSD License), and [typing](https://pypi.org/project/typing/) (PSF License). To install these dependencies into your project: + +- Add `-r itly/requirements.txt` to your requirements.txt +- Run `pip` as usual + +You can also run `pip install -r ./itly/requirements.txt` to install the dependencies yourself. + +If you've configured Itly with Segment, the steps above will also install those vendor's SDKs: + +- [analytics-python](https://pypi.org/project/analytics-python/) (MIT) for Segment + +Because Amplitude does not offer a Python SDK, support for Amplitude is built into the Itly SDK itself. + +### Import into your app + +To use the library, you'll need to import it first: + +```python +import itly +``` + +## API + +### Load + +Load the Itly SDK once when your application starts. The `load()` method accepts an options object that lets you configure how the Itly SDK works: + +| Options | Description | +|-|-| +| `context`| An object with a set of properties to add to every event sent by the Itly SDK.

Only available if there is at least one [source template](/working-with-templates#adding-a-template-to-a-source) associated with your your team's tracking plan.| +| `disabled`| Specifies whether the Itly SDK does any work. When true, all calls to the Itly SDK will be no-ops. Useful in local or development environments.

Optional. Defaults to `false`.| +| `environment` | Specifies the environment the Itly SDK is running in: either `production` or `development`. Environment determines which Access Token is used to load the underlying analytics provider libraries.

The option also determines safe defaults for handling event validation errors. In production, when the SDK detects an invalid event, it will log an error but still let the event through. In development, the SDK will throw an exception to alert you that something is wrong.

Optional. Defaults to `development`.| +| `destinations` | Specifies any analytics provider-specific configuration. The Itly SDK passes these objects in when loading the underlying analytics provider libraries.

Optional.| +| `logger` | To log Itly's logs to a custom logger, implement the `ItlyLogger` protocol and set `logger` to an instance of your class. The Itly SDK will call into your class with all debug, info, warn, and error-level messages.

[Click here](https://bitbucket.org/seasyd/examples/src/master/python/itly/_itly.py) to see an example written in Python.

Optional. Defaults to standard out. | +| `validation` | Configures the Itly SDK's behavior when events or traits fail validation against your tracking plan. Supports the following properties:

`disabled`
Disables validation altogether. Defaults to `false`.

`fail_on_error`
Specifies whether the SDK should throw an exception when validation fails. Defaults to `true` in development, `false` in production.| + +For example: + +```python +itly.load(itly.Options( + context=itly.Context( + version="1.0" + ), + logger=SampleLogger(), + destinations=itly.DestinationsOptions( + custom=itly.CustomOptions( + adapter=CustomDestination() + ) + ) +)) +``` + +### Track + +To track an event, call the event’s corresponding function. Every event in your tracking plan gets its own function in the Itly SDK. + +For example, in the code snippet below, our tracking plan contains an event called `Process Started`. The event was defined with one required property called `user_id` and one optional property called `available_processors`. The `user_id` property's type is a string. The `available_processors` property's type an integer. + +```python +itly.process_started("some-user-id", + available_processors=multiprocessing.cpu_count() +) +``` + + + + + + diff --git a/docs/data/python.md b/docs/data/python.md index eb87b3c2c..878daa502 100644 --- a/docs/data/python.md +++ b/docs/data/python.md @@ -1,11 +1,9 @@ --- id: python -title: Python -icon: material/language-python +title: Python (Itly) --- -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; + :::note Previous Version Still using the **Python (Legacy)** runtime? Docs for the previous version are available [here](python-legacy). diff --git a/docs/data/ruby-v2.md b/docs/data/ruby-v2.md index a24646b28..9e67fad50 100644 --- a/docs/data/ruby-v2.md +++ b/docs/data/ruby-v2.md @@ -1,11 +1,9 @@ --- id: ruby-v2 title: Ruby -icon: material/language-ruby --- -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; + :::note Previous Version Still using the **Ruby (Legacy)** runtime? Docs for the previous version are available [here](ruby). diff --git a/docs/data/ruby.md b/docs/data/ruby.md new file mode 100644 index 000000000..6c8b12e6c --- /dev/null +++ b/docs/data/ruby.md @@ -0,0 +1,112 @@ +--- +id: ruby +title: Ruby (Itly) +--- + + + +Iteratively supports tracking analytics events from Ruby apps. + +In Ruby, the tracking library exposes a type-safe function for every event in your team’s tracking plan. The function’s arguments correspond to the event’s properties and are strongly typed to allow for code completion and compile-time checks. + +## Installation + +### Generate the SDK + +If you have not yet installed the Ampli CLI, [install it now](/using-the-ampli-cli). + +To generate the Itly SDK, run `ampli pull {source}` in the top-most folder of your project. By default, the SDK will be generated in `./itly/lib/`. + +:::note Tip +`{source}` is the name of the source you created in your tracking plan (e.g. `ruby`). +::: + +### Install dependencies + +To validate your analytics events, the Ruby SDK depends on [JSONSchemer](https://github.com/davishmcclurg/json_schemer) (MIT). To install this dependency into your project: + +- Add `gem "itly", path: "./itly"` to your `Gemfile` +- Run `bundle install` as usual + +If you've configured Itly with Segment, the steps above will also install those vendor's SDKs: + +- [SimpleSegment](https://github.com/whatthewhat/simple_segment) (MIT) for Segment +- [amplitude-api](https://github.com/toothrot/amplitude-api) (MIT) for Amplitude + + +### Import into your app + +To use the library, you'll need to import it first: + +```python +require 'itly' +``` + +## API + +### Load + +Load the Itly SDK once when your application starts. The `load` method accepts an options object that lets you configure how the Itly SDK works: + +| Options | Description | +|-|-| +| `context`| An object with a set of properties to add to every event sent by the Itly SDK.

Only available if there is at least one [source template](/working-with-templates#adding-a-template-to-a-source) associated with your your team's tracking plan.| +| `disabled`| Specifies whether the Itly SDK does any work. When true, all calls to the Itly SDK will be no-ops. Useful in local or development environments.

Optional. Defaults to `false`.| +| `environment` | Specifies the environment the Itly SDK is running in: either `production` or `development`. Environment determines which Access Token is used to load the underlying analytics provider libraries.

The option also determines safe defaults for handling event validation errors. In production, when the SDK detects an invalid event, it will log an error but still let the event through. In development, the SDK will throw an exception to alert you that something is wrong.

Optional. Defaults to `development`.| +| `destinations` | Specifies any analytics provider-specific configuration. The Itly SDK passes these objects in when loading the underlying analytics provider libraries.

Optional.| +| `logger` | To log Itly's logs to a custom logger, implement the `ItlyLogger` protocol and set `logger` to an instance of your class. The Itly SDK will call into your class with all debug, info, warn, and error-level messages.

[Click here](https://bitbucket.org/seasyd/examples/src/master/ruby/itly/lib/itly/itly_base.rb) to see an example written in Ruby.

Optional. Defaults to standard out. | + +For example: + +```python +# With no context properties or custom destinations +Itly.load() + +# With context properties (e.g. a string property called version) +Itly.load do |options| + options.context = Itly::Context.new( + version: '1.0' + ) +end + +# With all options +Itly.load do |options| + options.environment = ENV['APP_ENV'] || :development + options.destinations.segment = { + max_queue_size: 1000 + } + options.destinations.custom = CustomDestinationAdapter.new('custom', {}) + options.logger = Logger.new(STDOUT), + options.context = Itly::Context.new( + version: '1.0' + ) +end +``` + +### Track + +To track an event, call the event’s corresponding function. Every event in your tracking plan gets its own function in the Itly SDK. + +For example, in the code snippet below, our tracking plan contains an event called `Process Started`. The event was defined with one required property called `user_id` and one optional property called `available_processors`. The `user_id` property's type is a string. The `available_processors` property's type an integer. + +```python +Itly.process_started('some-user-id', + available_processors: Etc.nprocessors +) +``` + + + + + + diff --git a/docs/data/using-the-ampli-cli.md b/docs/data/using-the-ampli-cli.md index 1132ee387..b194a5200 100644 --- a/docs/data/using-the-ampli-cli.md +++ b/docs/data/using-the-ampli-cli.md @@ -128,11 +128,8 @@ By default, your tracking library will be placed in: | Browser | `./src/ampli` | | Node.js | `./src/ampli` | | iOS | `./ampli` | -| Android | `./app/src/main/java/io/ampli` | -| JRE | `./src/main/java/io/ampli` | -| Python | `./ampli` | -| Ruby | `./ampli` | -| .NET | `./ampli` | +| Android | `./app/src/main/java/com/amplitude/ampli` | +| JRE | `./src/main/java/com/amplitude/ampli` | To override the default location, pass the `-p` argument. Ampli will remember your custom location and use it going forward. @@ -141,7 +138,9 @@ will remember your custom location and use it going forward. ampli pull web -p ./src/analytics ``` -Include `-b {branch}` to generate a tracking library from a particular branch, rather than **main**. By default, the last published version will be used. If you'd like to generate a tracking library for another version, include `-v {version}` and specify the tracking plan's version. +Include `-b {branch}` to generate a tracking library from a particular branch, rather than **main**. By default, +the last published version will be used. If you'd like to generate a tracking library for another version, include +`-v {version}` and specify the tracking plan's version. ### `ampli status` Check the status of your instrumentation by linting (verifying) your source code for analytics. diff --git a/docs/data/using-the-tracking-library.md b/docs/data/using-the-tracking-library.md index b223e433f..0b2ec1f5e 100644 --- a/docs/data/using-the-tracking-library.md +++ b/docs/data/using-the-tracking-library.md @@ -23,7 +23,7 @@ OldLibrary.trackEvent( You track them like this: ```java -Itly.productViewed( +ampli.productViewed( name = "Moto 360" ) ``` @@ -38,6 +38,5 @@ Iteratively supports 12 platforms today with more on the way. ## Destinations -Iteratively supports the following analytics destinations out of the box. If your destination is not listed, you can create a custom destination to send events to another analytics provider or your own endpoint. - - +The Ampli SDK sends events to Amplitude out of the box. If you would like to send data to other analytics destinations, + you can create a custom [middleware](/middleware). diff --git a/docs/analytics/analytics-recieving-cohorts-from-amplitude.md b/docs/integrations/analytics-recieving-cohorts-from-amplitude.md similarity index 100% rename from docs/analytics/analytics-recieving-cohorts-from-amplitude.md rename to docs/integrations/analytics-recieving-cohorts-from-amplitude.md diff --git a/docs/analytics/analytics-shopify-plugin.md b/docs/integrations/analytics-shopify-plugin.md similarity index 100% rename from docs/analytics/analytics-shopify-plugin.md rename to docs/integrations/analytics-shopify-plugin.md diff --git a/docs/integrations/index.md b/docs/integrations/index.md new file mode 100644 index 000000000..247f0eab3 --- /dev/null +++ b/docs/integrations/index.md @@ -0,0 +1,6 @@ +--- +title: Integrations Overview + +--- + +WORDs \ No newline at end of file diff --git a/includes/postman.md b/includes/postman.md new file mode 100644 index 000000000..fe9ac3193 --- /dev/null +++ b/includes/postman.md @@ -0,0 +1,4 @@ +!!! tip "Run the Amplitude Collection in Postman" + + For more examples requests and responses, run our Postman Collection. + [![Run in Postman](https://run.pstmn.io/button.svg)](https://app.getpostman.com/run-collection/4b6ae54e2be09f0b9109?action=collection%2Fimport) \ No newline at end of file diff --git a/includes/sdkresources.md b/includes/sdkresources.md new file mode 100644 index 000000000..746bff3e6 --- /dev/null +++ b/includes/sdkresources.md @@ -0,0 +1,4 @@ +???info "SDK Resources" + - [JavaScript SDK Reference :material-book:](https://amplitude.github.io/Amplitude-JavaScript/) + - [JavaScript SDK Repo :material-github:](https://github.com/amplitude/Amplitude-JavaScript) + - [JavaScript SDK Releases :material-code-tags-check:](https://github.com/amplitude/Amplitude-Javascript/releases) \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index 9f64455e8..f4ac67183 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -25,7 +25,7 @@ theme: # Default values, taken from mkdocs_theme.yml language: en features: - #- announce.dismiss + #- announce.dismiss # this feature is perenially buggy, so keep it disabled unless necessary. - content.code.annotate - content.tabs.link # - header.autohide @@ -41,8 +41,6 @@ theme: - search.suggest # - toc.integrate #this is a really noisy feature, IMO. font: false # Prevents autoloading of google fonts, for privacy reasons. - #text: IBM Plex Sans - #code: IBM Plex Sans Mono favicon: assets/favicon.ico logo: assets/logo.png extra_css: @@ -115,54 +113,62 @@ extra: # Navigation nav: -- Analytics Docs: +- Analytics: - analytics/index.md - - analytics/batch-event-upload.md - - SDKs: - - analytics/sdks/sdk-javascript-overview.md - - analytics/sdks/sdk-android-overview.md - - Integrations: - - analytics/analytics-shopify-plugin.md - - analytics/analytics-recieving-cohorts-from-amplitude.md -- Experiment Docs: +- Experiment: - experiment/index.md -- Data Docs: +- Data: - data/index.md - Getting Started: - data/getting-started.md - data/what-is-a-tracking-plan.md - data/creating-your-tracking-plan.md - - data/best-practices.md - - data/track-page-views.md - - data/identifying-users-and-groups.md - data/working-with-templates.md - - data/typical-workflow.md + - data/identifying-users-and-groups.md + - data/tracking-page-views.md + - data/best-practices.md - data/working-with-branches.md + - data/typical-workflow.md - data/observe.md - data/granular-event-destinations.md + - data/middleware-overview.md - Instrumentation: + - data/ampli-sdk-overview.md - data/using-the-ampli-cli.md - - data/integrating-with-ci.md - data/using-the-tracking-library.md - - data/iglu-api.md + - data/integrating-with-ci.md - data/unit-testing.md - data/user-lookup.md - - data/import.md + - data/iglu-api.md - Sources: - - data/android-ampli.md - data/browser-ampli.md - - data/ios-ampli.md - data/nodejs-ampli.md - - data/jre-v3.md + - data/ios-ampli.md + - data/android-ampli.md + - data/jre-ampli.md + - Sources (Legacy): + - data/browser.md + - data/nodejs.md + - data/ios.md + - data/android.md - data/jre.md - data/python.md - - data/ruby-v2.md + - data/ruby.md - data/dotnet.md - Resources: - - data/migration-guide.md - data/managing-your-account.md + - data/import.md - data/integrations.md -- API Reference: http://localhost:4567/#amplitude-api-reference + - data/migration-guide.md +- Integrations: + - integrations/index.md + - integrations/analytics-shopify-plugin.md + - integrations/analytics-recieving-cohorts-from-amplitude.md +- API Reference: + - apis/index.md + - apis/identify-api.md + - apis/attribution-api.md + - Partner Hub: - partners/index.md diff --git a/overrides/home.html b/overrides/home.html index e3c0ca4ba..cdeddd888 100644 --- a/overrides/home.html +++ b/overrides/home.html @@ -39,6 +39,15 @@ margin: 0 auto; } + .banner-hero__content p a { + color: var(--md-primary-bg-color); + } + + .banner-hero__content p a:hover { + color: var(--md-primary-bg-color); + text-decoration: underline; + } + .banner-hero .md-button { margin-top: .5rem; margin-right: .5rem; @@ -213,15 +222,15 @@ @@ -239,7 +248,7 @@

  • Getting Started
  • Use Cases
  • Data Ingestion Guide
  • - See all the doc + See all of the Data doc @@ -251,7 +260,7 @@

    Track Events
  • Getting Started
  • Use Cases
  • Featured Guide
  • -
  • See all the doc +
  • See all of the Amplitude Analytics docs
  • @@ -263,7 +272,7 @@

  • Getting Started
  • Use Cases
  • Featured Guide
  • -
  • See all the doc
  • +
  • See all of the Amplitude Experiment docs