├── README.md ├── docs ├── DIRECT_AUTH_FOR_DEVELOPERS.md ├── stickers_direct_auth.md ├── stickers_snapkit.md └── vanilla-sticker-picker │ ├── README.md │ └── index.html └── images ├── bfd_logo_black.png ├── bfd_logo_green.png └── bfd_logo_white.png /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 | 5 | # Bitmoji for Developers documentation 6 | 7 | 1. [Bitmoji Direct Authorization](docs/DIRECT_AUTH_FOR_DEVELOPERS.md) 8 | 1. [Bitmoji Direct - Standalone Stickers for Snap Kit](docs/stickers_snapkit.md) 9 | 1. [Bitmoji Direct - Standalone Stickers for Bitmoji Direct API](docs/stickers_snapkit.md) 10 | 1. [Bitmoji Direct Search - Vanilla JavaScript Search](docs/vanilla-sticker-picker/README.md) 11 | 12 | ## Notice for Existing Developers Using Bitmoji For Identity 13 | _Going forward, Snap will no longer be supporting the "Bitmoji For Identity" product on our platform. This product documentation has been formally removed for some time, but we understand this may be disruptive to your business, so we want to provide an alternative option. Fortunately, Bitmoji services are still available to developers through this link: https://github.com/Bitmoji/BitmojiForDevelopers/blob/main/docs/stickers_snapkit.md._ 14 | 15 | Copyright ® 2020-2021 Snap Inc. All rights reserved. All information subject to change without notice. 16 | 17 | [Snap Developer Terms of Service](https://www.snap.com/en-US/terms/developer) 18 | 19 | [Snap Inc. Terms of Service](https://www.bitmoji.com/support/terms.html) 20 | -------------------------------------------------------------------------------- /docs/DIRECT_AUTH_FOR_DEVELOPERS.md: -------------------------------------------------------------------------------- 1 | ![image](https://user-images.githubusercontent.com/31291049/109557561-44a8b900-7aa6-11eb-8390-9371c293448b.png) 2 | 3 | # Bitmoji Direct Authorization 4 | Bitmoji Direct Authorization allows users to connect their Bitmoji to 3rd party experiences outside of Bitmoji and Snapchat. Users control access to their Bitmoji through the Bitmoji iOS and Android apps. 5 | 6 | ## Overview 7 | Bitmoji Direct Authorization provides a standard OAuth2 flow for requesting and accessing Bitmoji user data. Apps which are integrated with Bitmoji may request access using www.bitmoji.com/connect/ on both mobile devices and on desktop web. Users approve access to their Bitmoji within Bitmoji apps, and can manage connected apps within the Connected Apps settings screen. 8 | 9 | See [RFC6749](https://tools.ietf.org/html/rfc6749) and [RFC7636](https://tools.ietf.org/html/rfc7636) for more details about OAuth2 and Proof Key for Code Exchange. 10 | 11 | Once a user has connected an app, their data may be accessed by that app using the Direct API. The Direct API provides data such as the avatar, sticker packs, and search. 12 | 13 | ## Bitmoji App Support 14 | |Platform|Version|Supported|Release Date|Notes| 15 | |--------|-------------|-----|---|---| 16 | | Android | >= 11.19 | :white_check_mark: | Mar 15 2021 | | 17 | | iOS | >= 11.19 | :white_check_mark: | Mar 15 2021 | | 18 | | iOS | 11.17 | :warning: | Mar 1 2021 | Connected Apps screen not available | 19 | | iOS | 11.15 | :warning: | Feb 17 2021 | Connected Apps screen not available | 20 | 21 | ## Configuring Your App 22 | Developers must have a Snapchat account and register in the Snap Kit Developer portal. 23 | 24 | In the portal developers may create an Org and an App. The App ID, Organization ID, and OAuth2 Client IDs in the portal will be used by Direct Authorization. The developer must inform the Bitmoji Partnerships Team of the App ID they wish to use with Direct Auth. Bitmoji engineers will then configure Direct Authorization and the Direct API to allow access for the developer. 25 | 26 | ## Usage 27 | Their are two user flows for connecting a Bitmoji to an app: On mobile devices and on desktop web. Both flows are initiated using www.bitmoji.com/connect/. 28 | 29 | #### Making an Authorization Request 30 | Developers may make an OAuth2 Authorization Request to initiate the connection flow. 31 | 32 | Method | URL 33 | ---|--- 34 | GET | https://www.bitmoji.com/connect/ 35 | 36 | Query Parameter | Description 37 | ---|--- 38 | client_id | OAuth2 Client ID identifier for your app available in the developer portal. 39 | response_type | OAuth2 response type. Must be `code`. 40 | redirect_uri | OAuth2 Redirect URI. Values must be registered with the Bitmoji team. 41 | state | Optional OAuth2 state. 42 | code_challenge | OAuth2 PKCE code challenge. 43 | code_challenge_method | OAuth2 PKCE code challenge method. Must be `S256`. 44 | package_name | Optional package name for redirection on Android using intents. Must be registered with the Bitmoji team. 45 | 46 | Redirect URIs for use on iOS are strongly recommended to use Universal Links. On Android App Links are recommended, and custom URI schemes should be used in combination with the package name of the app receiving the redirect. 47 | 48 | #### Handling the Authorization Response 49 | When the user approves the access request, a `GET` request will be made to the redirect URI with the OAuth2 Authorization Response parameters. 50 | 51 | Query Parameter | Description 52 | ---|--- 53 | state | OAuth2 state matching the value in the authorization request, if used. 54 | code | OAuth2 authorization code. 55 | 56 | #### Retrieving an Access Token 57 | The Authorization Code value `code` may then be exchanged to retrieve an access token. 58 | 59 | Method | URL 60 | ---|--- 61 | POST | https://bitmoji.api.snapchat.com/direct/token 62 | 63 | Payload Value | Description 64 | ---|--- 65 | grant_type | OAuth2 grant type. Must be `authorization_code`. 66 | code | OAuth2 authorization code from the authorization response. 67 | client_id | Client identifier used in the authorization request. 68 | redirect_uri | Redirect URI used in the authorization request. 69 | code_verifier | OAuth2 PKCE code verifier. 70 | 71 | The response will be JSON containing an Access Token Response. 72 | 73 | Key | Description 74 | ---|--- 75 | access_token | May be used to access the Direct API. 76 | refresh_token | May be used to obtain a new access token. 77 | expires_in | Length of time until the access token expires in seconds. 78 | token_type | `bearer` 79 | 80 | #### Refreshing an Access Token 81 | The access tokens may be refreshed. The response will be JSON containing an Access Token Response. 82 | 83 | Method | URL 84 | ---|--- 85 | POST | https://bitmoji.api.snapchat.com/direct/token 86 | 87 | Payload Value | Description 88 | ---|--- 89 | client_id | Client identifier used in the authorization request. 90 | grant_type | OAuth2 grant type. Must be `refresh_token`. 91 | refresh_token | A refresh token. 92 | 93 | #### Revoking an Access Token 94 | The access tokens or refresh tokens may be revoked. Revoking a token causes all tokens associated with the authorization session to be disabled. 95 | 96 | Method | URL 97 | ---|--- 98 | POST | https://bitmoji.api.snapchat.com/direct/token/revoke 99 | 100 | Payload Value | Description 101 | ---|--- 102 | token | Either an access token or refresh token. 103 | 104 | ### Mobile 105 | When an iOS or Android mobile app initiates the connection flow the request will be handled by the Bitmoji app, if installed. Otherwise the user will be asked to log into or sign up for Bitmoji through the browser. 106 | 107 | Bitmoji app flow: 108 | 109 | ![image](https://user-images.githubusercontent.com/31291049/109555125-242b2f80-7aa3-11eb-8fce-fc9990fde908.png) 110 | 111 | 112 | ### Desktop Web 113 | In a desktop web browser, a user may log in or create an account via the web form or scan a QR code. 114 | 115 | If the user scans the code with their phone camera, then complete the connection flow in the Bitmoji app, if installed. If the app is not installed they will be redirected to the app store. 116 | 117 | QR Code flow: 118 | 119 | ![image](https://user-images.githubusercontent.com/31291049/109555088-1b3a5e00-7aa3-11eb-9e95-618d78b584d0.png) 120 | 121 | ### Limits 122 | Access tokens expire in 1 hour. 123 | 124 | Refresh tokens expire in 90 days. 125 | 126 | ### Debugging 127 | OAuth errors are logged to the device console on iOS and Android. 128 | 129 | #### iOS 130 | Example 1. Sending wrong client Id, 131 | ``` 132 | [Bitmoji Direct Auth] ["message": Bad Request, "statusCode": 400, "error_description": invalid client_id "clientId", "error": invalid_client] 133 | ``` 134 | Example 2. Wrong code_challenge was send as part of request, 135 | ``` 136 | [Bitmoji Direct Auth] ["statusCode": 400, "message": Bad Request, "error_description": "code_challenge" length must be 43 characters long, "error": invalid_request] 137 | ``` 138 | 139 | #### Android 140 | Example 1. Sending an invalid redirect URI, 141 | ``` 142 | 2021-03-12 12:30:35.860 21758-21758/com.bitstrips.imoji I/ConsentPresenter: {"statusCode":400,"error":"invalid_request","message":"Bad Request","error_description":"invalid redirect_uri \"bad\""} 143 | ``` 144 | Example 2. Sending an invalid package name, 145 | ``` 146 | 2021-03-12 12:34:24.997 21758-21758/com.bitstrips.imoji I/ConsentPresenter: {"statusCode":400,"error":"invalid_request","message":"Bad Request","error_description":"invalid package_name \"bad\""} 147 | ``` 148 | 149 | ## Accessing User Data 150 | Once an access token is obtained, requests for Bitmoji user data may be made. 151 | 152 | #### The Avatar ID 153 | Each Bitmoji user has an Avatar ID which uniquely identifies their avatar. The Avatar ID for a user changes whenever the user updates their avatar. For example, changing an outfit or updating an attribute will result in a new Avatar ID. 154 | 155 | Method | URL 156 | ---|--- 157 | GET | https://bitmoji.api.snapchat.com/direct/avatar 158 | 159 | Header | Description 160 | ---|--- 161 | authorization | Must be `bearer ${access_token}` 162 | 163 | The response will be JSON. 164 | 165 | Key | Description 166 | ---|--- 167 | id | The avatar ID for the user. 168 | 169 | #### Rendering the Avatar 170 | An image URL containing the avatar may be composed such as `https://sdk.bitmoji.com/me/sticker/${avatarId}`. 171 | 172 | For example, 173 | ![avatar](https://sdk.bitmoji.com/me/sticker/AXdZZnpaOGt5A_sNnlgH1jR7lGZQJg). 174 | 175 | #### Error Handling 176 | Access tokens may expire or be revoked when a user disconnects their Bitmoji from the connected app. Developers are expected to handle these cases appropriately. 177 | 178 | When using access tokens to access user data, these errors will return 401 Unauthorized status codes. Information about the specific error is included in the body of the JSON response. 179 | 180 | Key | Description 181 | ---|--- 182 | statusCode | The HTTP status code. 183 | message | The HTTP status code name. 184 | error | An error code for the type of authorization error. 185 | error_description | A message for the authorization error. 186 | 187 | Error code | Description 188 | ---|--- 189 | expired_token | The token has expired. A refresh token may be used to attempt to retrieve a new token. 190 | revoked_token | The token is revoked. The user has disconnected from the app. The user must authorize the app to connect again. 191 | invalid_token | The token is malformed. 192 | 193 | Example 194 | ``` 195 | % curl -s 'https://bitmoji.api.snapchat.com/direct/avatar' -H "authorization: bearer $token" | jq 196 | { 197 | "statusCode": 401, 198 | "message": "Unauthorized", 199 | "error": "token_expired", 200 | "error_description": "The token has expired. A new token may be obtained using a refresh token." 201 | } 202 | ``` 203 | -------------------------------------------------------------------------------- /docs/stickers_direct_auth.md: -------------------------------------------------------------------------------- 1 | # Bitmoji Direct - Standalone Stickers 2 | 3 | The Standalone stickers API offers an easy way to create personalized experiences featuring Bitmoji. This feature allows the creation of URLs using an avatar and stickers from the Bitmoji collection. 4 | 5 | ## User avatar 6 | 7 | The base to create all custom URLs is the user avatar. This is an identifier that represents a user uniquely. This ID is unique per partner to guarantee privacy and separation. Currently, the only method to obtain a user's avatar is authenticating through Login Kit, the authentication SDK for Snap Kit. 8 | 9 | ### Fetching the avatar through Bitmoji Direct API 10 | 11 | This guide assumes familiarity with Bitmoji Direct Auth. You'll need to configure your app in the [developer portal](https://snapkit.com/docs/developer-portal). 12 | 13 | Once you are able to get the access token for a user, you can fetch their avatar_id using the `https://bitmoji.api.snapchat.com/direct/avatar` endpoint. An example using `curl`: 14 | 15 | ```bash 16 | $ TOKEN= 17 | $ curl -X POST https://bitmoji.api.snapchat.com/direct/avatar \ 18 | -H "Authorization: Bearer $TOKEN" 19 | 20 | {"id":"AUxuZkpWrWuY1hVhLWz6kFNO~bJ8mg"} 21 | ``` 22 | 23 | ### Selfie URL 24 | 25 | An image able to represent a user in a profile is called a selfie. It is straightforward to create a selfie given an avatar ID. The format of the URL is 26 | 27 | ``` 28 | https://sdk.bitmoji.com/me/sticker/ 29 | ``` 30 | 31 | so the example avatar id above combined with the selfie URL would be: 32 | 33 | ``` 34 | https://sdk.bitmoji.com/me/sticker/AWVscGhvWez65Dau7FgShF5VPT5C7A 35 | ``` 36 | 37 | ![](https://sdk.bitmoji.com/me/sticker/AWVscGhvWez65Dau7FgShF5VPT5C7A) 38 | 39 | 40 | ## Custom stickers 41 | 42 | This section will describe how to expand the selfie idea to allow the creation of customized stickers. 43 | 44 | ### Getting the Sticker IDs for your app 45 | 46 | The first step is to decide which are the Bitmoji images you want to use in your app. You can work with the Bitmoji team to browse the library and extract the sticker IDs. You will use them later to generate your own. 47 | 48 | ### Crafting your own stickers 49 | 50 | To create a sticker URL, you need to append the sticker ID to the avatar ID. Let's say that you want to render the sticker with ID `987cfa1b-cbd3-49c6-b4de-5d62bdd31bf8`. The format for custom stickers is: 51 | 52 | ``` 53 | https://sdk.bitmoji.com/me/sticker// 54 | ``` 55 | 56 | So, for avatar ID `AWVscGhvWez65Dau7FgShF5VPT5C7A` and sticker ID `987cfa1b-cbd3-49c6-b4de-5d62bdd31bf8` the URL is: 57 | 58 | ``` 59 | https://sdk.bitmoji.com/me/sticker/AWVscGhvWez65Dau7FgShF5VPT5C7A/b9baff8d-2774-464d-b513-c1d6be51e56c 60 | ``` 61 | 62 | ![](https://sdk.bitmoji.com/me/sticker/AWVscGhvWez65Dau7FgShF5VPT5C7A/b9baff8d-2774-464d-b513-c1d6be51e56c) 63 | 64 | ## Custom friendmoji stickers 65 | 66 | ### Building your friend network 67 | 68 | To make friendmoji work, you'll need to take care of your app's friend graph on your own. Each Bitmoji user has an unique avatar ID specific to your application. You can get this identifier as detailed above in the `User Data` section. 69 | 70 | ### Crafting your own friendmoji stickers 71 | If you have sticker IDs from our gallery with friendmoji support, you just need to add the friend id to the URL path to render the friendmoji: 72 | 73 | ``` 74 | https://sdk.bitmoji.com/me/sticker/// 75 | ``` 76 | 77 | So, for avatar ID `AWVscGhvWez65Dau7FgShF5VPT5C7A`, sticker ID `af7653b1-080b-4bda-a3bd-1ea8e2f6a3cf` and friend ID `AWVscGhvI4X~eAfUWuGRCRWGNHerTQ` the URL is: 78 | 79 | ``` 80 | https://sdk.bitmoji.com/me/sticker/AWVscGhvWez65Dau7FgShF5VPT5C7A/0e7afb8b-14de-4d30-8498-a00cfe20fa4d/AWVscGhvI4X~eAfUWuGRCRWGNHerTQ 81 | ``` 82 | 83 | ![](https://sdk.bitmoji.com/me/sticker/AWVscGhvWez65Dau7FgShF5VPT5C7A/0e7afb8b-14de-4d30-8498-a00cfe20fa4d/AWVscGhvI4X~eAfUWuGRCRWGNHerTQ) 84 | 85 | ### Single stickers featuring your friend 86 | 87 | You can use the `friend_id` instead of the user's `avatar_id` to render a friend in the context of your app. A classic example of this use case is a conversation list in a chat app where you want to show to the user their friend's avatar. The URLs are similar to the user ones. The only diffence is they must include the `friend=1` query parameter. 88 | 89 | So for sticker ID `987cfa1b-cbd3-49c6-b4de-5d62bdd31bf8` and friend ID `AWVscGhvI4X~eAfUWuGRCRWGNHerTQ` the URL is: 90 | ``` 91 | https://sdk.bitmoji.com/me/sticker/AWVscGhvI4X~eAfUWuGRCRWGNHerTQ/8e540795-8684-4cf1-853c-af2a41ec9abb?friend=1 92 | ``` 93 | 94 | ![](https://sdk.bitmoji.com/me/sticker/AWVscGhvI4X~eAfUWuGRCRWGNHerTQ/8e540795-8684-4cf1-853c-af2a41ec9abb?friend=1) 95 | 96 | ## Parameters 97 | 98 | Any of the previous URLs can use parameters to adapt the images to different scenarios 99 | 100 | ### Format 101 | 102 | An extension can be added to the URLs to configure the image format. The available values are: 103 | - `png` 104 | - `webp` (default) 105 | 106 | Example: 107 | 108 | ``` 109 | https://sdk.bitmoji.com/me/sticker/AUxuZkpWrWuY1hVhLWz6kFNO~bJ8mg/987cfa1b-cbd3-49c6-b4de-5d62bdd31bf8.png 110 | 111 | https://sdk.bitmoji.com/me/sticker/AUxuZkpWrWuY1hVhLWz6kFNO~bJ8mg/987cfa1b-cbd3-49c6-b4de-5d62bdd31bf8.webp 112 | ``` 113 | 114 | ### Size 115 | 116 | A query parameter can be used to request different image sizes. It is recommended to use `thumbnail` when creating a picker interface for faster loading: 117 | - `thumbnail` 118 | - `default` 119 | - `large` 120 | 121 | ``` 122 | https://sdk.bitmoji.com/me/sticker/AWVscGhvWez65Dau7FgShF5VPT5C7A/5ee3832d-7743-43c8-b6d7-ea47f11a1798?size=thumbnail 123 | 124 | https://sdk.bitmoji.com/me/sticker/AWVscGhvWez65Dau7FgShF5VPT5C7A/5ee3832d-7743-43c8-b6d7-ea47f11a1798?size=default 125 | 126 | https://sdk.bitmoji.com/me/sticker/AWVscGhvWez65Dau7FgShF5VPT5C7A/5ee3832d-7743-43c8-b6d7-ea47f11a1798?size=large 127 | ``` 128 | 129 | ![](https://sdk.bitmoji.com/me/sticker/AWVscGhvWez65Dau7FgShF5VPT5C7A/5ee3832d-7743-43c8-b6d7-ea47f11a1798?size=thumbnail) 130 | 131 | ![](https://sdk.bitmoji.com/me/sticker/AWVscGhvWez65Dau7FgShF5VPT5C7A/5ee3832d-7743-43c8-b6d7-ea47f11a1798?size=default) 132 | 133 | ![](https://sdk.bitmoji.com/me/sticker/AWVscGhvWez65Dau7FgShF5VPT5C7A/5ee3832d-7743-43c8-b6d7-ea47f11a1798?size=large) 134 | -------------------------------------------------------------------------------- /docs/stickers_snapkit.md: -------------------------------------------------------------------------------- 1 | # Bitmoji Direct - Standalone Stickers 2 | 3 | The Standalone stickers API offers an easy way to create personalized experiences featuring Bitmoji. This feature allows the creation of URLs using an avatar and stickers from the Bitmoji collection. 4 | 5 | ## User avatar 6 | 7 | The base to create all custom URLs is the user avatar. This is an identifier that represents a user uniquely. This ID is unique per partner to guarantee privacy and separation. Currently, the only method to obtain a user's avatar is authenticating through Login Kit, the authentication SDK for Snap Kit. 8 | 9 | ### Fetching the avatar through Login Kit 10 | 11 | This guide assumes familiarity with [Login Kit](https://snapkit.com/docs/login-kit). You'll need to configure your app in the [developer portal](https://snapkit.com/docs/developer-portal). 12 | 13 | Once you are able to get the access token for a user, you can fetch their avatar_id using the `https://api.snapkit.com/v1/me` endpoint. An example using `curl`: 14 | 15 | ```bash 16 | $ TOKEN= 17 | $ curl -X POST https://api.snapkit.com/v1/me \ 18 | --data '{"query": "{me{bitmoji{id}}}"}' \ 19 | -H "Content-Type: application/json" \ 20 | -H "Authorization: Bearer $TOKEN" 21 | 22 | {"data":{"me":{"bitmoji":{"id":"AUxuZkpWrWuY1hVhLWz6kFNO~bJ8mg"}}},"errors":[]} 23 | ``` 24 | 25 | ### Selfie URL 26 | 27 | An image able to represent a user in a profile is called a selfie. It is straightforward to create a selfie given an avatar ID. The format of the URL is 28 | 29 | ``` 30 | https://sdk.bitmoji.com/me/sticker/ 31 | ``` 32 | 33 | so the example avatar id above combined with the selfie URL would be: 34 | 35 | ``` 36 | https://sdk.bitmoji.com/me/sticker/AWVscGhvWez65Dau7FgShF5VPT5C7A 37 | ``` 38 | 39 | ![](https://sdk.bitmoji.com/me/sticker/AWVscGhvWez65Dau7FgShF5VPT5C7A) 40 | 41 | 42 | ## Custom stickers 43 | 44 | This section will describe how to expand the selfie idea to allow the creation of customized stickers. 45 | 46 | ### Getting the Sticker IDs for your app 47 | 48 | The first step is to decide which are the Bitmoji images you want to use in your app. You can work with the Bitmoji team to browse the library and extract the sticker IDs. You will use them later to generate your own. 49 | 50 | ### Crafting your own stickers 51 | 52 | To create a sticker URL, you need to append the sticker ID to the avatar ID. Let's say that you want to render the sticker with ID `987cfa1b-cbd3-49c6-b4de-5d62bdd31bf8`. The format for custom stickers is: 53 | 54 | ``` 55 | https://sdk.bitmoji.com/me/sticker// 56 | ``` 57 | 58 | So, for avatar ID `AWVscGhvWez65Dau7FgShF5VPT5C7A` and sticker ID `987cfa1b-cbd3-49c6-b4de-5d62bdd31bf8` the URL is: 59 | 60 | ``` 61 | https://sdk.bitmoji.com/me/sticker/AWVscGhvWez65Dau7FgShF5VPT5C7A/b9baff8d-2774-464d-b513-c1d6be51e56c 62 | ``` 63 | 64 | ![](https://sdk.bitmoji.com/me/sticker/AWVscGhvWez65Dau7FgShF5VPT5C7A/b9baff8d-2774-464d-b513-c1d6be51e56c) 65 | 66 | ## Custom friendmoji stickers 67 | 68 | ### Building your friend network 69 | 70 | To make friendmoji work, you'll need to take care of your app's friend graph on your own. Each Bitmoji user has an unique avatar ID specific to your application. You can get this identifier as detailed above in the `User Data` section. 71 | 72 | ### Crafting your own friendmoji stickers 73 | If you have sticker IDs from our gallery with friendmoji support, you just need to add the friend id to the URL path to render the friendmoji: 74 | 75 | ``` 76 | https://sdk.bitmoji.com/me/sticker/// 77 | ``` 78 | 79 | So, for avatar ID `AWVscGhvWez65Dau7FgShF5VPT5C7A`, sticker ID `af7653b1-080b-4bda-a3bd-1ea8e2f6a3cf` and friend ID `AWVscGhvI4X~eAfUWuGRCRWGNHerTQ` the URL is: 80 | 81 | ``` 82 | https://sdk.bitmoji.com/me/sticker/AWVscGhvWez65Dau7FgShF5VPT5C7A/0e7afb8b-14de-4d30-8498-a00cfe20fa4d/AWVscGhvI4X~eAfUWuGRCRWGNHerTQ 83 | ``` 84 | 85 | ![](https://sdk.bitmoji.com/me/sticker/AWVscGhvWez65Dau7FgShF5VPT5C7A/0e7afb8b-14de-4d30-8498-a00cfe20fa4d/AWVscGhvI4X~eAfUWuGRCRWGNHerTQ) 86 | 87 | ### Single stickers featuring your friend 88 | 89 | You can use the `friend_id` instead of the user's `avatar_id` to render a friend in the context of your app. A classic example of this use case is a conversation list in a chat app where you want to show to the user their friend's avatar. The URLs are similar to the user ones. The only diffence is they must include the `friend=1` query parameter. 90 | 91 | So for sticker ID `987cfa1b-cbd3-49c6-b4de-5d62bdd31bf8` and friend ID `AWVscGhvI4X~eAfUWuGRCRWGNHerTQ` the URL is: 92 | ``` 93 | https://sdk.bitmoji.com/me/sticker/AWVscGhvI4X~eAfUWuGRCRWGNHerTQ/8e540795-8684-4cf1-853c-af2a41ec9abb?friend=1 94 | ``` 95 | 96 | ![](https://sdk.bitmoji.com/me/sticker/AWVscGhvI4X~eAfUWuGRCRWGNHerTQ/8e540795-8684-4cf1-853c-af2a41ec9abb?friend=1) 97 | 98 | ## Parameters 99 | 100 | Any of the previous URLs can use parameters to adapt the images to different scenarios 101 | 102 | ### Format 103 | 104 | An extension can be added to the URLs to configure the image format. The available values are: 105 | - `png` 106 | - `webp` (default) 107 | 108 | Example: 109 | 110 | ``` 111 | https://sdk.bitmoji.com/me/sticker/AUxuZkpWrWuY1hVhLWz6kFNO~bJ8mg/987cfa1b-cbd3-49c6-b4de-5d62bdd31bf8.png 112 | 113 | https://sdk.bitmoji.com/me/sticker/AUxuZkpWrWuY1hVhLWz6kFNO~bJ8mg/987cfa1b-cbd3-49c6-b4de-5d62bdd31bf8.webp 114 | ``` 115 | 116 | ### Size 117 | 118 | A query parameter can be used to request different image sizes. It is recommended to use `thumbnail` when creating a picker interface for faster loading: 119 | - `thumbnail` 120 | - `default` 121 | - `large` 122 | 123 | ``` 124 | https://sdk.bitmoji.com/me/sticker/AWVscGhvWez65Dau7FgShF5VPT5C7A/5ee3832d-7743-43c8-b6d7-ea47f11a1798?size=thumbnail 125 | 126 | https://sdk.bitmoji.com/me/sticker/AWVscGhvWez65Dau7FgShF5VPT5C7A/5ee3832d-7743-43c8-b6d7-ea47f11a1798?size=default 127 | 128 | https://sdk.bitmoji.com/me/sticker/AWVscGhvWez65Dau7FgShF5VPT5C7A/5ee3832d-7743-43c8-b6d7-ea47f11a1798?size=large 129 | ``` 130 | 131 | ![](https://sdk.bitmoji.com/me/sticker/AWVscGhvWez65Dau7FgShF5VPT5C7A/5ee3832d-7743-43c8-b6d7-ea47f11a1798?size=thumbnail) 132 | 133 | ![](https://sdk.bitmoji.com/me/sticker/AWVscGhvWez65Dau7FgShF5VPT5C7A/5ee3832d-7743-43c8-b6d7-ea47f11a1798?size=default) 134 | 135 | ![](https://sdk.bitmoji.com/me/sticker/AWVscGhvWez65Dau7FgShF5VPT5C7A/5ee3832d-7743-43c8-b6d7-ea47f11a1798?size=large) 136 | -------------------------------------------------------------------------------- /docs/vanilla-sticker-picker/README.md: -------------------------------------------------------------------------------- 1 | # Bitmoji Search API: Web Sample (plain) 2 | 3 | ## Generate the project 4 | 5 | Create a directory for your project and minimal `index.html` file 6 | 7 | ```html 8 | 9 | 10 | 11 | 12 | 13 | Bitmoji Picker 14 | 15 | 16 |

Hello Bitmoji

17 | 18 | 19 | ``` 20 | 21 | You need to serve the website through a server. An easy option is using Python 22 | 23 | ```bash 24 | $ python3 -m http.server 25 | ``` 26 | 27 | you should see a message like: 28 | 29 | ``` 30 | Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) 31 | ``` 32 | 33 | Open `http://localhost:8000` in your browser to verify you see your initial web. 34 | 35 | ## Configuring OAuth 36 | 37 | We'll be using Login Kit. For more information check the [website](https://kit.snapchat.com/login-kit). 38 | 39 | ### Configure the app in the Developer Portal 40 | Create your Snap Kit app in `https://kit.snapchat.com/portal/`. Make sure to add Bitmoji Avatar permission. 41 | 42 | In the Authorization section, enable `Web` for the Developement Environment. Next add `http://localhost:8000` to the Redirect URLs section. 43 | 44 | > Note: If you want to test with users other than your own, make sure to add them at the bottom in the test users section. 45 | 46 | Finally, copy the `CLIENT ID` for the development enviroment. You'll need it in the next step. 47 | 48 | ### Configure the JS Login Kit library 49 | 50 | Going back to `index.html`, replace `

Hello Bitmoji

` with the Login Kit boilerplate 51 | 52 | ```html 53 |
54 | 55 |
56 |
57 |
58 | 99 | ``` 100 | 101 | Now, replace in that boilerplate `YOUR_CLIENT_ID` with the value that you copied from the Developer Portal in the previous step. Also replace `YOUR_REDIRECT_URI` with `http://localhost:8000`. 102 | 103 | If you reload the page you should see the `Continue with Snapchat` button. You can test that going through the OAuth process, after clicking it, shows your name and avatar on the webpage. 104 | 105 | --- 106 | 107 | # Fetching content from Bitmoji Direct 108 | 109 | ## Extracting the token from Login Kit 110 | 111 | To hit the Bitmoji Direct endpoints, you'll need a valid Login Kit token. The boilerplate above uses it behind the scenes. Let's change the callback handler to fetch the token instead 112 | 113 | ```js 114 | handleResponseCallback: function () { 115 | snap.loginkit.fetchUserInfo().then( 116 | function (result) { 117 | const token = snap.loginkit.getSharedDataAccessToken(); 118 | loadBitmojiContent(token); 119 | }, 120 | function (err) { 121 | console.log(err); // Error 122 | } 123 | ); 124 | } 125 | ``` 126 | 127 | Replace the Login Kit the boilerplate markup to test the data 128 | ```html 129 |
130 | 131 |
132 |
133 | ``` 134 | 135 | with 136 | ```html 137 |
138 |
139 |
140 | ``` 141 | 142 | ## Showing popular stickers 143 | 144 | ### Fetching the content 145 | In the new callback a non-existent `loadBitmojiContent(token)` function is being called. Let's create a `script` tag with its code. 146 | 147 | Bitmoji Direct provides a specific pack with the `https://bitmoji.api.snapchat.com/direct/pack/` endpoint. The popular stickers are in a pack called `popular` so the endpoint is `https://bitmoji.api.snapchat.com/direct/pack/popular`. To authenticate the user, you need to pass the token in the `Authorization` header. 148 | 149 | ```html 150 | 165 | ``` 166 | 167 | The `data` field contains the payload. Each sticker has a `uri` property with an image URL. That's all it is needed to render the content. 168 | 169 | ### Displaying the content 170 | 171 | With the information from the previous step you can easily display all the stickers with adding this code to the function 172 | 173 | ```js 174 | const stickerPicker = document.getElementById('stickers'); 175 | stickers.forEach(sticker => { 176 | const image = new Image(100, 100); 177 | image.src = sticker.uri; 178 | stickerPicker.appendChild(image); 179 | }); 180 | ``` 181 | 182 | > Note: This is an extremely inneficient way of displaying the data. We are focused on the minimal code that you can then adapt to your own libraries and frameworks. 183 | 184 | With this code you should now see a lot of stickers featuring your avatar 185 | 186 | ## Providing Search functionality 187 | 188 | ### Adding controls 189 | 190 | With a text input and a button is easy to implement a basic search UI. Update the sticker-picker div to 191 | 192 | ```html 193 |
194 | 198 |
199 |
200 | ``` 201 | 202 | Bitmoji Direct provides search functionality through the `https://bitmoji.api.snapchat.com/direct/search?q=YOUR_SEARCH_TERM` endpoint. To authenticate the user, you need to pass the token in the `Authorization` header. 203 | 204 | You can add the following code after the sticker loading code to provide basic search functionality 205 | 206 | ```js 207 | const searchBox = document.getElementById('search-box'); 208 | searchBox.style.display = 'block'; 209 | const searchButton = document.getElementById('search-button'); 210 | 211 | searchButton.addEventListener('click', async (e) => { 212 | e.preventDefault(); 213 | const searchText = document.getElementById('searchbox').value; 214 | const response = await fetch(`${HOST}/direct/search?q=${searchText}`, { 215 | headers: { 216 | Authorization: `Bearer ${token}` 217 | } 218 | }); 219 | const json = await response.json(); 220 | const stickers = json.data; 221 | 222 | stickerPicker.childNodes.forEach(node => node.remove()) 223 | stickers.forEach(sticker => { 224 | const image = new Image(100, 100); 225 | image.src = sticker.uri; 226 | stickerPicker.appendChild(image); 227 | }); 228 | }); 229 | ``` 230 | 231 | If you type `hello` in the search box and hit enter the content should be replaced with stickers matching your search term. 232 | 233 | ### Clean up the code 234 | 235 | After our last step there is a significant amount of duplication. You can simplify significantly refactoring to 236 | 237 | ```js 238 | const HOST = 'https://bitmoji.api.snapchat.com'; 239 | 240 | async function fetchFromAPI(url, token) { 241 | const response = await fetch(url, { 242 | headers: { 243 | Authorization: `Bearer ${token}` 244 | } 245 | }); 246 | const json = await response.json(); 247 | return json.data; 248 | } 249 | 250 | function getPopularStickers(token) { 251 | return fetchFromAPI(`${HOST}/direct/pack/popular`, token); 252 | } 253 | 254 | function getStickerSearchResults(token, searchText) { 255 | return fetchFromAPI(`${HOST}/direct/search?q=${searchText}`, token); 256 | } 257 | 258 | function renderStickers(stickers) { 259 | const stickerPicker = document.getElementById('stickers'); 260 | stickerPicker.innerHTML = ''; 261 | stickers.forEach(sticker => { 262 | const image = new Image(100, 100); 263 | image.src = sticker.uri; 264 | stickerPicker.appendChild(image); 265 | }); 266 | } 267 | 268 | async function loadBitmojiContent(token) { 269 | const stickers = await getPopularStickers(token); 270 | renderStickers(stickers); 271 | 272 | const searchBox = document.getElementById('search-box'); 273 | searchBox.style.display = 'block'; 274 | 275 | const searchButton = document.getElementById('search-button'); 276 | searchButton.addEventListener('click', async (e) => { 277 | e.preventDefault(); 278 | const searchText = document.getElementById('searchbox').value; 279 | const searchResultStickers = await getStickerSearchResults(token, searchText); 280 | renderStickers(searchResultStickers); 281 | }); 282 | } 283 | ``` 284 | 285 | ## Providing pack browsing functionality 286 | 287 | ### Showing available packs 288 | 289 | Bitmoji Direct also groups content in a set of packs. In a similar fashion to `popular`, you can get stickers grouped by a given tag such as `yes`, `hello` or `happy`. To get a set of tags you can suggest to your users you can call the `https://bitmoji.api.snapchat.com/direct/packs` endpoint. 290 | 291 | Update the sticker `div` to 292 | 293 | ```html 294 |
295 | 299 |
300 |
301 |
302 | ``` 303 | 304 | and now load the packs into `
` with 305 | 306 | ```js 307 | 308 | (...) 309 | 310 | function getPacks(token) { 311 | return fetchFromAPI(`${HOST}/direct/packs`, token); 312 | } 313 | 314 | (... in loadBitmojiContent) 315 | const packs = await getPacks(token); 316 | const tagsContainer = document.getElementById('tags'); 317 | packs.forEach(pack => { 318 | const packLink = document.createElement('a'); 319 | packLink.innerHTML = pack.name; 320 | packLink.style.marginRight = '24px'; 321 | packLink.href = "#"; 322 | tagsContainer.appendChild(packLink); 323 | }); 324 | ``` 325 | 326 | ### Showing stickers within pack when clicking 327 | 328 | Now you can add the event handler to show the relevant content when clicking one of the tags. To do so, the `id` field within the pack is used. `popular` is just another pack `id` field. Let's refactor `getPopularSticker` to accept any packId 329 | 330 | ```js 331 | function getPackStickers(token, packId) { 332 | return fetchFromAPI(`${HOST}/direct/pack/${packId}`, token); 333 | } 334 | 335 | (... in loadBitmojiContent) 336 | const stickers = await getPackStickers(token, 'popular'); 337 | ``` 338 | 339 | Finally, let's add the click handler for the tags 340 | 341 | ```js 342 | packLink.addEventListener('click', async (e) => { 343 | e.preventDefault(); 344 | const stickers = await getPackStickers(token, pack.id); 345 | renderStickers(stickers); 346 | }); 347 | ``` 348 | 349 | ## Picking a sticker 350 | 351 | When users select a sticker an action like should happen. For instance, you may want to share the sticker in a 1:1 conversation in a chat application. To do this the same URI used to display the sticker preview may be used. 352 | 353 | Let's update the app UI to include an area to display the selected image 354 | ```html 355 |
356 |
357 | 361 |
362 |
363 |
364 |
365 | 366 |
367 |
368 |
369 | ``` 370 | 371 | Now in the function where we render the stickers, we can add a handler to call a function with the click event is triggered: 372 | ```js 373 | function renderStickers(stickers) { 374 | const stickerPicker = document.getElementById('stickers'); 375 | stickerPicker.innerHTML = ''; 376 | stickers.forEach(sticker => { 377 | const image = new Image(100, 100); 378 | image.src = sticker.uri; 379 | image.onclick = () => shareSticker(sticker); 380 | stickerPicker.appendChild(image); 381 | }); 382 | } 383 | 384 | function shareSticker(sticker) { 385 | document.getElementById('share-area').src = sticker.uri; 386 | } 387 | ``` 388 | 389 | If you test this code it will work, but the shared image will apear pixelated. To allow faster loading times in your picker, stickers are loaded on their `thumbnail` size. This may be undesirable for the sharing use case where a higher image resolution may be required. It is trivial to do this. Stickers have a number of query parameters attached to them, you can manipulate the `size` parameter to load a bigger size image. The available options are: 390 | - `default`: 400x400 pixels 391 | - `large`: 800x800 pixels 392 | 393 | Adding the size parameter to the example: 394 | ```js 395 | function shareSticker(sticker) { 396 | document.getElementById('share-area').src = sticker.uri.replace('size=thumbnail', 'size=default'); 397 | } 398 | ``` 399 | 400 | Bitmoji may be notified that a sticker has been picked to share. A stub example could be: 401 | 402 | ```js 403 | function shareSticker(sticker) { 404 | document.getElementById('share-area').src = sticker.uri.replace('size=thumbnail', 'size=default'); 405 | fetch(`${HOST}/direct/event/${sticker.on_share}`, { method: 'post' }); 406 | } 407 | ``` 408 | 409 | ## Customizing content 410 | 411 | ### Locale 412 | The `/packs`, `/pack/{packId}` and `/search` endpoints support a `locale` query parameter. The content will be returned in the locale of your choice if supported. I will default to English. 413 | 414 | The locales supported currently are: `en`, `ar`, `de`, `es`, `fr`, `it`, `ja`, `ko` and `pt`. 415 | 416 | If you don't provide an explicit `locale` parameter but the `accept-language` HTTP header is set, the API will resolve based on the header. 417 | 418 | ### Time 419 | The `/packs` and `/pack/{packId}` endpoints support a `time` parameter. 420 | 421 | Bitmoji content is variable depending on time of day. To be able to display the right content to your users you can send a date string in the `time` query parameter and timely content will be returned if available. 422 | 423 | Example of valid time strings are `2020-10-15T13:05:05`(no timezone) or `2020-10-15T18:02:04-04:00`(with timezone). 424 | 425 | ### Pagination 426 | 427 | The `/pack/{packId}` and `/search` endpoints support optional `limit` and `page` query parameters to paginate through the returned data. `limit` 428 | should be a positive integer while `page` should be 0 or positive. If only a `limit` param is passed, the `page` defaults to 0. Specifying only 429 | `page` doesn't affect the results. 430 | 431 | To help with pagination, the result from Bitmoji direct API also returns metadata in the JSON result, this can be ignored if you aren't using 432 | pagination. This includes the field `next` - URL path with query pointing to the next page, `prev` URL path with query pointing to the previous 433 | page and `total` - the total number of elements for this query (this can be used to set the page size). `next` and `prev` are null if 434 | pagination params weren't specified or if no `next` or `prev` page exists. Note that `next` and `prev` preserve original query params. 435 | 436 | As an example, the result for `https://bitmoji.api.snapchat.com/direct/search?q=hi&locale=en&limit=10&page=2` is as follows: 437 | 438 | ```json 439 | { 440 | "data": [...], 441 | "metadata": { 442 | "next": "/direct/search?q=hi&locale=en&limit=10&page=3", 443 | "prev": "/direct/search?q=hi&locale=en&limit=10&page=1", 444 | "total": 56 445 | } 446 | } 447 | ``` 448 | 449 | ## Full code for reference 450 | 451 | ```html 452 | 453 | 454 | 455 | 456 | 457 | Bitmoji Picker 458 | 459 | 460 | 461 |
462 |
463 | 467 |
468 |
469 |
470 |
471 | 472 |
473 |
474 |
475 | 511 | 512 | 584 | 585 | 586 | 587 | 588 | ``` 589 | -------------------------------------------------------------------------------- /docs/vanilla-sticker-picker/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Bitmoji Picker 7 | 8 | 9 | 10 |
11 |
12 | 16 |
17 |
18 |
19 |
20 | 21 |
22 |
23 |
24 | 60 | 61 | 133 | 134 | 135 | 136 | -------------------------------------------------------------------------------- /images/bfd_logo_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bitmoji/BitmojiForDevelopers/3d0d0d166b9f5e8f64bc1ac9fee683d974456b31/images/bfd_logo_black.png -------------------------------------------------------------------------------- /images/bfd_logo_green.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bitmoji/BitmojiForDevelopers/3d0d0d166b9f5e8f64bc1ac9fee683d974456b31/images/bfd_logo_green.png -------------------------------------------------------------------------------- /images/bfd_logo_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bitmoji/BitmojiForDevelopers/3d0d0d166b9f5e8f64bc1ac9fee683d974456b31/images/bfd_logo_white.png --------------------------------------------------------------------------------