npm package: @haptik/react-native
Description: React native wrapper around native SDKs
Author: Pratham Agrawal
Latest version: 0.0.1

# HaptikRN

- [Installation](#installation)
  - [iOS](#ios)
  - [Android](#android)
- [Usage](#usage)
  - [Basic Example](#basic-example)
- [Available Methods](#available-methods)
    - [`signup(options)`](#signupoptions)
    - [`renewSignupToken({token, authType, authId})`](#renewsignuptokentoken-authtype-authid)
    - [`setUserData(userData)`](#setuserdatauserdata)
    - [`isSignedUp()`](#issignedup)
    - [`open(viaName, launchMessage, hideLaunchMessage)`](#openvianame-launchmessage-hidelaunchmessage)
    - [`sendMessage(message)`](#sendmessagemessage)
    - [`getUnreadCount(viaName)`](#getunreadcountvianame)
    - [`setTheme(theme = {})`](#setthemetheme--)
    - [`setDeviceToken(token)`](#setdevicetokentoken)
    - [`isHaptikNofication(notification)`](#ishaptiknoficationnotification)

## Installation
The react native integration for the SDKs is available as npm package.

Start by installing and linking the module using `npm`

```bash
npm install @haptik/react-native --save
npx react-native link
```

### iOS
- Install the pods that come with the integration by running `pod install`

  ```bash
  cd ios
  pod install
  ```

- Add `use_frameworks!` to the `Podfile` inside the `ios` directory. Ensure that you disable Flipper.

  ```Podfile
  platform :ios, '9.0'
  use_frameworks!
  ...

  # add_flipper_pods!
  # post_install do |installer|
  #   flipper_post_install(installer)
  # end
  ```

- Disable Flipper initialization by commenting out the following lines in `ios/AppName/AppDelegate.m`

  ```Objc
  #import <React/RCTBridge.h>
  #import <React/RCTBundleURLProvider.h>
  #import <React/RCTRootView.h>

  //#if DEBUG
  //#import <FlipperKit/FlipperClient.h>
  //#import <FlipperKitLayoutPlugin/FlipperKitLayoutPlugin.h>
  //#import <FlipperKitUserDefaultsPlugin/FKUserDefaultsPlugin.h>
  //#import <FlipperKitNetworkPlugin/FlipperKitNetworkPlugin.h>
  //#import <SKIOSNetworkPlugin/SKIOSNetworkAdapter.h>
  //#import <FlipperKitReactPlugin/FlipperKitReactPlugin.h>
  //
  //static void InitializeFlipper(UIApplication *application) {
  //  FlipperClient *client = [FlipperClient sharedClient];
  //  SKDescriptorMapper *layoutDescriptorMapper = [[SKDescriptorMapper alloc] initWithDefaults];
  //  [client addPlugin:[[FlipperKitLayoutPlugin alloc] initWithRootNode:application withDescriptorMapper:layoutDescriptorMapper]];
  //  [client addPlugin:[[FKUserDefaultsPlugin alloc] initWithSuiteName:nil]];
  //  [client addPlugin:[FlipperKitReactPlugin new]];
  //  [client addPlugin:[[FlipperKitNetworkPlugin alloc] initWithNetworkAdapter:[SKIOSNetworkAdapter new]]];
  //  [client start];
  //}
  //#endif

  @implementation AppDelegate

  - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
  {
  //#if DEBUG
  //  InitializeFlipper(application);
  //#endif

  ```

- Add the following authentication information to the `Info.plist` file inside the `ios/AppName` directory

  ```xml
  <key>HaptikLib</key>
  <dict>
    <key>clientID</key>
    <string>CLIENT_ID_HERE</string>
    <key>baseUrl</key>
    <string>BASE_URL_HERE</string>
    <key>runEnvironment</key>
    <string>1</string>
  </dict>
  ```

  > You can contact Haptik for the CLIENT_ID, and BASE_URL

- iOS should be good to go.

### Android
- Add `tools:replace` support by adding it to your `AndroidManifest.xml` header located in `android/app/src/main/`
  ```xml
  <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.haptikrnintegration" xmlns:tools="http://schemas.android.com/tools">
  ```

- Add the following values to the application `AndroidManifest.xml` located in `android/app/src/main/`
  ```xml
  <meta-data android:name="ai.haptik.android.sdk.ClientId" android:resource="@string/haptik_sdk_client_id" />

  <!-- Geo API key needs to be put only if you require to enable maps in the SDK -->
  <meta-data android:name="com.google.android.geo.API_KEY" android:value="YOUR GEO API KEY HERE" tools:replace="android:value" />

  <!-- Pass the Geo API key here, if you do not have one, pass empty string -->
  <meta-data android:name="ai.haptik.places.sdk.api.key" android:value="YOUR PLACES SDK API KEY HERE" tools:replace="android:value" />

  <activity android:name="ai.haptik.android.sdk.messaging.ChatActivity" android:parentActivityName=".MainActivity">
    <meta-data android:name="ai.haptik.android.sdk.messaging.backAsUp" android:value="true" />
  </activity>
  ```

- Add the clientId key to the `strings.xml` file located in `android/app/src/main/res/values`

  ```xml
  <string name="haptik_sdk_client_id">CLIENT_ID</string>
  ```

  > You can request the client id from Haptik

- Add maven repository for the android sdk in `build.gradle` located in `android/app`

  ```gradle
  allprojects {
    repositories {
      mavenLocal()
      ...
      maven {
          url "https://artifactory.hellohaptik.com/artifactory/libs-release-local"
          credentials {
              username "ARTIFACTORY_USERNAME"
              password "ARTIFACTORY_PASSWORD"
          }
      }
    }
  }
  ```

  > Please request Haptik to provide `ARTIFACTORY_USERNAME` & `ARTIFACTORY_PASSWORD`

- Enable `MultiDex` support on your react-native android application by following this guide
https://medium.com/@aungmt/multidex-on-androidx-for-rn-0-60-x-cbb37c50d85

- Android should be good to go.


## Usage

### Basic Example
```jsx
import React from 'react';
import { View, Text, TouchableOpacity } from 'react-native';

import HaptikRN from '@haptik/react-native';

const VIA_NAME = 'testdemochannel';
const BRAND_COLOR = '#1350A0';

const App = () => {
  const [unreadCount, setUnreadCount] = React.useState('N/A');

  const themeChat = () => {
    return HaptikRN.setTheme({
      brandColor: BRAND_COLOR,
      businessChatBackground: '#F5F5F5',
      businessChatText: '#000000',
      messageTimeStamp: '#000000',
    });
  };

  const openChat = async () => {
    const isSignedUp = await HaptikRN.isSignedUp();
    if (isSignedUp) {
      HaptikRN.open(VIA_NAME).catch(console.error);
    } else {
      HaptikRN.signup({
        authType: 'test',
        authID: 'test',
        authToken: 'test',
      })
        .then(themeChat)
        .then(() => HaptikRN.open(VIA_NAME, 'Hi'))
        .catch(console.error);
    }
  };

  React.useEffect(() => {
    themeChat().catch(console.error);
  }, []);

  return (
    <View style={styles.body}>
      <TouchableOpacity onPress={openChat}>
        <View>
          <Text> Open Chat </Text>
        </View>
      </TouchableOpacity>
    </View>
  );
};
```
> Request Haptik for the `authType` and `VIA_NAME` for your IVA

## Available Methods

#### `signup(options)`
Signup bridge method. When no authType is provided, it defaults to guest signup (basic)
```
@param {Object} options auth options
@param {String} options.authType authentication type
@param {String} options.authCode authentication token
@param {String} options.authId authentication id

@returns {Promise} Resolves upon completion
```   

#### `renewSignupToken({token, authType, authId})`
Renew signup token bridge method
@param {Object} options auth options
@param {String} options.authType authentication type
@param {String} options.authCode authentication token
@param {String} options.authId authentication id

@returns {Promise} Resolves upon completion

Sets the user data for a signed up user. All data passed in the userData object is forwarded to the native SDK client.

#### `setUserData(userData)`
```
@param {Object} userData arbitrary dict of key, value pairs
@returns {Promise} Resolves upon completion
```

#### `isSignedUp()`
Checks whether the user has already signed up or not.
```
@returns {Promise} Resolves with the boolean value upon completion
```

#### `open(viaName, launchMessage, hideLaunchMessage)`
Opens the chat window with a particular business via name
```
@param {String} viaName The business via name (ex. reminderschannel)
@param {String} launchMessage An optional message to launch the channel with
@param {String} hideLaunchMessage Whether to hide the launch message or not
@returns {Promise} Resolves upon completion
```
  
#### `sendMessage(message)`
Sends a message to the sdk from the user's side programmatically.
```
@note: NOT SUPPORTED ON IOS
@param {String} message the message to be sent
@returns {Promise} Resolves upon completion
```  

#### `getUnreadCount(viaName)`
Fetched the unread count for a given business via name.
```
@param {String} viaName The business via name (ex. reminderschannel)
@returns {Promise} Resolves with the unread count value upon completion
```

#### `setTheme(theme = {})`
Sets the theme for the sdk. Useful for setting brand colors and fonts.
> === All colors must be in 6 digit hex code strings (ex. #FFFFFF) ===
```
@param {Object} theme the theme object that contains all the theme configurations
@param {String} theme.brandColor The client's main primary brand color
@param {String} theme.businessChatBackground The background color for the chat
@param {String} theme.businessChatText The color for the chat text
@param {String} theme.messageTimeStamp The color for the message timestamps
@param {String} theme.lightFont The font string for light weights
@param {String} theme.regularFont The font string for regular weights
@param {String} theme.mediumFont The font string for medium weights
@param {String} theme.boldFont The font string for bold weights
@param {String} theme.italicFont The font string for italic weights

@returns {Promise} Resolves once the theme is successfully set
```  
    
#### `setDeviceToken(token)`
Sets the device token for supporting notifications.
```
@param {String} token the string representation of the device token to be set.
@returns {Promise} Resolves once the token is set.
```

#### `isHaptikNofication(notification)`
Checks whether a particular notification was sent by Haptik or not.
```
@param {Object} notification the notification object to be checked
@returns {Promise} Resolves with the boolean value upon completion
```