# Introduction

This is the official documentation of TapTalk.io's Products.

There are three documentation consist of TapTalk.io's Products. The first one is OneTalk Omnichannel Documentation, and the second one is PowerTalk Chat SDK Documentation, and the last one is SendTalk API Documentation. OneTalk Omnichannel Documentation is used if you want to integrate Live Chat Channel into your Android and iOS platform,  PowerTalk Chat SDK Documentation is used if you want to implement PowerTalk Chat SDK (Chat function) into your apps, while SendTalk API Documentation is used if you want to send the message from SendTalk using our provided API. Please refer to the following links to read the documentation based on your needs.

[OneTalk Omnichannel Documentation](/onetalk-omnichannel-documentation/getting-started)\
[PowerTalk Chat SDK Documentation](/powertalk-chat-sdk-documentation/getting-started)\
[SendTalk API Documentation](/sendtalk-api-documentation/introduction)


# Getting Started with OneTalk

This documentation is made for those who are new to OneTalk

OneTalk is an omnichannel solution for your marketing, sales, and customer support needs. This documentation includes a comprehensive guide on what things to do first and a more advanced guide like integrating other channels such as WhatsApp to your inbox.

### Things to do first:

* [**Step by step guide to inviting team members**](https://docs.taptalk.io/onetalk-omnichannel-documentation/getting-started/team-members)
* [**Step by step guide to add topics in your organization**](https://docs.taptalk.io/onetalk-omnichannel-documentation/getting-started/add-topic)
* [**Step by step guide to assign agents to your created topics**](https://docs.taptalk.io/onetalk-omnichannel-documentation/getting-started/assign-agent-to-topic)
* [**Step by step guide to use paid proactive chat feature**](/onetalk-omnichannel-documentation/getting-started/paid-proactive-chat)

### Channel integrations:

* [**Integrate Telegram to your inbox**](https://docs.taptalk.io/onetalk-omnichannel-documentation/onetalk-channel-integration/telegram-integration)
* [**Integrate WhatsApp SME to your inbox**](https://docs.taptalk.io/onetalk-omnichannel-documentation/onetalk-channel-integration/whatsapp-sme-integration)
* [**Integrate Web Live Chat to your inbox**](https://docs.taptalk.io/onetalk-omnichannel-documentation/onetalk-channel-integration/live-chat/onetalk-web/get-started)
* [**Integrate iOS Live Chat to your inbox**](https://docs.taptalk.io/onetalk-omnichannel-documentation/onetalk-channel-integration/live-chat/onetalk-ios/get-started-ios)
* [**Integrate Android Live Chat to your inbox**](https://docs.taptalk.io/onetalk-omnichannel-documentation/onetalk-channel-integration/live-chat/onetalk-android/get-started-android)

### Integration APIs:

* [**Integration API**](/onetalk-omnichannel-documentation/onetalk-integration-api)


# Team Members

A step by step guide on how to invite team members into your organization in OneTalk by TapTalk.io.

## Getting Started with Members

Inviting team members to your organization is a straight forward process and should be the first thing to do once you access OneTalk's dashboard.

{% hint style="info" %}
&#x20;Inviting team members can only be done if your role is **Owner** or **Admin**
{% endhint %}

### Step 1: Go to Organization

To get started, on the very left side menu click on **Organization**

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MQFg3opI0-sghMUnOCn%2F-MQFg9ez0T5MmFPRR4ED%2Fminimized.png?alt=media\&token=3989a45f-281c-43c5-bbef-31c86962b73d)

### Step **2**: Go to Members

A submenu should appear with different options, go ahead and select **Members** (this should be the default selection once you click on organization).

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOaaOGTLaDP5VqnQYSe%2F-MOdOxRQKHMbTAhFFX8x%2FScreenshot%202020-12-16%20at%2009.35.39.png?alt=media\&token=47bc1675-af45-4a83-8387-fbb17eb64098)

### Step 3: Click Invite Member

On the right-hand side, click on the button <img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOkEYcxO80ixr8pooTz%2F-MOkEh1zpdaXaU6eT7If%2Fbttn-inviteMember.png?alt=media&amp;token=21ce8714-7d80-4067-b7b2-428fb0b05237" alt="" data-size="original">&#x20;

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MP2kZhacUpzHC9Xko6i%2F-MP2sZLbA0xLMPAz-Jyd%2Finvite%20members.png?alt=media\&token=4e13370f-e5e5-4903-9c26-81d02c74aef2)

### Step 4: Invite Member form

#### Enter your team member's email address

{% hint style="info" %}
Make sure the email address is accessible by you or the invited person
{% endhint %}

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MP2kZhacUpzHC9Xko6i%2F-MP2scYjd6lqKVs-ZuMj%2Fenter%20email.png?alt=media\&token=cdf0d916-7bcb-40fa-92da-2eed240d7bed)

#### Select a Role & Access

Select a role for the invited member (you can change this later).

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MP2kZhacUpzHC9Xko6i%2F-MP2sfEMRCQ8N7ux9MUt%2Fselect%20role.png?alt=media\&token=61fbbe49-f8a7-468b-b487-7816b1f4e715)

#### **Assign Topics (optional)**

Assign your team member to a topic or topics by selecting at least one topic (you can update this later).

{% hint style="info" %}
If you haven't created a topic before, you'll have one default topic named **General**
{% endhint %}

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MP2tXg2YXJxthgKBHkv%2F-MP2vfgZzD6MiyHO4K4F%2Fassign%20topics.png?alt=media\&token=a6384ce9-2d11-4a34-a337-7b59d69c2fe0)

#### Send Invitation

Once everything is filled click on the button <img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOkEYcxO80ixr8pooTz%2F-MOkErEf3hHyyht0Remy%2Fbttn-confirm-sendInvitation.png?alt=media&amp;token=c9442980-26cd-4660-a203-db863afa6e10" alt="" data-size="original">&#x20;

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MP2kZhacUpzHC9Xko6i%2F-MP2sjVm0lDS3EleDosb%2Fsend%20invitation.png?alt=media\&token=9ea7edc5-781c-4b33-8dd4-2a8118c48cd5)

### Step 5: Accept Invitation

Please check for an email from the sender *OneTalk by TapTalk.io* and click <img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOkEYcxO80ixr8pooTz%2F-MOkF-iSO04BvDtl_rkx%2Fbttn-confirm-joinNow.png?alt=media&amp;token=6eb348e7-20e9-4c45-88b2-b6e0e8c42bd8" alt="" data-size="original">&#x20;

{% hint style="info" %}
Please **check your spam folders** for this email if you can't find it in your inbox.
{% endhint %}

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOaIyK2iX068jA9NrXn%2F-MOaY_ojVA7OM17wNr-R%2FScreenshot%202020-12-15%20at%2020.18.31.png?alt=media\&token=0d7bfd64-46e1-4cff-bf62-e2ffc5933523)

### Sign up for OneTalk by TapTalk.io

Once the invited member has clicked on Join Now, a new tab will open prompting the member to sign up. Continue with the sign up process and they will be good to go!


# Add Topic

A step by step guide on how to add a topic in OneTalk by TapTalk.io.

## Topics to better organize your messages

Having the right topics for the right channels can help you efficiently match the right type of questions to expect to the right agents.

{% hint style="info" %}
Adding topics can only be done if your role is **Owner** or **Admin**
{% endhint %}

{% hint style="info" %}
We recommend you to have at least one other invited and verified member other than you (the owner) in the organization. [**Invite members**](/onetalk-omnichannel-documentation/getting-started/team-members#step-4-invite-member-form) if you haven't already done so.
{% endhint %}

### Step 1: Go to Organization

To get started, on the very left side menu click on **Organization.**

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOaIyK2iX068jA9NrXn%2F-MOaSp2TqvKO47h-Rix5%2FScreenshot%202020-12-15%20at%2019.46.46.png?alt=media\&token=3a08c85f-838b-4566-b291-7541a09a3616)

### Step **2**: Go to Topics

A submenu should appear with different options, go ahead and select **Topics.**

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOjt62Bh9y6blThLo2U%2F-MOk4iCSeyUxyfGI904J%2FScreenshot%202020-12-17%20at%2016.44.44.png?alt=media\&token=f522ec9c-24c7-493a-b0ed-964f8a9c1228)

### Step 3: Add a topic

On the right-hand side, click on the button <img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOjt62Bh9y6blThLo2U%2F-MOkE2co_gpsNk35Y6h3%2Fbttn-addTopic.png?alt=media&amp;token=dfca673a-c15b-473a-849f-c8735d52a017" alt="" data-size="original">&#x20;

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOjt62Bh9y6blThLo2U%2F-MOk73OfU9hR5k2bOdaf%2F1%20cell.png?alt=media\&token=7d372012-469a-4196-bc69-b854fa95463c)

### Step 4: Type a topic name

Type in a topic name inside the text box (e.g Billing)

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOjt62Bh9y6blThLo2U%2F-MOk9dYoghp7KN2vKoEz%2F1%20cell-modal.png?alt=media\&token=dd39b91c-a2c7-4bb8-8479-756391612970)

### Step 5: Confirm topic name

To confirm the topic name, click the button <img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOjt62Bh9y6blThLo2U%2F-MOkE-51Yql763fisrmY%2Fbttn-confirm-addTopic.png?alt=media&amp;token=3f603431-3ebf-4d13-8b06-024fd0c51add" alt="" data-size="original">&#x20;

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOjt62Bh9y6blThLo2U%2F-MOkB79hAl3QfsD2y6HX%2F1%20cell-modal%20copy.png?alt=media\&token=ad1d7673-bd21-4515-90bc-21a1237f2870)

### Congratulations! You have just created a topic!

You will be redirected to the topic's detail, where you can edit the topic name and assign an agent.

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOjt62Bh9y6blThLo2U%2F-MOkC_EnwDNbktGokgQz%2F1.0%20%5BTopics%5D%20Topic%20details%20-%20Empty%20state.png?alt=media\&token=5a78cc92-6d79-4f3a-8629-3cdea61273e8)

### What to do next?

We recommend you to assign at least one agent (member) to the topic you have just created. If you wish to assign an agent right after creating a topic, go ahead and click on the button <img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOjt62Bh9y6blThLo2U%2F-MOkDe5HNGVK_4mGjBOI%2Fbttn-assign-agent.png?alt=media&amp;token=3d9283a3-12c5-4dd1-a89a-8d3efd73c7aa" alt="" data-size="original"> and follow the next guide [**Assign Agent to Topic**](/onetalk-omnichannel-documentation/getting-started/assign-agent-to-topic#step-4-assign-an-agent) (skip to step 4).


# Assign Agent to Topic

A step by step guide on how to integrate assign an agent to a topic in OneTalk by TapTalk.io.

## Get your cases handled by the right people

Make sure the right agents are handling the right cases. With OneTalk you can achieve this by assigning specific agents to a specific topic.

{% hint style="info" %}
Assigning agents to topics can only be done if your role is **Owner** or **Admin**
{% endhint %}

{% hint style="info" %}
If you have just added a new topic and still on the topic detail page, [**skip to step 4**](/onetalk-omnichannel-documentation/getting-started/assign-agent-to-topic#step-4-assign-an-agent)
{% endhint %}

### Step 1: Go to Organization

To get started, on the very left side menu click on **Organization**

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOaIyK2iX068jA9NrXn%2F-MOaSp2TqvKO47h-Rix5%2FScreenshot%202020-12-15%20at%2019.46.46.png?alt=media\&token=3a08c85f-838b-4566-b291-7541a09a3616)

### Step **2**: Go to Topics

A submenu should appear with different options, go ahead and select **Topics.**

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOjt62Bh9y6blThLo2U%2F-MOk4iCSeyUxyfGI904J%2FScreenshot%202020-12-17%20at%2016.44.44.png?alt=media\&token=f522ec9c-24c7-493a-b0ed-964f8a9c1228)

### Step 3: Open topic details

Select a topic and click on the button <img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOkF7_DmPFbPEDuL1T1%2F-MOkXFc-GBOj-AazWfDN%2Fbttn-Details.png?alt=media&amp;token=f28d8ad2-1ec6-43a8-bf69-b8de3cacb110" alt="" data-size="original">&#x20;

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOkF7_DmPFbPEDuL1T1%2F-MOkWxdDVtA8pp5we74Z%2F1%20cell-Billing.png?alt=media\&token=d87d82e9-9a08-4344-b9c2-dbd002e743ea)

### Step 4: Assign an agent

Once you have opened topic details, click on the button <img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOjt62Bh9y6blThLo2U%2F-MOkDe5HNGVK_4mGjBOI%2Fbttn-assign-agent.png?alt=media&amp;token=3d9283a3-12c5-4dd1-a89a-8d3efd73c7aa" alt="" data-size="original">&#x20;

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOkF7_DmPFbPEDuL1T1%2F-MOkZT7aUVvWGOJvvzf5%2Ftopic-detail.png?alt=media\&token=bfa844b2-5e06-44f8-97b9-e480b0293eda)

### Step 5: Search and assign an agent

Click on the text box to select or search for a member (you can add multiple at once)

{% hint style="info" %}
This will only show members that has created an account for OneTalk. If you cannot find any of the team members you are looking for, please refer to [**Team Members**](/onetalk-omnichannel-documentation/getting-started/team-members#step-4-invite-member-form) step 4.
{% endhint %}

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOkF7_DmPFbPEDuL1T1%2F-MOka_eS3AOHKBALlMhS%2Fmodal-assignAgent.png?alt=media\&token=629144cb-4546-4001-8a3f-09a49c24c03c)

### Step 6: Confirm agents

Once you have selected a team member, click on the button <img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOkF7_DmPFbPEDuL1T1%2F-MOkbR5jWy8pvpMCro57%2Fbttn-confirm-Agent.png?alt=media&amp;token=8f0c1d21-f2d3-4ddb-96d5-1239c62923d2" alt="" data-size="original"> to confirm

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOkF7_DmPFbPEDuL1T1%2F-MOkb9NEG1gH62BE83hK%2Fmodal-confirmAgent.png?alt=media\&token=57a97c02-e11d-4934-8de3-3b55187dfc81)

### Congratulations! You now have an assigned agent to this topic!

Once confirmed, your newly assigned agent will show up under the section **Assigned Agents**

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOkF7_DmPFbPEDuL1T1%2F-MOkcVPPvvF5orMyTCRz%2Fjust-addedAgent.png?alt=media\&token=ef12dc7f-9aee-4155-b591-c2e39bad8a26)


# Paid Proactive Chat

A step by step guide on how to create a proactive chat by TapTalk.io

## Introduction

By using our Paid Proactive Chat, you can simply reach out to your customer first without waiting for your customer to chat with you in the first place, so you can reach more customers using our feature by sending them a broadcast, a new message, or automatic message using our API.

### Types of Proactive Chat

There are three types of proactive chat that you can use, as explained below :

* [**Broadcast Message**](/onetalk-omnichannel-documentation/getting-started/paid-proactive-chat#broadcast-message)
* [**Start New Conversation**](/onetalk-omnichannel-documentation/getting-started/paid-proactive-chat#start-new-conversation)
* [**Send Message API**](/onetalk-omnichannel-documentation/getting-started/paid-proactive-chat#send-message-api)

#### Broadcast Message

With Broadcast Message, you can send a bulk message to 100 customers at one time so you don't need to send it manually.

#### Start New Conversation

If you want to send a specific message to a specific number of recipients, just simply use our Start New Conversation feature that accessible in our OneTalk Inbox.

#### Send Message API

Another alternative is by using our Send Message API feature. By using our API, you can simply integrate it with your system, and send the message via WhatsApp by calling our API. You can use it to send an automated message like OTP and transactional notification to your customer using our message API.

### **Pricing per Message**

You can check this table below for the detailed pricing of the outbound message of proactive chat that we implement on both WhatsApp SME and WhatsApp Business API.

**WhatsApp SME - Outbound Message**

|                             **Item**                            | **Text** | **Image** | **Video** | **Document** |
| :-------------------------------------------------------------: | :------: | :-------: | :-------: | :----------: |
| <p><strong>Outbound</strong></p><p><strong>Message</strong></p> |  IDR 75  |  IDR 150  |  IDR 300  |    IDR 300   |

**WhatsApp Business API - Outbound Template Message**

|            **Item**           |   **First 250K**  |   **Next 750K**   | <p><strong>Next</strong> </p><p><strong>2M</strong></p> | <p><strong>Next</strong> </p><p><strong>3M</strong></p> | <p><strong>Next</strong></p><p><strong>4M</strong></p> | <p><strong>Next</strong></p><p><strong>5M</strong></p> | <p><strong>Next</strong></p><p><strong>10M</strong></p> | <p><strong>Next</strong></p><p><strong>>25M</strong></p> |
| :---------------------------: | :---------------: | :---------------: | :-----------------------------------------------------: | :-----------------------------------------------------: | :----------------------------------------------------: | :----------------------------------------------------: | :-----------------------------------------------------: | :------------------------------------------------------: |
| **Outbound Template Message** | <p>IDR<br>514</p> | <p>IDR<br>510</p> |                    <p>IDR<br>504</p>                    |                    <p>IDR<br>494</p>                    |                    <p>IDR<br>485</p>                   |                    <p>IDR<br>393</p>                   |                    <p>IDR<br>456</p>                    |                     <p>IDR<br>456</p>                    |

## How to Get Started

Please follow our steps below to get started using our paid proactive chat.

{% hint style="warning" %}
**Important Note**\
This feature can be accessed by the administrator or the member with sufficient permission.
{% endhint %}

### Step 1: **Go to Organization**

To get started, on the very left side menu click **Organization**

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-McSazV9bpkamFV5xcT2%2F-McSbwqry0Dm9HoO0l68%2FHome.png?alt=media\&token=a2587181-8384-4214-b8b5-6464e2a7d968)

### Step **2**: **Go to Balance & Top Up**

Click the submenu of **Balance & Top Up** and on **the Top Up Now** ta&#x62;**,** follow the instructions to top up your balance.

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-McSYf6oBcj6a5mY0Mj2%2F-McS_imsFfWLLStw8ChF%2FTop%20Up%20Now.png?alt=media\&token=c36d2c4b-a438-4f8c-92b6-bd20a2ea4989)

1. Transfer the amount you would like to top up to the TapTalk.io account.
2. After doing a top-up, confirm your top-up by sending an attachment of proof of your transaction to either email [**topup@taptalk.io**](mailto:topup@taptalk.io)**,** WhatsApp **+6283144484847,** or **click on the “Live Chat” button** on the bottom right of your screen.
3. Please allow up to **1x24 hours** for your balance to be updated. We will also send you the invoice email to the registered account.

## How to Check Top Up History

Please follow our step by step below to check your top up history.

### Step 1: **Go to Organization**

To get started, on the very left side menu click **Organization**

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-McSazV9bpkamFV5xcT2%2F-McSbwqry0Dm9HoO0l68%2FHome.png?alt=media\&token=a2587181-8384-4214-b8b5-6464e2a7d968)

### Step **2**: **Go to Top Up History**

Click the submenu of **Balance & Top Up** and choose the **Top Up History** ta&#x62;**,** to see the detail of your top up history.

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-McScjy42DFlNItJGUSz%2F-McSluVCBr3a9XgD7m48%2FTop%20Up%20History.png?alt=media\&token=9f0cef3f-bcac-4acd-a157-dab37ae2dd56)

## How to Check Balance Statement

Please follow our steps below to check your balance statement.

### Step 1: **Go to Organization**

To get started, on the very left side menu click **Organization**

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-McSazV9bpkamFV5xcT2%2F-McSbwqry0Dm9HoO0l68%2FHome.png?alt=media\&token=a2587181-8384-4214-b8b5-6464e2a7d968)

### Step **2**: **Go to Balance Statement**

Click the submenu of **Balance & Top Up** and choose the **Balance Statement** ta&#x62;**,** to see the list of your balance transaction report.

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-McScjy42DFlNItJGUSz%2F-McSn0DNE_a2FLt5sOcI%2FBalance%20Statement.png?alt=media\&token=879778d6-69c7-4b9c-a291-779ae41f2321)


# Channel Integration


# Telegram Integration

A comprehensive step by step guide on how to integrate Telegram as a channel into OneTalk by TapTalk.io.

If you wish to integrate Telegram as a channel into [OneTalk by TapTalk.io](https://taptalk.io/onetalk), the most important thing to do is to create a Telegram bot and obtain the Bot token.

In this article, we will explain to you step-by-step how to create a Telegram bot and obtain the bot token and then integrating the Telegram into our dashboard.&#x20;

If you already have the Telegram Bot and have Bot Token, please proceed to [step 2](/onetalk-omnichannel-documentation/onetalk-channel-integration/telegram-integration#step-2-integrating-telegram-into-onetalk-by-taptalk-io-dashboard).

### Step 1: Create Telegram Bot and Obtain Bot Token

You can follow these steps for a quick way to create a bot on Telegram. For more detailed information, you can find it on the [official site](https://core.telegram.org/bots).

**1.Open @BotFather in Telegram**

Open your Telegram app, find Telegram bot named "**@botfather**", he will help you with creating and managing your bot.

![Search @botfather in Telegram](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MHKR9l2L-Ojp7s7WbiO%2F-MHKRrP5QrjWm4jLav8Q%2FScreen%20Shot%202020-09-16%20at%2012.30.22.png?alt=media\&token=19c31934-5492-4169-93b8-17e9aba5a674)

![Click "Start" to start creating a new bot](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MHKR9l2L-Ojp7s7WbiO%2F-MHKSAB-z6y5OImU2CPC%2FScreen%20Shot%202020-09-16%20at%2012.23.38.png?alt=media\&token=b1d25563-1c62-4711-9007-442fedecf41b)

**2.Create new Telegram bot**

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOAfFgvx2pGUFfmowXm%2F-MOAiHDOYMF8i64rh5NC%2FScreen%20Shot%202020-12-10%20at%2015.16.08.png?alt=media\&token=69b8869a-a019-4b79-9991-e3ee58500b79)

Click Start and type **"/newbot"** for creating a new Telegram bot. You can type “/help” for all possible commands that the Botfather can operate.

Follow the instructions given and create a new name for your bot. If you are making a bot only for experimentation, as it has to be a unique name, you can use namespace your bot by placing your name before it in its username. On completion, Botfather will generate a link to your bot and your **bot token**.

Congrats! You've just created your Telegram bot with the provided bot token. You will see a new API token generated for it. In the sample above, it's **1453797035:AAHwi4rkmgpDihooGSE677QL3uCxJmErdNQ**. \
Now you can copy that token and input the bot token into our Telegram integration page.

### Step 2: Integrating Telegram into OneTalk by TapTalk.io Dashboard

After you create your Telegram Bot and obtain Telegram Bot Token, you can integrate your Telegram Bot into our dashboard, please follow these steps for a quick way to integrate the Telegram Bot

**1. Create New Channel**\
Open [OneTalk Dashboard](https://onetalk.taptalk.io), click **Integration > Telegram** menu and click **Add Channel**

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOAfFgvx2pGUFfmowXm%2F-MOAiYLykfoSusV6NOqN%2FScreen%20Shot%202020-12-10%20at%2015.13.50.png?alt=media\&token=e177bba4-0db2-4636-b84d-0790946fbdf3)

**2. Insert Channel Name & Validate Bot Token**

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOAfFgvx2pGUFfmowXm%2F-MOAjkmTDcyua6_dc3NP%2FScreen%20Shot%202020-12-10%20at%2015.20.19.png?alt=media\&token=8df596e9-d702-4cdc-999b-c264c287ace0)

**Select the topic** for this channel (Each Telegram bot will be **tied into a single topic** of your own choosing so that each incoming message to these accounts will be grouped to the topic of your choice), then **input your Bot Token**. After that click **Validate Button.**

**3. Connect the Channel**\
Make sure your Bot Token is valid. If your Bot Token is valid, the Bot Username and Bot Name will be shown here. After that you can press **Connect button** to connect your Telegram Bot to our dashboard.

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOAfFgvx2pGUFfmowXm%2F-MOAkdiWMP53bk115CVc%2FScreen%20Shot%202020-12-10%20at%2015.20.32.png?alt=media\&token=a51b0f40-0aa0-4096-95c0-8d34613945c5)

Congrats! Your Telegram Bot is now connected to our dashboard, now you can send and receive messages that are coming from that particular Telegram account. \
\
For more information about the integration process, please do not hesitate to send us an email at **<dev@taptalk.io>**.


# WhatsApp SME Integration

A comprehensive step by step guide on how to integrate WhatsApp SME as a channel into OneTalk by TapTalk.io.

Integrating OneTalk with WhatsApp SME will allow you to receive and reply incoming messages from WhatsApp in your inbox.

{% hint style="warning" %}
**Before you get started:** You will need a WhatsApp account number with an accessible mobile phone at your reach.
{% endhint %}

{% hint style="info" %}
Integrating WhatsApp SME can only be done if your role is **Owner** or **Admin.**
{% endhint %}

### Step 1: Create a WhatsApp SME channel

Start by clicking **Integration** on the side men&#x75;**.**

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MP2XOexYEN64RChqeYD%2F-MP2XSdfW87OOPKde26m%2FScreenshot%202020-12-21%20at%2011.21.06.png?alt=media\&token=3824845d-e70a-48e3-8d76-1d7f32268766)

A submenu should appear with different channel options, go ahead and select **WhatsApp SME**.

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOoA6gPf6tV-tWCOtTa%2F-MOoAuqx-BjVkzJNnivV%2FwasmeSelect.png?alt=media\&token=b9525f1a-6463-4168-84ce-89d7e0c0ed93)

Once selected, go ahead and click on the button <img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOoA6gPf6tV-tWCOtTa%2F-MOoBV9reiOCmKhFUxMH%2Fbttn-addChannel.png?alt=media&amp;token=4bb19b35-3c7a-4d8f-9e52-5a2b7fbfca69" alt="" data-size="original">&#x20;

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOoA6gPf6tV-tWCOtTa%2F-MOoGqMGZtQfVt1hsC8i%2FwasmeEmpty.png?alt=media\&token=3e5df507-c6ae-4208-a8d5-2a979ca7eb93)

Fill out the **Account Name** form.

{% hint style="info" %}
**Pro tip:** Fill out your *Account Name* as your selected WhatsApp account phone number.
{% endhint %}

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOoMo3hltF9YY0LKxpM%2F-MOoWju81CSMg9S7hmEG%2FwasmeAccountName.png?alt=media\&token=dc66c0b8-0c63-4e8b-8ba5-eabacc97bb3c)

After you have filled out your form, go ahead and select a topic for this channel (you can change this later). This topic list will correspond to the topics you have created in the **Topics** page.

{% hint style="info" %}
If you don't find the desired topic to choose from, you can always [**add a topic**](https://app.gitbook.com/@taptalk/s/omnichannel/~/drafts/-MOaJ-Dp29xLiLb1W9b9/onetalk-omnichannel-documentation/getting-started/add-topic/@drafts).
{% endhint %}

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOoMo3hltF9YY0LKxpM%2F-MOoWnuacXuxbjws-1QM%2FwasmeTopic.png?alt=media\&token=3e426502-ef21-4335-97d5-442f02a61d97)

Once you have filled both form, click on the button <img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOoMo3hltF9YY0LKxpM%2F-MOoWz01C9FB6LscWc6_%2Fbttn-continuePayment.png?alt=media&amp;token=44fe9237-3026-48af-886c-1b7e37d7fb5b" alt="" data-size="original">&#x20;

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOoMo3hltF9YY0LKxpM%2F-MOoWsKw8AzO0xElnFVS%2FwasmePayment.png?alt=media\&token=011c8ee0-7c04-470d-9c89-7317be86f5cf)

A pop-up displaying the **Terms and Condition** of using WhatsApp SME will appear with the following terms:

* I acknowledge there is a possiblity of this WhatsApp SME number being banned by WhatsApp SME for sending marketing, promotion, spam messages to one or more recipients at once.<br>
* I understand that exceeding the recommended usage can also result in ban by WhatsApp SME.<br>
* I take full responsibilty for any repercussions resulted.

If you agree with the above terms and wish to continue with the setup, click on <img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOoMo3hltF9YY0LKxpM%2F-MOoRJxlld8J8LBahtLY%2Fbttn-Accept.png?alt=media&amp;token=2559ec17-ca19-4137-a96f-34828b596281" alt="" data-size="original"> , if you wish to learn more about this please don't hesitate to [**contact us**](mailto:hello@taptalk.io).

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOoMo3hltF9YY0LKxpM%2F-MOoX23gJbQU0fsWGM-6%2FTermsAndCondition.png?alt=media\&token=2752fb6d-b0ec-4a22-b04f-ac38e0d703e0)

After accepting the terms and conditions above, you will be directed to the page **Review Payment**. Below you'll see:

1. **Your WhatsApp SME plan** (this plan varies depending on the tier you have chosen for OneTalk, you can see more in detail on [**our pricing page**](https://taptalk.io/onetalk/pricing?utm_source=display-ads\&utm_medium=cpc\&utm_campaign=general\&utm_term=a1))**.**<br>
2. **Your current Payment Method** (the default will be set to manual if you have not updated it).

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOoXP41mm2VITpEqoBu%2F-MOobRAeGFho0GlpeUZI%2FwasmeReviewPayment.png?alt=media\&token=05a7a1a7-4d79-4822-a9cc-db16da2e3eb5)

If you wish to change to annual payments, simply activate the toggle <img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOoc5vTGaoNYDE1PRAO%2F-MOocXcLOOFZrXHPeFNn%2FtoggleActive.png?alt=media&amp;token=a8539cb6-e2fa-4a6d-84e8-2ba201a6d153" alt="" data-size="original"> where your WhatsApp SME plan is located.

{% hint style="info" %}
**The total amount due will change** depending if you choose to pay monthly or annually for your WhatsApp SME channel
{% endhint %}

![Monthly Payment](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOoc5vTGaoNYDE1PRAO%2F-MOodmlttV5fjQwXXgzG%2FWhatsApp%20SME-Monthly.png?alt=media\&token=036ea585-7b26-4899-b379-7578894f6274)

![Annual Payment](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOoc5vTGaoNYDE1PRAO%2F-MOodsR4bDldxgGIbhP4%2FWhatsApp%20SME-Annually.png?alt=media\&token=7c686345-2a8c-4a0a-b140-278fd6ea8813)

If you wish to change how you pay, click on the button <img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOoc5vTGaoNYDE1PRAO%2F-MOoeRn-wr9chtzoDbLA%2Fbttn-Method.png?alt=media&amp;token=64148b35-3804-45e1-ae46-13df01bb0f73" alt="" data-size="original"> where your current payment method is located and **follow this guide on Payment Settings**.

{% hint style="warning" %}
**Caution:** If you decide to change payment method, keep in mind that you will lose all the progress you have made so you will have to **repeat step 1**.
{% endhint %}

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOoghHIfPHsWCDFxy_2%2F-MOohAS0odXSTTlMPCbo%2FwasmeChangeMethod.png?alt=media\&token=e8e4bbc0-b3c7-42ca-9ba6-c9db478678c8)

Once you're happy with the current options, go ahead and click <img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOoghHIfPHsWCDFxy_2%2F-MOokXU0OPh5zbPf_y2r%2Fbttn-Confirm.png?alt=media&amp;token=9fae4ab9-58cb-41fc-93f3-a230b182b51e" alt="" data-size="original">&#x20;

{% hint style="info" %}
**Manual Payments:** Please allow up to 24 hours for our team to setup your channel after your payment has been verified. You will need to complete the payment before it reaches the due date once the invoice is generated.
{% endhint %}

{% hint style="info" %}
**Annual Payments:** Please allow up to 24 hours for our team to setup your channel after your payment has been verified. Your next payment will be auto deducted from the card above once it reaches the due date.
{% endhint %}

### Step 2: Confirm and Make Payment

Once you have clicked **Confirm and Make Payment** an alert should appear on the bottom left of the screen:

![Alert indicating that the channel has been created successfully](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOp0IKwmQw5UlbKea-j%2F-MOp3k-tXe237GAdlWnN%2FchannelCreated.png?alt=media\&token=d29b5ee3-ca6a-4f19-9bc2-e4a78e198c46)

{% hint style="info" %}
Your next screen will depend on which payment method you have chosen to create this channel.
{% endhint %}

Select one of the steps below according to your payment method:

* [**Click here for Manual Payment method**](https://app.gitbook.com/@taptalk/s/omnichannel/~/drafts/-MP2LlXtxCbjbc0eK-AC/onetalk-omnichannel-documentation/onetalk-channel-integration/whatsapp-sme-integration/@drafts#manual-payment-method-instructions)<br>
* [**Click here for Automatic Payment method**](https://app.gitbook.com/@taptalk/s/omnichannel/~/drafts/-MOaJ-Dp29xLiLb1W9b9/onetalk-omnichannel-documentation/onetalk-channel-integration/whatsapp-sme-integration/@drafts#automatic-payment-method-instructions)

### **Manual Payment method instructions**

If you have selected manual payment, you will be redirected to **Invoice Detail.**

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOpPdrjz0CEhcFShk_y%2F-MOpPnDE1fASXZxRREhJ%2FinvoiceDetail.png?alt=media\&token=c6879476-a045-4017-a9e4-309ac71bbfef)

Please make payment before the *due date* as stated under the invoice title. To make payment follow the instruction that is beside the total due:

![Payment instruction](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOpPdrjz0CEhcFShk_y%2F-MOpQc7FCGStMSkShBoh%2FinvoiceDetailPay.png?alt=media\&token=1634996a-1c65-4fcd-b606-09c7f934b4e3)

{% hint style="warning" %}
**Important Note:** Before transferring, please make sure you pay exactly as the total states in the invoice
{% endhint %}

![Total amount due](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOpPdrjz0CEhcFShk_y%2F-MOpQgbULJ19QrPNMWEr%2FinvoiceDetailPayTotal.png?alt=media\&token=ff8f1b22-065f-4bed-b5fc-9e1d3f605007)

Once you have transferred, please email the payment proof as an image or PDF to [**sales@taptalk.io**](mailto:sales@taptalk.io), don't forget to include your business name and invoice number in the body message.

![Invoice number](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOpPdrjz0CEhcFShk_y%2F-MOpQlzFAREiG20eImk3%2FinvoiceNumber.png?alt=media\&token=dbed05d7-05c8-4f9c-90b8-bc7ef0c1d9fd)

{% hint style="info" %}
Please allow up to 24 hours for you payment to be verified.
{% endhint %}

To find out whether your payment has been verified, select **WhatsApp SME** on the left side menu and [**jump to step 3**](https://app.gitbook.com/@taptalk/s/omnichannel/~/drafts/-MOaJ-Dp29xLiLb1W9b9/onetalk-omnichannel-documentation/onetalk-channel-integration/whatsapp-sme-integration/@drafts#step-3-setting-up-your-whatsapp-sme).

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOpQpNTCmfBbLg7s9jT%2F-MOpRGcgSQden_yoTqq5%2FinvoiceChannel.png?alt=media\&token=79c8c065-3d59-49c5-b6be-5f0425ae6248)

### **Automatic Payment method instructions**

If you have selected automatic payment, you will be redirected to **Verify Payment.**

{% hint style="info" %}
Keep in mind that this view may vary depending on what type of card you have chosen
{% endhint %}

![Verify payment view](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOpM3W60_sRCFcOjYxK%2F-MOpNZfwA5BG0KjO7DT6%2FVerifyPayment.png?alt=media\&token=fc45e842-5c5a-42f6-bd49-5906a8ccccd1)

Follow the instructions that will appear in the above view. Once success you be redirected to your newly created **channel details**.

### **Step 3: Setting up your WhatsApp SME**

There are quite a few statuses that will be displayed for your newly created channel depending on your payment method. Assuming you have just completed Step 2 (regardless of Manual or Automatic Payment) here are the statuses you may see:

* **Not paid** - Your payment may have not been verified by our team or you have an overdue payment. <br>
* **Waiting for setup** - Your payment has been verified by our team and it is in the process of setting up your WhatsApp account.<br>
* **Got QR code** - Your WhatsApp account has been setup and is ready for you to integrate with OneTalk inbox.

![You can see the status in the channel list ](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOpZWTKyW9TyRXOdzuC%2F-MOpa1Ljw5XqUmqUVtBS%2FchannelGotQR.png?alt=media\&token=155599e1-b20e-492d-a493-ff23fe4689e4)

{% hint style="info" %}
**For Automatic Payment Method**: You will be directed to the page below after verifying your payment.
{% endhint %}

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOphAV1cd2YkbTFL3Us%2F-MOpkR3Vs3BPspvY0I-T%2FwaitingSetupDetail.png?alt=media\&token=b8b28e5b-043c-4899-bf03-18abca5c83a7)

Proceed to channel details by clicking on the created channel once your status is showing **Got QR code**.

{% hint style="info" %}
If it has been more than 24 hours and your status is still either **Not paid** or **Waiting for setup** please don't hesitate to [**contact us**](mailto:dev@taptalk.io).
{% endhint %}

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOpcfK9NmFZxoPGMtoF%2F-MOpfeRktKtxL7MLD4jH%2FgotQR.png?alt=media\&token=dea4cc3d-b9af-43aa-9f7c-830700ba644a)

In the channel details page, click on <img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOphAV1cd2YkbTFL3Us%2F-MOpkkO4wbn46xmdbEgl%2Fbttn-QR.png?alt=media&amp;token=f57cfebd-db27-4907-8955-57b37554b0a6" alt="" data-size="original">&#x20;

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOpkmGlOuxVnE7Fk40-%2F-MOpl8E0Q8TVSMoL8JmA%2FScanQR.png?alt=media\&token=f1e9dd72-17dd-4e69-b538-d14dd290a9e8)

A pop up alert will appear asking whether the phone number used has been active for more than 30 days, prompting you to choose from two options:

* No, Under 30 Days&#x20;
* Yes, More Than 30 Days&#x20;

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOplT3f9yT3HQj7LKRR%2F-MOpmwkmmxu8d9fXixlc%2Funder30.png?alt=media\&token=99ace07e-586a-46c6-8222-7ab804d2e124)

{% hint style="warning" %}
If you are unsure, go with [**No, Under 30 Days**](https://app.gitbook.com/@taptalk/s/omnichannel/~/drafts/-MOaJ-Dp29xLiLb1W9b9/onetalk-omnichannel-documentation/onetalk-channel-integration/whatsapp-sme-integration/@drafts#no-under-30-days-secure-authentication) which will lead you to Secure Authentication page.
{% endhint %}

Jump to one of these sections depending which one you have chosen:

* [**No, Under 30 Days (Secure Authentication)**](https://app.gitbook.com/@taptalk/s/omnichannel/~/drafts/-MOaJ-Dp29xLiLb1W9b9/onetalk-omnichannel-documentation/onetalk-channel-integration/whatsapp-sme-integration/@drafts#no-under-30-days-secure-authentication)<br>
* [**Yes, More Than 30 Days (Authenticate Now)**](https://app.gitbook.com/@taptalk/s/omnichannel/~/drafts/-MOaJ-Dp29xLiLb1W9b9/onetalk-omnichannel-documentation/onetalk-channel-integration/whatsapp-sme-integration/@drafts#yes-more-than-30-days-authenticate-now)

### **No, Under 30 Days (Secure Authentication)**

If you decided to click on **No, Under 30 Days**, you will be directed to Secure Authentication page.

{% hint style="warning" %}
Make sure you are using **Google Chrome**
{% endhint %}

Firstly click on **Secure Authorization**.

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOplT3f9yT3HQj7LKRR%2F-MOpr2OWRkdcjaUcd6CU%2FsecureAuth1.png?alt=media\&token=0266c9b6-6ed0-4708-aad0-259788d9871d)

Click on **Install extension**

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOplT3f9yT3HQj7LKRR%2F-MOpsIMozpwm3GW5sFIQ%2FsecureAuth2A.png?alt=media\&token=6aa66f3c-78db-4221-a6fa-045450e365a2)

{% hint style="warning" %}
**Important Note:** Once you have installed the chrome extension make sure you **refresh the page**, do not click OK.
{% endhint %}

You will be taken back to the same view as you started at Secure Authentication. Go ahead and click on **Secure Authorization** again.

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOplT3f9yT3HQj7LKRR%2F-MOpsw0vyHDFZzUhuDQ9%2FsecureAuth1.png?alt=media\&token=aa1d623a-2652-4431-8799-ac8830be8ba2)

Open WhatsApp mobile app on your phone, go to **Settings > WhatsApp Web/Desktop > Scan QR Code.**&#x20;

Once done, you will be taken back to your channel details page.&#x20;

Jump to section [**Authentication done**](https://app.gitbook.com/@taptalk/s/omnichannel/~/drafts/-MP2LlXtxCbjbc0eK-AC/onetalk-omnichannel-documentation/onetalk-channel-integration/whatsapp-sme-integration/@drafts#authentication-done).

### **Yes, More than 30 Days (Authenticate Now)**

If you decided to click on **Yes, More than 30 Days**, you will be directed to Authenticate Now page.&#x20;

Follow the instruction that are on the page or simply open WhatsApp mobile app on your phone, go to **Settings > WhatsApp Web/Desktop > Scan QR Code**.

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOptiMPL-fHHVyrpDOP%2F-MOpwc39TsHZhYWfKP07%2FAuthNow.png?alt=media\&token=189c4448-3f42-4db8-9f11-9c1bd727728d)

Once done, you will be taken back to your channel details page.

### Authentication done!

Congratulations, you have successfully integrated your WhatsApp account with OneTalk. There are some key points that needs to be kept in mind:

* **There will be a syncing process time up to 48 hours**, this entirely depends on the volume of messages you have on your WhatsApp account and also your internet connection. This may cause up to a 10 minute delay in receiving messages. <br>
* **You must monitor the mobile phone connected with WhatsApp SME**. We recommend you keep charge of the mobile phone at all times and make sure it has a stable internet connection.<br>
* **You cannot use WhatsApp Web/Desktop on the same account of WhatsApp SME**. You can still reply messages through WhatsApp mobile app but we highly recommend you download OneTalk's Mobile agent app on [**Google Play Store**](https://play.google.com/store/apps/details?id=io.taptalk.onetalk) instead.

![You are now ready to receive and reply to incoming messages from WhatsApp on OneTalk!](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOq-4gWwBffWqC9iAOx%2F-MOq0Ovua2ZyMaASfDWf%2FAuthenticated.png?alt=media\&token=096fc307-1093-4a98-9718-69a04ac12918)


# Instagram Comment & DM Integration

A comprehensive step by step guide on how to integrate Instagram DM as a channel into OneTalk by TapTalk.io.

Integrating OneTalk with Instagram DM will allow you to receive and reply incoming messages from Instagram in your inbox.

Integrating OneTalk with Instagram Comment will allow you to receive and reply incoming comments on your Instagram posts from Instagram users.

{% hint style="warning" %}
**Before you get started:** You will need an **Instagram** **Business** **Account** or **Instagram** **Creator** **Account**, not a personal Instagram Account, and you will also need a **Facebook Page** connected to your Instagram account.

Please follow this link for more information:

[Instagram Business Account](https://help.instagram.com/502981923235522) or [Instagram Creator Account](https://help.instagram.com/2358103564437429)\
[Facebook Page Connected to Instagram Account](https://help.instagram.com/399237934150902)
{% endhint %}

{% hint style="info" %}
Integrating Instagram DM can only be done if your role is **Owner** or **Admin.**
{% endhint %}

### Step 1: Create an Instagram DM channel

Start by clicking **Integration** on the side men&#x75;**.**

​A submenu should appear with different channel options, go ahead and select **Instagram DM**.

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-Mj3x0YwIqkHTgztIquj%2F-Mj3xK_Abyr8s3o0qktx%2FScreen%20Shot%202021-09-08%20at%2017.28.32.png?alt=media\&token=3402e978-59d4-4447-9aff-b4bad62a476b)

Once selected, go ahead and click on the button ![](https://firebasestorage.googleapis.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOoA6gPf6tV-tWCOtTa%2F-MOoBV9reiOCmKhFUxMH%2Fbttn-addChannel.png?alt=media\&token=4bb19b35-3c7a-4d8f-9e52-5a2b7fbfca69)

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-Mj3xRb6t744hir_uZcC%2F-Mj40BnGjv9h2MrqWEYv%2F2A%20FB%20Messenger%20-%20Empty.png?alt=media\&token=5ad2284a-1d57-43af-8376-30c4c57cd8fa)

**Next,** you will have to login with your Facebook account, please click the **Continue with Facebook** button.

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-Mj3xRb6t744hir_uZcC%2F-Mj40N7_IdvGTo9qoRWf%2F2B%20FB%20Messenger%20-%204%20channels.png?alt=media\&token=6452f70d-450d-4389-bfe6-f5d71553659e)

{% hint style="warning" %}
**Note:** Make sure you login with the Facebook account which has the access to the Facebook Page&#x20;
{% endhint %}

### Step 2: Login to Facebook account

Start by clicking **Continue with Facebook** button, you will be prompt to input your email or password for the first time, or after you've done login, it will show a popup like this.

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-Mj3BmvW38ohWFZcb59T%2F-Mj3S2866UiNyoPIJlHa%2Flogged%20in.png?alt=media\&token=f53a6d31-a2da-4520-9e32-e5a78fd2c619)

### Step 3: Choose Instagram account

Next, it will prompt a pop-up to select an Instagram account, select all the accounts that you wish to integrate to OneTalk.

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-Mj3BmvW38ohWFZcb59T%2F-Mj3SNKjlAmbCYpbCvVy%2Fselect%20Account.png?alt=media\&token=b7445448-ee85-4adc-ad4b-fef1a3faa284)

### Step 4: Choose connected Facebook Page

Next, choose the Facebook Page that connected to that account

{% hint style="warning" %}
**Note:** Please note that you have to connect your **Instagram** Account to **Facebook Page**

For more information please refer to this page below :\
[Facebook Page Connected to Instagram Account](https://help.instagram.com/399237934150902)
{% endhint %}

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-Mj3BmvW38ohWFZcb59T%2F-Mj3YDE1Tz8EK7JwCp_Q%2Fselect%20Pages.png?alt=media\&token=8fef1cd8-879a-4776-befb-c1c328e96259)

After you choose the **Instagram** **account** and **Facebook** **Page**, you will be prompt to choose the permission, please select all the permission and click continue.

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-Mj3BmvW38ohWFZcb59T%2F-Mj3Z7NZfZi3-zDIAMa3%2Fallowed.png?alt=media\&token=e1a76471-a476-4143-897c-2997555fce06)

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-Mj3BmvW38ohWFZcb59T%2F-Mj3Zn8cIkRRp7g4us7N%2Fsuccess.png?alt=media\&token=6036318e-0359-4a1e-9fd6-c8bd114b2fbd)

Once you've seen the popup above, means your account is now connected to OneTalk.

### Step 5: Choose connected Facebook Page

After you successfully logged in into your Facebook account, you will be shown screen as below:

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-Mj3BmvW38ohWFZcb59T%2F-Mj3rQczVhFpUWfL1fcr%2Fno%20button.png?alt=media\&token=97b4eece-6324-4955-a918-c7a13d6d9255)

Choose the FB Page you wish to integrate. Also, choose the related OneTalk topic for that channel

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-Mj3xRb6t744hir_uZcC%2F-Mj40hgcAZAtMQ5VS32e%2Fselect%20topics.png?alt=media\&token=62409809-5992-44e0-a018-714ce67d0c94)

After you choose the FB Page and Topic, click **Create Channel Button** on the top right of the screen.

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-Mj3xRb6t744hir_uZcC%2F-Mj40qWRngelY_Ydu_GV%2Factive.png?alt=media\&token=42d5b7ea-5999-4768-a704-50b03157fdf8)

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-Mj3xRb6t744hir_uZcC%2F-Mj41-Z0JjPmkuhSxi12%2F5A%20FB%20Messenger%20-%20Channel%20Details.png?alt=media\&token=5ec2272c-3429-48c8-9088-880cc5ce5751)

### Step 6: Enable Message Control on Instagram

One more step! After you've successfully connected your Instagram account to OneTalk, please make sure you activate **Allow Access to Messages** on your **Instagram** account.

To activate that, please follow this step:\
Open **Instagram,** go to **Settings** > **Privacy** > **Messages,** then turn on **Allow Access to Messages**

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-Mj41QqdHnqXxQwqx8Te%2F-Mj4AZi1ryOmvPkolDdY%2Fphoto_2021-09-08%2018.31.49.jpeg?alt=media\&token=28df9a9b-edfb-4974-b5bf-45923ded7d1c)

Congrats! You've successfully connected your Instagram account to OneTalk. For more information feel free to contact us via **<support@taptalk.io>** or simply click the link below to chat from [**WhatsApp**](https://api.whatsapp.com/send/?phone=6282180885808\&text=Halo+TapTalk.io%2C+Saya+ingin+bertanya+terkait+integrasi+channel+saya)**.**


# Facebook Comment & Messenger Integration

A comprehensive step by step guide on how to integrate Facebook Messang as a channel into OneTalk by TapTalk.io.

Integrating OneTalk with Facebook Messenger will allow you to receive and reply incoming messages from Facebook in your inbox.

Integrating OneTalk with Facebook Comment will allow you to receive and reply incoming comments on your Facebook Page's posts from Facebook users.

{% hint style="info" %}
Integrating Facebook Messanger can only be done if your role is **Owner** or **Admin.**
{% endhint %}

### Step 1: Create an Facebook Messanger channel

Start by clicking **Integration** on the side men&#x75;**.**

​A submenu should appear with different channel options, go ahead and select **Facebook Messanger**.

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2F4V3SmQZMO9loWSE586D2%2FScreen%20Shot%202022-04-21%20at%2015.59.40.png?alt=media\&token=57cd1cef-f3c8-4d9b-a60d-3845761b488d)

Once selected, go ahead and click on the **Add Channel** button

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2Fs63KhhUrAKHwDHwTu5f6%2FScreen%20Shot%202022-04-21%20at%2015.59.08.png?alt=media\&token=f90df75c-dc97-4961-8f93-f2e13a6e8e79)

**Next,** you will have to login with your Facebook account, please click the **Continue with Facebook** button.

{% hint style="warning" %}
**Note:** Make sure you login with the Facebook account which has the access to the Facebook Page&#x20;
{% endhint %}

### Step 2: Login to Facebook account

Start by clicking **Continue with Facebook** button, you will be prompt to input your email or password for the first time, or after you've done login, it will show a popup like this.

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2Fjvrgh4gQlJTrqSmidFJD%2FScreen%20Shot%202022-04-21%20at%2016.07.35.png?alt=media\&token=2e35efb0-5864-4e68-b278-0de9be4ba0ff)

### Step 3: Choose Facebook Page

Next, it will prompt a pop-up to select Facebook Page. Select all the pages that you wish to integrate to OneTalk

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-Mj3BmvW38ohWFZcb59T%2F-Mj3YDE1Tz8EK7JwCp_Q%2Fselect%20Pages.png?alt=media\&token=8fef1cd8-879a-4776-befb-c1c328e96259)

After you choose the **Facebook** **Page**, you will be prompt to choose the permission, please select all the permission and click **DONE**.

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-Mj3BmvW38ohWFZcb59T%2F-Mj3Z7NZfZi3-zDIAMa3%2Fallowed.png?alt=media\&token=e1a76471-a476-4143-897c-2997555fce06)

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-Mj3BmvW38ohWFZcb59T%2F-Mj3Zn8cIkRRp7g4us7N%2Fsuccess.png?alt=media\&token=6036318e-0359-4a1e-9fd6-c8bd114b2fbd)

Once you've seen the popup above, means your account is now connected to OneTalk.

### Step 4: Choose connected Facebook Page

After you successfully logged in into your Facebook account, you will be shown screen as below:

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-Mj3BmvW38ohWFZcb59T%2F-Mj3rQczVhFpUWfL1fcr%2Fno%20button.png?alt=media\&token=97b4eece-6324-4955-a918-c7a13d6d9255)

Choose the FB Page you wish to integrate. Also, choose the related OneTalk topic for that channel

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2Ft7CzU1Ba6fr7XwrP6ZFf%2FScreen%20Shot%202022-04-21%20at%2016.11.59.png?alt=media\&token=07fba752-9d72-4c3d-989f-f83560758d95)

After you choose the FB Page and Topic, click **Create Channel Button** on the top right of the screen.

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2FtHUma0TMGPolMfachk7H%2FScreen%20Shot%202022-04-21%20at%2016.13.59.png?alt=media\&token=7bd4bceb-efb2-4a81-a599-abfb398dddf3)

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2FZqeylxh40P3aMWXR1eZX%2FScreen%20Shot%202022-04-21%20at%2016.15.12.png?alt=media\&token=dc94bec4-2182-49eb-8c68-aec3efabf7fd)

**Congrats! You've successfully connected your Facebook account to OneTalk**.&#x20;

For more information feel free to contact us via **<support@taptalk.io>** or simply click the link below to chat from [**WhatsApp**](https://api.whatsapp.com/send/?phone=6282180885808\&text=Halo+TapTalk.io%2C+Saya+ingin+bertanya+terkait+integrasi+channel+saya)**.**


# Live Chat Integration (iOS, Android, Web)

A comprehensive step by step guide on how to integrate Live Chat as a channel into OneTalk by TapTalk.io.

Integrating OneTalk Live Chat will allow you to receive and reply incoming messages from your website or mobile app in your inbox.

{% hint style="warning" %}
**Before you get started:** You will need a website or mobile app (Android or iOS) to integrate with OneTalk Live Chat.
{% endhint %}

{% hint style="info" %}
Integrating OneTalk Live Chat can only be done if your role is **Owner** or **Admin.**
{% endhint %}

### Step 1: Create a **Live Chat** channel

Start by clicking **Integration** on the side men&#x75;**.**

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOo57RuynyYDdP9lVTw%2F-MOoA1fmhPQchAQr9X1b%2FhoverIntergration.png?alt=media\&token=38bcb196-648f-4b95-9ac9-406f4951ce9b)

A submenu should appear with different channel options, go ahead and select **Live Chat** (this should be the default page once you click Integration).

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOqU_51fahgTjfC1jQV%2F-MOqUdaA99jt6MkYybjm%2FliveChatEmpty.png?alt=media\&token=53a4b3b9-3794-406b-86c4-1a66228f2c93)

Once selected, go ahead and click on the button <img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOoA6gPf6tV-tWCOtTa%2F-MOoBV9reiOCmKhFUxMH%2Fbttn-addChannel.png?alt=media&amp;token=4bb19b35-3c7a-4d8f-9e52-5a2b7fbfca69" alt="" data-size="original">&#x20;

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOqU_51fahgTjfC1jQV%2F-MOqUpiUlVjr9Vk2y5cG%2FliveChatEmptyAdd.png?alt=media\&token=03651a30-778e-4d6f-a9d6-487d49706b24)

### Step 2: Select platform

Depending on what platform you choose, the steps may vary. Jump to the section:

* [**Setup Live Chat for iOS**](/onetalk-omnichannel-documentation/onetalk-channel-integration/live-chat#setup-live-chat-for-ios)<br>
* [**Setup Live Chat for Android**<br>](/onetalk-omnichannel-documentation/onetalk-channel-integration/live-chat#setup-live-chat-for-android)
* [**Setup Live Chat for Web**](/onetalk-omnichannel-documentation/onetalk-channel-integration/live-chat#setup-live-chat-for-web)

### **Setup Live Chat for iOS**

Enter your iOS app **Bundle ID**

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOqUs8xyP60p0Qp-23b%2F-MOqZ7TKes-SvIy7k_qi%2FScreenshot%202020-12-18%20at%2022.54.57.png?alt=media\&token=27983558-6597-43a7-9266-e6fc3587baa7)

Once filled, click on <img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOqUs8xyP60p0Qp-23b%2F-MOqZs7-EsHNWrX9AFCT%2Fbttn-CreateChannel.png?alt=media&amp;token=0147d3d5-fb8e-4892-95a9-10783d15a306" alt="" data-size="original">&#x20;

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOqUs8xyP60p0Qp-23b%2F-MOq_--Qgo962KrDcOTY%2FScreenshot%202020-12-18%20at%2022.57.30.png?alt=media\&token=282d99cc-5936-4f79-9624-839d51c1d5a5)

Once created, you will be redirected to the channel's details, where you can copy its secret key and paste it in your app.

{% hint style="info" %}
Please refer to [**OneTalk Live Chat for iOS**](https://docs.taptalk.io/onetalk-omnichannel-documentation/onetalk-channel-integration/live-chat/onetalk-ios/get-started-ios) once you have created this channel.
{% endhint %}

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOqaJh9inTYN8detj9z%2F-MOqahohs9CDOcpEuRlp%2FliveChat-iOS.png?alt=media\&token=e67bdef0-5674-47aa-8ecb-0eeb533b4d8b)

### **Setup Live Chat for Android**

Enter your Android app **Package Name**

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOqaJh9inTYN8detj9z%2F-MOqbUDw8Pni_7B2vn0Z%2FScreenshot%202020-12-18%20at%2023.09.07.png?alt=media\&token=8d3a157f-31e1-45e7-baa7-2e2800e60ee4)

Once filled, click on <img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOqUs8xyP60p0Qp-23b%2F-MOqZs7-EsHNWrX9AFCT%2Fbttn-CreateChannel.png?alt=media&amp;token=0147d3d5-fb8e-4892-95a9-10783d15a306" alt="" data-size="original">&#x20;

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOqaJh9inTYN8detj9z%2F-MOqbbrGsJ-kt2vaHNwa%2FScreenshot%202020-12-18%20at%2023.09.07%20copy.png?alt=media\&token=85a712c6-03a4-486e-9d63-ac205ad33bec)

Once created, you will be redirected to the channel's details, where you can copy its secret key and paste it in your app.

{% hint style="info" %}
Please refer to [**OneTalk Live Chat for Android**](https://docs.taptalk.io/onetalk-omnichannel-documentation/onetalk-channel-integration/live-chat/onetalk-android/get-started-android) once you have created this channel
{% endhint %}

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOqaJh9inTYN8detj9z%2F-MOqbkJ2N2F1xXWRa4_k%2FliveChat-Android.png?alt=media\&token=6f0c29df-7b9e-45b9-b7e0-b453666d56fd)

### **Setup Live Chat for Web**

Enter your Web **CORS**. [**Learn more about CORS**](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS).

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOqbr6-Z_O2JMwIlXkT%2F-MOqdSPp_hzvgijOclY-%2FScreenshot%202020-12-18%20at%2023.15.34.png?alt=media\&token=b64d5e27-ba99-47e8-a8a2-7e1486ddc6a5)

Once filled, click on <img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOqUs8xyP60p0Qp-23b%2F-MOqZs7-EsHNWrX9AFCT%2Fbttn-CreateChannel.png?alt=media&amp;token=0147d3d5-fb8e-4892-95a9-10783d15a306" alt="" data-size="original">&#x20;

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOqbr6-Z_O2JMwIlXkT%2F-MOqdYuajSOIrE7TRz-P%2FScreenshot%202020-12-18%20at%2023.15.34%20copy.png?alt=media\&token=7f1b2f7f-4032-444e-b49a-efd1ab5831b1)

Once created, you will be redirected to the channel's details, where you can copy the script generated and paste it this snippet code on your web page inside the \<head> tag.&#x20;

This will enable OneTalk's live chat to be displayed on your web.

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOqdaYryDe3WJQd0gns%2F-MOqg0qeP6zbJuV-w7bc%2FScreenshot%202020-12-18%20at%2023.27.45.png?alt=media\&token=e15d4282-c477-4587-b46b-aaf3d001cb73)

You can change the widgets color according to your brand color. Simply scroll down and enter your desired hex code or simply choose with the gradient slider.

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOqdaYryDe3WJQd0gns%2F-MOqgn8G_v6VT9Ws3cBN%2FScreenshot%202020-12-18%20at%2023.32.26.png?alt=media\&token=c37281c3-9d59-4a07-a597-d836fe6d9364)

Once done, don't forget to click <img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOqdaYryDe3WJQd0gns%2F-MOqhqagqf1lWqbFL6mh%2Fbttn-SaveChanges.png?alt=media&amp;token=e9220993-7e1d-4856-8d0e-a5922f6c97d6" alt="" data-size="original">&#x20;

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MOqdaYryDe3WJQd0gns%2F-MOqhup73x0T1VdjMMw0%2FScreenshot%202020-12-18%20at%2023.36.42.png?alt=media\&token=fcdd80c6-a771-4144-9bfc-e02d172cb8a5)

{% hint style="info" %}
Please refer to [**OneTalk Live Chat for Web**](https://docs.taptalk.io/onetalk-omnichannel-documentation/onetalk-channel-integration/live-chat/onetalk-web/get-started) once you have created this channel
{% endhint %}


# OneTalk Live Chat for Android

To start implementing OneTalk Live Chat for Android, please click the Get Started section


# Get Started

{% hint style="warning" %}
**Before you get started:** Make sure you have [**created a channel in OneTalk dashboard**](/onetalk-omnichannel-documentation/onetalk-channel-integration/live-chat#setup-live-chat-for-android) and obtain the **`APP_KEY_SECRET.`**
{% endhint %}

### Configure and Initialize TapTalk.io Omnichannel Android SDK

#### Step 1: Install TapTalk.io SDK

To start, open your Android project and add the following repositories to your **top-level** build.gradle file.

{% code title="build.gradle (project)" %}

```groovy
allprojects {
    repositories {
        google()
        mavenCentral()
        maven {
            url = "https://jitpack.io"
        }
        maven {
            url = "https://s3.amazonaws.com/repo.commonsware.com"
        }
    }
}
```

{% endcode %}

Then add the following dependency to your **app-level** build.gradle:

{% code title="build.gradle (:app)" %}

```groovy
dependencies {
    implementation("com.github.taptalk-io:taptalk.io-omnichannel-android:3.0.0")
}
```

{% endcode %}

{% hint style="info" %}
You can check a more updated version release notes of the SDK [here](https://github.com/taptalk-io/taptalk.io-omnichannel-android/releases).
{% endhint %}

{% hint style="warning" %}
**Note**: In the app **build.gradle** file, make sure that your project is using supported Java 8 language features under the `android` tag like below
{% endhint %}

{% code title="build.gradle (:app)" %}

```groovy
android {
    ...
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_17
        targetCompatibility = JavaVersion.VERSION_17
    }
}
```

{% endcode %}

#### Step 2: Initialize TapTalkLive

&#x20;In order to use TapTalkLive SDK, you must first initialize a TapTalkLive instance by passing the **`CONTEXT`**, **`APP_KEY_SECRET`**, **`CLIENT_APP_ICON`**, and **`CLIENT_APP_NAME`** assigned to your application to the **`init`** method as a parameter. Generally, initialization is implemented in the **Application** class in your project.

{% tabs %}
{% tab title="Java" %}
{% code title="Application.java" %}

```java
import io.taptalk.taptalklive.TapTalkLive;
import io.taptalk.taptalklive.Listener.TapTalkLiveListener;
import io.taptalk.taptalklive.API.Model.ResponseModel.TTLErrorModel;

...

TapTalkLive.init(
    CONTEXT, 
    APP_KEY_SECRET, 
    CLIENT_APP_ICON, 
    CLIENT_APP_NAME,
    new TapTalkLiveListener() {
        @Override
        public void onInitializationCompleted() {
            // Handle initialization success here
        }
        
        @Override
        public void onInitializationFailed(TTLErrorModel error) {
            // Handle initialization failure here
        }
    }
);
```

{% endcode %}
{% endtab %}

{% tab title="Kotlin" %}
{% code title="Application.kt" %}

```kotlin
import io.taptalk.taptalklive.TapTalkLive
import io.taptalk.taptalklive.Listener.TapTalkLiveListener
import io.taptalk.taptalklive.API.Model.ResponseModel.TTLErrorModel

...

TapTalkLive.init(
    CONTEXT, 
    APP_KEY_SECRET, 
    CLIENT_APP_ICON, 
    CLIENT_APP_NAME,
    object : TapTalkLiveListener() {
        override fun onInitializationCompleted() {
            // Handle initialization success here
        }

        override fun onInitializationFailed(error: TTLErrorModel?) {
            // Handle initialization failure here
        }
    }
)
```

{% endcode %}
{% endtab %}
{% endtabs %}

{% hint style="info" %}

#### Parameters

**`CONTEXT`** (Context) application context\
**`APP_KEY_SECRET`**: (String) application key Secret\
**`CLIENT_APP_ICON`**: (int) drawable resource ID of your application's icon\
**`CLIENT_APP_NAME`**: (String) your application name\
**`tapTalkLiveListener`**: (TapTalkLiveListener) an interface to detect TapTalkLive Android SDK's delegates and callbacks
{% endhint %}

{% hint style="info" %}
Note: A more complete implementation of TapTalkLiveListener callbacks can be seen in the [Event Listeners page](/onetalk-omnichannel-documentation/onetalk-channel-integration/live-chat/onetalk-android/event-listener).
{% endhint %}

#### Step 3: Enable Chat Features

Please follow the steps in [Enable Chat Features](/powertalk-chat-sdk-documentation/powertalk-android/enable-chat-features) page to enable TapTalk.io's chat features, such as contact sync and sending media, document, and location messages.

### Open TapTalk Omnichannel View

To open TapTalkLive's view UI for your application, you can use the **`openTapTalkLiveView`** method from the **TapTalkLive** class. This will open a homepage activity containing a list of available channels, the user's latest case, and QnA path.

{% tabs %}
{% tab title="Java" %}
{% code title="YourActivity.java" %}

```java
import io.taptalk.taptalklive.TapTalkLive;

TapTalkLive.openTapTalkLiveView(YourActivity.this);
```

{% endcode %}
{% endtab %}

{% tab title="Kotlin" %}
{% code title="YourActivity.kt" %}

```kotlin
import io.taptalk.taptalklive.TapTalkLive

TapTalkLive.openTapTalkLiveView(this@YourActivity)
```

{% endcode %}
{% endtab %}
{% endtabs %}

{% hint style="info" %}
**`openTapTalkLiveView`** will return **`true`** if opening the view is successful, and will return `false` if it fails due to incomplete initialization. TapTalkLive initialization might not be completed if the device is not connected to internet or an incorrect **`APP_KEY_SECRET`** parameter was provided.
{% endhint %}


# Event Listener

The Android SDK provides event listener to listen to various events on the client app. Through these event delegates, TapTalk.io notifies the client app of events that happen on your app.

You can listen through general events from the Live Chat SDK through the **TapTalkLiveListener** class. An instance of TapTalkLiveListener will be required to initialize the Live Chat SDK. A more complete implementation will be explained in this page.

{% tabs %}
{% tab title="Java" %}
{% code title="Application.java" %}

```java
import io.taptalk.taptalklive.TapTalkLive;
import io.taptalk.taptalklive.Listener.TapTalkLiveListener;
import io.taptalk.taptalklive.API.Model.ResponseModel.TTLErrorModel;
import io.taptalk.taptalklive.API.Model.TTLScfPathModel;
import io.taptalk.TapTalk.Model.TAPMessageModel;

...

TapTalkLive.init(
    CONTEXT, 
    APP_KEY_SECRET, 
    CLIENT_APP_ICON, 
    CLIENT_APP_NAME,
    new TapTalkLiveListener() {
        @Override
        public void onInitializationCompleted() {
            // Initialization success
        }
        
        @Override
        public void onInitializationFailed(TTLErrorModel error) {
            // Initialization failed
        }

        @Override
        public void onNotificationReceived(TAPMessageModel message) {
            // TapTalk.io SDK receives a message notification
            // Calling super will show TapTalk.io's default notification for the app
            super.onNotificationReceived(message);
        }
    
        @Override
        public void onCloseButtonInHomePageTapped(Activity activity) {
            // User closes the home page
        }
    
        @Override
        public void onCloseButtonInCreateCaseFormTapped(Activity activity) {
            // User closes the create case form
        }
    
        @Override
        public void onCloseButtonInCaseListTapped(Activity activity) {
            // User closes the case list page
        }
    
        @Override
        public void onTaskRootChatRoomClosed(Activity activity) {
            // A chat room activity was closed by user when no other activity in the application is present
            // You may start another activity to keep the app open, otherwise the app will stay closed
    }
    
        @Override
        public void onSeeAllMessagesButtonTapped(Activity activity) {
            // User taps the See All Messages button in home page
            // Calling super will open the case list page
            super.onSeeAllMessagesButtonTapped(activity);
        }
    
        @Override
        public void onCreateNewMessageButtonTapped(Activity activity) {
            // User taps the New Messages button in home or case list page
            // Calling super will open the create new case form
            super.onCreateNewMessageButtonTapped(activity);
        }
    
        @Override
        public void onCaseListItemTapped(Activity activity, TAPMessageModel lastMessage) {
            // User taps a case from a list in home or case list page
            // Calling super will open the selected chat room
            super.onCaseListItemTapped(activity, lastMessage);
        }
    
        @Override
        public void onFaqChildTapped(Activity activity, TTLScfPathModel scfPath) {
            // User taps a FAQ from a list in home or FAQ details page
            // Calling super will open the selected FAQ details page
            super.onFaqChildTapped(activity, scfPath);
        }
    
        @Override
        public void onCloseButtonInFaqDetailsTapped(Activity activity, TTLScfPathModel scfPath) {
            // User closes the FAQ details page
        }
    
        @Override
        public void onTalkToAgentButtonTapped(Activity activity, TTLScfPathModel scfPath) {
            // User taps the Talk to Agent button in home or FAQ details page
            // Calling super will open the create new case form
            super.onTalkToAgentButtonTapped(activity, scfPath);
        }
        
        @Override
        public void onFaqContentUrlTapped(Activity activity, TTLScfPathModel scfPath, String url) {
            // User taps a url in FAQ content
            // Calling super will open the selected url using TapTalk.io's in-app browser
            super.onFaqContentUrlTapped(activity, scfPath, url);
        }
        
        @Override
        public void onFaqContentUrlLongPressed(Activity activity, TTLScfPathModel scfPath, String url) {
            // User long presses a url in FAQ content
            // Calling super will copy the selected url to the device's clipboard
            super.onFaqContentUrlLongPressed(activity, scfPath, url);
        }
        
        @Override
        public void onFaqContentEmailAddressTapped(Activity activity, TTLScfPathModel scfPath, String email) {
            // User taps an email address in FAQ content
            // Calling super will open the device's email composer for the selected email address
            super.onFaqContentEmailAddressTapped(activity, scfPath, email)
        }
        
        @Override
        public void onFaqContentEmailAddressLongPressed(Activity activity, TTLScfPathModel scfPath, String email) {
            // User long presses an email address in FAQ content
            // Calling super will copy the selected email address to the device's clipboard
            super.onFaqContentEmailAddressLongPressed(activity, scfPath, email)
        }
        
        @Override
        public void onFaqContentPhoneNumberTapped(Activity activity, TTLScfPathModel scfPath, String phone) {
            // User taps a phone number in FAQ content
            // Calling super will open the device's phone app to dial the selected phone number
            super.onFaqContentPhoneNumberTapped(activity, scfPath, phone)
        }
        
        @Override
        public void onFaqContentPhoneNumberLongPressed(Activity activity, TTLScfPathModel scfPath, String phone) {
            // User long presses a phone number in FAQ content
            // Calling super will copy the selected phone number to the device's clipboard
            super.onFaqContentPhoneNumberLongPressed(activity, scfPath, phone)
        }
    }
);
```

{% endcode %}
{% endtab %}

{% tab title="Kotlin" %}
{% code title="Application.kt" %}

```kotlin
import io.taptalk.taptalklive.TapTalkLive
import io.taptalk.taptalklive.Listener.TapTalkLiveListener
import io.taptalk.taptalklive.API.Model.ResponseModel.TTLErrorModel
import io.taptalk.taptalklive.API.Model.TTLScfPathModel
import io.taptalk.TapTalk.Model.TAPMessageModel

...

TapTalkLive.init(
    CONTEXT, 
    APP_KEY_SECRET, 
    CLIENT_APP_ICON, 
    CLIENT_APP_NAME,
    object : TapTalkLiveListener() {
        override fun onInitializationCompleted() {
            // Initialization success
        }
        
        override fun onInitializationFailed(error: TTLErrorModel?) {
            // Initialization failed
        }

        override fun onNotificationReceived(message: TAPMessageModel?) {
            // TapTalk.io SDK receives a message notification
            // Calling super will show TapTalk.io's default notification for the app
            super.onNotificationReceived(message)
        }
        
        override fun onCloseButtonInHomePageTapped(activity: Activity?) {
            // User closes the home page
        }
    
        override fun onCloseButtonInCreateCaseFormTapped(activity: Activity?) {
            // User closes the create case form
        }
    
        override fun onCloseButtonInCaseListTapped(activity: Activity?) {
            // User closes the case list page
        }
    
        override fun onTaskRootChatRoomClosed(activity: Activity?) {
            // A chat room activity was closed by user when no other activity in the application is present
            // You may start another activity to keep the app open, otherwise the app will stay closed
        }
    
        override fun onSeeAllMessagesButtonTapped(activity: Activity?) {
            // User taps the See All Messages button in home page
            // Calling super will open the Case List page
            super.onSeeAllMessagesButtonTapped(activity)
        }
    
        override fun onCreateNewMessageButtonTapped(activity: Activity?) {
            // User taps the New Messages button in home or case list page
            // Calling super will open the Create New Case form
            super.onCreateNewMessageButtonTapped(activity)
        }
    
        override fun onCaseListItemTapped(activity: Activity?, lastMessage: TAPMessageModel?) {
            // User taps a case from a list in home or case list page
            // Calling super will open the selected chat room
            super.onCaseListItemTapped(activity, lastMessage)
        }
    
        override fun onFaqChildTapped(activity: Activity?, scfPath: TTLScfPathModel?) {
            // User taps a FAQ from a list in home or FAQ details page
            // Calling super will open the selected FAQ details page
            super.onFaqChildTapped(activity, scfPath)
        }
    
        override fun onCloseButtonInFaqDetailsTapped(activity: Activity?, scfPath: TTLScfPathModel?) {
            // User closes the FAQ details page    
        }
    
        override fun onTalkToAgentButtonTapped(activity: Activity?, scfPath: TTLScfPathModel?) {
            // User taps the Talk to Agent button in home or FAQ details page
            // Calling super will open the Create New Case form
            super.onTalkToAgentButtonTapped(activity, scfPath)
        }
        
        override fun onFaqContentUrlTapped(activity: Activity?, scfPath: TTLScfPathModel?, url: String?) {
            // User taps a url in FAQ content
            // Calling super will open the selected url using TapTalk.io's in-app browser
            super.onFaqContentUrlTapped(activity, scfPath, url)
        }
        
        override fun onFaqContentUrlLongPressed(activity: Activity?, scfPath: TTLScfPathModel?, url: String?) {
            // User long presses a url in FAQ content
            // Calling super will copy the selected url to the device's clipboard
            super.onFaqContentUrlLongPressed(activity, scfPath, url)
        }
        
        override fun onFaqContentEmailAddressTapped(activity: Activity?, scfPath: TTLScfPathModel?, email: String?) {
            // User taps an email address in FAQ content
            // Calling super will open the device's email composer for the selected email address
            super.onFaqContentEmailAddressTapped(activity, scfPath, email)
        }
        
        override fun onFaqContentEmailAddressLongPressed(activity: Activity?, scfPath: TTLScfPathModel?, email: String?) {
            // User long presses an email address in FAQ content
            // Calling super will copy the selected email address to the device's clipboard
            super.onFaqContentEmailAddressLongPressed(activity, scfPath, email)
        }
        
        override fun onFaqContentPhoneNumberTapped(activity: Activity?, scfPath: TTLScfPathModel?, phone: String?) {
            // User taps a phone number in FAQ content
            // Calling super will open the device's phone app to dial the selected phone number
            super.onFaqContentPhoneNumberTapped(activity, scfPath, phone)
        }
        
        override fun onFaqContentPhoneNumberLongPressed(activity: Activity?, scfPath: TTLScfPathModel?, phone: String?) {
            // User long presses a phone number in FAQ content
            // Calling super will copy the selected phone number to the device's clipboard
            super.onFaqContentPhoneNumberLongPressed(activity, scfPath, phone)
        }
    }
)
```

{% endcode %}
{% endtab %}
{% endtabs %}

TapTalkLiveListener listens to changes in the following methods:

<table data-header-hidden data-full-width="false"><thead><tr><th width="412">Method Name</th><th>Invoked When</th></tr></thead><tbody><tr><td>Method Name</td><td>Invoked When</td></tr><tr><td><strong><code>onInitializationCompleted()</code></strong></td><td>TapTalkLive instance has finished initialization process.</td></tr><tr><td><strong><code>onInitializationFailed()</code></strong></td><td>TapTalkLive instance initialization failed with an error.</td></tr><tr><td><strong><code>onNotificationReceived()</code></strong></td><td>User receives new message from TapTalk.io through notification. Returns the newly received <strong>message</strong>.</td></tr><tr><td><strong><code>onCloseButtonInHomePageTapped()</code></strong></td><td>User closes the home page. Returns the home <strong>activity</strong> instance.</td></tr><tr><td><strong><code>onCloseButtonInCreateCaseFormTapped()</code></strong></td><td>User closes the create case form page. Returns the create case form <strong>activity</strong> instance.</td></tr><tr><td><strong><code>onCloseButtonInCaseListTapped()</code></strong></td><td>User closes the case list page. Returns the case list <strong>activity</strong> instance.</td></tr><tr><td><strong><code>onTaskRootChatRoomClosed()</code></strong></td><td>A chat room activity was closed by user when no other activity in the application is present (application will close).</td></tr><tr><td><strong><code>onSeeAllMessagesButtonTapped()</code></strong></td><td>User taps the See All Messages button in home page. Returns the current <strong>activity</strong> instance.</td></tr><tr><td><strong><code>onCreateNewMessageButtonTapped()</code></strong></td><td>User taps the New Messages button in home or case list page. Returns the current <strong>activity</strong> instance.</td></tr><tr><td><strong><code>onCaseListItemTapped()</code></strong></td><td>User taps a case from a list in home or case list page. Returns the current <strong>activity</strong> instance and selected case's <strong>last message</strong>.</td></tr><tr><td><strong><code>onFaqChildTapped()</code></strong></td><td>User taps a FAQ from a list in home or FAQ details page. Returns the current <strong>activity</strong> instance and selected <strong>SCF Path</strong>.</td></tr><tr><td><strong><code>onCloseButtonInFaqDetailsTapped()</code></strong></td><td>User closes the FAQ details page. Returns the current <strong>activity</strong> instance and selected <strong>SCF Path</strong>.</td></tr><tr><td><strong><code>onTalkToAgentButtonTapped()</code></strong></td><td>User taps the Talk to Agent button in home or FAQ details page. Returns the current <strong>activity</strong> instance and selected <strong>SCF Path</strong>.</td></tr><tr><td><strong><code>onFaqContentUrlTapped()</code></strong></td><td>User taps a url in FAQ content. Returns the current <strong>activity</strong> instance, selected <strong>SCF Path</strong>, and the selected <strong>url</strong>.</td></tr><tr><td><strong><code>onFaqContentUrlLongPressed()</code></strong></td><td>User long presses a url in FAQ content. Returns the current <strong>activity</strong> instance, selected <strong>SCF Path</strong>, and the selected <strong>url</strong>.</td></tr><tr><td><strong><code>onFaqContentEmailAddressTapped()</code></strong></td><td>User taps an email address in FAQ content. Returns the current <strong>activity</strong> instance, selected <strong>SCF Path</strong>, and the selected <strong>email address</strong>.</td></tr><tr><td><strong><code>onFaqContentEmailAddressLongPressed()</code></strong></td><td>User long presses an email address in FAQ content. Returns the current <strong>activity</strong> instance, selected <strong>SCF Path</strong>, and the selected <strong>email address</strong>.</td></tr><tr><td><strong><code>onFaqContentPhoneNumberTapped()</code></strong></td><td>User taps a phone number in FAQ content. Returns the current <strong>activity</strong> instance, selected <strong>SCF Path</strong>, and the selected <strong>phone number</strong>.</td></tr><tr><td><strong><code>onFaqContentPhoneNumberLongPressed()</code></strong></td><td>User long presses a phone number in FAQ content. Returns the current <strong>activity</strong> instance, selected <strong>SCF Path</strong>, and the selected <strong>phone number</strong>.</td></tr></tbody></table>


# Authentication

TapTalk.io Omnichannel SDK provides some essential methods to handle user authentication.

### Authenticate User (Optional)

You can authenticate the user that is currently logged in before calling **`openTapTalkLiveView`**. To do this, provide the user's full name and email by calling **`authenticateUser`** from the **TapTalkLive** class after initializing the SDK.

{% tabs %}
{% tab title="Java" %}
{% code title="YourActivity.java" %}

```java
import io.taptalk.taptalklive.TapTalkLive;
import io.taptalk.taptalklive.Listener.TTLCommonListener;

...

TapTalkLive.requestAccessToken(FULL_NAME, EMAIL, new TTLCommonListener() {
    @Override
    public void onSuccess(String successMessage) {
        // Authentication successful
    }

    @Override
    public void onError(String errorCode, String errorMessage) {
        
    }
});
```

{% endcode %}
{% endtab %}

{% tab title="Kotlin" %}
{% code title="YourActivity.kt" %}

```kotlin
import io.taptalk.taptalklive.TapTalkLive
import io.taptalk.taptalklive.Listener.TTLCommonListener

...

TapTalkLive.authenticateUser(FULL_NAME, EMAIL, object : TTLCommonListener() {
    override fun onSuccess(successMessage: String?) {
        // Authentication successful
    }

    override fun onError(errorCode: String?, errorMessage: String?) {
        
    }
})
```

{% endcode %}
{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`NAME`**: (String) current user's full name\
**`EMAIL`**: (String) current user's email address
{% endhint %}

After successfully authenticated, user will no longer be required to fill name and email to create a case.

### Authenticate with Auth Ticket (Optional)

You can also authenticate using an existing auth ticket with **`requestAccessToken`** method from the **TapTalkLive** class after initializing the SDK.

{% tabs %}
{% tab title="Java" %}
{% code title="YourActivity.java" %}

```java
import io.taptalk.taptalklive.TapTalkLive;
import io.taptalk.taptalklive.Listener.TTLCommonListener;

...

TapTalkLive.requestAccessToken(AUTH_TICKET, new TTLCommonListener() {
    @Override
    public void onSuccess(String successMessage) {
        // Authentication successful
    }

    @Override
    public void onError(String errorCode, String errorMessage) {
        
    }
});
```

{% endcode %}
{% endtab %}

{% tab title="Kotlin" %}
{% code title="YourActivity.kt" %}

```kotlin
import io.taptalk.taptalklive.TapTalkLive
import io.taptalk.taptalklive.Listener.TTLCommonListener

...

TapTalkLive.requestAccessToken(AUTH_TICKET, object : TTLCommonListener() {
    override fun onSuccess(successMessage: String?) {
        // Authentication successful
    }

    override fun onError(errorCode: String?, errorMessage: String?) {
        
    }
})
```

{% endcode %}
{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`AUTH_TICKET`**: (String) existing auth ticket retrieved from the server
{% endhint %}

### Logout

You can clear the currently authenticated user data using the **`logout`** method. After logout is finished, locally saved user and chat data will be cleared, and you may authenticate another user.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.taptalklive.TapTalkLive;
import io.taptalk.taptalklive.Listener.TTLCommonListener;

...

TapTalkLive.logout(new TTLCommonListener() {
    @Override
    public void onSuccess(String successMessage) {
        // Successfully logged out
    }

    @Override
    public void onError(String errorCode, String errorMessage) {
        // An error occured, but local data is still cleared
    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.taptalklive.TapTalkLive;
import io.taptalk.taptalklive.Listener.TTLCommonListener;

...

TapTalkLive.logout(object : TTLCommonListener() {
    override fun onSuccess(successMessage: String?) {
        // Successfully logged out
    }

    override fun onError(errorCode: String?, errorMessage: String?) {
        // An error occured, but local data is still cleared
    }
})
```

{% endtab %}
{% endtabs %}

### Logout and Clear TapTalkLive Data

Call this method when you need to logout and clear all local cached data from Omnichannel SDK.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.taptalklive.TapTalkLive;

...

TapTalkLive.clearAllTapLiveData();
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.taptalklive.TapTalkLive;

...

TapTalkLive.clearAllTapLiveData()
```

{% endtab %}
{% endtabs %}


# Case & Topic

### Get Available Topics

You can get the list of available topics by calling **`getTopicList`**.

{% tabs %}
{% tab title="Java" %}
{% code title="YourActivity.java" %}

```java
import io.taptalk.taptalklive.TapTalkLive;
import io.taptalk.taptalklive.Listener.TTLGetTopicListListener;
import io.taptalk.taptalklive.API.Model.TTLTopicModel;

...

TapTalkLive.getTopicList(new TTLGetTopicListListener() {
    @Override
    public void onSuccess(List<TTLTopicModel> topics) {
        // Successfully fetched topics
    }

    @Override
    public void onError(String errorCode, String errorMessage) {
        
    }
});
```

{% endcode %}
{% endtab %}

{% tab title="Kotlin" %}
{% code title="YourActivity.kt" %}

```kotlin
import io.taptalk.taptalklive.TapTalkLive
import io.taptalk.taptalklive.Listener.TTLGetTopicListListener
import io.taptalk.taptalklive.API.Model.TTLTopicModel

...

TapTalkLive.getTopicList(object : TTLGetTopicListListener() {
    override fun onSuccess(topics: MutableList<TTLTopicModel>?) {
        // Successfully fetched topics
    }
    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endcode %}
{% endtab %}
{% endtabs %}

### Get Active User's Case List

To use this method, you need to first finish [authentication](/onetalk-omnichannel-documentation/onetalk-channel-integration/live-chat/onetalk-android/authentication#authenticate-user-optional) process.

Once authenticated, you can obtain the active user's case list by calling **`getUserCaseList`**.

{% tabs %}
{% tab title="Java" %}
{% code title="YourActivity.java" %}

```java
import io.taptalk.taptalklive.TapTalkLive;
import io.taptalk.taptalklive.Listener.TTLGetCaseListListener;
import io.taptalk.taptalklive.API.Model.TTLCaseModel;

...

TapTalkLive.getUserCaseList(new TTLGetCaseListListener() {
    @Override
    public void onSuccess(List<TTLCaseModel> cases) {
        // Successfully fetched user cases
    }

    @Override
    public void onError(String errorCode, String errorMessage) {
        
    }
});
```

{% endcode %}
{% endtab %}

{% tab title="Kotlin" %}
{% code title="YourActivity.kt" %}

```kotlin
import io.taptalk.taptalklive.TapTalkLive
import io.taptalk.taptalklive.Listener.TTLGetCaseListListener
import io.taptalk.taptalklive.API.Model.TTLCaseModel

...

TapTalkLive.getUserCaseList(object : TTLGetCaseListListener() {
    override fun onSuccess(cases: MutableList<TTLCaseModel>?) {
        // Successfully fetched user cases
    }
    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endcode %}
{% endtab %}
{% endtabs %}

### Create a New Case

To use this method, you need to first finish [authentication](/onetalk-omnichannel-documentation/onetalk-channel-integration/live-chat/onetalk-android/authentication#authenticate-user-optional) process.

Once authenticated, you can create a new case for the user by calling **`createNewCase`**, providing the **topic ID** and **first message**.

{% tabs %}
{% tab title="Java" %}
{% code title="YourActivity.java" %}

```java
import io.taptalk.taptalklive.TapTalkLive;
import io.taptalk.taptalklive.Listener.TTLCreateCaseListener;
import io.taptalk.taptalklive.API.Model.TTLCaseModel;

...

TapTalkLive.createNewCase(TOPIC_ID, FIRST_MESSAGE, new TTLCreateCaseListener() {
    @Override
    public void onSuccess(TTLCaseModel caseModel) {
        // Successfully created a new case
    }

    @Override
    public void onError(String errorCode, String errorMessage) {
        
    }
});
```

{% endcode %}
{% endtab %}

{% tab title="Kotlin" %}
{% code title="YourActivity.kt" %}

```kotlin
import io.taptalk.taptalklive.TapTalkLive
import io.taptalk.taptalklive.Listener.TTLCreateCaseListener
import io.taptalk.taptalklive.API.Model.TTLCaseModel

...

TapTalkLive.createNewCase(TOPIC_ID, FIRST_MESSAGE, object : TTLCreateCaseListener() {
    override fun onSuccess(caseModel: TTLCaseModel?) {
        // Successfully created a new case
    }
    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endcode %}
{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`TOPIC_ID`**: (int) ID of the selected topic, can be obtained from [**`getTopicList`**](#get-available-topics)\
**`FIRST_MESSAGE`**: (String) message to be sent by the user to start a case
{% endhint %}


# Navigate Live Chat UI

You may optionally navigate through TapTalk.io Omnichannel Live Chat's UI, such as case list and chat room, using the following methods:

### Open TapTalk Omnichannel View

To open TapTalkLive's view UI for your application, you can use the **`openTapTalkLiveView`** method from the **TapTalkLive** class. This will open a homepage activity containing a list of available channels, the user's latest case, and QnA path.

{% tabs %}
{% tab title="Java" %}
{% code title="YourActivity.java" %}

```java
import io.taptalk.taptalklive.TapTalkLive;

...

TapTalkLive.openTapTalkLiveView(YourActivity.this);
```

{% endcode %}
{% endtab %}

{% tab title="Kotlin" %}
{% code title="YourActivity.kt" %}

```kotlin
import io.taptalk.taptalklive.TapTalkLive

...

TapTalkLive.openTapTalkLiveView(this@YourActivity)
```

{% endcode %}
{% endtab %}
{% endtabs %}

{% hint style="info" %}
**`openTapTalkLiveView`** will return **`true`** if opening the view is successful, and will return `false` if it fails due to incomplete initialization. TapTalkLive initialization might not be completed if the device is not connected to internet or an incorrect **`APP_KEY_SECRET`** parameter was provided.
{% endhint %}

### Open Case List View

You can open the user's case list page by calling **`openCaseListView`**. If no user is authenticated, create case form will be opened instead.

{% tabs %}
{% tab title="Java" %}
{% code title="YourActivity.java" %}

```java
import io.taptalk.taptalklive.TapTalkLive;

...

TapTalkLive.openCaseListView(YourActivity.this);
```

{% endcode %}
{% endtab %}

{% tab title="Kotlin" %}
{% code title="YourActivity.kt" %}

```kotlin
import io.taptalk.taptalklive.TapTalkLive

...

TapTalkLive.openCaseListView(this@YourActivity)
```

{% endcode %}
{% endtab %}
{% endtabs %}

### Get Case List Fragment

You may optionally attach TapTalk Omnichannel's case list fragment to your own activity. To obtain the chat list fragment instance, use the **`getCaseListFragment`** method.&#x20;

{% tabs %}
{% tab title="Java" %}
{% code title="YourActivity.java" %}

```java
import io.taptalk.taptalklive.TapTalkLive;

...

TTLCaseListFragment fragment = TapTalkLive.getCaseListFragment();
```

{% endcode %}
{% endtab %}

{% tab title="Kotlin" %}
{% code title="YourActivity.kt" %}

```kotlin
import io.taptalk.taptalklive.TapTalkLive

...

val fragment = TapTalkLive.getCaseListFragment()
```

{% endcode %}
{% endtab %}
{% endtabs %}

{% hint style="info" %}
**`getCaseListFragment`** will return a **`TTLCaseListFragment`** instance.
{% endhint %}

### Open Existing Case's Chat Room

To use this method, you need to first finish [authentication](/onetalk-omnichannel-documentation/onetalk-channel-integration/live-chat/onetalk-android/authentication#authenticate-user-optional) process.

Once authenticated, you can open a chat room from one the user's case by calling **`openCaseChatRoom`**, providing the **context** and **XC Room ID**. You may obtain XC Room ID from one of the [active user's case list](/onetalk-omnichannel-documentation/onetalk-channel-integration/live-chat/onetalk-android/case-and-topic#get-active-users-case-list), or by [creating a new case](/onetalk-omnichannel-documentation/onetalk-channel-integration/live-chat/onetalk-android/case-and-topic#create-a-new-case).

{% tabs %}
{% tab title="Java" %}
{% code title="YourActivity.java" %}

```java
import io.taptalk.taptalklive.TapTalkLive;
import io.taptalk.taptalklive.Listener.TTLCommonListener;

...

TapTalkLive.openCaseChatRoom(YourActivity.this, XC_ROOM_ID, new TTLCommonListener() {
    @Override
    public void onSuccess(String successMessage) {
        // Successfully opened chat room
    }

    @Override
    public void onError(String errorCode, String errorMessage) {
        
    }
});
```

{% endcode %}
{% endtab %}

{% tab title="Kotlin" %}
{% code title="YourActivity.kt" %}

```kotlin
import io.taptalk.taptalklive.TapTalkLive
import io.taptalk.taptalklive.Listener.TTLCommonListener

...

TapTalkLive.openCaseChatRoom(this@YourActivity, XC_ROOM_ID, object : TTLCommonListener() {
    override fun onSuccess(successMessage: String?) {
        // Successfully opened chat room
    }
    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endcode %}
{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`CONTEXT`**: (Context) Context or your current Activity\
**`XC_ROOM_ID`**: (String) XC Room ID of the user's case, can be obtained from [**`getUserCaseList`**](/onetalk-omnichannel-documentation/onetalk-channel-integration/live-chat/onetalk-android/case-and-topic#get-active-users-case-list) or [**`createNewCase`**](/onetalk-omnichannel-documentation/onetalk-channel-integration/live-chat/onetalk-android/case-and-topic#create-a-new-case)`(TTLCaseModel.tapTalkXCRoomID)`
{% endhint %}


# Customize UI Appearance

&#x20;You can customize the appearance of the TapTalkLive view's color scheme. To do this, open your application's `colors.xml` file and override the values present in TapTalk.io library's `values.xml` file.

### Customize Default Color Theme

To customize the UI's color theme, open your `colors.xml` file and add override following values with your own colors:

{% tabs %}
{% tab title="colors.xml" %}

```xml
<!--TapTalkLive Default Colors-->
<color name="ttlColorPrimaryExtraLight">@color/yourExtraLightColor</color>
<color name="ttlColorPrimaryLight">@color/yourLightColor</color>
<color name="ttlColorPrimary">@color/yourPrimaryLightColor</color>
<color name="ttlColorPrimaryDark">@color/yourDarkColor</color>
<color name="ttlColorAccent">@color/yourAccentColor</color>
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
**Note**: you can override the default color values partially, but it is recommended to change all of them accordingly to make sure the color theme within the chat UI matches
{% endhint %}

### Customize General Colors

The following are the values used as general component colors, present in `colors.xml`

{% tabs %}
{% tab title="colors.xml" %}

```xml
<!--Light text color on dark background-->
<color name="ttlColorTextLight">@color/yourLightTextColor</color>

<!--Medium text color generally used on subtitles or placeholders-->
<color name="ttlColorTextMedium">@color/yourMediumTextColor</color>

<!--Dark text color on light background-->
<color name="ttlColorTextDark">@color/yourDarkTextColor</color>

<!--Identifies successful actions-->
<color name="ttlColorSuccess">@color/yourSuccessTextColor</color>

<!--Identifies errors or destructive actions-->
<color name="ttlColorError">@color/yourErrorTextColor</color>

<!--Primary colored icons used on light background-->
<color name="ttlColorPrimaryIcon">@color/yourPrimaryIconColor</color>

<!--White icons used on colored background-->
<color name="ttlColorWhiteIcon">@color/yourCustomLightIconColor</color>

<!--Default color for gray icons-->
<color name="ttlColorGrayIcon">@color/yourGrayIconColor</color>

<!--Default icon color for successful actions-->
<color name="ttlColorSuccessIcon">@color/yourSuccessIconColor</color>

<!--Default icon color for errors or destructive actions-->
<color name="ttlColorDestructiveIcon">@color/yourDestructiveIconColor</color>
```

{% endtab %}
{% endtabs %}


# OneTalk Live Chat for iOS

To start implementing OneTalk Live Chat for iOS, please click the Get Started section


# Get Started

{% hint style="warning" %}
**Before you get started:** Make sure you have [**created a channel in OneTalk dashboard**](/onetalk-omnichannel-documentation/onetalk-channel-integration/live-chat#setup-live-chat-for-ios) and obtain the **`APP_KEY_SECRET.`**` `&#x20;
{% endhint %}

### Configure and Initialize TapTalk.io Omnichannel iOS SDK

#### Step 1: Install TapTalk.io Omnichannel iOS SDK

1. You can install the TapTalk.io Omnichannel iOS SDK using [CocoaPods](https://cocoapods.org/) like the following. If you are new to CocoaPods, you can see more information in [Cocoapods guides](https://guides.cocoapods.org/using/getting-started.html). To create a **Podfile**, open a terminal window, navigate to your project directory, and then create a **Podfile** by running the following command in the terminal:

```bash
$ pod init
```

Then **Podfile** will be created in your project directory. Open the **Podfile** and add the following lines to the **Podfile**.

```ruby
# Please make sure you define platform on your Podfile
# Make sure to use ios 11.0 for minimum deployment target

platform :ios, '11.0'

target "YourProjectName" do
    
    ...
    
    pod 'TapTalkLive'
    pod 'JSONModel', '1.8.0', :modular_headers => true
    
end
```

{% hint style="warning" %} <mark style="color:red;">**Note**</mark><mark style="color:red;">:</mark> <mark style="color:red;"></mark><mark style="color:red;">**For SDK version 1.1.0 and above,  remove**</mark><mark style="color:red;">**`use_frameworks!`**</mark><mark style="color:red;">**&#x20;**</mark><mark style="color:red;">**and add additional pod implementation with modular headers to handle some compatibility issues.**</mark>

For versions below 1.1.0, please remove **`pod 'JSONModel'`** implementation on the code above with **`use_frameworks!`**
{% endhint %}

{% hint style="warning" %}
**Note:** Please make sure you implement ios version 11.0`platform :ios, '11.0'` for minimum deployment target to obtain latest update of TapTalk.io SDK
{% endhint %}

Since TapTalk.io use uses **`git-lfs`** (Git Large Files Storage) you will need to install **GIT LFS** to clone/install TapTalk.io SDK through **Cocoapods**.

{% hint style="warning" %}
**Note**: Make sure to install **`git-lfs`**&#x62;efore pod install, otherwise the pod install / pod update will be error&#x20;
{% endhint %}

Easiest way to install [git-lfs](https://git-lfs.github.com) is using [brew](https://brew.sh):

{% tabs %}
{% tab title="Terminal" %}

```bash
brew install git-lfs
git lfs install
```

{% endtab %}
{% endtabs %}

Next, after the **`git-lfs`** is installed, install the TapTalk.io through CocoaPods.

```bash
$ pod install
```

#### Step 2: Grant permission in your application project

To make sure TapTalk.io Omnichannel iOS have all permission to access user's media, file, location, and contact, the application needs to ask for permissions. Go to your **info.plist**, and add the following key-value pairs.

| Information Property Key                            | Information Property Value                                                                                                                                                             |
| --------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Privacy - Camera Usage Description                  | $(PRODUCT\_NAME) needs to request access to your camera to take profile picture and to send image chat.                                                                                |
| Privacy - Contacts Usage Description                | $(PRODUCT\_NAME) need your permission to access your contact, we will sync your contact to our server and automatically find your friend so it is easier for you to find your friends. |
| Privacy - Photo Library Additions Usage Description | $(PRODUCT\_NAME) needs to request access to your photo library to save photo.                                                                                                          |
| Privacy - Photo Library Usage Description           | $(PRODUCT\_NAME) needs to request access to your photo library to take profile picture and to send image chat.                                                                         |
| Privacy - Location When In Use Usage Description    | $(PRODUCT\_NAME) needs to request access to your location to send location chat.                                                                                                       |

{% hint style="info" %}
**Note**: You can change **Information Property Value** based on your own preferences. These values will appear when the application requests permission from the user.
{% endhint %}

![Adding new key in info.plist](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-LzpjUyPVVETR4wSOgJn%2F-LzpjgZSXJKtiMFJ6Edq%2F8b43524-Screen_Shot_2019-08-28_at_13.57.43.png?alt=media\&token=f8fb75d2-8578-4456-ba53-0bda817a7a09)

![Adding new key in info.plist](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-LzpjUyPVVETR4wSOgJn%2F-LzpjgZSXJKtiMFJ6Edq%2F8b43524-Screen_Shot_2019-08-28_at_13.57.43.png?alt=media\&token=f8fb75d2-8578-4456-ba53-0bda817a7a09)

#### Step 3: Enable background modes

Background modes is required to handle background process in TapTalk.io. It is used to run some processes in the background before the app is killed. For more information about the processes, check out the [background process section](/onetalk-omnichannel-documentation/onetalk-channel-integration/live-chat/onetalk-ios/background-process-in-taptalklive-ios).

To enable **background modes**, go to **Target** -> **Capabilities**, then turn **Background Modes** toggle to **ON**, next select **Background fetch** and **Remote notifications**

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-LzpjoPXCyDtXUTiNSXg%2F-Lzpk4nGaQ8fBhUqHqNN%2Feaab744-Screen_Shot_2019-08-28_at_13.37.54.png?alt=media\&token=7a41a275-97e7-48aa-a11a-ee283d9ac68e)

After you turn on the **Background Modes**, **Required background modes** key will be added automatically in your **Info.plist** as shown below.

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-LzpjoPXCyDtXUTiNSXg%2F-LzpkK_5kgOcDdlpGK5k%2F979a00b-Screen_Shot_2019-08-28_at_13.44.36.png?alt=media\&token=3da5a3ec-927b-461a-98b7-626c3ac5a7f7)

#### Step 4: Initialize TapTalk.io Omnichannel Application Delegate

To allow the iOS SDK to respond to the connection and state changes in your iOS client app, you have to implement all of our application delegate methods in your **`UIApplicationDelegate`** methods in appDelegate file.

After you initialize the TapTalk.io Omnichannel, you have to connect and implement these methods in your **`UIApplicationDelegate`** methods in **appDelegate** file to make sure TapTalk.io Omnichannel runs smoothly in your application.

| TapTalk.io Omnichannel Application Delegate Method | Description                                                                                   |
| -------------------------------------------------- | --------------------------------------------------------------------------------------------- |
| `application:didFinishLaunchingWithOptions:`       | Tells the delegate that the launch process is almost done and the app is almost ready to run. |
| `applicationWillResignActive:`                     | Tells the delegate that the app is about to become inactive.                                  |
| `applicationDidEnterBackground:`                   | Tells the delegate that the app is now in the background.                                     |
| `applicationWillEnterForeground:`                  | Tells the delegate that the app is about to enter the foreground.                             |
| `applicationDidBecomeActive:`                      | Tells the delegate that the app has become active.                                            |
| `applicationWillTerminate:`                        | Tells the delegate when the app is about to terminate.                                        |
| `handleException:`                                 | Tells the delegate when application throws exception.                                         |

{% code title="AppDelegate.m" %}

```csharp
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  
    //Implement TapTalk Omnichannel didFinishLaunchingWithOptions here    
    [[TapTalkLive sharedInstance] application:application didFinishLaunchingWithOptions:launchOptions];
    
    //Other code
    ...
    
    return YES;
}
```

{% endcode %}

{% code title="AppDelegate.m" %}

```csharp
- (void)applicationWillResignActive:(UIApplication *)application {
  
    //Implement TapTalk Omnichannel applicationWillResignActive here
    [[TapTalkLive sharedInstance] applicationWillResignActive:application];
  
    //Other code
    ...
}
```

{% endcode %}

{% code title="AppDelegate.m" %}

```csharp
- (void)applicationDidEnterBackground:(UIApplication *)application {
    //Implement TapTalk Omnichannel applicationDidEnterBackground here
    [[TapTalkLive sharedInstance] applicationDidEnterBackground:application];
  
    //Other code
    ...
}
```

{% endcode %}

{% code title="AppDelegate.m" %}

```csharp
- (void)applicationWillEnterForeground:(UIApplication *)application {
  
    //Implement TapTalk Omnichannel applicationWillEnterForeground here
    [[TapTalkLive sharedInstance] applicationWillEnterForeground:application];
  
    //Other code
    ...
  }
```

{% endcode %}

{% code title="AppDelegate.m" %}

```csharp
- (void)applicationDidBecomeActive:(UIApplication *)application {
  
    //Implement TapTalk Omnichannel applicationDidBecomeActive here    
    [[TapTalkLive sharedInstance] applicationDidBecomeActive:application];
  
    //Other code
    ...
}
```

{% endcode %}

{% code title="AppDelegate.m" %}

```csharp
- (void)applicationWillTerminate:(UIApplication *)application {
  
    //Implement TapTalk Omnichannel applicationWillTerminate here
    [[TapTalkLive sharedInstance] applicationWillTerminate:application];
  
    //Other code
    ...
}
```

{% endcode %}

You have to add below code `NSSetUncaughtExceptionHandler(&handleExceptions);` in `application:didFinishLaunchingWithOptions:`method to register uncaught exception handler and add delegate function `handleExceptions`.

<pre class="language-csharp" data-title="AppDelegate.m"><code class="lang-csharp">- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Register Uncaught Exception Handler
    NSSetUncaughtExceptionHandler(&#x26;handleExceptions);
}

// Add delegate function to handle exceptions
- (void)handleExceptions:(NSException *exception) {
    // Implement TapTalk Omnichannel handleException method
<strong>    [[TapTalkLive sharedInstance] handleException:exception];
</strong>}
</code></pre>

{% hint style="warning" %}
**Note**: Don't forget to register for exception handler inside **`application:didFinishLaunchingWithOptions:`**&#x6D;ethod and implement **`handleExceptions`** method in **appDelegate** class to make sure TapTalk.io able to handle exceptions.
{% endhint %}

#### Step 5: Initialize TapTalk.io Omnichannel iOS in your application class

In order to use TapTalk.io Omnichannel, you must first initialize an instance by passing the `APP_KEY_SECRET` and `API_BASE_URL` assigned to your application to the `initWithSecretKey:` method as a parameter. Generally, initialization is implemented in the **appDelegate** `application:didFinishLaunchingWithOptions:` method.

{% code title="AppDelegate.m" %}

```csharp
// Import TapTalk.io Omnichannel
#import <TapTalkLive/TapTalkLive.h>

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {\
    [[TapTalkLive sharedInstance] initWithSecretKey:APP_KEY_SECRET
    success:^{
        // Succcessfully initialized TapTalkLive
    }
    failure:^(NSString *errorMessage) {
        
    }];
}

...

@end
```

{% endcode %}

{% hint style="info" %}
**Parameters**\
**`APP_KEY_SECRET`**: (String) application key Secret
{% endhint %}

To allow the Omnichannel iOS SDK to respond to the connection and state changes in your iOS client app, you have to implement all of our application delegate methods in your UIApplicationDelegate methods in appDelegate file. You can follow the instructions in [Implement Application Delegate page](broken://pages/-M0HF7Yf9vZbl8CGgLYG).

### Initialize Google Places API Key (Optional)

To enable location search result preview while sending location message, a Google Places API Key is required. To obtain the API key for your application, you can check [the documentation](https://developers.google.com/places/web-service/get-api-key) provided by Google. To initialize, insert your obtained key using the `initializeGooglePlacesApiKey()` method.

```csharp
#import <TapTalkLive/TapTalkLive.h>
  
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {  
    //Initialize Google Places API Key
    [[TapTalkLive sharedInstance] initializeGooglePlacesAPIKey:GOOGLE_PLACES_API_KEY]; 
}
```

{% hint style="info" %}
**Parameters**\
**`GOOGLE_PLACES_API_KEY`**: (String) Google Places API key
{% endhint %}

### Open TapTalk.io Omnichannel View

To open TapTalk Omnichannel's view UI for your application, you can use the **`presentTapTalkLiveViewWithCurrentNavigationController:animated`** or **`pushTapTalkLiveViewWithCurrentNavigationController:animated`** method from the **TapTalkLive** class. This will open a homepage view controller containing a list of available channels, the user's latest case, and QnA path.

```csharp
#import <TapTalkLive/TapTalkLive.h>

/**
Called to show TapTalk Live view with present animation

 @param navigationController (UINavigationController *) your current navigation controller
 @param animated (BOOL) make the present animated or not
*/
[[TapTalkLive sharedInstance] presentTapTalkLiveViewWithCurrentNavigationController:NAVIGATION_CONTROLLER animated:ANIMATED];

/**
Called to show TapTalk Live view with push animation

 @param navigationController (UINavigationController *) your current navigation controller
 @param animated (BOOL) make the present animated or not
*/
[[TapTalkLive sharedInstance] pushTapTalkLiveViewWithCurrentNavigationController:NAVIGATION_CONTROLLER animated:ANIMATED];
```

{% hint style="info" %}
**Parameters**\
**`NAVIGATION_CONTROLLER`**: (UINavigationController) your current active navigation controller\
**`ANIMATED`**: (BOOL) boolean to state animation active or not
{% endhint %}


# Background Process in TapTalk.io Omnichannel iOS

An application integrated with TapTalk.io Omnichannel iOS framework will keep executing some certain tasks even when the app is on the background if the conditions are met, this is done to make sure that the users' chat experience proceed smoothly. The background services will be automatically terminated once all the tasks are completed or reached a timeout. Please follow the following section to [enable background mode in your application](/onetalk-omnichannel-documentation/onetalk-channel-integration/live-chat/onetalk-ios/get-started-ios#step-4-enable-background-modes), The following are the processes that is required to run in the background:

### Pending Message Queue

Messages that the user is going to send are placed into a queue before they are sent to the server. If the app enters background when unsent messages exist in this queue, TapTalk.io services will keep running until all the pending messages are delivered to the server and all other tasks are completed.

### File Downloads

When a user-initiated file download from TapTalk.io Omnichannel iOS, such as file message or video message, is in progress, TapTalkLive will preserve the download progress even if the app is moved to background. The services will stop once all the file downloads and other tasks are finished.

### File Uploads

TapTalk.io Omnichannel iOS background process will also be kept running in background when user is sending messages with attachment, such as image, video, and file messages. The services will stop once all the file uploads and other tasks are finished.

####


# Event Delegate

The iOS SDK provides event delegates to listen to various events on the client app. Through these event delegates, TapTalk.io notifies the client app of events that happen on your app.

You will need to register the delegate objects to receive event callbacks from TapTalk.io.

| **Event Delegate Name**                                                                                                                        | **Description**                                     |
| ---------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------- |
| [TapTalkLiveDelegate](/onetalk-omnichannel-documentation/onetalk-channel-integration/live-chat/onetalk-ios/event-delegate#taptalklivedelegate) | Listens to general event changes in the application |

### TapTalkLiveDelegate

General events such as notifications will be notified through `TapTalkLiveDelegate`. A `TapTalkLiveDelegate` instance is required when initializing TapTalk.

{% hint style="info" %}
**Note:** Make sure to add **`#import <TapTalkLive/TapTalkLive.h>`** before registering the delegate
{% endhint %}

{% tabs %}
{% tab title="Objective-C" %}
{% code title="ViewController.m" %}

```csharp
#import <TapTalkLive/TapTalkLive.h>

// Add TapTalkLiveDelegate declaration
@interface ViewController () <TapTalkLiveDelegate>

@end
  
@implementation ViewController
  
- (void)function {
    // Set TapTalkLive delegate to self
    [[TapTalkLive sharedInstance] setDelegate:self];
}

#pragma mark - Delegate
#pragma mark - TapTalkLiveDelegate

- (void)didTappedCloseButtonInCreateCaseViewWithCurrentShownNavigationController:(UINavigationController *)navigationController {
    // Listen to event when user click close button in create case view    
}

- (void)didTappedCloseButtonInCaseListViewWithCurrentShownNavigationController:(UINavigationController *)navigationController {
    // Listen to event when user click close button in case list / room list view 
}

- (void)didTappedCloseButtonInHomePageViewWithCurrentShownNavigationController:(UINavigationController *)navigationController {
    // User closes the home page
}

- (void)didTappedCloseButtonInCreateCaseViewWithCurrentShownNavigationController:(UINavigationController *)navigationController {
    // User closes the create case form
}

- (void)didTappedCloseButtonInCaseListViewWithCurrentShownNavigationController:(UINavigationController *)navigationController {
    // User closes the case list page
}

- (void)seeAllMessagesButtonDidTappedWithCurrentShownNavigationController:(UINavigationController *)navigationController {
    // User taps the See All Messages button in home page
    // Implementing this will prevent opening the case list page by default
}

- (void)createNewMessageButtonDidTappedWithCurrentShownNavigationController:(UINavigationController *)navigationController {
    // User taps the New Messages button in home or case list page
    // Implementing this will prevent opening the create new case form by default
}

- (void)caseListItemDidTappedWithCurrentShownNavigationController:(UINavigationController *)navigationController lastMessage:(TAPMessageModel *)lastMessage {
    // User taps a case from a list in home or case list page
    // Implementing this will prevent opening the selected chat room by default
}

- (void)faqChildDidTapped:(TTLFaqModel *)faqModel currentShownNavigationController:(UINavigationController *)navigationController {
    // User taps a FAQ from a list in home or FAQ details page
    // Implementing this will prevent opening the selected FAQ details page by default
}

- (void)closeButtonInFaqDetailsViewDidTapped:(TTLFaqModel *)faqModel currentShownNavigationController:(UINavigationController *)navigationController {
    // User closes the FAQ details page
}

- (void)talkToAgentButtonDidTapped:(TTLFaqModel *)faqModel currentShownNavigationController:(UINavigationController *)navigationController {
    // User taps the Talk to Agent button in home or FAQ details page
    // Implementing this will prevent opening the create new case form by default
}

- (void)faq:(TTLFaqModel *)faqModel contentUrlDidTapped:(NSURL *)url currentShownNavigationController:(UINavigationController *)navigationController {
    // User taps a url in FAQ content
}

- (void)faq:(TTLFaqModel *)faqModel contentUrlDidLongPressed:(NSURL *)url currentShownNavigationController:(UINavigationController *)navigationController {
    // User long presses a url in FAQ content
}

- (void)faq:(TTLFaqModel *)faqModel contentEmailAddressDidTapped:(NSURL *)emailAddress currentShownNavigationController:(UINavigationController *)navigationController {
    // User taps an email address in FAQ content
}

- (void)faq:(TTLFaqModel *)faqModel contentEmailAddressDidLongPressed:(NSURL *)emailAddress currentShownNavigationController:(UINavigationController *)navigationController {
    // User long presses an email address in FAQ content
}

- (void)faq:(TTLFaqModel *)faqModel contentPhoneNumberDidTapped:(NSURL *)phoneNumber currentShownNavigationController:(UINavigationController *)navigationController {
    // User taps a phone number in FAQ content
}

- (void)faq:(TTLFaqModel *)faqModel contentPhoneNumberDidLongPressed:(NSURL *)phoneNumber currentShownNavigationController:(UINavigationController *)navigationController {
    // User long presses a phone number in FAQ content
}
  
@end
```

{% endcode %}
{% endtab %}
{% endtabs %}

| **Method Name**                                                                                    | **Invoked When**                                                                                                                                                      |
| -------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`didTappedCloseButtonInHomePageViewWithCurrentShownNavigationController:`**                      | User closes the home page. Returns the currently shown **navigation controller**.                                                                                     |
| **`didTappedCloseButtonInCreateCaseViewWithCurrentShownNavigationController:`**                    | User closes the create case form page. Returns the currently shown **navigation controller**.                                                                         |
| **`didTappedCloseButtonInCaseListViewWithCurrentShownNavigationController:`**                      | User closes the case list page. Returns the currently shown **navigation controller**.                                                                                |
| **`seeAllMessagesButtonDidTappedWithCurrentShownNavigationController:`**                           | User taps the See All Messages button in home page. Returns the currently shown **navigation controller**.                                                            |
| **`createNewMessageButtonDidTappedWithCurrentShownNavigationController:`**                         | User taps the New Messages button in home or case list page. Returns the currently shown **navigation controller**.                                                   |
| **`caseListItemDidTappedWithCurrentShownNavigationController:lastMessage:`**                       | User taps a case from a list in home or case list page. Returns the currently shown **navigation controller** and selected case's **last message**.                   |
| **`faqChildDidTapped:currentShownNavigationController:`**                                          | User taps a FAQ from a list in home or FAQ details page. Returns the selected **FAQ Model** and currently shown **navigation controller**.                            |
| **`closeButtonInFaqDetailsViewDidTapped:currentShownNavigationController:`**                       | User closes the FAQ details page. Returns the selected **FAQ Model** and currently shown **navigation controller**.                                                   |
| **`talkToAgentButtonDidTapped:currentShownNavigationController:`**                                 | User taps the Talk to Agent button in home or FAQ details page. Returns the selected **FAQ Model** and currently shown **navigation controller**.                     |
| **`faq:contentUrlDidTapped:currentShownNavigationController:navigationController:`**               | User taps a url in FAQ content. Returns the currently shown **navigation controller**, selected **FAQ Model**, and the selected **url**.                              |
| **`faq:contentUrlDidLongPressed:currentShownNavigationController:navigationController:`**          | User long presses a url in FAQ content. Returns the currently shown **navigation controller**, selected **FAQ Model**, and the selected **url**.                      |
| **`faq:contentEmailAddressDidTapped:currentShownNavigationController:navigationController:`**      | User taps an email address in FAQ content. Returns the currently shown **navigation controller**, selected **FAQ Model**, and the selected **email address**.         |
| **`faq:contentEmailAddressDidLongPressed:currentShownNavigationController:navigationController:`** | User long presses an email address in FAQ content. Returns the currently shown **navigation controller**, selected **FAQ Model**, and the selected **email address**. |
| **`faq:contentPhoneNumberDidTapped:currentShownNavigationController:navigationController:`**       | User taps a phone number in FAQ content. Returns the currently shown **navigation controller**, selected **FAQ Model**, and the selected **phone number**.            |
| **`faq:contentPhoneNumberDidLongPressed:currentShownNavigationController:navigationController:`**  | User long presses a phone number in FAQ content. Returns the currently shown **navigation controller**, selected **FAQ Model**, and the selected **phone number**.    |


# Authentication

TapTalk.io Omnichannel SDK provides some essential methods to handle user authentication.

### Authenticate User (Optional)

You can authenticate the user that is currently logged in before calling **`presentTapTalkLiveView`** or **`pushTapTalkLiveView`**. To do this, provide the user's full name and email by calling **`authenticateUser`** from the **TapTalkLive** class after initializing the SDK.

<pre class="language-csharp"><code class="lang-csharp"><strong>#import &#x3C;TapTalkLive/TapTalkLive.h>
</strong>
[[TapTalkLive sharedInstance] authenticateUserWithFullName:NAME
                                                     email:EMAIL
success:^(NSString *message) {
    // Successfully authenticated user
}
failure:^(NSError *error) {
        
}];
</code></pre>

{% hint style="info" %}
**Parameters**\
**`NAME`**: (NSString \*) current user's full name\
**`EMAIL`**: (NSString \*) current user's email address
{% endhint %}

After successfully authenticated, user will no longer be required to fill name and email to create a case.

### Authenticate with Auth Ticket (Optional)

You can also authenticate using an existing auth ticket with **`requestAccessTokenWithAuthTicket`** method from the **TapTalkLive** class after initializing the SDK.

```csharp
#import <TapTalkLive/TapTalkLive.h>

[[TapTalkLive sharedInstance] requestAccessTokenWithAuthTicket:AUTH_TICKET
success:^(NSString *message) {
    // Successfully authenticated user
}
failure:^(NSError *error) {
        
}];
```

{% hint style="info" %}
**Parameters**\
**`AUTH_TICKET`**: (NSString \*) existing auth ticket retrieved from the server
{% endhint %}

### Logout

You can clear the currently authenticated user data using the **`logout`** method. After logout is finished, locally saved user and chat data will be cleared, and you may authenticate another user.

```csharp
#import <TapTalkLive/TapTalkLive.h>

[[TapTalkLive sharedInstance] logout:^(NSString *message) {
    // Successfully logged out
}
failure:^(NSError *error) {
    // An error occured, but local data is still cleared
}];
```

### Logout and Clear TapTalkLive Data

Call this method when you need to logout and clear all local cached data from Omnichannel SDK.

```csharp
#import <TapTalkLive/TapTalkLive.h>

[[TapTalkLive sharedInstance] clearAllTapLiveData];
```


# Case & Topic

### Get Available Topics

You can get the list of available topics by calling **`getTopicList`**.

{% tabs %}
{% tab title="Objective-C" %}
{% code title="YourViewController.m" %}

```csharp
#import <TapTalkLive/TapTalkLive.h>

[[TapTalkLive sharedInstance] getTopicListWithSuccess:^(NSArray<TTLTopicModel *> *topicListArray) {
    // Successfully fetched topics
}
failure:^(NSError *error) {
    
}];
```

{% endcode %}
{% endtab %}
{% endtabs %}

### Get Active User's Case List

To use this method, you need to first finish [authentication](/onetalk-omnichannel-documentation/onetalk-channel-integration/live-chat/onetalk-ios/authentication#authenticate-user-optional) process.

Once authenticated, you can obtain the active user's case list by calling **`getUserCaseList`**.

{% tabs %}
{% tab title="Objective-C" %}
{% code title="YourViewController" %}

```csharp
#import <TapTalkLive/TapTalkLive.h>

[[TapTalkLive sharedInstance] getUserCaseListListWithSuccess:^(NSArray<TTLCaseModel *> *caseListArray) {
    // Successfully fetched user cases
}
failure:^(NSError *error) {
    
}];
```

{% endcode %}
{% endtab %}
{% endtabs %}

### Create a New Case

To use this method, you need to first finish [authentication](/onetalk-omnichannel-documentation/onetalk-channel-integration/live-chat/onetalk-ios/authentication#authenticate-user-optional) process.

Once authenticated, you can create a new case for the user by calling **`createNewCase`**, providing the **topic ID** and **first message**.

{% tabs %}
{% tab title="Objective-C" %}
{% code title="YourViewController" %}

```csharp
#import <TapTalkLive/TapTalkLive.h>

[[TapTalkLive sharedInstance] createNewCaseWithTopicID:TOPIC_ID
                                          firstMessage:FIRST_MESSAGE
success:^(TTLCaseModel *caseModel) {
    // Successfully created a new case
}
failure:^(NSError *error) {
    
}];
```

{% endcode %}
{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`TOPIC_ID`**: (String) ID of the selected topic, can be obtained from [**`getTopicList`**](#get-available-topics)\
**`FIRST_MESSAGE`**: (String) message to be sent by the user to start a case
{% endhint %}


# Navigate Live Chat UI

You may optionally navigate through TapTalk.io Omnichannel Live Chat's UI, such as case list and chat room, using the following methods:

### Open TapTalk Omnichannel View

To open TapTalk Omnichannel's view UI for your application, you can use the **`presentTapTalkLiveViewWithCurrentNavigationController:animated`** or **`pushTapTalkLiveViewWithCurrentNavigationController:animated`** method from the **TapTalkLive** class. This will open an activity containing a chat room list for your user, and will open a **Create Case Form** activity on top if the user is new or do not have any existing case.

{% tabs %}
{% tab title="Objective-C" %}
{% code title="YourViewController.m" %}

```csharp
#import <TapTalkLive/TapTalkLive.h>

/**
Called to show TapTalk Live view with present animation

 @param navigationController (UINavigationController *) your current navigation controller
 @param animated (BOOL) make the present animated or not
*/
[[TapTalkLive sharedInstance] presentTapTalkLiveViewWithCurrentNavigationController:NAVIGATION_CONTROLLER animated:ANIMATED];

/**
Called to show TapTalk Live view with push animation

 @param navigationController (UINavigationController *) your current navigation controller
 @param animated (BOOL) make the present animated or not
*/
[[TapTalkLive sharedInstance] pushTapTalkLiveViewWithCurrentNavigationController:NAVIGATION_CONTROLLER animated:ANIMATED];

/**
Obtain main view controller of TapTalk Live
*/
[[TapTalkLive sharedInstance] getTapTalkLiveViewMainController];
```

{% endcode %}
{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`NAVIGATION_CONTROLLER`**: (UINavigationController) your current active navigation controller\
**`ANIMATED`**: (BOOL) boolean to state animation active or not
{% endhint %}

### Open Case List View

You can open the user's case list page by calling **`openCaseListView`**. If no user is authenticated, create case form will be opened instead.

{% tabs %}
{% tab title="Objective-C" %}
{% code title="YourViewController.m" %}

```csharp
#import <TapTalkLive/TapTalkLive.h>

[[TapTalkLive sharedInstance] presentCaseListViewWithCurrentNavigationController:NAVIGATION_CONTROLLER animated:ANIMATED];
```

{% endcode %}
{% endtab %}
{% endtabs %}

### Open Existing Case's Chat Room

To use this method, you need to first finish [authentication](/onetalk-omnichannel-documentation/onetalk-channel-integration/live-chat/onetalk-ios/authentication#authenticate-user-optional) process.

Once authenticated, you can open a chat room from one the user's case by calling **`openCaseChatRoom`**, providing the **context** and **XC Room ID**. You may obtain XC Room ID from one of the [active user's case list](/onetalk-omnichannel-documentation/onetalk-channel-integration/live-chat/onetalk-ios/case-and-topic#get-active-users-case-list), or by [creating a new case](/onetalk-omnichannel-documentation/onetalk-channel-integration/live-chat/onetalk-ios/case-and-topic#create-a-new-case).

{% tabs %}
{% tab title="Objective-C" %}
{% code title="YourViewController.m" %}

```csharp
#import <TapTalkLive/TapTalkLive.h>

[[TapTalkLive sharedInstance] openCaseChatRoomWithXCRoomID:XC_ROOM_ID
                                      navigationController:NAVIGATION_CONTROLLER 
                                                  animated:ANIMATED
success:^(NSString *successMessage) {
    // Successfully opened chat room
}
failure:^(NSError *error) {
    
}];
```

{% endcode %}
{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`XC_ROOM_ID`**: (String) XC Room ID of the user's case, can be obtained from [**`getUserCaseList`**](/onetalk-omnichannel-documentation/onetalk-channel-integration/live-chat/onetalk-android/case-and-topic#get-active-users-case-list) or [**`createNewCase`**](/onetalk-omnichannel-documentation/onetalk-channel-integration/live-chat/onetalk-android/case-and-topic#create-a-new-case)`(TTLCaseModel.tapTalkXCRoomID)`\
**`NAVIGATION_CONTROLLER`**: (UINavigationController) your current active navigation controller\
**`ANIMATED`**: (BOOL) boolean to state animation active or not
{% endhint %}


# Customize UI Appearance

You can customize the appearance of the TapTalkLive view's color scheme. To do this, you can add the methods below to your `AppDelegate` class.

{% hint style="info" %}
**Note:** Don't forget to add **`#import <TapTalkLive/TTLStyleManager.h>`**
{% endhint %}

## Default Color Theme

### Customize default color theme

To customize the chat UI's color theme, you can define your own color by accessing `TTLStyleManager` using the following method.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalkLive/TTLStyleManager.h>

//You can use this method
[[TTLStyleManager sharedManager] setDefaultColor:COLOR forType:TYPE];

// Example: set your default primary color
[[TTLStyleManager sharedManager] setDefaultColor:[UIColor blueColor] forType:TTLDefaultColorPrimary];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`COLOR`**: (UIColor) Your preferred color\
**`TYPE`**: (Enum TTLDefaultColor) type of default color
{% endhint %}

{% hint style="warning" %}
**Note:** you can override the default color values partially, but it is recommended to change all of them accordingly to make sure the color theme within the chat UI matches
{% endhint %}

### Obtain default color theme

You can get customized chat UI's color theme by accessing `TTLStyleManager` using the following method.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalkLive/TTLStyleManager.h>

// Obtain default primary color
UIColor *color = [[TTLStyleManager sharedManager] getDefaultColorForType:TTLDefaultColorPrimary];
```

{% endtab %}
{% endtabs %}

| **TTLDefaultColorType**          | **Description**                                                                                                                  |
| -------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| TTLDefaultColorPrimary           | Your default primary brand color, will be used in various style, icons and shapes in the TapTalk.io SDK.                         |
| TTLDefaultColorPrimaryExtraLight | Your default primary brand color with extra light accent, will be used in various style, icons and shapes in the TapTalk.io SDK. |
| TTLDefaultColorPrimaryLight      | Your default primary brand color with light accent, will be used in various style, icons and shapes in the TapTalk.io SDK.       |
| TTLDefaultColorPrimaryDark       | Your default primary brand color with dark accent, will be used in various style, icons and shapes in the TapTalk.io SDK.        |

### Customize general colors

The following are the values used as general component colors, you can set the colors by calling the same method as above in `TTLStyleManager`.

| **TTLDefaultColorType**        | **Description**                                                |
| ------------------------------ | -------------------------------------------------------------- |
| TTLDefaultColorSuccess         | Identifies successful actions.                                 |
| TTLDefaultColorError           | Identifies errors or destructive actions.                      |
| TTLDefaultColorTextLight       | Light text color on dark background.                           |
| TTLDefaultColorTextMedium      | Medium text color generally used on subtitles or placeholders. |
| TTLDefaultColorTextDark        | Dark text color on light background.                           |
| TTLDefaultColorIconPrimary     | Primary colored icons used on light background.                |
| TTLDefaultColorIconWhite       | White icons used on colored background.                        |
| TTLDefaultColorIconGray        | Default color for gray icons.                                  |
| TTLDefaultColorIconSuccess     | Default icon color for successful actions.                     |
| TTLDefaultColorIconDestructive | Default icon color for errors or destructive actions.          |

### Font Style

{% hint style="danger" %}
If you are using a custom font on your application, don't forget to add key **'Fonts Provided by application'** in your **info.plist file**. Otherwise, font won't be loaded
{% endhint %}

![Add custom font in info.plist](https://files.readme.io/6be4107-Screen_Shot_2020-03-10_at_12.25.12.png)

### Customize default font style

To use your application's font resource in the chat UI, set the following values in `TTLStyleManager` method with the following example:

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalkLive/TTLStyleManager.h>

// You can use this method to set default font
[[TTLStyleManager sharedManager] setDefaultFont:FONT forType:TYPE];

// For example: set your default regular font
[[TTLStyleManager sharedManager] setDefaultFont:[UIFont boldSystemFontOfSize:16.0f] forType:TTLDefaultFontRegular];
```

{% endtab %}
{% endtabs %}

### Obtain default font style

To use your application's font resource in the chat UI, you can obtain `UIFont` by using this method.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalkLive/TTLStyleManager.h>

// Obtain regular font
UIFont *obtainedFont = [[TTLStyleManager sharedManager] getDefaultFontForType:TTLDefaultFontRegular];
```

{% endtab %}
{% endtabs %}

| TTLDefaultFontType    | Description                                         |
| --------------------- | --------------------------------------------------- |
| TTLDefaultFontRegular | Your defined default font family with regular style |
| TTLDefaultFontMedium  | Your defined default font family with medium style  |
| TTLDefaultFontBold    | Your defined default font family with bold style    |
| TTLDefaultFontItalic  | Your defined default font family with italic style  |


# OneTalk Live Chat for Web

To start implementing OneTalk Live Chat for Web, please click the Get Started section

&#x20;


# Get Started

{% hint style="warning" %}
**Before you get started:** Make sure you have [**created a channel in OneTalk dashboard**](/onetalk-omnichannel-documentation/onetalk-channel-integration/live-chat#setup-live-chat-for-web) and obtain the **`APP_KEY_SECRET.`**` `&#x20;
{% endhint %}

### Configure and Initialize TapTalk.io Omnichannel Web Launcher

To Configure TapTalkLive Web Launcher you need to add this script to your head tag of your Application.

{% code title="YourApplication.html" %}

```markup
<script src="https://storage.googleapis.com/f8a350-taplive-prd-public/static/launcher/web/v1.0/main.js"></script>
<script>
    TapTalkLive.init("YOUR_SECRET_KEY_HERE");
    TapTalkLive.setBrandColor(55,165,215); //your r,g,b color code 
</script>
```

{% endcode %}


# Callback

This web SDK provides callback for several events that occur on the LiveChat widget

<pre><code><strong>// Called when there is a case created
</strong><strong>tapliveCallback.tapliveOnCreateCase = (caseModel, fullname, email, url) => {
</strong>    // action here
}

// Called when user send a message
tapliveCallback.tapliveOnSendMessage = (message, fullname, email, url) => {
    // action here
}

// Called when LiveChat launcher is opened
tapliveCallback.tapliveOnOpen = () => {
    // action here
}

// Called when LiveChat launcher is closed
tapliveCallback.tapliveOnClose = () => {
    // action here
}
</code></pre>


# Method

This web SDK provides methods for web's system to call

### Init

```
TapTalkLive.init(secretKey, isLoggedInWithAccessToken<boolean>, showLoadingScreen<boolean>, isOpenLauncherByDefault<boolean>, withoutRoomList<boolean>);
```

### Set Language

```
TapTalkLive.setTapliveLanguage("en or id");
```

### Set Brand Color

```
TapTalkLive.setBrandColor(r, g, b);
```

### Hide/Show "Powered By TapTalk.io" wording

```
TapTalkLive.setHideTaplivePower();
```

### Set Base API URL

```
setTapliveApiBaseURL(baseAPIUrl);
```

### Get Case List

```
tapliveGetCaseList({
    onSuccess: (data) => {
        // action here
    },
    onError: (errorMessage) => {
        // action here
    }
})
```

### Get Topic List

```
tapliveGetTopicList({
    onSuccess: (data) => {
        // action here
    },
    onError: (message) => {
        // action here
    }
})
```

### Create Case

```
tapliveCreateCaseWithCallback(int_topicid, string_message, {
    onSuccess: (data) => {
        // action here
    },
    onError: (message) => {
        // action here
    }
})
```

### Open/Close Launcher

```
TapTalkLive.toggleLauncher((boolean) => {
    // action here
});
```


# OneTalk Live Chat for React Native

To start implementing OneTalk Live Chat for React Native, please select either one of Get Started - Android or Get Started - iOS section


# Get Started - Android

This section will cover a step-by-step approach to bridge your React Native project to OneTalk Live Chat Android SDK. We will be using Android Studio to configure native code in React Native project.

{% hint style="warning" %}
**Before you get started:** Make sure you have [**created a channel in OneTalk dashboard**](/onetalk-omnichannel-documentation/onetalk-channel-integration/live-chat#setup-live-chat-for-android) and obtain the **`APP_KEY_SECRET.`**&#x20;
{% endhint %}

### Configure and Initialize TapTalk.io Omnichannel Android SDK for React Native project

#### Step 1: Open React Native project's android folder in Android Studio

To begin, open the *android* folder inside your React Native project root folder as a project using Android Studio. Once all gradle dependencies are downloaded, we will follow the first step of OneTalk Android Live Chat implementation by installing the *omnichannel* SDK for the android project.

#### Step 2: Install TapTalk.io Omnichannel SDK

To start, open your Android project and add the following repositories to your **top-level build.gradle** file.

{% code title="build.gradle (project)" %}

```groovy
allprojects {
    repositories {
        google()
        mavenCentral()
        maven {
            url = "https://jitpack.io"
        }
        maven {
            url = "https://s3.amazonaws.com/repo.commonsware.com"
        }
    }
}
```

{% endcode %}

Then add the following dependency to your **app-level** build.gradle:

{% code title="build.gradle (:app)" %}

```groovy
dependencies {
    implementation("com.github.taptalk-io:taptalk.io-omnichannel-android:3.0.0")
}
```

{% endcode %}

{% hint style="info" %}
You can check a more updated version release notes of the SDK [here](https://github.com/taptalk-io/taptalk.io-omnichannel-android/releases).
{% endhint %}

{% hint style="warning" %}
**Note**: In the app **build.gradle** file, make sure that your project is using supported Java 8 language features under the `android` tag like below
{% endhint %}

{% code title="build.gradle (:app)" %}

```groovy
android {
    ...
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_17
        targetCompatibility = JavaVersion.VERSION_17
    }
}
```

{% endcode %}

{% hint style="warning" %}
Note: If you are getting a dex error when building the project (e.g. `Cannot fit requested classes in a single dex file`), try to enable multidex in the app **build.gradle** file.
{% endhint %}

{% code title="build.gradle (:app)" %}

```groovy
android {
    
    ...

    defaultConfig {
        ...
        multiDexEnabled true
    }
}
```

{% endcode %}

After adding the required dependency, sync your project and begin the next step by creating an activity class to bridge React Native app to OneTalk live chat view.

#### Step 3: Create OneTalkWrapper Activity in React Native project folder

Create a new Blank Activity in the android project folder *(android/app/src/main/java/com/yourprojectname/)* and name it as *OneTalkWrapperActivity.java.* We will use this activity's context to help the app open OneTalk live chat view, then close the activity afterwards. The activity will look like the code below.

{% code title="OneTalkWrapperActivity.java" %}

```java
import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

import io.taptalk.taptalklive.TapTalkLive;

public class OneTalkWrapperActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_one_talk_wrapper);

        TapTalkLive.openTapTalkLiveView(OneTalkWrapperActivity.this);
        finish();
    }
}
```

{% endcode %}

{% hint style="info" %}
**`openTapTalkLiveView`** will return **`true`** if opening the view is successful, and will return `false` if it fails due to incomplete initialization. TapTalkLive initialization might not be completed if the device is not connected to internet or an incorrect **`APP_KEY_SECRET`** parameter was provided.
{% endhint %}

Once the activity is added, we will create a java module file that contains a react method to open OneTalk live chat view from your React Native app.

#### Step 4: Create Java Module file in React Native project folder

Create a new Java class inside the android project folder *(android/app/src/main/java/com/yourprojectname/)* . We will name this file *OneTalkStarterModule.java*. This class will inherit `ReactContextBaseJavaModule`*.*

In this class, create a react method named `navigateToOneTalk()` to open OneTalk Live Chat view from the previously created activity. Annotating this method with `@ReactMethod` will enable the method to be invoked from JavaScript of a React Native app.

{% tabs %}
{% tab title="Java" %}
{% code title="OneTalkStarterModule.java" %}

```java
import android.content.Intent;

import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;

import org.jetbrains.annotations.NotNull;

class OneTalkStarterModule extends ReactContextBaseJavaModule {

    OneTalkStarterModule(ReactApplicationContext reactContext) {
        super(reactContext);
    }

    @NotNull
    @Override
    public String getName() {
        return "OneTalkStarter";
    }

    @ReactMethod
    void navigateToOneTalk() {
        Intent intent = new Intent(getReactApplicationContext(), OneTalkWrapperActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        getReactApplicationContext().startActivity(intent);
    }
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

{% hint style="info" %}
A class inheriting `ReactContextBaseJavaModule` requires that a function called`getName()` is always implemented.
{% endhint %}

{% hint style="info" %}
**`FLAG_ACTIVITY_NEW_TASK`** is required to be added to the `intent`'s flags if we are to open a new activity from a non-activity context (In this case, *React Application Context*).
{% endhint %}

#### Step 5: Register the module

Next step is to register the module we just created. To continue, create another Java class in the android project folder that inherits `ReactPackage`. We will name this file `OneTalkStarterPackage`.

&#x20;Override the `createNativeModules()` function and add the `OneTalkStarterModule` object to modules array.&#x20;

{% tabs %}
{% tab title="Java" %}
{% code title="OneTalkStarterPackage.java" %}

```java
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;

import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class OneTalkStarterPackage implements ReactPackage {

    @NotNull
    @Override
    public List<ViewManager> createViewManagers(@NotNull ReactApplicationContext reactContext) {
        return Collections.emptyList();
    }

    @NotNull
    @Override
    public List<NativeModule> createNativeModules(@NotNull ReactApplicationContext reactContext) {
        List<NativeModule> modules = new ArrayList<>();

        modules.add(new OneTalkStarterModule(reactContext));

        return modules;
    }
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

#### Step 6: Provide the package in MainApplication.java

We will need to provide the `OneTalkStarterPackage` in the `getPackages()` method of the *MainApplication.java* file.

{% tabs %}
{% tab title="Java" %}
{% code title="MainApplication.java" %}

```java
public class MainApplication extends Application implements ReactApplication {

    private final ReactNativeHost mReactNativeHost =
            new ReactNativeHost(this) {
                
                ...
                
                @Override
                protected List<ReactPackage> getPackages() {
                    @SuppressWarnings("UnnecessaryLocalVariable")
                    List<ReactPackage> packages = new PackageList(this).getPackages();
                    
                    ...
                    
                    // Add package
                    packages.add(new OneTalkStarterPackage());
                    
                    return packages;
                }
            };
            
    ...     
          
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

#### Step 7. Initialize OneTalk Live Chat SDK

Still in the *MainApplication.java* file, we will initialize OneTalk Live Chat SDK on the application's `onCreate()` method by calling `TapTalkLive.init()`.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.taptalklive.TapTalkLive;
import io.taptalk.taptalklive.Listener.TapTalkLiveListener

public class MainApplication extends Application implements ReactApplication {

    ...

    @Override
    public void onCreate() {
        super.onCreate();
        
        ...
        
        TapTalkLive.init(
            CONTEXT, 
            APP_KEY_SECRET, 
            CLIENT_APP_ICON, 
            CLIENT_APP_NAME,
            new TapTalkLiveListener() {
                @Override
                public void onInitializationCompleted() {
                    super.onInitializationCompleted();
                }

                @Override
                public void onCloseButtonInCreateCaseFormTapped() {
                    super.onCloseButtonInCreateCaseFormTapped();
                }

                @Override
                public void onCloseButtonInCaseListTapped() {
                    super.onCloseButtonInCaseListTapped();
                }
            }
        );
    }
    
    ...
    
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**

**`CONTEXT`** (Context) application context\
**`APP_KEY_SECRET`**: (String) application key Secret\
**`CLIENT_APP_ICON`**: (int) drawable resource ID of your application's icon\
**`CLIENT_APP_NAME`**: (String) your application name\
**`tapTalkLiveListener`**: (TapTalkLiveListener) an interface to detect TapTalkLive Android SDK's delegates and callbacks
{% endhint %}

{% hint style="info" %}
You may configure what your app will do when the user closes the chat view's *Create Case Form* page or *Case List* page from *TapTalkLiveListener*'s `onCloseButtonInCreateCaseFormTapped()` and `onCloseButtonInCaseListTapped()` respectively.
{% endhint %}

#### Step 8: Enable Chat Features

Please follow the steps in [Enable Chat Features](/powertalk-chat-sdk-documentation/powertalk-android/enable-chat-features) page to enable TapTalk.io's chat features, such as contact sync and sending media, document, and location messages.

#### Step 9. Open OneTalk Live Chat View

Once the module set up is done, you can find a place in your application where you would like to add a call to the native module’s `navigateToOneTalk()` method to open OneTalk Live Chat view.&#x20;

&#x20;In order to access your native module from JavaScript you need to first import `NativeModules` from React Native:

```javascript
import { NativeModules } from 'react-native';
```

You can then invoke the native method `navigateToOneTalk()` to open OneTalk Live Chat view. Here we will be using a button's  `onPress()` method as an example.

```javascript
<Button
    onPress={() => NativeModules.OneTalkStarter.navigateToOneTalk()}
    title='Launch OneTalk'
/>
```

{% hint style="info" %}
**Note**: You can check a more complete implementation guide in the [OneTalk Live Chat for Android](/onetalk-omnichannel-documentation/onetalk-channel-integration/live-chat/onetalk-android) section.
{% endhint %}


# Authentication - Android

TapTalk.io Omnichannel SDK provides some essential methods to handle user authentication.

### Authenticate User (Optional)

You can authenticate the user that is currently logged in before calling **`navigateToOneTalk`**. To do this, you can add an authentication method in the previously created Java Module. (See [Get Started - Android](https://docs.taptalk.io/onetalk-omnichannel-documentation/onetalk-channel-integration/live-chat/onetalk-live-chat-for-react-native/pages/-MP8oEr3FwZYsUAdaKIf#configure-and-initialize-taptalk.io-omnichannel-android-sdk-for-react-native-project)). We will add a `@ReactMethod` named **`authenticateUser`**.

{% code title="OneTalkStarterModule.java" %}

```java
import android.content.Intent;

import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;

import org.jetbrains.annotations.NotNull;

class OneTalkStarterModule extends ReactContextBaseJavaModule {

    OneTalkStarterModule(ReactApplicationContext reactContext) {
        super(reactContext);
    }

    @NotNull
    @Override
    public String getName() {
        return "OneTalkStarter";
    }

    @ReactMethod
    void navigateToOneTalk() {
        Intent intent = new Intent(getReactApplicationContext(), OneTalkWrapperActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        getReactApplicationContext().startActivity(intent);
    }
    
    @ReactMethod
    void authenticateUser(String name, String email, Callback successCallback, Callback errorCallback) {
        TapTalkLive.authenticateUser(name, email, new TTLCommonListener() {
            @Override
            public void onSuccess(String successMessage) {
                successCallback.invoke(successMessage);
            }
            @Override
            public void onError(String errorCode, String errorMessage) {
                errorCallback.invoke(errorMessage);
            }
        });
    }
}
```

{% endcode %}

{% hint style="info" %}
**Parameters**

**`name`**: (String) name of the user to be authenticated

**`email`**: (String) email of the user to be authenticated

**`successCallback`**: (Callback) invoked when the authentication is successful

**`errorCallback`**: (Callback) invoked when an error occurred during authentication
{% endhint %}

You can then call the method from JavaScript as such:

```javascript
NativeModules.OneTalkStarter.authenticateUser(
    'USER_NAME', 
    'USER_EMAIL',
    (successMessage) => {
        // Successfully authenticated user
    },
    (errorMessage) => {
        // An error occurred during authentication
      }
);
```

After successfully authenticated, user will no longer be required to fill name and email to create a case.

### Logout and Clear TapTalkLive Data

You may also add another method when you need to logout and clear all local cached data from Omnichannel SDK. We will name this method **`clearAllTapLiveData`**.

{% code title="OneTalkStarterModule.java" %}

```java
import io.taptalk.taptalklive.TapTalkLive;

class OneTalkStarterModule extends ReactContextBaseJavaModule {

    ...
    
    @ReactMethod
    void clearAllTapLiveData() {
        TapTalkLive.clearAllTapLiveData();
    }
}
```

{% endcode %}

You can then call the method from JavaScript when needed.

```javascript
NativeModules.OneTalkStarter.clearAllTapLiveData();
```


# Get Started - iOS

This section will cover a step-by-step approach to bridge your React Native project to OneTalk Live Chat iOS SDK. We will be using Xcode to configure native code in the React Native project.

{% hint style="warning" %}
**Before you get started:** Make sure you have [**created a channel in OneTalk dashboard**](/onetalk-omnichannel-documentation/onetalk-channel-integration/live-chat#setup-live-chat-for-ios) and obtain the **`APP_KEY_SECRET.`**` `&#x20;
{% endhint %}

### Configure and Initialize TapTalk.io Omnichannel iOS SDK for React Native project

#### Step 1: Install TapTalk.io Omnichannel iOS SDK **with CocoaPods**

You can install the TapTalk.io Omnichannel iOS SDK using [CocoaPods](https://cocoapods.org/) like the following. If you are new to CocoaPods, you can see more information in [Cocoapods guides](https://guides.cocoapods.org/using/getting-started.html). First, navigate to the *ios* folder of your React Native project directory, and check if a file named **Podfile** exists. If there is no **Podfile** in the *ios* folder, we will create a new one using terminal. Open a terminal window and navigate to the *ios* directory of your React Native project, then create a **Podfile** by running the following command in the terminal:

```
$ pod init
```

Then **Podfile** will be created in your project directory. Open the **Podfile** and add the following lines to the **Podfile**.

```ruby
# Please make sure you define platform on your Podfile
# Make sure to use ios 11.0 for minimum deployment target

platform :ios, '11.0'

target "YourProjectName" do
    
    ...
    
    pod 'TapTalkLive'
    pod 'JSONModel', '1.8.0', :modular_headers => true
    
endru
```

{% hint style="warning" %} <mark style="color:red;">**Note**</mark><mark style="color:red;">:</mark> <mark style="color:red;"></mark><mark style="color:red;">**For SDK version 1.1.0 and above,  remove**</mark><mark style="color:red;">**`use_frameworks!`**</mark><mark style="color:red;">**&#x20;**</mark><mark style="color:red;">**and add additional pod implementation with modular headers to handle some compatibility issues.**</mark>

For versions below 1.1.0, please remove **`pod 'AFNetworking`**' and **`pod 'JSONModel'`** implementation on the code above with **`use_frameworks!`**
{% endhint %}

{% hint style="warning" %}
**Note:** Please make sure you implement ios version 11.0`platform :ios, '11.0'` for minimum deployment target to obtain latest update of TapTalk.io SDK
{% endhint %}

{% hint style="warning" %}
**Note:** If you are using SDK version lower than 1.1.0 and your **podfile** has Flipper enabled, disable it by commenting the following lines to enable `use_frameworks!`.
{% endhint %}

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

Next, open your terminal window and move to the *ios* directory of your React Native project, then install the updated pod by running this command in your terminal:

```bash
$ pod install
```

#### Step 2: Open React Native project's ios workspace in Xcode

After the pod has finished installing, navigate to the *ios* folder inside your React Native project root folder and locate a file named **YourProjectName.xcworkspace**, then open this file with Xcode. We will follow the next steps by configuring the project from Xcode.

#### Step 3: Grant permission in your application project

To make sure TapTalk.io Omnichannel iOS have all permission to access user's media, file, location, and contact, the application needs to ask for permissions. Go to your **info.plist**, and add the following key-value pairs.

| Information Property Key                            | Information Property Value                                                                                                                                                             |
| --------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Privacy - Camera Usage Description                  | $(PRODUCT\_NAME) needs to request access to your camera to take profile picture and to send image chat.                                                                                |
| Privacy - Contacts Usage Description                | $(PRODUCT\_NAME) need your permission to access your contact, we will sync your contact to our server and automatically find your friend so it is easier for you to find your friends. |
| Privacy - Photo Library Additions Usage Description | $(PRODUCT\_NAME) needs to request access to your photo library to save photo.                                                                                                          |
| Privacy - Photo Library Usage Description           | $(PRODUCT\_NAME) needs to request access to your photo library to take profile picture and to send image chat.                                                                         |
| Privacy - Location When In Use Usage Description    | $(PRODUCT\_NAME) needs to request access to your location to send location chat.                                                                                                       |

{% hint style="info" %}
**Note**: You can change **Information Property Value** based on your own preferences. These values will appear when the application requests permission from the user.
{% endhint %}

![Adding new key in info.plist](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-LzpjUyPVVETR4wSOgJn%2F-LzpjgZSXJKtiMFJ6Edq%2F8b43524-Screen_Shot_2019-08-28_at_13.57.43.png?alt=media\&token=f8fb75d2-8578-4456-ba53-0bda817a7a09)

#### Step 4: Enable background modes

Background modes is required to handle background process in TapTalk.io. It is used to run some processes in the background before the app is killed. For more information about the processes, check out the [background process section](/onetalk-omnichannel-documentation/onetalk-channel-integration/live-chat/onetalk-ios/background-process-in-taptalklive-ios).

To enable **background modes**, go to **Target** -> **Capabilities**, then turn **Background Modes** toggle to **ON**, next select **Background fetch** and **Remote notifications**

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-LzpjoPXCyDtXUTiNSXg%2F-Lzpk4nGaQ8fBhUqHqNN%2Feaab744-Screen_Shot_2019-08-28_at_13.37.54.png?alt=media\&token=7a41a275-97e7-48aa-a11a-ee283d9ac68e)

After you turn on the **Background Modes**, **Required background modes** key will be added automatically in your **Info.plist** as shown below.

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-LzpjoPXCyDtXUTiNSXg%2F-LzpkK_5kgOcDdlpGK5k%2F979a00b-Screen_Shot_2019-08-28_at_13.44.36.png?alt=media\&token=3da5a3ec-927b-461a-98b7-626c3ac5a7f7)

####

#### Step 5: Initialize TapTalk.io Omnichannel Application Delegate

To allow the iOS SDK to respond to the connection and state changes in your iOS client app, you have to implement all of our application delegate methods in your **`UIApplicationDelegate`** methods in appDelegate file.

After you initialize the TapTalk.io Omnichannel, you have to connect and implement these methods in your **`UIApplicationDelegate`** methods in **appDelegate** file to make sure TapTalk.io Omnichannel runs smoothly in your application.

| TapTalk.io Omnichannel Application Delegate Method | Description                                                                                   |
| -------------------------------------------------- | --------------------------------------------------------------------------------------------- |
| `application:didFinishLaunchingWithOptions:`       | Tells the delegate that the launch process is almost done and the app is almost ready to run. |
| `applicationWillResignActive:`                     | Tells the delegate that the app is about to become inactive.                                  |
| `applicationDidEnterBackground:`                   | Tells the delegate that the app is now in the background.                                     |
| `applicationWillEnterForeground:`                  | Tells the delegate that the app is about to enter the foreground.                             |
| `applicationDidBecomeActive:`                      | Tells the delegate that the app has become active.                                            |
| `applicationWillTerminate:`                        | Tells the delegate when the app is about to terminate.                                        |
| `handleException:`                                 | Tells the delegate when application throws exception.                                         |

{% code title="AppDelegate.m" %}

```csharp
@interface AppDelegate () <TapTalkLiveDelegate>

@end

...

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  
    // Implement TapTalk Omnichannel didFinishLaunchingWithOptions here    
    [[TapTalkLive sharedInstance] application:application didFinishLaunchingWithOptions:launchOptions];
    
    // Other code
    ...
    
    return YES;
}
```

{% endcode %}

{% code title="AppDelegate.m" %}

```csharp
- (void)applicationWillResignActive:(UIApplication *)application {
  
    // Implement TapTalk Omnichannel applicationWillResignActive here
    [[TapTalkLive sharedInstance] applicationWillResignActive:application];
  
    // Other code
    ...
}
```

{% endcode %}

{% code title="AppDelegate.m" %}

```csharp
- (void)applicationDidEnterBackground:(UIApplication *)application {
    // Implement TapTalk Omnichannel applicationDidEnterBackground here
    [[TapTalkLive sharedInstance] applicationDidEnterBackground:application];
  
    // Other code
    ...
}
```

{% endcode %}

{% code title="AppDelegate.m" %}

```csharp
- (void)applicationWillEnterForeground:(UIApplication *)application {
  
    // Implement TapTalk Omnichannel applicationWillEnterForeground here
    [[TapTalkLive sharedInstance] applicationWillEnterForeground:application];
  
    // Other code
    ...
  }
```

{% endcode %}

{% code title="AppDelegate.m" %}

```csharp
- (void)applicationDidBecomeActive:(UIApplication *)application {
  
    // Implement TapTalk Omnichannel applicationDidBecomeActive here    
    [[TapTalkLive sharedInstance] applicationDidBecomeActive:application];
  
    // Other code
    ...
}
```

{% endcode %}

{% code title="AppDelegate.m" %}

```csharp
- (void)applicationWillTerminate:(UIApplication *)application {
  
    // Implement TapTalk Omnichannel applicationWillTerminate here
    [[TapTalkLive sharedInstance] applicationWillTerminate:application];
  
    // Other code
    ...
}
```

{% endcode %}

You have to add below code `NSSetUncaughtExceptionHandler(&handleExceptions);` in `application:didFinishLaunchingWithOptions:`method to register uncaught exception handler and add delegate function `handleExceptions`.

{% code title="AppDelegate.m" %}

```csharp
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Register Uncaught Exception Handler
    NSSetUncaughtExceptionHandler(&handleExceptions);
}

// Add delegate function to handle exceptions
- (void)handleExceptions:(NSException *exception) {
    // Implement TapTalk Omnichannel handleException method
    [[TapTalkLive sharedInstance] handleException:exception];
}
```

{% endcode %}

{% hint style="warning" %}
**Note**: Don't forget to register for exception handler inside **`application:didFinishLaunchingWithOptions:`**&#x6D;ethod and implement **`handleExceptions`** method in **appDelegate** class to make sure TapTalk.io Omnichannel SDK is able to handle exceptions.
{% endhint %}

#### Step 6: Initialize TapTalk.io Omnichannel iOS in your application class

In order to use TapTalk.io Omnichannel, you must first initialize an instance by passing the `APP_KEY_SECRET` and `API_BASE_URL` assigned to your application to the `initWithSecretKey:` method as a parameter. Generally, initialization is implemented in the **appDelegate** `application:didFinishLaunchingWithOptions:` method.

{% code title="AppDelegate.m" %}

```csharp
// Import TapTalk.io Omnichannel
#import <TapTalkLive/TapTalkLive.h>

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [[TapTalkLive sharedInstance] initWithSecretKey:APP_KEY_SECRET];
}

...

@end
```

{% endcode %}

{% hint style="info" %}
**Parameters**\
**`APP_KEY_SECRET`**: (String) application key Secret
{% endhint %}

#### **Step 7: Create a method in AppDelegate to navigate to OneTalk Live Chat View**

After the configurations above are completed, we will add a method named `navigateToOneTalk` in the project's AppDelegate to navigate to OneTalk Live Chat view. Open your **AppDelegate.m** file and add the following:

{% code title="AppDelegate.m" %}

```csharp
@interface AppDelegate () <TapTalkLiveDelegate>

// Add a UINavigationController variable
@property (strong, nonatomic) UINavigationController *navigationController;

@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  [[TapTalkLive sharedInstance] application:application didFinishLaunchingWithOptions:launchOptions];
  
  RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
  RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
                                                   moduleName:@"TapLiveReactNative"
                                            initialProperties:nil];

  rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
  
  _window = [[UIWindow alloc] initWithFrame:CGRectMake(0.0f, 0.0f, CGRectGetWidth([UIScreen mainScreen].bounds), CGRectGetHeight([UIScreen mainScreen].bounds))];
  
  // Initialize navigation controller
  UIViewController *rootViewController = [[UIViewController alloc] init];
  rootViewController.view = rootView;
  _navigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController];
  [self.navigationController setNavigationBarHidden:YES animated:YES];
  self.window.rootViewController = self.navigationController;
  [self.window makeKeyAndVisible];
  
  [[TapTalkLive sharedInstance] initWithSecretKey:SECRET_KEY];
  
  NSSetUncaughtExceptionHandler(&handleExceptions);
  
  return YES;
}

...

// Method to open live chat view
- (void)navigateToOneTalk {
    [[TapTalkLive sharedInstance] presentTapTalkLiveViewWithCurrentNavigationController:self.navigationController animated:ANIMATED];
}

@end
```

{% endcode %}

{% hint style="info" %}
**Parameters**\
**`NAVIGATION_CONTROLLER`**: (UINavigationController) your current active navigation controller\
**`ANIMATED`**: (BOOL) boolean to state if view controller transition animation is enabled
{% endhint %}

Then open your **AppDelegate.h** file and add the following lines to enable the previously created method to be called from another file.

{% code title="AppDelegate.h" %}

```csharp
@interface AppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeDelegate>

- (void)navigateToOneTalk;

...

@end
```

{% endcode %}

#### **Step 8: Create module file in the project folder**

We will create a module file that contains a react method to open OneTalk live chat view from your React Native app. To create a new file, check the left panel on your Xcode and make sure the *Project Navigator* tab (folder icon) is active. Then right click on *YourProjectName* folder (expanded from *YourProjectName.xcodeproj*), and select *New File*.

Select *Cocoa Touch Class*, then press *Next*.

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MQLsHCpbN8OBEQWCESs%2F-MQVl_r0_RWRtI1q-jAY%2Fimage.png?alt=media\&token=7ad8a2a6-3e4b-4312-a867-75a3245ed2a3)

We will name this file *OneTalkStarterModule*. Select *NSObject* as the subclass and *Objective-C* as the language, then press *Next*, and press *Create* on the next window.

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MQLsHCpbN8OBEQWCESs%2F-MQVlgXuM0EopSWNFdmC%2Fimage.png?alt=media\&token=40b57732-9cfe-421d-9d0c-e4c501663f55)

Two files named *OneTalkStarterModule.h* and *OneTalkStarterModule.m* will be generated in your project folder. First, open *OneTalkStarterModule.h* and update its contents with the following:

{% code title="OneTalkStarterModule.h" %}

```csharp
#import <React/RCTBridgeModule.h>

NS_ASSUME_NONNULL_BEGIN

@interface OneTalkStarterModule : NSObject <RCTBridgeModule>

@end

NS_ASSUME_NONNULL_END
```

{% endcode %}

Then open the *OneTalkStarterModule.m* file and modify it like below:

{% code title="OneTalkStarterModule.m" %}

```csharp
#import "OneTalkStarterModule.h"
#import "AppDelegate.h"

@implementation OneTalkStarterModule

RCT_EXPORT_MODULE(OneTalkStarter);

RCT_EXPORT_METHOD(navigateToOneTalk)
{
  dispatch_async(dispatch_get_main_queue(), ^{
    AppDelegate *appDelegate = (AppDelegate *) [UIApplication sharedApplication].delegate;
    [appDelegate navigateToOneTalk];
  });
}

RCT_EXPORT_METHOD(getActivityName:(RCTResponseSenderBlock) callback)
{
  callback(@[@"OneTalkStarter (callback)"]);
}

@end
```

{% endcode %}

{% hint style="info" %}
**RCT\_EXPORT\_MODULE** exposes this module to react via a compile time macro.

**RCT\_EXPORT\_METHOD** will enable the method to be invoked from javascript of a React Native app.
{% endhint %}

#### Step 9. Open OneTalk Live Chat View

Once the module set up is done, you can find a place in your application where you would like to add a call to the native module’s `navigateToOneTalk()` method to open OneTalk Live Chat view.&#x20;

&#x20;In order to access your native module from JavaScript you need to first import `NativeModules` from React Native:

```javascript
import { NativeModules } from 'react-native';
```

You can then invoke the native method `navigateToOneTalk()` to open OneTalk Live Chat view. Here we will be using a button's  `onPress()` method as an example.

```javascript
<Button
    onPress={() => NativeModules.OneTalkStarter.navigateToOneTalk()}
    title='Launch OneTalk'
/>
```

{% hint style="info" %}
**Note**: You can check a more complete implementation guide in the [OneTalk Live Chat for iOS](/onetalk-omnichannel-documentation/onetalk-channel-integration/live-chat/onetalk-ios) section.
{% endhint %}


# Authentication - iOS

TapTalk.io Omnichannel SDK provides some essential methods to handle user authentication.

### Authenticate User (Optional)

You can authenticate the user that is currently logged in before calling **`navigateToOneTalk`**. To do this, you can add an authentication method in the previously created module file. (See [Get Started - iOS](https://docs.taptalk.io/onetalk-omnichannel-documentation/onetalk-channel-integration/live-chat/onetalk-live-chat-for-react-native/pages/-MQV25u4ATdW02mvTwhv#configure-and-initialize-taptalk.io-omnichannel-ios-sdk-for-react-native-project)). We will add a `RCT_EXPORT_METHOD` named **`authenticateUser`**.

You can start by adding an authentication method in **AppDelegate.m**.

{% code title="AppDelegate.m" %}

```csharp
@interface AppDelegate () <TapTalkLiveDelegate>

...

// Method to authenticate user
- (void)authenticateUserWithFullName:(NSString *)fullName 
                               email:(NSString *)email 
                             success:(void (^)(NSString *message))success 
                               error:(void (^)(NSString *message))error {

    [[TapTalkLive sharedInstance] authenticateUserWithFullName:fullName 
                                                         email:email 
    success:^(NSString *message) {
        success(message);
    } 
    failure:^(NSError *error) {
        error(error.localizedDescription);
    }];
}

@end
```

{% endcode %}

{% hint style="info" %}
**Parameters**\
**`fullName`**: (NSString \*) current user's full name\
**`email`**: (NSString \*) current user's email address\
**`success`**: (void (^)(NSString \*message)) success callback containing a message\
**`error`**: (void (^)(NSString \*message)) success callback containing the error message
{% endhint %}

Then open your **AppDelegate.h** file and add the following lines to enable the previously created method to be called from another file.

{% code title="AppDelegate.h" %}

```csharp
@interface AppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeDelegate>

...

- (void)authenticateUserWithFullName:(NSString *)fullName 
                               email:(NSString *)email 
                             success:(void (^)(NSString *message))success 
                               error:(void (^)(NSString *message))error;

@end
```

{% endcode %}

Then open the previously created **OneTalkStarterModule.m** and add a method to bridge the authentication method from AppDelegate to JavaScript.

{% code title="OneTalkStarterModule.m" %}

```csharp
...

RCT_EXPORT_METHOD(authenticateUser:(NSString *)fullName
                             email:(NSString *)email
                   successCallback:(RCTResponseSenderBlock)successCallback
                     errorCallback:(RCTResponseSenderBlock)errorCallback)
{
    dispatch_async(dispatch_get_main_queue(), ^{
        AppDelegate *appDelegate = (AppDelegate *) [UIApplication sharedApplication].delegate;
        [appDelegate authenticateUserWithFullName:fullName 
                                            email:email 
        success:^(NSString *message) {
            successCallback(@[message]);
        }
        failure:^(NSString *message) {
            errorCallback(@[message]);
        ];
    });
}
```

{% endcode %}

You can then call the method from JavaScript as such:

```csharp
NativeModules.OneTalkStarter.authenticateUser(
    'USER_NAME', 
    'USER_EMAIL',
    (successMessage) => {
        // Successfully authenticated user
    },
    (errorMessage) => {
       // An error occurred during authentication
    }
);
```

After successfully authenticated, user will no longer be required to fill name and email to create a case.

### Logout and Clear TapTalkLive Data

You may also add another method when you need to logout and clear all local cached data from Omnichannel SDK. We will name this method **`clearAllTapLiveData`**.

Start by adding an authentication method in **AppDelegate.m** and **AppDelegate.h**.

{% code title="AppDelegate.m" %}

```csharp
@interface AppDelegate () <TapTalkLiveDelegate>

...

// Method to clear all live chat data
- (void)clearAllTapLiveData {
    [[TapTalkLive sharedInstance] clearAllTapLiveData];
}

@end
```

{% endcode %}

{% code title="AppDelegate.h" %}

```csharp
@interface AppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeDelegate>

...

- (void)clearAllTapLiveData;

@end
```

{% endcode %}

Then add the method to **OneTalkStarterModule.m**.

{% code title="OneTalkStarterModule.m" %}

```csharp
...

RCT_EXPORT_METHOD(clearAllTapLiveData)
{
    dispatch_async(dispatch_get_main_queue(), ^{
        AppDelegate *appDelegate = (AppDelegate *) [UIApplication sharedApplication].delegate;
        [appDelegate clearAllTapLiveData];
    });
}
```

{% endcode %}

You can then call the method from JavaScript when needed.

```javascript
NativeModules.OneTalkStarter.clearAllTapLiveData();
```


# OneTalk Live Chat for Flutter

To start implementing OneTalk Live Chat for React Native, please select either one of Get Started - Android or Get Started - iOS section


# Get Started - Android

This section will cover a step-by-step approach to bridge your Flutter project to OneTalk Live Chat Android SDK. We will be using Android Studio to configure native code in Flutter project.

{% hint style="warning" %}
**Before you get started:** Make sure you have [**created a channel in OneTalk dashboard**](/onetalk-omnichannel-documentation/onetalk-channel-integration/live-chat#setup-live-chat-for-android) and obtain the **`APP_KEY_SECRET.`**&#x20;
{% endhint %}

### Configure and Initialize TapTalk.io Omnichannel Android SDK for Flutter project

#### Step 1: Open Flutter project's android folder in Android Studio

To begin, open the **android** folder inside your Flutter project root folder as a project using Android Studio. Once all gradle dependencies are downloaded, we will follow the first step of OneTalk Android Live Chat implementation by installing the *omnichannel* SDK for the android project.

#### Step 2: Install TapTalk.io Omnichannel SDK

To start, open your Android project and add the following repositories to your **top-level build.gradle** file.

{% code title="build.gradle (project)" %}

```groovy
allprojects {
    repositories {
        google()
        mavenCentral()
        maven {
            url = "https://jitpack.io"
        }
        maven {
            url = "https://s3.amazonaws.com/repo.commonsware.com"
        }
    }
}
```

{% endcode %}

Then add the following dependency to your **app-level** build.gradle:

{% code title="build.gradle (:app)" %}

```groovy
dependencies {
    implementation("com.github.taptalk-io:taptalk.io-omnichannel-android:3.0.0")
}
```

{% endcode %}

{% hint style="info" %}
You can check a more updated version release notes of the SDK [here](https://github.com/taptalk-io/taptalk.io-omnichannel-android/releases).
{% endhint %}

{% hint style="warning" %}
**Note**: In the app **build.gradle** file, make sure that your project is using supported Java 8 language features under the `android` tag like below
{% endhint %}

{% code title="build.gradle (:app)" %}

```groovy
android {
    ...
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_17
        targetCompatibility = JavaVersion.VERSION_17
    }
}
```

{% endcode %}

{% hint style="warning" %}
Note: If you are getting a dex error when building the project (e.g. `Cannot fit requested classes in a single dex file`), try to enable multidex in the app **build.gradle** file.
{% endhint %}

{% code title="build.gradle (:app)" %}

```groovy
android {
    
    ...

    defaultConfig {
        ...
        multiDexEnabled true
    }
}
```

{% endcode %}

After adding the required dependency, sync your project and begin the next step by writing custom platform-specific code using platform channels.

#### Step 3: Create Flutter Platform Client

If you have finished this step from the [iOS side](/onetalk-omnichannel-documentation/onetalk-channel-integration/live-chat/onetalk-live-chat-for-flutter/get-started-ios#step-6-create-flutter-platform-client), you can skip to the [next step](#step-3-add-an-android-platform-specific-implementation).

In this example, we will add the following inside the MyHomePageState class:

1. Method Channel to connect to the native Android host
2. `openOneTalkLiveChatTalkUI()` function to open the Live Chat's view
3. A button to call the `openOneTalkLiveChatTalkUI()` function

{% tabs %}
{% tab title="Dart" %}
{% code title="main.dart" %}

```dart
class _MyHomePageState extends State<MyHomePage> {
  
  // Create the MethodChannel
  static const oneTalkLiveChatMethodChannel = MethodChannel('io.taptalk.onetalklivechat');
  
  // Function to open the live chat view
  Future<void> _openOneTalkLiveChatTalkUI() async {
    try {
      // Initialize OneTalk Live Chat SDK
      final bool isOneTalkInitialized = await oneTalkLiveChatMethodChannel.invokeMethod('initOneTalkLiveChat');
      if (isOneTalkInitialized) {
        // Open live chat view
        await oneTalkLiveChatMethodChannel.invokeMethod('openLiveChatView');
      }
    }
    on PlatformException catch (e) {
      // Call might fail if the platform doesn’t support the platform API
      print(e.message);
    }
  }
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      ...
      body:
        ...
          // Sample button to call openOneTalkLiveChatTalkUI
          ElevatedButton(
            onPressed: _openOneTalkLiveChatTalkUI,
            child: Text(
              'Get Started with OneTalk Live Chat',
            ),
          ),
      ...
    );
  }
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

Please note the name parameter in the MethodChannel constructor that was used (`io.taptalk.onetalklivechat`), and the method name in the `invokeMethod()` parameter (`initOneTalkLiveChat` & `openLiveChatView`). We will use the same names later to configure Flutter engine in the native side.

#### Step 4: Add an Android platform-specific implementation <a href="#step-3-add-an-android-platform-specific-implementation" id="step-3-add-an-android-platform-specific-implementation"></a>

Next, we will configure the native side of the Android host implementation. Go back to previously opened Android Studio project, and open **MainActivity** file. We will do the following to the Activity:

1. Add a MethodChannel Result variable to handle asynchronous call
2. override `configureFlutterEngine` to handle calls from the MethodChannel that we previously created.
3. Add native functions to init OneTalk Live Chat SDK and open the live chat view

{% tabs %}
{% tab title="Java" %}
{% code title="MainActivity.java" %}

```java
import io.taptalk.taptalklive.TapTalkLive;
import io.taptalk.taptalklive.Listener.TapTalkLiveListener;

public class MainActivity extends FlutterActivity {

    // MethodChannel Result to handle asynchronous call
    private MethodChannel.Result oneTalkMethodChannelResult = null;

    // Override configureFlutterEngine
    @Override
    public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
        super.configureFlutterEngine(flutterEngine);
        
        // Handle MethodChannel calls
        new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), "io.taptalk.onetalklivechat")
            .setMethodCallHandler((call, result) -> {
                // Save result to variable
                oneTalkMethodChannelResult = result;
                switch (call.method) {
                    // Call native methods
                    case "initOneTalkLiveChat":
                        initOneTalkLiveChat();
                        break;
                    case "openLiveChatView":
                        openLiveChatView();
                        break;
                    default:    
                        result.notImplemented();
                }
            }
        );
    }
    
    // Method to initialize OneTalk Live Chat SDK
    private void initOneTalkLiveChat() {
        TapTalkLive.init(
            getApplicationContext(),
            ONETALK_APP_KEY_SECRET,
            R.drawable.your_app_icon,
            getString(R.string.your_app_name),
            new TapTalkLiveListener() {
                @Override
                public void onInitializationCompleted() {
                    if (oneTalkMethodChannelResult != null) {
                        oneTalkMethodChannelResult.success(true);
                    }
                }
            }
        );
    }

    // Method to open live chat view
    private void openLiveChatView() {
        boolean isSuccess = TapTalkLive.openTapTalkLiveView(this);
        if (oneTalkMethodChannelResult != null) {
            oneTalkMethodChannelResult.success(true);
        }
    }
}
```

{% endcode %}
{% endtab %}

{% tab title="Kotlin" %}
{% code title="MainActivity.kt" %}

```kotlin
import io.taptalk.taptalklive.TapTalkLive
import io.taptalk.taptalklive.Listener.TapTalkLiveListener

class MainActivity: FlutterActivity() {

    // MethodChannel Result to handle asynchronous call
    private var oneTalkMethodChannelResult: MethodChannel.Result? = null

    // Override configureFlutterEngine
    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)

        // Handle MethodChannel calls
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, "io.taptalk.onetalklivechat")
            .setMethodCallHandler {
                call, result ->
                // Save result to variable
                oneTalkMethodChannelResult = result
                when (call.method) {
                    // Call native methods
                    "initOneTalkLiveChat" -> initOneTalkLiveChat()
                    "openLiveChatView" -> openLiveChatView()
                    else -> result.notImplemented()
                }
            }
    }
    
    // Method to initialize OneTalk Live Chat SDK
    private fun initOneTalkLiveChat() {
        TapTalkLive.init(
            applicationContext,
            ONETALK_APP_KEY_SECRET,
            R.drawable.your_app_icon,
            getString(R.string.your_app_name),
            object : TapTalkLiveListener() {
                override fun onInitializationCompleted() {
                    oneTalkMethodChannelResult?.success(true)
                }
            }
        )
    }

    // Method to open live chat view
    private fun openLiveChatView() {
        val isSuccess = TapTalkLive.openTapTalkLiveView(this)
        oneTalkMethodChannelResult?.success(isSuccess)
    }
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

{% hint style="info" %}
**`openTapTalkLiveView`** will return **`true`** if opening the view is successful, and will return `false` if it fails due to incomplete initialization. TapTalkLive initialization might not be completed if the device is not connected to internet or an incorrect **`APP_KEY_SECRET`** parameter was provided.
{% endhint %}

#### Step 5: Enable Chat Features

Please follow the steps in [Enable Chat Features](/powertalk-chat-sdk-documentation/powertalk-android/enable-chat-features) page to enable TapTalk.io's chat features, such as contact sync and sending media, document, and location messages.

You can now try running the app. Pressing the sample button will invoke the `openOneTalkLiveChatTalkUI()` method that we previously created, which will initialize OneTalk Live Chat SDK, and open the live chat view once the initialization is completed. You may also try a different implementation and separate the **init** and the **open view** methods. You can also add more calls to other native methods with the same approach using the same MethodChannel.

{% hint style="info" %}
**Note**: You can check a more complete implementation guide in the [OneTalk Live Chat for Android](/onetalk-omnichannel-documentation/onetalk-channel-integration/live-chat/onetalk-android) section.
{% endhint %}


# Get Started - iOS

This section will cover a step-by-step approach to bridge your Flutter project to OneTalk Live Chat iOS SDK. We will be using Xcode to configure native code in Flutter project.

{% hint style="warning" %}
**Before you get started:** Make sure you have [**created a channel in OneTalk dashboard**](/onetalk-omnichannel-documentation/onetalk-channel-integration/live-chat#setup-live-chat-for-android) and obtain the **`APP_KEY_SECRET.`**&#x20;
{% endhint %}

### Configure and Initialize TapTalk.io Omnichannel iOS SDK for Flutter project

#### Step 1: Install TapTalk.io Omnichannel iOS SDK **with CocoaPods**

You can install the TapTalk.io Omnichannel iOS SDK using [CocoaPods](https://cocoapods.org/) like the following. If you are new to CocoaPods, you can see more information in [Cocoapods guides](https://guides.cocoapods.org/using/getting-started.html). First, navigate to the **ios** folder of your Flutter project directory, and check if a file named **Podfile** exists. If there is no **Podfile** in the **ios** folder, we will create a new one using terminal. Open a terminal window and navigate to the **ios** directory of your Flutter project, then create a **Podfile** by running the following command in the terminal:

{% tabs %}
{% tab title="Terminal" %}

```bash
$ pod init
```

{% endtab %}
{% endtabs %}

Then **Podfile** will be created in your project directory. Open the **Podfile** and add the following lines to the **Podfile**.

{% tabs %}
{% tab title="Podfile" %}

```ruby
# If you specified a platform for your project,
# please make sure to use ios 11.0 for minimum deployment target
platform :ios, '11.0'
use_frameworks!

target "YourProjectName" do
    pod 'TapTalkLive'
end
```

{% endtab %}
{% endtabs %}

Since TapTalk.io use uses **`git-lfs`** (Git Large Files Storage) you will need to install **GIT LFS** to clone/install TapTalk.io SDK through **Cocoapods**.

{% hint style="warning" %}
**Note**: Make sure to install **`git-lfs`**&#x62;efore pod install, otherwise the pod install / pod update will return an error
{% endhint %}

Easiest way to install [git-lfs](https://git-lfs.github.com) is using [brew](https://brew.sh):

{% tabs %}
{% tab title="Terminal" %}

```bash
brew install git-lfs
git lfs install
```

{% endtab %}
{% endtabs %}

Next, after the **`git-lfs`** is installed, install the TapTalk.io SDK through CocoaPods.

{% tabs %}
{% tab title="Terminal" %}

```bash
$ pod install
```

{% endtab %}
{% endtabs %}

#### Step 3: Include Pods Runner in xcconfig

After the pod is successfully installed, we will handle the implementation in the native side using **Xcode**. Open the **xcworkspace** file in your project's **ios** folder. (The default project name for iOS should be Runner, in this case, open Runner.xcworkspace).

If you previously created a new Podfile in the **ios** folder, open **Debug.xcconfig** file under the Flutter folder (you can also press *Cmd + Shift + O* to search by file name) and add the following:

{% tabs %}
{% tab title="Debug.xcconfig" %}

```objectivec
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
```

{% endtab %}
{% endtabs %}

Then open the **Release.xcconfig** file and add the following lines:

{% tabs %}
{% tab title="Release.xcconfig" %}

```objectivec
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"
```

{% endtab %}
{% endtabs %}

#### Step 4: Grant permission in your application project

To make sure TapTalk.io has all permission to access the user's media, file, location, and contact, the application needs to ask for permission. Open the **info.plist** file under the Runner folder, and add the following key-value pairs.

<table data-header-hidden><thead><tr><th width="339">Information Property Key</th><th>Information Property Value</th></tr></thead><tbody><tr><td><strong>Information Property Key</strong></td><td><strong>Information Property Value</strong></td></tr><tr><td>Privacy - Camera Usage Description</td><td>$(PRODUCT_NAME) needs to request access to your camera to send image messages and take profile picture.</td></tr><tr><td>Privacy - Contacts Usage Description</td><td>$(PRODUCT_NAME) need your permission to access your contact, we will sync your contact to our server and automatically find your friend so it is easier for you to find your friends.</td></tr><tr><td>Privacy - Photo Library Additions Usage Description</td><td>$(PRODUCT_NAME) needs to request access to your photo library to save photos.</td></tr><tr><td>Privacy - Photo Library Usage Description</td><td>$(PRODUCT_NAME) needs to request access to your photo library to send image messages and select profile picture.</td></tr><tr><td>Privacy - Location When In Use Usage Description</td><td>$(PRODUCT_NAME) needs to request access to your location to send location messages.</td></tr></tbody></table>

{% hint style="info" %}
**Note:** You can change **Information Property Value** with your preferred message, the string value will be displayed when the application requests the permission.
{% endhint %}

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MHKsq4vOlouRa03adbb%2F-MHLISj3JHnpzjIeKv5r%2F8b43524-Screen_Shot_2019-08-28_at_13.57.43.png?alt=media\&token=b918d137-bd53-43fc-84df-ae605c44b0c9)

#### Step 5: Enable background modes

Background modes is required to handle background process in TapTalk.io. It is used to run some processes in the background before the app is killed. For more information about the processes, check out the [background process section](/powertalk-chat-sdk-documentation/powertalk-ios/background-process-in-taptalk.io).\
To enable **background modes**, go to **Target** -> **Capabilities**, then turn **Background Modes** toggle to **ON**, next select **Background fetch** and **Remote notifications**

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MHKsq4vOlouRa03adbb%2F-MHLIm1-VkzIwjxQilqS%2Feaab744-Screen_Shot_2019-08-28_at_13.37.54.png?alt=media\&token=02281a47-665d-4403-8062-8fb0fe48c64b)

After you turn on the **Background Modes**, **Required background modes** key will be added automatically in your **Info.plist** as shown below.

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MHKsq4vOlouRa03adbb%2F-MHLItjSE_HAsYniTXmS%2F979a00b-Screen_Shot_2019-08-28_at_13.44.36.png?alt=media\&token=ed490114-336d-4b7c-9777-7a6ddd88a521)

After adding the required dependency, sync your project and begin the next step by writing custom platform-specific code using platform channels.

#### Step 6: Create Flutter Platform Client

If you have finished this step from the [Android side](/onetalk-omnichannel-documentation/onetalk-channel-integration/live-chat/onetalk-live-chat-for-flutter/get-started-android#step-3-create-flutter-platform-client), you can skip to the [next step](#step-3-add-an-android-platform-specific-implementation).

In this example, we will add the following inside the MyHomePageState class:

1. Method Channel to connect to the native iOS host
2. `openOneTalkLiveChatTalkUI()` function to open the Live Chat's view
3. A button to call the `openOneTalkLiveChatTalkUI()` function

{% tabs %}
{% tab title="First Tab" %}
{% code title="main.dart" %}

```dart
class _MyHomePageState extends State<MyHomePage> {
  
  // Create the MethodChannel
  static const oneTalkLiveChatMethodChannel = MethodChannel('io.taptalk.onetalklivechat');
  
  // Function to open the live chat view
  Future<void> _openOneTalkLiveChatTalkUI() async {
    try {
      // Initialize OneTalk Live Chat SDK
      final bool isOneTalkInitialized = await oneTalkLiveChatMethodChannel.invokeMethod('initOneTalkLiveChat');
      if (isOneTalkInitialized) {
        // Open live chat view
        await oneTalkLiveChatMethodChannel.invokeMethod('openLiveChatView');
      }
    }
    on PlatformException catch (e) {
      // Call might fail if the platform doesn’t support the platform API
      print(e.message);
    }
  }
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      ...
      body:
        ...
          // Sample button to call openOneTalkLiveChatTalkUI
          ElevatedButton(
            onPressed: _openOneTalkLiveChatTalkUI,
            child: Text(
              'Get Started with OneTalk Live Chat',
            ),
          ),
      ...
    );
  }
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

Please note the name parameter in the MethodChannel constructor that was used (`io.taptalk.onetalklivechat`), and the method name in the `invokeMethod()` parameter (`initOneTalkLiveChat` & `openLiveChatView`). We will use the same names later to configure Flutter engine in the native side.

#### Step 7: Add an iOS platform-specific implementation <a href="#step-3-add-an-android-platform-specific-implementation" id="step-3-add-an-android-platform-specific-implementation"></a>

Next, we will configure the native side of the iOS host implementation. Go back to previously opened Xcode project, and open **AppDelegate.m** file. We will do the following:

1. Add a MethodChannel Result variable to handle asynchronous call
2. setMethodCallHandler to handle calls from the MethodChannel that we previously created.
3. Add native functions to initialize & authenticate OneTalk Live Chat SDK and open the chat room list view

{% tabs %}
{% tab title="Objective-C" %}

<pre class="language-csharp" data-title="AppDelegate.m"><code class="lang-csharp">// Import TapTalkLive
#import &#x3C;TapTalkLive/TapTalkLive.h>

@interface AppDelegate () &#x3C;TapTalkLiveDelegate>

// MethodChannel Result to handle asynchronous call
@property (nonatomic) FlutterResult oneTalkMethodChannelResult;

@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  
    [GeneratedPluginRegistrant registerWithRegistry:self];
  
    // Override point for customization after application launch.
    
    FlutterViewController *controller = (FlutterViewController *) self.window.rootViewController;
    
    // Create MethodChannel
    FlutterMethodChannel *oneTalkMethodChannel = [FlutterMethodChannel methodChannelWithName:@"io.taptalk.onetalklivechat"
                                                                             binaryMessenger:controller.binaryMessenger];
    // Handle MethodChannel calls
    [oneTalkMethodChannel setMethodCallHandler:^(FlutterMethodCall *call, FlutterResult result) {
<strong>        // Save result to variable
</strong><strong>        self->_oneTalkMethodChannelResult = result;
</strong>        
        // Call native methods
        if ([call.method isEqualToString:@"initOneTalkLiveChat"]) {
            [self initOneTalkLiveChat];
        }
        else if ([call.method isEqualToString:@"openLiveChatView"]) {
            [self openLiveChatView];
        }
        else {
            result(FlutterMethodNotImplemented);
        }
    }];
    
    return [super application:application didFinishLaunchingWithOptions:launchOptions];
}

// Method to initialize OneTalk Live Chat SDK
- (void)initOneTalkLiveChat {
    [[TapTalkLive sharedInstance] initWithSecretKey:ONETALK_APP_KEY_SECRET
    success:^{
        if (self.oneTalkMethodChannelResult != nil) {
            self.oneTalkMethodChannelResult(@(YES));
        }
    }
    failure:^(NSString *errorMessage) {
        if (self.oneTalkMethodChannelResult != nil) {
            self.oneTalkMethodChannelResult([FlutterError errorWithCode:YOUR_ERROR_CODE
                                                                message:errorMessage
                                                                details:nil]);
        }
    }];
}

// Method to open live chat view
- (void)openLiveChatView {
    UINavigationController *rootNavigationController = (UINavigationController *) [UIApplication sharedApplication].keyWindow.rootViewController;
    [[TapTalkLive sharedInstance] presentTapTalkLiveViewWithCurrentNavigationController:rootNavigationController animated:YES];
    if (self.oneTalkMethodChannelResult != nil) {
        self.oneTalkMethodChannelResult(@(YES));
    }
}
</code></pre>

{% endtab %}
{% endtabs %}

#### Step 8: Initialize TapTalk.io Omnichannel Application Delegate

To allow the iOS SDK to respond to the connection and state changes in your iOS client app, you have to implement all of our application delegate methods in your **`UIApplicationDelegate`** methods in appDelegate file.

After you initialize the TapTalk.io Omnichannel, you have to connect and implement these methods in your **`UIApplicationDelegate`** methods in **appDelegate** file to make sure TapTalk.io Omnichannel runs smoothly in your application.

| TapTalk.io Omnichannel Application Delegate Method | Description                                                                                   |
| -------------------------------------------------- | --------------------------------------------------------------------------------------------- |
| `application:didFinishLaunchingWithOptions:`       | Tells the delegate that the launch process is almost done and the app is almost ready to run. |
| `applicationWillResignActive:`                     | Tells the delegate that the app is about to become inactive.                                  |
| `applicationDidEnterBackground:`                   | Tells the delegate that the app is now in the background.                                     |
| `applicationWillEnterForeground:`                  | Tells the delegate that the app is about to enter the foreground.                             |
| `applicationDidBecomeActive:`                      | Tells the delegate that the app has become active.                                            |
| `applicationWillTerminate:`                        | Tells the delegate when the app is about to terminate.                                        |
| `handleException:`                                 | Tells the delegate when application throws exception.                                         |

{% tabs %}
{% tab title="Objective-C" %}
{% code title="AppDelegate.m" %}

```csharp
// Import TapTalkLive
#import <TapTalkLive/TapTalkLive.h>

// Implement TapTalkLiveDelegate
@interface AppDelegate () <TapTalkLiveDelegate>

// Properties
...

@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  
    // Implement TapTalk Omnichannel didFinishLaunchingWithOptions here    
    [[TapTalkLive sharedInstance] application:application didFinishLaunchingWithOptions:launchOptions];
    
    // Register Uncaught Exception Handler
    NSSetUncaughtExceptionHandler(&handleExceptions);
    
    // Other code
    ...
    
    return [super application:application didFinishLaunchingWithOptions:launchOptions];
}

- (void)applicationWillResignActive:(UIApplication *)application {
  
    // Implement TapTalk Omnichannel applicationWillResignActive here
    [[TapTalkLive sharedInstance] applicationWillResignActive:application];
  
    // Other code
    ...
}

- (void)applicationDidEnterBackground:(UIApplication *)application {
    // Implement TapTalk Omnichannel applicationDidEnterBackground here
    [[TapTalkLive sharedInstance] applicationDidEnterBackground:application];
  
    // Other code
    ...
}

- (void)applicationWillEnterForeground:(UIApplication *)application {
  
    // Implement TapTalk Omnichannel applicationWillEnterForeground here
    [[TapTalkLive sharedInstance] applicationWillEnterForeground:application];
  
    // Other code
    ...
}

- (void)applicationDidBecomeActive:(UIApplication *)application {
  
    // Implement TapTalk Omnichannel applicationDidBecomeActive here    
    [[TapTalkLive sharedInstance] applicationDidBecomeActive:application];
  
    // Other code
    ...
}

- (void)applicationWillTerminate:(UIApplication *)application {
  
    // Implement TapTalk Omnichannel applicationWillTerminate here
    [[TapTalkLive sharedInstance] applicationWillTerminate:application];
  
    // Other code
    ...
}

// Add function to handle exceptions
- (void)handleExceptions:(NSException *exception) {
  // Implement TapTalk Omnichannel handleException method
  [[TapTalkLive sharedInstance] handleException:exception];
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

{% hint style="warning" %}
**Note**: Don't forget to register for exception handler inside **`application:didFinishLaunchingWithOptions:`**&#x6D;ethod and implement **`handleExceptions`** method in **appDelegate** class to make sure TapTalk.io Omnichannel SDK is able to handle exceptions.
{% endhint %}

You can now try running the app. Pressing the sample button will invoke the `openOneTalkLiveChatTalkUI()` method that we previously created, which will initialize OneTalk Live Chat SDK, and open the live chat view once the initialization is completed. You may also try a different implementation and separate the **init** and the **open view** methods. You can also add more calls to other native methods with the same approach using the same MethodChannel.

{% hint style="info" %}
**Note**: You can check a more complete implementation guide in the [OneTalk Live Chat for iOS](/onetalk-omnichannel-documentation/onetalk-channel-integration/live-chat/onetalk-ios) section.
{% endhint %}


# Google Business Messages Integration

A comprehensive step by step guide on how to integrate Google Business Messages as a channel into OneTalk by TapTalk.io.

Integrating OneTalk with your Google Business Messages will allow you to receive and reply incoming messages from your Business' Google Maps Location or Google Search Domain.

{% hint style="info" %}
Integrating Google Business Messages can only be done if you have a **verified** **location** managed with your Google email.
{% endhint %}

### Step 1: Create Google Business Messages Channel

Start by clicking **Integration** on the side menu.

A submenu will appear with different channel options, go ahead and select **Google Business Messages.**

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2Fq885KUn5JtGaf72e3kGh%2Fimage.png?alt=media\&token=1662aa57-3bec-4ef7-9720-3151e17f57f5)

Once selected, go ahead and click on the **Add Channel** button on top right corner of the page.

<figure><img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2FPDfT6LE4J3Ko9lOT87e7%2Fimage.png?alt=media&amp;token=dd59bcb4-4ede-4619-908b-eeb3261b70cb" alt=""><figcaption></figcaption></figure>

1. Choose a topic to be assigned to the channel.

<figure><img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2FQwl6x4N6kYtoHjG35WDu%2Fimage.png?alt=media&amp;token=2a491679-bce6-4eee-9150-298f94e84182" alt=""><figcaption></figcaption></figure>

2. Setup your Channel Profile\
   This display name and profile logo will appear on your channel's profile.

<figure><img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2F8rU34CKwB7tIvOA3a9kM%2Fimage.png?alt=media&amp;token=981c02c7-e172-48be-b145-c05aee8c2138" alt=""><figcaption></figcaption></figure>

3. Setup Greeting Message for you channel\
   This message will appear when your customer enter the chatroom for the first time.

<figure><img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2FIM1QKVhtgUj9Pi6KW0uP%2Fimage.png?alt=media&amp;token=923061dd-e7e3-4f02-934b-b9b8f85bb4ff" alt=""><figcaption></figcaption></figure>

4. Enable / Disable Entry points for your channel

<figure><img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2Fbl6xIFga3KTiog9wbLFi%2Fimage.png?alt=media&amp;token=185ae8f8-4fd2-4596-a738-7b08145f67c7" alt=""><figcaption></figcaption></figure>

Enabling **Local Entry Point** will allow your customers to reach you by clicking 'Chat' button in  your Google Maps business's location.

{% hint style="info" %}
You can manage the locations later after you have successfully created a Google Business Messages Channel.
{% endhint %}

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2F9UHEpX5RPcECuVQkJJH6%2Fimage.png?alt=media\&token=f333377f-09bd-44e5-b70f-821b914350d2)

Enabling **Non-Local Entry Point** will allow your customers to reach you by clicking 'Chat' button on your business' domain from Google Search result.

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2FwOj0uaV6JL7piuJhUGZH%2Fimage.png?alt=media\&token=b878d28b-3702-4b1b-aab1-7f6e899b901d)

To setup your **Non-Local Entry Point**, you must input these data:

1. Domain(s)<br>

   <figure><img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2FkpAHMi1H7K8ocdR5Bnx3%2Fimage.png?alt=media&amp;token=ef3859d0-a5c8-478e-9632-598ddb961398" alt=""><figcaption></figcaption></figure>

   You can add list of domains that you want to be the entry points for your customers to reach you.
2. Region<br>

   <figure><img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2F8bnMuHsxOEA1xfgucNUK%2Fimage.png?alt=media&amp;token=40f89950-2403-4750-a569-c87a3ee52e1c" alt=""><figcaption></figcaption></figure>

   Choose region to filter from where your customer can reach you according to their region.
3. Phone Number\
   ![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2F78cApTNj5g8vLtLBo2nl%2Fimage.png?alt=media\&token=13fed66b-930b-4794-81c4-f2c59b14bd55)\
   &#x20;Phone number for conversations started from non-local entry points.
4. Contact Us URL\
   ![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2FQN5wXCIfOi0wvWRpWcji%2Fimage.png?alt=media\&token=0786c7fa-91e7-491e-a9c1-ed33e66c1c57)\
   A link to your business' contact us page and checked the checkbox according to the form of contact that are available in the link you have input.

Once you have filled all the required data, click create channel button to finalize.

<figure><img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2FZRHgGiu37GmLmaJEtSvv%2Fimage.png?alt=media&amp;token=4ccdd9af-9bea-42e2-90cb-caf30983b57f" alt=""><figcaption></figcaption></figure>

Once you have successfully created channel, you can continue to the next step.

### Step 2: Request Verification for your channel

{% hint style="warning" %}
Before starting the verification process, note that some fields can not be modified once you have verified your channel:

1. Channel Profile
2. Enable / Disable Local and Non-Local Entry Points
3. Non-Local Entry Point's data
   {% endhint %}

A verification must be done before you can continue to the next setup for your channel.

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2FAXNXGR4yv2YAUjr6nrGq%2Fimage.png?alt=media\&token=5a677f74-ec24-4da3-b25f-fd4a39e84f99)

Click 'Request Verification' to start channel verification.

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2FUQqThuOKZ8fEOTSZxrlg%2Fimage.png?alt=media\&token=d4d550c8-3ed2-48f2-9a6a-caaee26fab2d)

{% hint style="info" %}
Note: Domain in the 'Employee Email' must be related to the business that you want to integrate
{% endhint %}

Fill in required data to request verification and click 'Request Verification' button.

After submitting, Google will automatically send you 2 separate emails to the email that you input to Employee Email field.

### Step 3: Confirm verification through employee email

Check your email for 2 email from Google.

**First email** will contain security key that you will have to use to confirm verification in the second email.

<figure><img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2FxUybXimnxghEOx8KrFUk%2Fimage.png?alt=media&amp;token=7dc82e7b-557b-4c38-aced-cb202dd3adc0" alt=""><figcaption></figcaption></figure>

Second email will contain an instruction from Google that will ask you to reply their approval email for TapTalk to send messages that represent your brand.

<figure><img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2F3dA8bzXDX3iLwOZPWERf%2Fimage.png?alt=media&amp;token=af9b5049-c731-4886-9994-2b973a94c7a7" alt=""><figcaption></figcaption></figure>

You must reply to the second email to continue the verification process with this line:

“I, \[name of brand employee] and \[title of employee], grant \[messaging\_partner\_name] the right to send Business Messages using the information specified in this email. Security key: \[Google-provided security key from separate email]”

{% hint style="info" %}
There's a chance that you will receive blank security key, then you have to send the second email without the security key.
{% endhint %}

After you replied to the second email, Google will start the review of your verification request and will get back to you through email no later than 1 business day.

<figure><img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2F3NtxVTLFuIQkc7vXivdC%2Fimage.png?alt=media&amp;token=cca11480-1622-4ba3-985a-64f8700a5beb" alt=""><figcaption></figcaption></figure>

Continue to **Step 4** if you use **Local Entry Point** for your Google Business Messages Channel.

Continue to **Step 5** if you only use **Non-Local Entry Point** for your channel.

### Step 4: Setup Local Entry Points

<figure><img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2F9kP98HnTQWyfpiAr2omM%2Fimage.png?alt=media&amp;token=a1fbaf9f-7125-4e58-81c7-acf73347775b" alt=""><figcaption></figcaption></figure>

To enable / disable Local Entry Point click 'Edit' button on the top right corner.

To add location to Local Entry Point click 'Add Location' button on the top right corner and a pop up will appear.

<figure><img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2FaJ8dgU5cFhaiWmcA2LUS%2Fimage.png?alt=media&amp;token=62e82824-0fc1-41ae-b087-d1b705f70cd7" alt=""><figcaption></figcaption></figure>

You can add location in 2 ways:

1. Manual Add New Location<br>

   <figure><img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2F6HabHt3HS0vC0Zwh54HG%2Fimage.png?alt=media&amp;token=9402eef7-a87a-40b3-9b77-ebc613546343" alt=""><figcaption></figcaption></figure>

   Input Place ID and Place Alias to add a location to your Local Entry Point List. Click the hyperlink below Place ID field to find the ID that you need to input for your location.<br>

   <figure><img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2FoxYMy1Xvm6QYR4XYAvjc%2Fimage.png?alt=media&amp;token=9eead413-d9f8-46e0-8d52-ea23febf2b84" alt=""><figcaption></figcaption></figure>

   Once you have been redirected to Google Developer Page, find your location by searching it on the top left corner of this page and copy the Place ID of your location.\
   Paste the ID to Place ID field, input Place Alias, and click save changes to finalize adding your location to Local Entry Point.
2. Import Locations\
   To add many locations at once, you can use import locations feature. Download template first and then you can copy your data into the template for upload.

Once you have added your locations, a table with all your locations will show up on Entry Point page. Next you will have to request verification for the locations before you can continue to the next step.

<figure><img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2FYcAKK7XQLpO08wm7cIq9%2Fimage.png?alt=media&amp;token=42ba4803-57a3-46ee-a415-614a68db474e" alt=""><figcaption></figcaption></figure>

To request verification for the locations, you can simply click 'Request Verification' button on 'Verification Status' column.

### Step 5: Launch Entry Point

You can change the status of your entry points to launched by clicking the button 'Launch'. Launching your channel's entry point means you are enabling your customers to reach you through listed locations / domains.&#x20;

<figure><img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2F2DAuc0eOqJ4iYd1Dm0xd%2Fimage.png?alt=media&amp;token=3a85be5e-87db-451b-b746-7a2eb7975abf" alt=""><figcaption></figcaption></figure>

For **Local Entry Point**, every locations in the launch table is the locations that has already been verified.&#x20;

<figure><img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2FuLwoBZQAuBurrMIh7qmG%2Fimage.png?alt=media&amp;token=bbf1f55f-5c83-4cf4-9a94-d2a60c613faa" alt=""><figcaption></figcaption></figure>

For **Non-Local Entry Point**, launch list will show the regions that you have chosen. This list will only appear if you have Non-Local enabled and channel profile verified.

**Congrats! You've successfully launched your entry point to OneTalk and you can start receiving and sending messages through OneTalk inbox**.&#x20;

For more information feel free to contact us via **<support@taptalk.io>** or simply click the link below to chat from [**WhatsApp**](https://api.whatsapp.com/send/?phone=6282180885808\&text=Halo+TapTalk.io%2C+Saya+ingin+bertanya+terkait+integrasi+channel+saya)**.**


# Google Business Profile Integration

A comprehensive step by step guide on how to integrate Google Business Profile as a channel into OneTalk by TapTalk.io.

Integrating OneTalk with your Google Business Profile will allow you to receive and reply incoming reviews from your Business' Google Maps Location.

{% hint style="info" %}
Integrating Google Business Profile can only be done if you have a **verified** **location** connected to your Google Account.
{% endhint %}

### Step 1: Create Google Business Profile Channel

Start by clicking **Integration** on the side menu.

A submenu will appear with different channel options, go ahead and select **Google Business Profile.**

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2FnznV3lwhmJSQx4I1v2zd%2Fimage.png?alt=media\&token=e0f0f813-46e6-4b6b-ba8b-b0b52b1e9bf9)

Once selected, go ahead and click on the **Add Channel** button on top right corner of the page.

<figure><img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2Fc96NuTetJB1aeA1dB2vT%2Fimage.png?alt=media&amp;token=e763a5fd-c3e9-4765-8f12-1d93abb96101" alt=""><figcaption></figcaption></figure>

Next, you will have to login with you Google Account, please click the Connect with Google button.

### Step 2: Login with your Google Account

Start by clicking Connect with Google button, you will be prompt to input your email and password if this is your first time login to Google Account through OneTalk Dashboard.

<figure><img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2FBvuB716NIphQV0vHEbKj%2Fimage.png?alt=media&amp;token=14a8767f-d583-44c6-b5be-a8f7628b0af1" alt=""><figcaption></figcaption></figure>

Google will ask for your permission to let TapTalk.io access your data

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2FBb1NUXwoiBGxIZSBraCB%2Fimage.png?alt=media\&token=2006490d-7a1d-4609-a13c-1c303bd54902)

After clicking 'next', you will grant TapTalk.io a permission to access your data such as&#x20;

1. Account Information\
   This will allow TapTalk.io to get information like your account name to be shown on OneTalk Dashboard
2. Account Locations\
   This will allow TapTalk.io to get list of locations from your account that can be integrate with OneTalk Dashboard
3. Account Locations Reviews\
   This will allow TapTalk.io to get list of reviews from the locations that have been integrated to OneTalk Dashboard

### Step 3: Choose Location from Connected Google Account

After succesfully connected your Google Account to OneTalk Dashboard, you will be shown screen as below:

<figure><img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2FAk8FurYZYMzJIQX7CpV2%2Fimage.png?alt=media&amp;token=c5e64a1d-b093-4429-9550-72d6a261b833" alt=""><figcaption></figcaption></figure>

Click 'Select Business Profile' next to choose the location you want to integrate with OneTalk Dashboard.

<figure><img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2Fneotx1AI9zTwPYKmsq4b%2Fimage.png?alt=media&amp;token=9a6ae2df-40d1-44c9-8c09-4f66489bcebf" alt=""><figcaption></figcaption></figure>

First, you have to choose from your Personal account or Location Group account.

<figure><img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2FfKxMeuzDnsn0fJv4n62W%2Fimage.png?alt=media&amp;token=4cc61d6a-0d98-48b3-9764-ae1e1a7b6e8a" alt=""><figcaption></figcaption></figure>

Second, choose the location you want to integrate.

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2FsEw7YD8xxXbUEIG4VCmR%2Fimage.png?alt=media\&token=c6d9cfc8-30e4-46df-b75f-cd527058ed3a)

After selecting the location, you need to input Channel name dan choose topic to continue create channel.

<figure><img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2FFzS3gyhdQx5xcNGKdmFd%2Fimage.png?alt=media&amp;token=a91e1e0f-78d7-489f-9e46-0d5254e30abb" alt=""><figcaption></figcaption></figure>

**Congrats! You've successfully connected your Location to OneTalk**.&#x20;

For more information feel free to contact us via **<support@taptalk.io>** or simply click the link below to chat from [**WhatsApp**](https://api.whatsapp.com/send/?phone=6282180885808\&text=Halo+TapTalk.io%2C+Saya+ingin+bertanya+terkait+integrasi+channel+saya)**.**


# Tokopedia Integration

A comprehensive step by step guide on how to integrate your Tokopedia shop as a channel into OneTalk by TapTalk.io.

Integrating OneTalk with your Tokopedia shop will allow you to receive and reply incoming message from your shop's chat.

{% hint style="info" %}
Integrating Tokopedia can only be done if you have a **Power Merchant, Power Merchant PRO and Official Store** as your shop status.
{% endhint %}

### Step 1: Create Tokopedia Channel

Start by clicking **Integration** on the side menu.

A submenu will appear with different channel options, go ahead and select **Tokopedia.**

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2FcDGYbxQ3vTCwkaM9CZOJ%2Fimage.png?alt=media\&token=7c595f55-6911-4d6c-be79-9b7f2ee59b36)

Once selected, go ahead and click on the **Add Channel** button on top right corner of the page.

<figure><img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2F3ReK0Bw7hgj2NPe0v5NT%2Fimage.png?alt=media&amp;token=2585b0d8-221b-4922-909d-657af8a2a99a" alt=""><figcaption></figcaption></figure>

Next, you will have to fill in your shop URL and choose a topic to be assigned to your channel and click "Save Changes" to submit.

<figure><img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2FJh6eWWRs0g1zMtKyBEDR%2Fimage.png?alt=media&amp;token=bcfbda93-e4ce-4a9f-a821-75154798ac1f" alt=""><figcaption></figcaption></figure>

### Step 2: Check your Tokopedia Seller email

<figure><img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2FITlLUonAsgTdKyy0uKjD%2Fimage.png?alt=media&amp;token=7246c2be-0b30-4f14-b160-a6a45ad5ce71" alt=""><figcaption></figcaption></figure>

Once you have created a Tokopedia channel, you should check your Tokopedia's account email regularly for any confirmation mail from Tokopedia.

### Step 3: Accept Tokopedia confirmation email&#x20;

If you received an email from Tokopedia that ask for your permission to let TapTalk.io to have access managing your shop, please click accept.

<figure><img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2F8tFKVjAItFD3K6YSclxZ%2Fimage.png?alt=media&amp;token=20468fcc-0e6a-4162-8d3f-d1c6bb399989" alt=""><figcaption></figcaption></figure>

Once you clicked "Accept" you can contact TapTalk.io's team to help you finalize your shop's channel at OneTalk.

### Step 4: Set TapTalk permission to manage your shop

To enable TapTalk to manage your Tokopedia shop, you must go to this URL <https://seller.tokopedia.com> and give TapTalk.io permission. Follow the steps below

<figure><img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2FRe1DTzHmP9pDOLIfdiRS%2Fimage.png?alt=media&amp;token=7c3663c7-2d79-48c7-8884-bd85daef57eb" alt=""><figcaption></figcaption></figure>

<figure><img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2FU9FVKkVG8saPT7LRIQ9m%2Fimage.png?alt=media&amp;token=1075f608-3fbd-414f-a7fa-bd1a944e3c74" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
If you can not enable a certain permission for TapTalk.io, make sure you deactivate the other third party's permission first and try enabling TapTalk.io permission again.
{% endhint %}

**Congrats! You've successfully connected your Tokopedia shop to OneTalk**.&#x20;

For more information feel free to contact us via **<support@taptalk.io>** or simply click the link below to chat from [**WhatsApp**](https://api.whatsapp.com/send/?phone=6282180885808\&text=Halo+TapTalk.io%2C+Saya+ingin+bertanya+terkait+integrasi+channel+saya)**.**


# Integration API

The API provides set of methods that can be used when integrating into OneTalk


# Inbox API

The set of methods that can be used when for OneTalk Inbox

## Send Message via WhatsApp

<mark style="color:green;">`POST`</mark> `https://onetalk-api.taptalk.io/api/integration/v1/inbox/send_message_whatsapp`

Send a message to the specified phone number via WhatsApp channel.\
\
The phone number must be registered in WhatsApp.\
\
If parameter **`withCase`** is true, the message will always be sent to an open case. If the user already has an open case, the message will be sent to that case. Otherwise, a new case will be created for the user.

#### Headers

| Name                                      | Type   | Description                                     |
| ----------------------------------------- | ------ | ----------------------------------------------- |
| API-Key<mark style="color:red;">\*</mark> | string | API key for accessing the API.                  |
| Content-Type                              | string | Content type of the request body.               |
| User-Agent                                | string | The user agent of the client accessing the API. |

#### Request Body

| Name        | Type    | Description                                                                                                                                             |
| ----------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| channelID   | string  | The channel ID.                                                                                                                                         |
| phone       | string  | The phone number to send the message to.                                                                                                                |
| messageType | string  | <p>The message type.<br>Allowed values: <strong><code>text</code></strong>, <strong><code>image</code></strong>, <strong><code>file</code></strong></p> |
| body        | string  | The message body (text message or file URL).                                                                                                            |
| filename    | string  | The name of the file (required for message type other than "text").                                                                                     |
| caption     | string  | The caption, if any (for message type "image").                                                                                                         |
| withCase    | boolean | If true, the message will be sent to the recipient's existing open case or a new case will be created.                                                  |
| topicID     | integer | The topic ID for new case.                                                                                                                              |

{% tabs %}
{% tab title="200 Response Success" %}

```json
HTTP/1.1 200 OK
{
  "status": 200,
  "error": {
    "code": "",
    "message": "",
    "field": ""
  },
  "data": {
    "success": true,
    "message": "The message has been added to queue",
    "caseID": "96212160DF",
    "trxID": "7f1007bf-d04b-4e83-9b2e-e193d3833ba1"
  }
}
```

{% endtab %}

{% tab title="400 Error 4xx (ParamValidationFailed, HeaderValidationFailed, TierNotSelected)" %}

```
40002 (ParamValidationFailed): The parameter validation failed.
HTTP/1.1 200 OK
{
  "status": 400,
  "error": {
    "code": "40002",
    "message": "Channel ID is required",
    "field": "channelID"
  },
  "data": {}
}

40002 (HeaderValidationFailed): The request header validation failed.
HTTP/1.1 200 OK
{
  "status": 400,
  "error": {
    "code": "40001",
    "message": "Request headers are required (API-Key)",
    "field": ""
  },
  "data": {}
}

49900 (TierNotSelected): The organization has not selected the tier.
HTTP/1.1 200 OK
{
  "status": 499,
  "error": {
    "code": "49900",
    "message": "Please select a tier",
    "field": ""
  },
  "data": {}
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
Click the <mark style="background-color:orange;">**right arrow**</mark> above on the right side of Sync User Contact API to see the full list of request parameters and the response.
{% endhint %}

{% hint style="warning" %}
**Channel ID** can be obtained in [OneTalk Dashboard](https://onetalk.taptalk.io)\
Go to **Integration** and click **WhatsApp for SME**, then click the channel detail and you can copy the **Channel ID**&#x20;
{% endhint %}

{% tabs %}
{% tab title="Request Example (text)" %}

```go
{
    "channelID": "2101081881",
    "phone": "6281212345678",
    "messageType": "text",
    "body": "Hi, this is a message.",
    "withCase": true,
    "topicID": 1
}
```

{% endtab %}

{% tab title="Request Example (image)" %}

```go
{
    "channelID": "2101081881",
    "phone": "6281212345678",
    "messageType": "image",
    "body": "http://www.example.com/chat/file/image/008dce72-06c0?token=802714",
    "filename": "my-photo.jpg",
    "caption": "This is the photo.",
    "withCase": true,
    "topicID": 1
}
```

{% endtab %}

{% tab title="Request Example (file)" %}

```javascript
{
    "channelID": "2101081881",
    "phone": "6281212345678",
    "messageType": "file",
    "body": "http://www.example.com/chat/file/008dce72-06c0.pdf",
    "filename": "Test.pdf",
    "caption": "",
    "withCase": false,
    "topicID": 1
}
```

{% endtab %}
{% endtabs %}

## Send Templated Message via WhatsApp Business API

<mark style="color:green;">`POST`</mark> `https://onetalk-api.taptalk.io/api/integration/v1/inbox/send_templated_message_whatsappba`

Send a templated message to the specified phone number via a WhatsApp Business API channel.\
\
The phone number must be registered in WhatsApp.\
\
If parameter **`withCase`** is true, the message will always be sent to an open case. If the user already has an open case, the message will be sent to that case. Otherwise, a new case will be created for the user.

#### Headers

| Name                                      | Type   | Description                                     |
| ----------------------------------------- | ------ | ----------------------------------------------- |
| API-Key<mark style="color:red;">\*</mark> | string | API key for accessing the API                   |
| Content-Type                              | string | Content type of the request body.               |
| User-Agent                                | string | The user agent of the client accessing the API. |

#### Request Body

| Name                                            | Type    | Description                                                                                            |
| ----------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------ |
| channelID<mark style="color:red;">\*</mark>     | string  | The channel ID.                                                                                        |
| phoneNumberID<mark style="color:red;">\*</mark> | string  | The phone number ID to send the message from.                                                          |
| phone<mark style="color:red;">\*</mark>         | string  | The phone number to send the message to.                                                               |
| templateName<mark style="color:red;">\*</mark>  | string  | The message template name.                                                                             |
| languageCode<mark style="color:red;">\*</mark>  | string  | The language code of the template message.                                                             |
| parameters                                      | object  | Parameters for the message template.                                                                   |
| header                                          | array   | Parameters for template header.                                                                        |
| name                                            | string  | Name of the parameter.                                                                                 |
| value                                           | string  | Value of the parameter.                                                                                |
| body                                            | array   | Parameters for template body.                                                                          |
| name                                            | string  | Name of the parameter.                                                                                 |
| value                                           | string  | Value of the parameter.                                                                                |
| footer                                          | array   | Parameters for template footer.                                                                        |
| name                                            | string  | Name of the parameter.                                                                                 |
| value                                           | string  | Value of the parameter.                                                                                |
| buttons                                         | array   | Parameters for template buttons.                                                                       |
| name                                            | string  | Name of the parameter.                                                                                 |
| value                                           | string  | Value of the parameter.                                                                                |
| withCase                                        | boolean | If true, the message will be sent to the recipient's existing open case or a new case will be created. |
| topicID                                         | integer | The topic ID for new case.                                                                             |
| assigneeType                                    | string  | Assignee type for new case. Value: `"chatbot"` or `"agent"`.                                           |

{% tabs %}
{% tab title="200 " %}

```json
HTTP/1.1 200 OK
{
  "status": 200,
  "error": {
    "code": "",
    "message": "",
    "field": ""
  },
  "data": {
    "success": true,
    "message": "The message has been added to queue",
    "caseID": "96212160DF",
    "trxID": "7f1007bf-d04b-4e83-9b2e-e193d3833ba1"
  }
}
```

{% endtab %}

{% tab title="400 40002 (ParamValidationFailed): The parameter validation failed.
40002 (HeaderValidationFailed): The request header validation failed.
49900 (TierNotSelected): The organization has not selected the tier." %}

```json
HTTP/1.1 200 OK
{
  "status": 400,
  "error": {
    "code": "40002",
    "message": "Channel ID is required",
    "field": "channelID"
  },
  "data": {}
}


HTTP/1.1 200 OK
{
  "status": 400,
  "error": {
    "code": "40001",
    "message": "Request headers are required (API-Key)",
    "field": ""
  },
  "data": {}
}


HTTP/1.1 200 OK
{
  "status": 499,
  "error": {
    "code": "49900",
    "message": "Please select a tier",
    "field": ""
  },
  "data": {}
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
Click the <mark style="background-color:orange;">**right arrow**</mark> above on the right side of Sync User Contact API to see the full list of request parameters and the response.
{% endhint %}

{% hint style="warning" %}
**Channel ID** can be seen in [OneTalk Dashboard](https://onetalk.taptalk.io)\
Go to **Integration** and click **WhatsApp Business API**, then click the channel detail and you can copy the **Channel ID**&#x20;
{% endhint %}

{% tabs %}
{% tab title="Request Example " %}

```json
{
  "channelID": "2100480937",
  "phoneNumberID": "103011859190563",
  "phone": "6281212345678",
  "templateName": "greetings_v1",
  "languageCode": "en",
  "parameters": {
    "header": [
      //Text Template Type, Header with Variable
      {
        "name": "variable_name",
        "value": "Good Morning"
      },
      //Dynamic Media Template Type, Media Type "Document"
      {
        "name": "document",
        "value": "https://taptalk.io/file_path_url.pdf"
      },
      //Dynamic Media Template Type, Media Type "Image"
      {
        "name": "image",
        "value": "https://taptalk.io/file_path_url.pdf"
      },
      //Dynamic Media Template Type, Media Type "Video"
      {
        "name": "video",
        "value": "https://taptalk.io/file_path_url.pdf"
      },
    ],
    "body": [
      {
        "name": "name",
        "value": "John"
      },
      {
        "name": "office_hours",
        "value": "09:00 - 17:00"
      }
    ],
    "footer": [],
    "buttons": [
      {
        "name": "url_0",
        "value": "1d-1"
      }
    ]
  },
  "withCase": true,
  "topicID": 1,
  "assigneeType": "chatbot"
}

```

{% endtab %}
{% endtabs %}

## Get Updated Case List

<mark style="color:blue;">`GET`</mark> `https://onetalk-api.taptalk.io/api/integration/v1/inbox/case/get_updated_list`

Get the list of new and updated cases since `since_timestamp`.

#### Headers

| Name                                      | Type   | Description                                     |
| ----------------------------------------- | ------ | ----------------------------------------------- |
| API-Key<mark style="color:red;">\*</mark> | string | API key for accessing the API                   |
| Content-Type                              | string | Content type of the request body.               |
| User-Agent                                | string | The user agent of the client accessing the API. |

#### Request Body

<table><thead><tr><th>Name</th><th width="189">Type</th><th>Description</th></tr></thead><tbody><tr><td>since_timestamp	<mark style="color:red;">*</mark></td><td>long</td><td>Timestamp in Unix milliseconds to start getting the updates from.<br></td></tr><tr><td>limit</td><td>integer</td><td><p>Maximum number of items to retrieve.</p><p>Default value: <code>100</code></p><p>Size range: <code>1..100</code></p></td></tr></tbody></table>

{% tabs %}
{% tab title="200: OK Response Success" %}

```javascript
HTTP/1.1 200 OK
{
  "status": 200,
  "error": {
    "code": "",
    "message": "",
    "field": ""
  },
  "data": {
    "cases": [
      {
        "id": "00C49D438C",
        "contact": {
          "id": "76379c2a-14b7-4c88-88c7-17244be50acf",
          "fullName": "Jony XL",
          "alias": "",
          "email": "",
          "phone": "6287776325008",
          "agentRemark": "",
          "createdTime": 1587352926788,
          "updatedTime": 0
        },
        "agent": {
          "email": "jony@taptalk.io",
          "fullName": "Jony"
        },
        "firstMessage": "1",
        "isClosed": false,
        "isJunk": false,
        "agentRemark": "",
        "createdTime": 1587352928385,
        "updatedTime": 1640367746510
      }
    ],
    "hasMore": false,
    "lastTimestamp": 1640367746510
  }
}
```

{% endtab %}

{% tab title="400: Bad Request Error 4xx (ParamValidationFailed, HeaderValidationFailed, TierNotSelected)" %}

```javascript
40002 (ParamValidationFailed): The parameter validation failed.
HTTP/1.1 200 OK
{
  "status": 400,
  "error": {
    "code": "40002",
    "message": "Since timestamp is invalid",
    "field": "since_timestamp"
  },
  "data": {}
}

40002 (HeaderValidationFailed): The request header validation failed.
HTTP/1.1 200 OK
{
  "status": 400,
  "error": {
    "code": "40001",
    "message": "Request headers are required (API-Key)",
    "field": ""
  },
  "data": {}
}

49900 (TierNotSelected): The organization has not selected the tier.
HTTP/1.1 200 OK
{
  "status": 499,
  "error": {
    "code": "49900",
    "message": "Please select a tier",
    "field": ""
  },
  "data": {}
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
Click the <mark style="background-color:orange;">**right arrow**</mark> above on the right side of Get Updated Case List API to see the full list of request parameters and the response.
{% endhint %}

{% tabs %}
{% tab title="Request Example" %}

```go
?since_timestamp=1640367001000&limit=100

```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="Response Example" %}

```json
{
  "status": 200,
  "error": {
    "code": "",
    "message": "",
    "field": ""
  },
  "data": {
    "cases": [
      {
        "id": "00C49D438C",
        "contact": {
          "id": "76379c2a-14b7-4c88-88c7-17244be50acf",
          "fullName": "John Doe",
          "alias": "",
          "email": "",
          "phone": "628123456789",
          "agentRemark": "",
          "createdTime": 1587352926788,
          "updatedTime": 0
        },
        "agent": {
          "email": "agent@taptalk.io",
          "fullName": "Agent"
        },
        "firstMessage": "1",
        "isClosed": false,
        "isJunk": false,
        "agentRemark": "",
        "createdTime": 1587352928385,
        "updatedTime": 1640367746510
      }
    ],
    "hasMore": false,
    "lastTimestamp": 1640367746510
  }
}
```

{% endtab %}
{% endtabs %}

![Success 200 Field Description](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2FfdzOf86WLGXoZmqs1XLq%2FScreen%20Shot%202022-01-10%20at%2012.23.47.png?alt=media\&token=4718d6b4-0bb5-4cad-9cb8-a24e38c2b2d0)

## Update Case

<mark style="color:green;">`POST`</mark> `https://onetalk-api.taptalk.io/api/integration/v1/inbox/case/update`

Update a case details. Only specify parameter for fields to be updated.

#### Headers

| Name                                      | Type   | Description                                     |
| ----------------------------------------- | ------ | ----------------------------------------------- |
| API-Key<mark style="color:red;">\*</mark> | string | API key for accessing the API                   |
| Content-Type                              | string | Content type of the request body.               |
| User-Agent                                | string | The user agent of the client accessing the API. |

#### Request Body

<table><thead><tr><th>Name</th><th width="189">Type</th><th>Description</th></tr></thead><tbody><tr><td>caseID<mark style="color:red;">*</mark></td><td>string</td><td>The case id.</td></tr><tr><td>agentRemark</td><td>string</td><td>Agent's Remark for the case, may be empty.</td></tr><tr><td>isJunk</td><td>boolean</td><td>If the case is junk.</td></tr></tbody></table>

{% tabs %}
{% tab title="Request Example" %}

```json
{
    "caseID": "00C49D438C",
    "agentRemark": "...",
    "isJunk": true
}
```

{% endtab %}
{% endtabs %}

200 Success Response

| Field   | Type    | Description              |
| ------- | ------- | ------------------------ |
| success | boolean | If updated successfully. |
| message | string  | The message.             |

{% tabs %}
{% tab title="200 Success Response" %}

```json
{
  "status": 200,
  "error": {
    "code": "",
    "message": "",
    "field": ""
  },
  "data": {
    "success": true,
    "message": "Case updated successfully",
  }
}
```

{% endtab %}
{% endtabs %}

4xx Error Response

| Name                   | Description                                                          |
| ---------------------- | -------------------------------------------------------------------- |
| ParamValidationFailed  | The parameter validation failed.                                     |
| FeatureNotAvailable    | The feature is not available due to the organization's current tier. |
| HeaderValidationFailed | The request header validation failed.                                |
| TierNotSelected        | The organization has not selected a tier.                            |

{% tabs %}
{% tab title="ParamValidationFailed" %}

```json
{
  "status": 400,
  "error": {
    "code": "40002",
    "message": "Case ID is required",
    "field": "caseID"
  },
  "data": {}
}
```

{% endtab %}

{% tab title="FeatureNotAvailable" %}

```json
{
  "status": 499,
  "error": {
    "code": "49901",
    "message": "This feature is not available for your current tier",
    "field": ""
  },
  "data": {}
}
```

{% endtab %}

{% tab title="HeaderValidationFailed" %}

```json
{
  "status": 400,
  "error": {
    "code": "40001",
    "message": "Request headers are required (API-Key)",
    "field": ""
  },
  "data": {}
}
```

{% endtab %}

{% tab title="TierNotSelected" %}

```json
{
  "status": 499,
  "error": {
    "code": "49900",
    "message": "Please select a tier",
    "field": ""
  },
  "data": {}
}
```

{% endtab %}
{% endtabs %}

## Add or Remove Case Labels

<mark style="color:green;">`POST`</mark> `https://onetalk-api.taptalk.io/api/integration/v1/inbox/case/add_or_remove_labels`

Add labels to a case or remove labels from a case.

#### Headers

| Name                                      | Type   | Description                                     |
| ----------------------------------------- | ------ | ----------------------------------------------- |
| API-Key<mark style="color:red;">\*</mark> | string | API key for accessing the API                   |
| Content-Type                              | string | Content type of the request body.               |
| User-Agent                                | string | The user agent of the client accessing the API. |

#### Request Body

<table><thead><tr><th>Name</th><th width="189">Type</th><th>Description</th></tr></thead><tbody><tr><td>caseID<mark style="color:red;">*</mark></td><td>string</td><td>The case ID.</td></tr><tr><td>addCaseLabels</td><td>string[]</td><td>Name of the case labels to be added.</td></tr><tr><td>removeCaseLabels</td><td>string[]</td><td>Name of the case labels to be removed.</td></tr></tbody></table>

{% tabs %}
{% tab title="Request Example" %}

```json
{
    "caseID": "00C49D438C",
    "addCaseLabels": [
        "vancouver",
        "oxford"
    ],
    "removeCaseLabels": [
        "savannah"
    ]
}
```

{% endtab %}
{% endtabs %}

200 Success Response

| Field   | Type    | Description              |
| ------- | ------- | ------------------------ |
| success | boolean | If updated successfully. |
| message | string  | The message.             |

{% tabs %}
{% tab title="200 Success Response" %}

```json
{
  "status": 200,
  "error": {
    "code": "",
    "message": "",
    "field": ""
  },
  "data": {
    "success": true,
    "message": "Case labels updated successfully",
  }
}
```

{% endtab %}
{% endtabs %}

Error 4xx

| Name                   | Description                                                          |
| ---------------------- | -------------------------------------------------------------------- |
| ParamValidationFailed  | The parameter validation failed.                                     |
| FeatureNotAvailable    | The feature is not available due to the organization's current tier. |
| HeaderValidationFailed | The request header validation failed.                                |
| TierNotSelected        | The organization has not selected a tier.                            |

{% tabs %}
{% tab title="ParamValidationFailed:" %}

```json
{
  "status": 400,
  "error": {
    "code": "40002",
    "message": "Case ID is required",
    "field": "caseID"
  },
  "data": {}
}
```

{% endtab %}

{% tab title="FeatureNotAvailable:" %}

```json
{
  "status": 499,
  "error": {
    "code": "49901",
    "message": "This feature is not available for your current tier",
    "field": ""
  },
  "data": {}
}
```

{% endtab %}

{% tab title="HeaderValidationFailed:" %}

```json
{
  "status": 400,
  "error": {
    "code": "40001",
    "message": "Request headers are required (API-Key)",
    "field": ""
  },
  "data": {}
}
```

{% endtab %}

{% tab title="TierNotSelected:" %}

```json
{
  "status": 499,
  "error": {
    "code": "49900",
    "message": "Please select a tier",
    "field": ""
  },
  "data": {}
}
```

{% endtab %}
{% endtabs %}


# User/Contact API

Use these sets of API if you wish to sync your user or contact into OneTalk's system.

### Request Auth Ticket

Request auth ticket for Live Chat on behalf of the specified user/contact, passing along the user's data to be saved to contacts. The auth ticket can be used to request an access token for Live Chat. An auth ticket is valid for 1 hour before it expires.

{% tabs %}
{% tab title="POST" %}

```
https://onetalk-api.taptalk.io/api/integration/v1/user/request_auth_ticket
```

{% endtab %}
{% endtabs %}

### Header

| Field   | Type   | Description                    |
| ------- | ------ | ------------------------------ |
| API-Key | String | API key for accessing the API. |

### Request

| Field               | Type   | Description                                                                                |
| ------------------- | ------ | ------------------------------------------------------------------------------------------ |
| customerUserID      | String | <p>User ID from customer's server.</p><p>Size Range <code>1..100</code></p>                |
| fullName            | String | <p>The user's full name.</p><p>Size Range <code>1..250</code></p>                          |
| alias (optional)    | String | <p>The user's alias.</p><p>Size Range <code>1..100</code></p>                              |
| email (optional)    | String | <p>The user's email address.</p><p>Size Range <code>1..250</code></p>                      |
| phone (optional)    | String | <p>The user's phone, must start with country code.</p><p>Size Range <code>1..20</code></p> |
| photoURL (optional) | String | The user's picture image URL                                                               |

{% tabs %}
{% tab title="Request Example" %}

```json
{
  "customerUserID": "company:123",
  "fullName": "John Doe",
  "alias": "",
  "email": "john_doe@example.com",
  "phone": "6281234567890",
  "photoURL": "http://www.example.com/photo/john_doe.jpg"
}
```

{% endtab %}
{% endtabs %}

### Success 200

| Field   | Type    | Description                                 |
| ------- | ------- | ------------------------------------------- |
| success | boolean | If successful.                              |
| message | string  | The message.                                |
| userID  | string  | The user ID from OneTalk.                   |
| ticket  | string  | The auth ticket to request an access token. |

{% tabs %}
{% tab title="Success Response" %}

```json
{
  "status": 200,
  "error": {
    "code": "",
    "message": "",
    "field": ""
  },
  "data": {
    "success": true,
    "message": "Contact updated successfully",
    "userID": "354c63e1-2485-4380-b307-4f2ea1ff69d0",
    "ticket": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
  }
}
```

{% endtab %}
{% endtabs %}

### Error 4xx

| Name                   | Description                               |
| ---------------------- | ----------------------------------------- |
| ParamValidationFailed  | The parameter validation failed.          |
| HeaderValidationFailed | The request header validation failed.     |
| TierNotSelected        | The organization has not selected a tier. |

{% tabs %}
{% tab title="ParamValidationFailed" %}

```json
{
  "status": 400,
  "error": {
    "code": "40002",
    "message": "Customer user ID is required",
    "field": "customerUserID"
  },
  "data": {}
}
```

{% endtab %}

{% tab title="HeaderValidationFailed" %}

```json
{
  "status": 400,
  "error": {
    "code": "40001",
    "message": "Request headers are required (API-Key)",
    "field": ""
  },
  "data": {}
}
```

{% endtab %}

{% tab title="TierNotSelected" %}

```json
{
  "status": 499,
  "error": {
    "code": "49900",
    "message": "Please select a tier",
    "field": ""
  },
  "data": {}
}
```

{% endtab %}
{% endtabs %}

### Sync User Contact

Sync a user from the customer's server to OneTalk contacts.

The sync process will check for existing contacts using all the following keys:

* customerUserID (required)
* phone (optional)

If no contact is found, a new contact will be created. If exactly one contact is found using the sync keys, the contact will be updated. If more than one contacts are found, the sync will be rejected because duplicate keys are not allowed.

Customer user ID can't be changed for existing contacts. So, if the existing contact is already tied to a different customer user ID, the sync will be rejected. However, if the existing contact is not tied to any customer user ID yet, it will be updated to the specified `customerUserID`.

{% tabs %}
{% tab title="POST" %}

```
https://onetalk-api.taptalk.io/api/integration/v1/user/sync_contact
```

{% endtab %}
{% endtabs %}

### Header

| Field                   | Description                                     |
| ----------------------- | ----------------------------------------------- |
| API-Key                 | API key for accessing the API.                  |
| Content-Type (optional) | Content type of the request body.               |
| User-Agent (optional)   | The user agent of the client accessing the API. |

### Request

| Field          | Type   | Description                                                                              |
| -------------- | ------ | ---------------------------------------------------------------------------------------- |
| customerUserID | String | <p>UserID from customer's server.<br>Size Range <code>1..100</code></p>                  |
| fullName       | String | <p>The user's full name.<br>Size Range <code>1..100</code></p>                           |
| alias          | String | <p>The user's alias.<br>Size Range <code>1..100</code></p>                               |
| email          | String | <p>The user's email address.<br>Size Range <code>1..100</code></p>                       |
| phone          | String | <p>The user's phone, must start with country code.<br>Size Range <code>1..100</code></p> |
| photoURL       | String | The user's picture image URL.                                                            |

{% tabs %}
{% tab title="Request Example" %}

```go
{
    "customerUserID": "company:123",
    "fullName": "John Doe",
    "alias": "",
    "email": "john_doe@example.com",
    "phone": "6281234567890",
    "photoURL": "http://www.example.com/photo/john_doe.jpg"
}
```

{% endtab %}
{% endtabs %}

### Success 200

| Field   | Type    | Description               |
| ------- | ------- | ------------------------- |
| success | boolean | If saved successfully.    |
| message | string  | The message.              |
| userID  | string  | The user ID from OneTalk. |

{% tabs %}
{% tab title="Success Response" %}

```json
{
  "status": 200,
  "error": {
    "code": "",
    "message": "",
    "field": ""
  },
  "data": {
    "success": true,
    "message": "Contact updated successfully",
    "userID": "354c63e1-2485-4380-b307-4f2ea1ff69d0"
  }
}
```

{% endtab %}
{% endtabs %}

### Error 4xx

| Name                   | Description                                 |
| ---------------------- | ------------------------------------------- |
| ParamValidationFailed  | The parameter validation failed.            |
| HeaderValidationFailed | The request header validation failed.       |
| TierNotSelected        | The organization has not selected the tier. |

{% tabs %}
{% tab title="ParamValidationFailed" %}

```json
{
  "status": 400,
  "error": {
    "code": "40002",
    "message": "Customer user ID is required",
    "field": "customerUserID"
  },
  "data": {}
}
```

{% endtab %}

{% tab title="HeaderValidationFailed" %}

```json
{
  "status": 400,
  "error": {
    "code": "40001",
    "message": "Request headers are required (API-Key)",
    "field": ""
  },
  "data": {}
}
```

{% endtab %}

{% tab title="TierNotSelected" %}

```json
{
  "status": 499,
  "error": {
    "code": "49900",
    "message": "Please select a tier",
    "field": ""
  },
  "data": {}
}
```

{% endtab %}
{% endtabs %}


# Live Chat Widget Callback Function

This documentation provides a flexible set of methods that can be used in your web projects. To invoke one of the methods below, please be sure to call a method after the embed code on your page.

Use this callback functions to manipulate the chat widget displayed on your website.

### OnCreateCase

This callback functions triggered every time the user create a new case

```jsx
<script>
tapliveCallback.tapliveOnCreateCase = (caseModel, fullname, email, url) => {
    // your action here
}
</script>
```

{% hint style="info" %}

#### Returned Parameters

`CaseModel`: (caseModel) data related to case.\
`fullname`: (String) full name of the user.\
`email`: (String) email of the user.\
`url`: (String) the page url when user access the live chat widget.
{% endhint %}

### OnSendMessage

This callback functions triggered every time the user send a message

```jsx
<script>
tapliveCallback.tapliveOnSendMessage = (message, fullname, email, url) => {
    // your action here
}
</script>
```

{% hint style="info" %}

#### Returned Parameters

`message`: (messageModel) data related to message.\
`fullname`: (String) full name of the user.\
`email`: (String) email of the user.\
`url`: (String) the page url when user access the live chat widget.
{% endhint %}

This documentation provides a flexible set of methods that can be used in your web projects. To invoke one of the methods below, please be sure to call a method after the embed code on your page.

Use this callback functions to manipulate the chat widget displayed on your website.

### TapliveIsAuthenticated

This function returns boolean if session is available or not

```jsx
<script>
TapTalkLive.tapliveIsAuthenticated();
</script>
```

### SetForceHide

This function is use to hide the launcher widget

```jsx
<script>
TapTalkLive.setForceHide();
</script>
```

### TapliveRequestAccessToken

This function is use to request taplive access token

```jsx
<script>
TapTalkLive.tapliveRequestAccessToken(key, () => {
    //do action here
});
</script>
```

### SetHideTaplivePower

This functions is use to hide taplive watermark

```jsx
<script>
TapTalkLive.setHideTaplivePower();
</script>
```

### LauncherLogout

This functions is use to logging out launcher widget

```jsx
<script>
TapTalkLive.launcherLogout(() => {
    //do action here
});
</script>
```


# Social Channel Button

You can add a social media channel directly into the OneTalk's live chat widget&#x20;

![OneTalk Live Chat Widget with Social Channel Button](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MgEKHk1i0sifsM-LF2L%2F-MgELaIpY5nIi6RelGsH%2FScreen%20Shot%202021-08-04%20at%2011.09.22.png?alt=media\&token=f5209dc7-05d7-469e-b19e-bd9b7f5ad6ce)

{% hint style="info" %}
**Note:**\
Please make sure you already implement OneTalk's Live Chat Widget. You can implement it[ by following this guide](/onetalk-omnichannel-documentation/onetalk-channel-integration/live-chat/onetalk-web)
{% endhint %}

### Configure Social Channel Button

#### Step 1: Make sure you already implement OneTalk's Live Chat Widget

Please refer to this [documentation](/onetalk-omnichannel-documentation/onetalk-channel-integration/live-chat/onetalk-web) for implementing OneTalk's Live Chat Widget

#### Step 2: Setup The Social Channel Button

In this example, we will add the social channel button for WhatsApp (Please make sure you have already created the WhatsApp channel).

Go to **Integration** > **WhatsApp for SME** > Click the **detail of the Channel**

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MgELjGzlF8scqtb6c8i%2F-MgEOmCN5BkQrbu7ghEe%2FScreen%20Shot%202021-08-04%20at%2011.02.31.png?alt=media\&token=20a8fb87-0b50-48b2-80f2-027105c877a7)

Scroll to **Channel Button** section > Click **Edit**&#x20;

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MgELjGzlF8scqtb6c8i%2F-MgEOysDNQHvVpbE6TFt%2FScreen%20Shot%202021-08-04%20at%2011.02.52.png?alt=media\&token=b4db09bd-cada-4dcd-9fc5-0a79fc4192b7)

Here you can fill **Title**, **Phone** **Number**, and **First** **Message** that will be shown

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MgELjGzlF8scqtb6c8i%2F-MgEPW3OLmFS8_ADGcsP%2FScreen%20Shot%202021-08-04%20at%2011.01.12.png?alt=media\&token=6576e336-022d-4ffd-8248-9e2a5fd9b3d8)

{% hint style="info" %}
If you wish to know where does this customer came from (from which URL), simply check the **"Include current Page URL in message"**
{% endhint %}

Later, it will be shown as below if the user click the **Channel Button**

![Click Channel Button without Include current Page URL](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MgELjGzlF8scqtb6c8i%2F-MgEQTo7O2x3X53uWFVG%2FScreen%20Shot%202021-08-04%20at%2011.29.25.png?alt=media\&token=abffd052-ca04-46e0-8d18-53ed235ed9c8)

![Click Channel Button with Include current Page URL](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MgELjGzlF8scqtb6c8i%2F-MgEQSIgu2_eoMduDFVr%2FScreen%20Shot%202021-08-04%20at%2011.03.44.png?alt=media\&token=c50f1b92-685b-459f-827b-2f8af160ed2f)


# Custom Chatbot Integration

A comprehensive step by step guide on how to integrate a custom chatbot into OneTalk by TapTalk.io


# Get Started

In this article, we will explain how to integrate a custom chatbot into your channel at [OneTalk by TapTalk.io](https://taptalk.io/onetalk).

### **Step 1: Create a Custom Chatbot**

To create a new chatbot, from the Dashboard page, choose **Integration -> Chatbots** and click on **Create Chatbot** button

<figure><img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2FEYAsPGMp5xCsH5QeFQzE%2Fcreate_custom_chatbot-1.png?alt=media&amp;token=e6e459e8-3d99-4bfb-af8a-f56e6f4a1eba" alt=""><figcaption></figcaption></figure>

Choose **Custom Chatbot** from the dropdown in the **Chatbot Type** field

<figure><img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2FtSAGNLUHlhAVcCKvdwZV%2Fphoto_2023-01-13%2021.24.40.jpeg?alt=media&amp;token=6edb7702-ec8d-48a5-97f0-2b6e2e89d2bd" alt=""><figcaption></figcaption></figure>

The **Chatbot URL** field will show up, **Chatbot URL** is the webhook endpoint for your chatbot engine to receive a message.

<figure><img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2F58vlaTDgeLRmHlf13czV%2Fphoto_2023-01-13%2021.24.48.jpeg?alt=media&amp;token=f95ecc9d-be9d-43c9-8aaf-2a134b295c3d" alt=""><figcaption></figcaption></figure>

Click the **Save Changes** Button and your newly created chatbot will show up on the **Chatbots** page.

<figure><img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2FCLZwIWhexigGYxbzfrup%2Fphoto_2023-01-13%2021.24.52.jpeg?alt=media&amp;token=69d73157-5b1e-440c-a54a-61862b67a7a3" alt=""><figcaption></figcaption></figure>

To view the chatbot details, click on the **View** button.

<figure><img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2F949FgvAJnwfCKBLJtyDu%2Fphoto_2023-01-13%2021.31.31.jpeg?alt=media&amp;token=1de3b8cb-e944-4ff2-8776-eca450a0fc31" alt=""><figcaption><p>Chatbot Details Page</p></figcaption></figure>

### **Step 2: Connect Chatbot to Channel**

To connect a chatbot to your channel, from the Dashboard page, select the channel where the chatbot will be connected to in **Channels** section.

<figure><img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2FTMi20sLqlicI70WrZKkJ%2Fconnect_chatbot_to_channel%2014.37.58.jpeg?alt=media&amp;token=5ef9c917-8237-476a-9f4c-34a99b2cdece" alt=""><figcaption></figcaption></figure>

Select your preferred channel, scroll down to the **Chatbot** section and click on the **Set Chatbot** button.

<figure><img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2FnprflpATDZrz5hKYNgb1%2Fconnect_chatbot_to_channel%2014.38.06.jpeg?alt=media&amp;token=f256b7f1-0d01-4021-95d8-d41ca1848fc9" alt=""><figcaption></figcaption></figure>

Select our previously created chatbot from the **Chatbot** **Path** dropdown and click on the **Save Changes** button.

<figure><img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2FhMqvjK0G5VVvv2t4moiT%2Fconnect_chatbot_to_channel%2014.38.13.jpeg?alt=media&amp;token=9bbf4f46-82bd-4b6f-984a-585db50e7076" alt=""><figcaption></figcaption></figure>

Congratulations, your chatbot has been successfully connected to your channel.

<figure><img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2F6id7dTZ1qd7KzzxighIM%2Fconnect_chatbot_to_channel%2014.38.18.jpeg?alt=media&amp;token=6a086bc9-e763-468f-9ee1-5069bc8d1495" alt=""><figcaption></figcaption></figure>


# Edit or Delete Chatbot

You can make an update to your chatbot details and config by going to **Chatbot List** page, then clicking on the **View** Icon Button to go to the **Chatbot Details** page.

<figure><img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2FCLZwIWhexigGYxbzfrup%2Fphoto_2023-01-13%2021.24.52.jpeg?alt=media&amp;token=69d73157-5b1e-440c-a54a-61862b67a7a3" alt=""><figcaption></figcaption></figure>

On the **Chatbot Details** page, you will see two sections, **Chatbot Details** section, and **Chatbot Configs** section.&#x20;

<figure><img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2Fcx1BZzm4cGlDcS6Jt7Ik%2Fphoto_2023-01-13%2021.24.56.jpeg?alt=media&amp;token=7fe475a0-a1dc-4d13-9cea-7f87caa88d32" alt=""><figcaption></figcaption></figure>

The **Chatbot Details** section will contain the basic information about your chatbots such as **Chatbot Name** and **Chatbot Type.** You can choose to edit your chatbot name or delete your chatbot.

<figure><img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2FEH60LPO6iOsmJXPcYG3p%2Fphoto_2022-12-14%2017.29.54.jpeg?alt=media&amp;token=4d0cf9de-ec7d-428d-aad6-b6d87de18fb8" alt=""><figcaption></figcaption></figure>

The **Chatbot Configs** section will contain the configuration information of your chatbot, there are the **Chatbot URL**, **Webhook URL**, and **Secret Key** field. By clicking on the **Edit** button, you can update the **Chatbot URL** of your chatbot.

<figure><img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2F949FgvAJnwfCKBLJtyDu%2Fphoto_2023-01-13%2021.31.31.jpeg?alt=media&amp;token=1de3b8cb-e944-4ff2-8776-eca450a0fc31" alt=""><figcaption></figcaption></figure>

If you click the **Delete** button in the **Chatbot Details** section, you will be prompted with a deletion confirmation pop-up. If you wish to delete your chatbot then click on the **Delete Chatbot** button.

<figure><img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2FUm54b6qZvnDRaUhVxFG3%2Fphoto_2022-12-14%2017.34.11.jpeg?alt=media&amp;token=901eedfb-8590-4537-a0c0-a4e3715cd152" alt=""><figcaption></figcaption></figure>


# Development

To develop Inbound messages and Webhooks please refer to this link: <https://taptalk-io.github.io/onetalk/chatbot/custom-chatbot.html>


# QnA via API

In this documentation, we will explain how to integrate a QnA via API in your QnA Path.

QnA via API is useful for organizations that wanted to make an QnA Path but need to answer the recipients with dynamic data.

Head to "Setup" and click "QnA Path" and create QnA Path

<figure><img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2F8WBjs11nRA44sUbejGNk%2Fimage.png?alt=media&amp;token=e0da9f1a-8410-4b3d-b8b5-58512243a986" alt=""><figcaption></figcaption></figure>

<figure><img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2FXdbWSjzBxb865RMFlKE6%2Fimage.png?alt=media&amp;token=0481d823-c7e0-4c93-a120-3a80c4f54f11" alt=""><figcaption></figcaption></figure>

Input title and choose "QnA via API" as the QnA type

<figure><img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2FKGTcmeIjkqeiainNRLqd%2Fimage.png?alt=media&amp;token=07e4e932-3b2a-44a8-8ec6-204f732c6dc9" alt=""><figcaption></figcaption></figure>

Insert your URL to the field and you can test API call to the url that you provided to see if the reply is correct.

Below is the example POST request payload that our system will send to the url that you have input:

```
{
  "caseID": "ABCD1234", // optional
  "channelType": "telegram|whatsapp|whatsappba|facebook|instagram|launcher|etc..."
  "contact": { // optional
    "customerUserID": "",
    "fullName": "John Doe",
    "alias": "",
    "phone": "" //optional
  }
}

```

Your API must return response with this payload when called:

```
{
  "type": "text|document|image|video",
  "text": { // if type = text
    "body": "Lorem ipsum dolor..."
  },
  "document": { // if type = document
    "url": "https://www.example.com/document.pdf",
    "filename": "Document.pdf",
    "caption": "Please see the attached document..."
  },
  "image": { // if type = image
    "url": "https://www.example.com/image.jpg",
    "caption": "Please see the image..."
  },
  "video": { // if type = video
    "url": "https://www.example.com/video.mp4",
    "caption": "Please watch the video for tutorial..."
  }
}
```

if the API call failed, our system will not send the error to your recipients, instead we will send a message that you have input in "Reply message on API error" field. But if you leave this fielf blank, then we will not reply anything to recipients.

<figure><img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2FSOnXU6VaVGLxiKkXDMUz%2Fimage.png?alt=media&amp;token=402cc4a6-e045-4bd9-92ce-e0a7c042959a" alt=""><figcaption></figcaption></figure>

Click "Create" on the top right corner to finalize creating a QnA via API.


# Webhook

In this documentation, we will explain how to use webhook in OneTalk.

Head to "Integration" and click "Webhooks" and you can start setup a webhook by clicking "Set" on the top right corner.

<figure><img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2FMpPpBryHHhGx6bQAOxQA%2Fimage.png?alt=media&amp;token=7e0f967c-72ee-480e-bffa-906d99fb7b10" alt=""><figcaption></figcaption></figure>

Enable the webhook and input "Webhook URL" field

<figure><img src="https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2FsNU7asbRlS0RUtdhwwdl%2Fimage.png?alt=media&amp;token=eb176d1e-6513-404a-b42b-bd4cf95a1710" alt=""><figcaption></figcaption></figure>

Next, you will have to choose a minimum of 1 event on "Subscribed Events" and click "Save Changes" to finalize your webhook.

## Webhook Events

### Integration Message Status

this webhook event updates your system about the change in status of messages sent via [Integration API](https://docs.taptalk.io/~/changes/FMvVnz8ZkLFBmR0Wx2wq/onetalk-omnichannel-documentation/onetalk-integration-api/inbox-api).

Request payload example:

<table><thead><tr><th width="245">Field</th><th width="119">Type</th><th>Description</th></tr></thead><tbody><tr><td>type</td><td>string</td><td>Type of webhook event</td></tr><tr><td>integrationMessageStatus</td><td>object</td><td>Contains data of webhook event</td></tr><tr><td>          channelID</td><td>string</td><td>Channel ID</td></tr><tr><td>          channelType</td><td>string</td><td>Channel type</td></tr><tr><td>          contactPhone</td><td>string</td><td>Recipient's phone number</td></tr><tr><td>          reason</td><td>string</td><td>Failed reason</td></tr><tr><td>          status</td><td>string</td><td>Status update on the message</td></tr><tr><td>          timestamp</td><td>timestamp</td><td>Timestamp on the status update</td></tr><tr><td>          trxID</td><td>string</td><td>Transaction ID</td></tr><tr><td>organizationID</td><td>int</td><td>Organization ID</td></tr></tbody></table>

```
{
  "type": "integration_message_status",
  "integrationMessageStatus": { 
    "channelID": "0123456",
    "channelType": "whatsapp|whatsappba",
    "contactPhone": "628123456789",
    "reason": "...",
    "status": "acknowledge|delivered|read|failed",
    "timestamp": 1587352926788,
    "trxID": "000000-0000-0000-0000-000000"
  },
  "organizationID": 1111
}
```

Status 'acknowledge' is updated when WhatsApp has received OneTalk's request to send the message.

Status 'delivered' is updated when WhatsApp recipient has received the message.

Status 'read' is upated when WhatsApp recipient has read the message.

Status 'failed' is updated when there's an error either from TapTalk.io's system or WhatsApp's system.

### Case Resolved

this webhook event updates your system about the changed in case status to "Resolved" in your organization.

Request payload example:

<table><thead><tr><th width="318">Field</th><th width="117">Type</th><th>Description</th></tr></thead><tbody><tr><td>organizationID</td><td>int</td><td>Organization ID</td></tr><tr><td>type</td><td>string</td><td>Type of webhook event</td></tr><tr><td>caseResolved</td><td>object</td><td>Contains data of webhook event</td></tr><tr><td>          caseID</td><td>string</td><td>Case ID</td></tr><tr><td>          channelType</td><td>string</td><td>Channel type</td></tr><tr><td>          channelID</td><td>string</td><td>Channel ID</td></tr><tr><td>          topicID</td><td>string</td><td>Topic ID</td></tr><tr><td>          topicName</td><td>string</td><td>Topic Name</td></tr><tr><td>          assigneeType</td><td>string</td><td>Type of case last assigned to</td></tr><tr><td>          chatbotID</td><td>string</td><td>Chatbot ID if assigned to bot</td></tr><tr><td>          chatbotName</td><td>string</td><td>Chatbot name id assigned to bot</td></tr><tr><td>          agentEmail</td><td>string</td><td>Agent's email if assigned to agent</td></tr><tr><td>          agentFullName</td><td>string</td><td>Agent's name if assigned to agent</td></tr><tr><td>          isJunk</td><td>boolean</td><td>Junk status</td></tr><tr><td>          agentRemark</td><td>string</td><td>Agent's remark on the case</td></tr><tr><td>          createdTime</td><td>timestamp</td><td>Created time</td></tr><tr><td>          counterStartTime</td><td>timestamp</td><td>The time to start counting duration from, in Unix milliseconds.</td></tr><tr><td>          firstResponseTime</td><td>timestamp</td><td>First response time by agent</td></tr><tr><td>          resolvedTime</td><td>timestamp</td><td>Case resolved time</td></tr><tr><td>          isResolvedByAgent</td><td>boolean</td><td>If case resolved by an agent</td></tr><tr><td>          isResolvedByChatbot</td><td>boolean</td><td>If case resolved by a bot</td></tr><tr><td>          isResolvedByContact</td><td>boolean</td><td>If case resolved by contact</td></tr><tr><td>          isResolvedBySystem</td><td>boolean</td><td>If case resolved by system</td></tr><tr><td>          labels</td><td>array</td><td>Array of labels tagged on the case</td></tr><tr><td>          contact</td><td>object</td><td>Contains data of contact</td></tr><tr><td>                    id</td><td>string</td><td>Contact ID</td></tr><tr><td>                    fullName</td><td>string</td><td>Contact's full name</td></tr><tr><td>                    alias</td><td>string</td><td>Contact's alias</td></tr><tr><td>                    email</td><td>string</td><td>Contact's email</td></tr><tr><td>                    phone</td><td>string</td><td>Contact's phone number</td></tr><tr><td>                    customerUserID</td><td>string</td><td>the userID from customer's server</td></tr><tr><td>                    companyName</td><td>string</td><td>Contact's company name</td></tr><tr><td>                    jobTitle</td><td>string</td><td>Contact's job title</td></tr><tr><td>                    agentRemark</td><td>string</td><td>Agent's remark on the contact</td></tr><tr><td>                    customField</td><td>object</td><td>Contains objects of custom field if  there's one or more custom field in the organization</td></tr><tr><td>                         *Field Code*</td><td>object</td><td>Custom field's field code</td></tr><tr><td>                              fieldType</td><td>string</td><td>Custom field's type</td></tr><tr><td>                              value</td><td>string</td><td>Custom field's value</td></tr></tbody></table>

```
{
    "organizationID": 1,
    "type": "case_resolved",
    "caseResolved": {
      "caseID": "958CCF3BB6",
      "channelType": "whatsapp",
      "channelID": "166090",
      "topicID": 1,
      "topicName": "Finance",
      "assigneeType": "agent",
      "chatbotID": "",
      "chatbotName": "",
      "agentEmail": "john@example.com",
      "agentFullName": "John",
      "isJunk": false,
      "agentRemark": "Hello world 3",
      "createdTime": 1589354307263,
      "counterStartTime": 1589354307263,
      "firstResponseTime": 1589355184000,
      "resolvedTime": 1615305000400,
      "isResolvedByAgent": true,
      "isResolvedByChatbot": false,
      "isResolvedByContact": false,
      "isResolvedBySystem": false,
      "labels": [
        "follow up",
        "hello world"
      ],
      "contact": {
        "id": "e148aa04-3e8f-4dd9-82c1-e53c1a93eac1",
        "fullName": "John Doe",
        "alias": "John",
        "email": "",
        "phone": "6281234567890",
        "customerUserID": "johndoe",
        "companyName": "",
        "jobTitle": "",
        "agentRemark": "",
        "customFields": {
          "customer_id": {
            "fieldType": "single_line",
            "value": ""
          },
          "deal_amount": {
            "fieldType": "number",
            "value": ""
          },
          "salutation": {
            "fieldType": "dropdown",
            "value": ""
          }
        }
      }
    }
  }
```


# Getting Started with PowerTalk

PowerTalk is an In-app chat framework for you to integrate the chat features into your apps.

Currently, you can implement the PowerTalk SDK into your iOS Apps, Android Apps, and Website using our Javascript SDK.

Please refer to these sections for more information to integrate with PowerTalk SDK.\
[iOS PowerTalk Documentation](/powertalk-chat-sdk-documentation/powertalk-ios/get-started)\
[Android PowerTalk Documentation](/powertalk-chat-sdk-documentation/powertalk-android/get-started)\
[Web (Javascript SDK) PowerTalk Documentation](/powertalk-chat-sdk-documentation/powertalk-javascript-sdk/get-started)\
[Server API PowerTalk Documentation](/powertalk-chat-sdk-documentation/powertalk-server-api/get-started)


# PowerTalk Android

TapTalk.io helps you to implement real-time chat with any type of your client app with speed and efficiency. Our Android SDK provides you with various methods to initialize, configure, and build the chat from the client-side - no server-side implementation is required because our reliable infra management service is delivered with the SDK. This page presents a brief overview of the SDK’s structure and abilities, then lets you go through the preliminary steps of implementing the SDK in your own app.


# Get Started

## Configure and Initialize TapTalk.io Android SDK

#### **Step 1: Create a new application from your dashboard**

**1.** Login to [TapTalk.io Dashboard](https://taptalk.io/), then choose **Development** -> **Apps**

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MHKsq4vOlouRa03adbb%2F-MHKvQJYwokZj2SvRd6U%2F08a4ad0-Screenly_-_9.0_Development_-_Apps_-_Empty_State2x.png?alt=media\&token=6f629f44-d932-400f-984d-2fb1a1f0e408)

**2**. Click **New App** Button, input **App Name** and choose **Platform**, and then click **Create New App** Button.

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MHKsq4vOlouRa03adbb%2F-MHKxC_cD1-kv3lPxiSk%2F58201a8-Screenly_-_9.1.0_Development_-_Apps_-_New_App_-_Empty_State2x.png?alt=media\&token=ab2fe069-a0b6-4d22-86d3-fdd8e51c235f)

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MHKsq4vOlouRa03adbb%2F-MHKxGJV7RBtqLBu8UwT%2Ff2a1418-Screenly_-_9.1.1_Development_-_Apps_-_New_App_-_Filled2x.png?alt=media\&token=5b628aa3-05ec-47e9-98ef-dbc2c23de5bc)

**3.** A pop-up dialog will be shown with provided **App Key ID** & **App Key Secret**

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MHKsq4vOlouRa03adbb%2F-MHKxQLyhxLOunGM05hx%2Ff869a40-Screenly_-_9.1.3_Development_-_Apps_-_New_App_-_Your_App_Key_-_Dismiss2x.png?alt=media\&token=b7bfb1cb-65ff-47e6-beda-69011f5addb8)

{% hint style="warning" %}
**Note:** Please remember to save your **App Key ID** & your **App Key Secret** because it will only be shown once and will be used in TapTalk.io initialization
{% endhint %}

#### Step 2: Install TapTalk.io SDK

To start, open your Android project and add the following repositories to your **top-level** build.gradle file.Project build.gradle

{% code title="build.gradle (project)" %}

```groovy
allprojects {
    repositories {
        google()
        mavenCentral()
        maven {
            url = "https://jitpack.io"
        }
        maven {
            url = "https://s3.amazonaws.com/repo.commonsware.com"
        }
    }
}
```

{% endcode %}

Then add the following dependency to your **app-level** build.gradle:

{% code title="build.gradle (:app)" %}

```groovy
dependencies {
    implementation("com.github.taptalk-io:taptalk.io-android:3.0.0")
}
```

{% endcode %}

{% hint style="info" %}
You can check a more updated version release notes of the SDK [here](https://github.com/taptalk-io/taptalk.io-android/releases).
{% endhint %}

In the app build.gradle file, make sure that your project is using the supported Java version like below.

{% code title="build.gradle (:app)" %}

```groovy
android {
    ...
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_17
        targetCompatibility = JavaVersion.VERSION_17
    }
}
```

{% endcode %}

#### Step 3: Initialize TapTalk.io in your Application class

In order to use TapTalk.io, you must first initialize a TapTalk instance by passing the `APP_ID`, `APP_SECRET`, `APP_ICON`, `APP_BASE_URL`, and `IMPLEMENTATION_TYPE` assigned to your application to the `init` method as a parameter. Generally, initialization is implemented in the **Application** class in your project.

{% hint style="warning" %}
**Note:** To get **BASE\_URL** you can follow our documentation on [how to get Base URL](/powertalk-chat-sdk-documentation/powertalk-server-api/base-url) on TapTalk.io
{% endhint %}

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Helper.TapTalk;
import io.taptalk.TapTalk.Listener.TapListener;

...

TapTalk.init(
    CONTEXT, 
    APP_KEY_ID, 
    APP_KEY_SECRET,            
    APP_ICON, 
    APP_NAME, 
    APP_BASE_URL,            
    IMPLEMENTATION_TYPE, 
    tapListener
);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Helper.TapTalk
import io.taptalk.TapTalk.Listener.TapListener

...

TapTalk.init(
  CONTEXT, 
  APP_KEY_ID, 
  APP_KEY_SECRET,            
  APP_ICON, 
  APP_NAME, 
  APP_BASE_URL,            
  IMPLEMENTATION_TYPE, 
  tapListener
)
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**CONTEXT**: (Context) application context\
**APP\_KEY\_ID**: (String) application key ID\
**APP\_KEY\_SECRET**: (String) application key Secret\
**APP\_ICON**: (int) drawable resource ID\
**APP\_NAME**: (String) your application name\
**APP\_BASE\_URL**: (String) base API URL\
**IMPLEMENTATION\_TYPE**: (enum) found in TapTalkImplentationType, more detailed information below\
**tapListener**: (TapListener) an interface to detect TapTalk Android SDK's delegates and callbacks
{% endhint %}

{% hint style="info" %}
**IMPLEMENTATION\_TYPE**\
TapTalkImplementationType consists of 3 types which are:\
**`TapTalkImplementationTypeUI`**: used for implementation with only TapUI\
**`TapTalkImplementationTypeCore`**: used for implementation with only TapCore\
**`TapTalkImplementationTypeCombine`**: used for implementation with both of TapCore and TapUI combined
{% endhint %}

{% hint style="info" %}
**Note**: In the [Event Listener](/powertalk-chat-sdk-documentation/powertalk-android/event-listener) page, you can find detailed information on the usages of TapTalk Android SDK's delegates and callbacks.
{% endhint %}

#### Step 4: Enable Chat Features

Please follow the steps in [Enable Chat Features](/powertalk-chat-sdk-documentation/powertalk-android/enable-chat-features) page to enable TapTalk.io's chat features, such as contact sync and sending media, document, and location messages.

#### Step 5: Authenticate to TapTalk.io

In order to use the abilities of the Android SDK in your client app, a TapTalk instance must be initiated in each client app through user authentication with TapTalk.io server. An authenticated user account allows the instance to communicate and interact with the server. To authenticate your user with the server, follow the instructions in [Authentication page](/powertalk-chat-sdk-documentation/powertalk-android/authentication).

### Open Your First Room List

To open room list view, you can simply use the `openRoomList()` method in the **TapUI** class. Creating a user interface won't be necessary, because TapTalk.io have provided an integrated user interface to be used in your application. To use TapTalk.io's chat interface, simply initialize our **TapUI** method and you are good to go. For more information about TapUI and TapCore, please see [TapUI and TapCore page](/powertalk-chat-sdk-documentation/powertalk-android/tapui-and-tapcore). In this example, we will open the room list view directly in your application's **MainActivity** `onCreate()` method.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Helper.TapTalk;
import io.taptalk.TapTalk.Manager.TapUI;

...

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
      
    if (TapTalk.isAuthenticated()) {
        // Show room list if authentication is completed
        TapUI.getInstance().openRoomList(this);
    }
    else {
        // Authentication is required
    }
    finish();
}
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Helper.TapTalk
import io.taptalk.TapTalk.Manager.TapUI

...

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
      
    if (TapTalk.isAuthenticated()) {
        // Show room list if authentication is completed
        TapUI.getInstance().openRoomList(this)
    }
    else {
        // Authentication is required
    }
    finish()
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Note**: For more information about Room List View for TapUI, please see [Room List section.](/powertalk-chat-sdk-documentation/powertalk-android/room-list)
{% endhint %}


# Enable Chat Features

Please follow the following steps to enable TapTalk.io's chat features, such as contact sync and sending media, document, and location messages.

### Add Permissions

Some of TapTalk.io's chat feature may require permissions to be added to your app. To do so, open **AndroidManifest.xml** file in your project and add the following permissions under the `<manifest>` tag if they are not yet present:

{% code title="AndroidManifest.xml" %}

```xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="your.package.name">

    <!--Permission for contact sync-->
    <uses-permission android:name="android.permission.READ_CONTACTS" />

    <!--Permission for media messages-->
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <!--Permission for location messages-->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

    <!--Permission for voice messages-->
    <uses-permission android:name="android.permission.RECORD_AUDIO"/>
    
    <!--Allow send images from camera-->
    <uses-feature
        android:name="android.hardware.camera"
        android:required="false" />
    
    ...
    
</manifest>
```

{% endcode %}

### Setup FileProvider in your application

To enable file transfer through chat messages, you need to define FileProvider in your application's **AndroidManifest.xml** file, under the `<application>` tag.

{% code title="AndroidManifest.xml" %}

```xml
<application
    android:name=".YourApplication"
    ...>

    <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="${applicationId}.fileprovider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths" />
    </provider>

</application>
```

{% endcode %}

If your project already has defined paths, make sure the following paths exist in your paths xml file:

{% code title="your\_file\_paths.xml" %}

```xml
<paths>
    <files-path name="YourFilesPath" path="." />
    <external-path name="YourExternalPath" path="." />
    <cache-path name="YourCachePath" path="."/>
    <external-files-path name="YourExternalFilesPath" path="."/>
    <external-cache-path name="YourExternalCachePath" path="."/>
</paths>
```

{% endcode %}

### Initialize Google Places API Key (Optional)

To enable location search result preview while sending location message, a Google Places API Key is required. To obtain the API key for your application, you can check [the documentation](https://developers.google.com/places/web-service/get-api-key) provided by Google. To initialize, insert your obtained key using the `initializeGooglePlacesApiKey()` method.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Helper.TapTalk;

TapTalk.initializeGooglePlacesApiKey(GOOGLE_PLACES_API_KEY);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Helper.TapTalk

TapTalk.initializeGooglePlacesApiKey(GOOGLE_PLACES_API_KEY)
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
Starting from version **2.16.0**, chat room location attachment will be enabled by default even when Google Places API Key is not provided, but location search will be hidden.\
To disable location attachment, you may call:

```java
TapUI.getInstance().setLocationAttachmentEnabled(false);
```

{% endhint %}

Your key also needs to be defined in your application's **AndroidManifest.xml** file, under the `<application>` tag.

{% code title="AndroidManifest.xml" %}

```xml
<application
    android:name=".YourApplication"
    ...>

    <meta-data
        android:name="com.google.android.geo.API_KEY"
        android:value="GOOGLE_PLACES_API_KEY" />

</application>
```

{% endcode %}

{% hint style="info" %}
**Parameters**\
**GOOGLE\_PLACES\_API\_KEY**: (String) Google Places API Key
{% endhint %}

### Enable Cleartext Traffic

To enable some network features, such as sending link preview in messages, please enable `usesCleartextTraffic` in **AndroidManifest.xml** file.

{% code title="AndroidManifest.xml" %}

```xml
<application
    android:name=".YourApplication"
    ...
    android:usesCleartextTraffic="true">

    ...

</application>
```

{% endcode %}


# Authentication

In order to use the abilities of the iOS SDK in your client app, a TapTalk instance must be initiated in each client app through user authentication with TapTalk.io server. An authenticated user account allows the instance to communicate and interact with the server. The following explains how to authenticate your user with the server.

![TapTalk.io's Authentication Flow](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MHKsq4vOlouRa03adbb%2F-MHLTpHao9rfmA05gZO6%2F3cee4ff-Login_Flow2x.png?alt=media\&token=e252a825-bf44-49ef-954d-f2c4a841f154)

When the user logs in to your application, your backend server will have to request an **Authentication Ticket** from TapTalk.io server. TapTalk.io server will return the requested **Authentication Ticket** and **user ID** to your backend server. The client application (iOS or Android) can then retrieve the ticket from your backend server to implement TapTalk.io's SDK by initializing the SDK using the obtained **Authentication Ticket**.

You can see the documentation on how to obtain Authentication Ticket from TapTalk.io's Server on the [Authentication in TapTalk.io's Server API page](/powertalk-chat-sdk-documentation/powertalk-server-api/authentication).

### Authenticate to TapTalk.io server with an Authentication Ticket

{% hint style="warning" %}
**Note:** authentication should only be called once before the user is logged in or when the callback `onTapTalkRefreshTokenExpired()` is triggered in TapListener
{% endhint %}

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Helper.TapTalk;
import io.taptalk.TapTalk.Listener.TapCommonListener;

...

TapTalk.authenticateWithAuthTicket(AUTH_TICKET, CONNECT_ON_SUCCESS, new TapCommonListener() {
    @Override
    public void onSuccess(String successMessage) {
        // Authentication successful
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Helper.TapTalk
import io.taptalk.TapTalk.Listener.TapCommonListener

...

TapTalk.authenticateWithAuthTicket(AUTH_TICKET, CONNECT_ON_SUCCESS, object : TapCommonListener() {
    override fun onSuccess(successMessage: String?) {
        // Authentication successful
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
`AUTH_TICKET` : (String) an authentication ticket is required for this method\
`CONNECT_WHEN_SUCCESS`: (BOOL) if set to YES, application will connect to TapTalk.io server after authentication is successfully completed
{% endhint %}

### Check Authentication Status

You can check authentication status by calling **`isAuthenticated()`** method

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Helper.TapTalk;

...

boolean isAuthenticated = TapTalk.isAuthenticated();
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Helper.TapTalk

...

var isAuthenticated = TapTalk.isAuthenticated()
```

{% endtab %}
{% endtabs %}

### Logout and Clear TapTalk.io Data

Call this method when you need to logout and clear all local cached data from TapTalk.io.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Helper.TapTalk;

...

// Logout from TapTalk.io
TapTalk.logoutAndClearAllTapTalkData();
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Helper.TapTalk;

...

// Logout from TapTalk.io
TapTalk.logoutAndClearAllTapTalkData()
```

{% endtab %}
{% endtabs %}

### Clear TapTalk.io Data

You can clear all TapTalk.io local cached data by calling `clearAllTapTalkData()` method.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Helper.TapTalk;

...

TapTalk.clearAllTapTalkData();
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Helper.TapTalk

...

TapTalk.clearAllTapTalkData()
```

{% endtab %}
{% endtabs %}


# TapUI and TapCore

There are three options to implement TapTalk.io chat framework to your application:

* **UI implementation method**: the go-to option to quickly integrate TapTalk.io to your app, uses the default user interface that is managed by the **TapUI** class.
* **Core implementation method**: a more advanced option to integrate TapTalk.io, which gives you more control over TapTalk.io functions. This method makes use of the **TapCore** classes to manage the chat functions inside the application.
* **Combined implementation method**: an implementation method that uses both **TapUI** and **TapCore**.

### What is TapUI?

TapUI is the manager class that is used to manage the **user interface** in UI implementation method. UI implementation is made to be the **easiest** and **quickest** method for developers to implement Taptalk.io chat framework in their application. Taptalk.io provides a default chat **user interface** so you are not required to create your own chat user interface as is usually done when implementing other chat SDK. TapUI also allows you to customize the chat appearance in your application so that it is not only easy and quick in integration, but will also fit your application's appearance with our **customizable theme**.

### What is TapCore?

TapCore is the manager class to manage **chat functions** for applications that use TapTalk.io core implementation method. While UI implementation gives you easiness and quickness in integration, Core implementation will give you more control over Taptalk.io's **more advanced functions**. You can **create your own chat user interface** as you wish, and also **customize your own chat logic** according to your needs. TapCore provides you the necessities to integrate TapTalk.io chat framework to your application.


# Background Process in TapTalk.io

An application integrated with TapTalk.io framework will keep executing some certain tasks even when the app is on the background if the conditions are met, this is done to make sure that the users' chat experience proceed smoothly. The background services will be automatically terminated once all the tasks are completed or reached a timeout. The following are the processes that is required to run in the background:

### Pending Messages Queue

Messages that the user is going to send are placed into a queue before they are sent to the server. If the app enters background when unsent messages exist in this queue, TapTalk.io services will keep running until all the pending messages are delivered to the server and all other tasks are completed.

### File Downloads

When a user-initiated file download from TapTalk.io, such as file message or video message, is in progress, TapTalk.io will preserve the download progress even if the app is moved to background. The services will stop once all the file downloads and other tasks are finished.

### File Uploads

TapTalk.io background process will also be kept running in background when user is sending messages with attachment, such as image, video, and file messages. The services will stop once all the file uploads and other tasks are finished.


# Connection

### Connect to TapTalk.io server

You can manually connect to TapTalk.io by calling `connect()` method.

{% hint style="warning" %}
**Note:** Please make sure that you have finished authentication by calling `authenticate()`method, otherwise, it will return an error
{% endhint %}

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Helper.TapTalk;
import io.taptalk.TapTalk.Listener.TapCommonListener;

...

TapTalk.connect(new TapCommonListener() {
    @Override
    public void onSuccess(String successMessage) {
        // Successfully connected to TapTalk.io server
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Helper.TapTalk
import io.taptalk.TapTalk.Listener.TapCommonListener

...

TapTalk.connect(object : TapCommonListener() {
    override fun onSuccess(successMessage: String?) {
        // Successfully connected to TapTalk.io server
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

### Disconnect from TapTalk.io server

You can disconnect from TapTalk.io when the user no longer needs to receive messages from an online state. But the user can still receive push notifications for new messages when the app is closed.

When the user is disconnected from the server, all event delegates will stop receiving event callbacks from the server.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Helper.TapTalk;

...

TapTalk.disconnect();
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Helper.TapTalk

...

TapTalk.disconnect()
```

{% endtab %}
{% endtabs %}

### Check Connection Status

You can check whether you are connected to TapTalk.io server by calling **`isConnected()`** method.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Helper.TapTalk;

...

boolean isConnected = TapTalk.isConnected();
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Helper.TapTalk

...

var isConnected = TapTalk.isConnected()
```

{% endtab %}
{% endtabs %}

### Enable / Disable Auto Connect

You can choose to enable or disable auto connect by calling these methods. TapTalk.io will automatically connect to the server every time the user opens the app from the background when auto connect is enabled. Please note that the **default value** is **enabled**.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Helper.TapTalk;

...

@Override
public void onCreate() {
    ...
    
    // Call this method to enable or disable auto connect
    // The default value is set to enabled if you do not set this method
    TapTalk.setAutoConnectEnabled(IS_ENABLED);
}
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Helper.TapTalk

...

override fun onCreate(savedInstanceState: Bundle?) {
    ...
    
    // Call this method to enable or disable auto connect
    // The default value is set to enabled if you do not set this method
    TapTalk.setAutoConnectEnabled(IS_ENABLED)
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}

#### Parameters

`IS_ENABLED`: (BOOL) set to true to enable auto connect to TapTalk server
{% endhint %}

### Get Auto Connect Status

Use this method to obtain auto connect status. This method will return **`true`** if auto connect is enabled

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Helper.TapTalk;

...

boolean isAutoConnectEnabled = TapTalk.isAutoConnectEnabled();
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Helper.TapTalk

...

var isAutoConnectEnabled = TapTalk.isAutoConnectEnabled()
```

{% endtab %}
{% endtabs %}


# Event Listener

The Android SDK provides interfaces to listen to various events on the client app. Through these interfaces, TapTalk.io notifies the client app of events that happen on your app. You will need to register the listener objects to receive event callbacks from TapTalk.io.

| Event Listener                                                                                                            | Description                                                                               |
| ------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
| [TapListener](/powertalk-chat-sdk-documentation/powertalk-android/event-listener#taplistener)                             | Listens to general event changes in the application                                       |
| [TapUIRoomListListener](/powertalk-chat-sdk-documentation/powertalk-android/event-listener#tapuiroomlistlistener)         | Listens to UI-related events in **Room List View** when UI implementation type is used    |
| [TapUIChatRoomListener](/powertalk-chat-sdk-documentation/powertalk-android/event-listener#tapuichatroomlistener)         | Listens to UI-related events in **Chat Room View** when UI implementation type is used    |
| [TapUIChatProfileListener](#tapuichatprofilelistener)                                                                     | Listens to UI-related events in **Chat Profile View** when UI implementation type is used |
| [TapUIMyAccountListener](#tapuimyaccountlistener)                                                                         | Listens to UI-related events in **My Account View** when UI implementation type is used   |
| [TapCustomKeyboardListener](/powertalk-chat-sdk-documentation/powertalk-android/event-listener#tapcustomkeyboardlistener) | Listens to custom keyboard-related events when UI implementation type is used             |
| [TapCoreMessageListener](/powertalk-chat-sdk-documentation/powertalk-android/event-listener#tapcoremessagelistener)       | Listens to events when a new/updated message is received by the application               |
| [TapCoreRoomListListener](#tapcoreroomlistlistener)                                                                       | Listens to changes to chat room's state in the room list                                  |
| [TapCoreChatRoomListener](/powertalk-chat-sdk-documentation/powertalk-android/event-listener#tapcorechatroomlistener)     | Listens to room status events such as typing events and online status                     |
| [TapCoreContactListener](#tapcorecontactlistener)                                                                         | Listens to contact related events such as block or unblock contact                        |

### TapListener

General events such as notifications will be notified through TapListener. A TapListener instance is required when initializing TapTalk.

We strongly suggest to override `onTapTalkRefreshTokenExpired` to handle authentication when the user's session has expired.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Helper.TapTalk;
import io.taptalk.TapTalk.Listener.TapListener;
import io.taptalk.TapTalk.Model.TAPMessageModel;

...

TapListener tapListener = new TapListener() {
    @Override
    public void onInitializationCompleted(String instanceKey) {
        // Initialization process has finished
    }
    
    @Override
    public void onTapTalkRefreshTokenExpired() {
        // Authentication is needed
    }

    @Override
    public void onTapTalkUnreadChatRoomBadgeCountUpdated(int unreadCount) {
        // Returns number of unread messages from the application
    }

    @Override
    public void onNotificationReceived(TAPMessageModel message) {
        // A new message from TapTalk.io is received
    }

    @Override
    public void onUserLogout() {
        // User has finished logging out from TapUI or TapTalk.logoutAndClearAllTapTalkData() process has completed
    }
  
    @Override
    public void onTaskRootChatRoomClosed(Activity activity) {
        // A chat room activity was closed by user when no other activity in the application is present
        // You may start another activity to keep the app open, otherwise the app will stay closed
    }
};

TapTalk.init(
  CONTEXT, 
  APP_KEY_ID, 
  APP_KEY_SECRET,            
  APP_ICON, 
  APP_NAME, 
  APP_BASE_URL,            
  IMPLEMENTATION_TYPE, 
  tapListener
);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Helper.TapTalk
import io.taptalk.TapTalk.Listener.TapListener
import io.taptalk.TapTalk.Model.TAPMessageModel

...

var tapListener: TapListener = object : TapListener() {
    override fun onInitializationCompleted(instanceKey: String) {
        // Initialization process has finished
    }
    
    override fun onTapTalkRefreshTokenExpired() {
        // Authentication is needed
    }

    override fun onTapTalkUnreadChatRoomBadgeCountUpdated(unreadCount: Int) {
        // Returns number of unread messages from the application
    }

    override fun onNotificationReceived(message: TAPMessageModel?) {
        // A new message from TapTalk.io is received
    }
    
    override fun onUserLogout() {
        // User has finished logging out from TapUI or TapTalk.logoutAndClearAllTapTalkData() process has completed
    }
  
    override fun onTaskRootChatRoomClosed(activity: Activity?) {
        // A chat room activity was closed by user when no other activity in the application is present
    }
}

TapTalk.init(
  CONTEXT, 
  APP_KEY_ID, 
  APP_KEY_SECRET,            
  APP_ICON, 
  APP_NAME, 
  APP_BASE_URL,            
  IMPLEMENTATION_TYPE, 
  tapListener
)
```

{% endtab %}
{% endtabs %}

TapListener listens to changes in the following methods:

| Method Name                                      | Invoked When                                                                                                                 |
| ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------- |
| **`onInitializationCompleted()`**                | TapTalk instance has finished initialization process.                                                                        |
| **`onTapTalkRefreshTokenExpired()`**             | User's refresh token has expired. An authentication with a new auth ticket is required.                                      |
| **`onTapTalkUnreadChatRoomBadgeCountUpdated()`** | The number of unread messages in the application is updated. Returns the **number** of unread messages from the application. |
| **`onNotificationReceived()`**                   | User receives new message from TapTalk.io through notification. Returns the newly received **message**.                      |
| **`onUserLogout()`**                             | User has finished logging out from TapUI or `TapTalk.logoutAndClearAllTapTalkData()` process has completed                   |
| **`onTaskRootChatRoomClosed()`**                 | A chat room activity was closed by user when no other activity in the application is present (application will close).       |

### TapUIRoomListListener

TapUIRoomListListener listens to UI-related events in **Room List View** when UI implementation type is used. You can register a TapUIRoomListListener instance in your application through the **TapUI** class as follows:

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapUI;
import io.taptalk.TapTalk.Listener.TapUIRoomListListener;
import io.taptalk.TapTalk.View.Fragment.TapUIMainRoomListFragment;

...

TapUI.getInstance().addRoomListListener(new TapUIRoomListListener() {
    @Override
    public void onSearchChatBarTapped(Activity activity, TapUIMainRoomListFragment mainRoomListFragment) {
        // Calling super will open search chat page by default
        super.onSearchChatBarTapped(activity, mainRoomListFragment);
    }
    
    @Override
    public void onCloseRoomListTapped(Activity activity) {
        // Calling super will close TapTalk's room list activity by default
        super.onCloseRoomListTapped(activity);
    }
    
    @Override
    public void onTapTalkAccountButtonTapped(Activity activity) {
        // Calling super will open TapTalk user account page by default
        super.onTapTalkAccountButtonTapped(activity);
    }
    
    @Override
    public void onNewChatButtonTapped(Activity activity) {
        // Calling super will open TapTalk start new chat page by default
        super.onNewChatButtonTapped(activity);
    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapUI
import io.taptalk.TapTalk.Listener.TapUIRoomListListener
import io.taptalk.TapTalk.View.Fragment.TapUIMainRoomListFragment

...

TapUI.getInstance().addRoomListListener(object : TapUIRoomListListener() {
    override fun onSearchChatBarTapped(activity: Activity, mainRoomListFragment: TapUIMainRoomListFragment) {
        // Calling super will open search chat page by default
        super.onSearchChatBarTapped(activity, mainRoomListFragment)
    }
    
    override fun onCloseRoomListTapped(activity: Activity) {
        // Calling super will close TapTalk's room list activity by default
        super.onCloseRoomListTapped(activity)
    }
    
    override fun onTapTalkAccountButtonTapped(activity: Activity) {
        // Calling super will open TapTalk user account page by default
        super.onTapTalkAccountButtonTapped(activity)
    }
    
    override fun onNewChatButtonTapped(activity: Activity) {
        // Calling super will open TapTalk start new chat page by default
        super.onNewChatButtonTapped(activity)
    }


})
```

{% endtab %}
{% endtabs %}

| Method Name                          | Invoked When                                                                                                                              |
| ------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------- |
| **`onSearchBarTapped()`**            | Search bar in room list is tapped by active user. Returns the room list **activity** instance and **TapUIMainRoomListFragment** instance. |
| **`onCloseRoomListTapped()`**        | TapTalk's room list activity is closed by active user. Returns the room list **activity** instance.                                       |
| **`onTapTalkAccountButtonTapped()`** | My account button in top right room list view is tapped by active user. Returns the room list **activity** instance.                      |
| **`onNewChatButtonTapped()`**        | Floating New Chat button on the bottom right of the room list view is tapped by active user. Returns the room list **activity** instance. |

### TapUIChatRoomListener

TapUIChatRoomListener listens to UI-related events in **Chat Room View** when UI implementation type is used.

Your are also able to customize existing long press menus through this listener.

You can register a TapUIChatRoomListener instance in your application through the **TapUI** class as follows:

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapUI;
import io.taptalk.TapTalk.Listener.TapUIChatRoomListener;
import io.taptalk.TapTalk.Model.TAPMessageModel;
import io.taptalk.TapTalk.Model.TAPRoomModel;
import io.taptalk.TapTalk.Model.TAPUserModel;
import io.taptalk.TapTalk.Model.TapLongPressMenuItem;

...

TapUI.getInstance().addChatRoomListener(new TapUIChatRoomListener() {
    @Override
    public void onTapTalkChatRoomOpened(Activity activity, TAPRoomModel room, @Nullable TAPUserModel otherUser) {
        // Returns activity instance and opened room model
    }

    @Override
    public void onTapTalkChatRoomClosed(Activity activity, TAPRoomModel room, @Nullable TAPUserModel otherUser) {
        // Returns activity instance and closed room model
    }
    @Override
    public void onTapTalkActiveUserSendMessage(Activity activity, TAPMessageModel messageModel, TAPRoomModel room) {
        // Returns activity instance, temporary message model to be sent, and the room where the message is being sent
    }
    
    @Override
    public void onTapTalkUserProfileButtonTapped(Activity activity, TAPRoomModel room, TAPUserModel user) {
        // Using super will open TapTalk user profile by default
        super.onTapTalkUserProfileButtonTapped(activity, room, user);
    }
  
    @Override
    public void onTapTalkGroupChatProfileButtonTapped(Activity activity, TAPRoomModel room) {
        // Using super will open TapTalk group chat profile by default
        super.onTapTalkGroupChatProfileButtonTapped(activity, room);
    }
  
    @Override
    public void onTapTalkGroupMemberAvatarTapped(Activity activity, TAPRoomModel room, TAPUserModel user) {
        // Using super will open TapTalk user profile by default
        super.onTapTalkGroupMemberAvatarTapped(activity, room, user);
    }

    @Override
    public void onTapTalkUserMentionTapped(Activity activity, TAPMessageModel messageModel, TAPUserModel user, boolean isRoomParticipant) {
        // Using super will open TapTalk user profile by default 
        super.onTapTalkUserMentionTapped(activity, messageModel, user, isRoomParticipant);
    }

    @Override
    public void onTapTalkMessageQuoteTapped(Activity activity, TAPMessageModel message, HashMap<String, Object> userInfo) {
        // Returns activity instance, tapped message, and userInfo
    }
    
    @Override
    public List<TapLongPressMenuItem> setMessageLongPressMenuItems(Context context, TAPMessageModel messageModel) {
        // Return your customized list of TapLongPressMenuItem here if you wish to change the message's long press menu options
        return super.setMessageLongPressMenuItems(context, messageModel);
    }

    @Override
    public List<TapLongPressMenuItem> setScheduledMessageLongPressMenuItems(Context context, TAPMessageModel messageModel) {
        // Return your customized list of TapLongPressMenuItem here if you wish to change the scheduled message's long press menu options
        return super.setScheduledMessageLongPressMenuItems(context, messageModel);
    }

    @Override
    public List<TapLongPressMenuItem> setLinkLongPressMenuItems(Context context, @Nullable TAPMessageModel messageModel, String url) {
        // Return your customized list of TapLongPressMenuItem here if you wish to change the url's long press menu options
        return super.setLinkLongPressMenuItems(context, messageModel, url);
    }

    @Override
    public List<TapLongPressMenuItem> setEmailLongPressMenuItems(Context context, @Nullable TAPMessageModel messageModel, String emailAddress) {
        // Return your customized list of TapLongPressMenuItem here if you wish to change the email address's long press menu options
        return super.setEmailLongPressMenuItems(context, messageModel, emailAddress);
    }

    @Override
    public List<TapLongPressMenuItem> setPhoneLongPressMenuItems(Context context, @Nullable TAPMessageModel messageModel, String phoneNumber) {
        // Return your customized list of TapLongPressMenuItem here if you wish to change the phone number's long press menu options
        return super.setPhoneLongPressMenuItems(context, messageModel, phoneNumber);
    }

    @Override
    public List<TapLongPressMenuItem> setMentionLongPressMenuItems(Context context, @Nullable TAPMessageModel messageModel, String mentionSpan) {
        // Return your customized list of TapLongPressMenuItem here if you wish to change the mention's long press menu options
        return super.setMentionLongPressMenuItems(context, messageModel, mentionSpan);
    }

    @Override
    public void onLongPressMenuItemSelected(Activity activity, TapLongPressMenuItem longPressMenuItem, TAPMessageModel messageModel) {
        // A long press menu item was selected by user
        // You may add your own response and delete the super below
        super.onLongPressMenuItemSelected(activity, longPressMenuItem, messageModel);
    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Model.TAPMessageModel
import io.taptalk.TapTalk.Model.TAPRoomModel
import io.taptalk.TapTalk.Model.TAPUserModel
import io.taptalk.TapTalk.Model.TapLongPressMenuItem

...

TapUI.getInstance().addChatRoomListener(object : TapUIChatRoomListener() {
    override fun onTapTalkChatRoomOpened(activity: Activity, room: TAPRoomModel, otherUser: TAPUserModel?) {
        // Returns activity instance and opened room model
    }
    
    override fun onTapTalkChatRoomClosed(activity: Activity, room: TAPRoomModel, otherUser: TAPUserModel?) {
        // Returns activity instance and closed room model
    }
    
    override fun onTapTalkActiveUserSendMessage(activity: Activity, messageModel: TAPMessageModel, room: TAPRoomModel) {
        // Returns activity instance, temporary message model to be sent, and the destination room
    }
    
    override fun onTapTalkUserProfileButtonTapped(activity: Activity, room: TAPRoomModel, user: TAPUserModel?) {
        // Using super will open TapTalk user profile by default
        super.onTapTalkUserProfileButtonTapped(activity, room, user)
    }
  
    override fun onTapTalkGroupChatProfileButtonTapped(activity: Activity, room: TAPRoomModel) {
        // Using super will open TapTalk group chat profile by default
        super.onTapTalkGroupChatProfileButtonTapped(activity, room)
    }
    
    override fun onTapTalkGroupMemberAvatarTapped(activity: Activity, room: TAPRoomModel, user: TAPUserModel) {
        // Using super will open TapTalk user profile by default
        super.onTapTalkGroupMemberAvatarTapped(activity, room, user)
    }

    override fun onTapTalkUserMentionTapped(activity: Activity, messageModel: TAPMessageModel, user: TAPUserModel, isRoomParticipant: Boolean) {
        // Using super will open TapTalk user profile by default
        super.onTapTalkUserMentionTapped(activity, messageModel, user, isRoomParticipant)
    }

    override fun onTapTalkMessageQuoteTapped(activity: Activity, message: TAPMessageModel, userInfo: HashMap<String, Any>?) {
        // Returns activity instance, tapped message, and userInfo
    }
    
    override fun setMessageLongPressMenuItems(context: Context, messageModel: TAPMessageModel): List<TapLongPressMenuItem> { 
        // Return your customized list of TapLongPressMenuItem here if you wish to change the message's long press menu options
        return super.setMessageLongPressMenuItems(context, messageModel)
    }

    override fun setScheduledMessageLongPressMenuItems(context: Context, messageModel: TAPMessageModel): List<TapLongPressMenuItem> { 
        // Return your customized list of TapLongPressMenuItem here if you wish to change the scheduled message's long press menu options
        return super.setScheduledMessageLongPressMenuItems(context, messageModel)
    }

    override fun setLinkLongPressMenuItems(context: Context, messageModel: TAPMessageModel?, url: String): List<TapLongPressMenuItem> {
        // Return your customized list of TapLongPressMenuItem here if you wish to change the url's long press menu options
        return super.setLinkLongPressMenuItems(context, messageModel, url)
    }

    override fun setEmailLongPressMenuItems(context: Context, messageModel: TAPMessageModel?, emailAddress: String): List<TapLongPressMenuItem> {
        // Return your customized list of TapLongPressMenuItem here if you wish to change the email address's long press menu options
        return super.setEmailLongPressMenuItems(context, messageModel, emailAddress)
    }

    override fun setPhoneLongPressMenuItems(context: Context, messageModel: TAPMessageModel?, phoneNumber: String): List<TapLongPressMenuItem> {
        // Return your customized list of TapLongPressMenuItem here if you wish to change the phone number's long press menu options
        return super.setPhoneLongPressMenuItems(context, messageModel, phoneNumber)
    }

    override fun setMentionLongPressMenuItems(context: Context, messageModel: TAPMessageModel?, mentionSpan: String): List<TapLongPressMenuItem> {
        // Return your customized list of TapLongPressMenuItem here if you wish to change the mention's long press menu options
        return super.setMentionLongPressMenuItems(context, messageModel, mentionSpan)
    }

    override fun onLongPressMenuItemSelected(activity: Activity, longPressMenuItem: TapLongPressMenuItem, messageModel: TAPMessageModel?) {
        // A long press menu item was selected by user
        // You may add your own response and delete the super below
        super.onLongPressMenuItemSelected(activity, longPressMenuItem, messageModel)
    }
})
```

{% endtab %}
{% endtabs %}

<table data-header-hidden><thead><tr><th width="440.3245778611632">Method Name</th><th>Invoked When</th></tr></thead><tbody><tr><td>Method Name</td><td>Invoked When</td></tr><tr><td><strong><code>onTapTalkChatRoomOpened()</code></strong></td><td>A chat room is opened. Returns the opened <strong>activity</strong> instance and <strong>room</strong> model.</td></tr><tr><td><strong><code>onTapTalkChatRoomClosed()</code></strong></td><td>A chat room is closed. Returns the closed <strong>activity</strong> instance and <strong>room</strong> model.</td></tr><tr><td><strong><code>onTapTalkActiveUserSendMessage()</code></strong></td><td>Active user sends any message to a chat room. Message may not yet be delivered to the room when this happens. Returns the <strong>activity</strong> instance, <strong>message</strong> to be sent, and the destination <strong>room</strong>. Returned message is temporary and the values will be updated through socket once the message is delivered.</td></tr><tr><td><strong><code>onTapTalkUserProfileButtonTapped()</code></strong></td><td>Profile button in a <strong>personal</strong> chat room is tapped by active user. Returns the <strong>activity</strong> instance, <strong>room</strong>, and recipient <strong>user</strong>.</td></tr><tr><td><strong><code>onTapTalkGroupChatProfileButtonTapped()</code></strong></td><td>Profile button in a <strong>group</strong> chat room is tapped by active user. Returns the <strong>activity</strong> instance and <strong>room</strong>.</td></tr><tr><td><strong><code>onTapTalkGroupMemberAvatarTapped()</code></strong></td><td>A group member's profile picture on a message bubble in <strong>group</strong> chat room is tapped by active user. Returns the <strong>activity</strong> instance, <strong>room</strong>, and recipient <strong>user</strong>.</td></tr><tr><td><strong><code>onTapTalkUserMentionTapped()</code></strong></td><td>A user mention span in a chat bubble is tapped by active user. Returns <strong>activity</strong> instance, <strong>message</strong> model, mentioned <strong>user</strong> model, and <strong>isRoomParticipant</strong></td></tr><tr><td><strong><code>onTapTalkMessageQuoteTapped()</code></strong></td><td>A quote inside a message bubble in a chat room is tapped by active user. Returns <strong>activity</strong> instance, tapped <strong>message</strong>, and <strong>userInfo</strong>.<br>UserInfo is a HashMap object embedded inside a message containing data specified by client, and is generally null when not specified.</td></tr><tr><td><strong><code>setMessageLongPressMenuItems()</code></strong></td><td>A message bubble in chat room is long pressed by user. TapTalk.io will request custom long press items from the client app to be displayed. Returns <strong>context</strong> and the long pressed <strong>message</strong>.</td></tr><tr><td><strong><code>setScheduledMessageLongPressMenuItems()</code></strong></td><td>A message bubble in scheduled messages chat room is long pressed by user. TapTalk.io will request custom long press items from the client app to be displayed. Returns <strong>context</strong> and the long pressed <strong>message</strong>.</td></tr><tr><td><strong><code>setLinkLongPressMenuItems()</code></strong></td><td>A URL inside a message bubble is long pressed by user. TapTalk.io will request custom long press items from the client app to be displayed. Returns <strong>context</strong>, the long pressed <strong>message</strong>, and the <strong>URL</strong>.</td></tr><tr><td><strong><code>setEmailLongPressMenuItems()</code></strong></td><td>An email address inside a message bubble is long pressed by user. TapTalk.io will request custom long press items from the client app to be displayed. Returns <strong>context</strong>, the long pressed <strong>message</strong>, and the <strong>email address</strong>.</td></tr><tr><td><strong><code>setPhoneLongPressMenuItems()</code></strong></td><td>A phone number inside a message bubble is long pressed by user. TapTalk.io will request custom long press items from the client app to be displayed. Returns <strong>context</strong>, the long pressed <strong>message</strong>, and the <strong>phone number</strong>.</td></tr><tr><td><strong><code>setMentionLongPressMenuItems()</code></strong></td><td>A mention span inside a message bubble is long pressed by user. TapTalk.io will request custom long press items from the client app to be displayed. Returns <strong>context</strong>, the long pressed <strong>message</strong>, and the <strong>mention span</strong>.</td></tr><tr><td><strong><code>onLongPressMenuItemSelected()</code></strong></td><td>A long press menu is selected by the active user. Returns the current <strong>activity</strong>, long pressed menu <strong>item</strong>, and the <strong>message</strong> model.</td></tr></tbody></table>

### TapUIChatProfileListener

TapUIChatProfileListener listens to UI-related events in **Chat Profile View** when UI implementation type is used. You can register a TapUIChatProfileListener instance in your application through the **TapUI** class as follows:

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapUI;
import io.taptalk.TapTalk.Listener.TapUIChatProfileListener;
import io.taptalk.TapTalk.Model.TAPRoomModel;
import io.taptalk.TapTalk.Model.TAPUserModel;

...

TapUI.getInstance().addChatProfileListener(new TapUIChatProfileListener() {
    @Override
    public void onReportUserButtonTapped(Activity activity, TAPRoomModel room, TAPUserModel reportedUser) {
        // Returns activity instance, room model, and user model
    }
    
    @Override
    public void onReportGroupButtonTapped(Activity activity, TAPRoomModel room) {
        // Returns activity instance and room model
    }

    @Override
    public void onGroupInCommonItemTapped(Activity activity, TAPRoomModel room) {
        // Returns activity instance and room model
    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapUI
import io.taptalk.TapTalk.Listener.TapUIChatProfileListener
import io.taptalk.TapTalk.Model.TAPRoomModel
import io.taptalk.TapTalk.Model.TAPUserModel

...

TapUI.getInstance().addChatProfileListener(object : TapUIChatProfileListener() {
    override fun onReportUserButtonTapped(activity: Activity, room: TAPRoomModel, reportedUser: TAPUserModel) {
        // Returns activity instance, room model, and user model
    }
    
    override fun onReportGroupButtonTapped(activity: Activity, room: TAPRoomModel) {
        // Returns activity instance and room model
    }
    
    override fun onGroupInCommonItemTapped(activity: Activity, room: TAPRoomModel) {
        // Returns activity instance and room model
    }
})
```

{% endtab %}
{% endtabs %}

<table data-header-hidden><thead><tr><th width="333">Method Name</th><th>Invoked When</th></tr></thead><tbody><tr><td>Method Name</td><td>Invoked When</td></tr><tr><td><strong><code>onReportUserButtonTapped()</code></strong></td><td>Active user taps the Report User button in chat profile view. Returns <strong>activity</strong> instance, <strong>room</strong> model, and the reported <strong>user</strong> model.</td></tr><tr><td><strong><code>onReportGroupButtonTapped()</code></strong></td><td>Active user taps the Report Group button in chat profile view. Returns <strong>activity</strong> instance and <strong>room</strong> model.</td></tr><tr><td><strong><code>onGroupInCommonItemTapped()</code></strong></td><td>Active user taps an item in Groups in Common list. Returns <strong>activity</strong> instance and <strong>room</strong> model.</td></tr></tbody></table>

### TapUIMyAccountListener

TapUIMyAccountListener listens to UI-related events in **My Account View** when UI implementation type is used. You can register a TapUIMyAccountListener instance in your application through the **TapUI** class as follows:

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapUI;
import io.taptalk.TapTalk.Listener.TapUIMyAccountListener;

...

TapUI.getInstance().addMyAccountListener(new TapUIMyAccountListener() {
    @Override
    public void onDeleteButtonInMyAccountPageTapped(@NonNull Activity activity) {
        // Returns My Account activity instance
    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapUI
import io.taptalk.TapTalk.Listener.TapUIMyAccountListener

...

TapUI.getInstance().addMyAccountListener(object : TapUIMyAccountListener() {
    override fun onDeleteButtonInMyAccountPageTapped(activity: Activity) {
        // Returns My Account activity instance
    }
})
```

{% endtab %}
{% endtabs %}

<table data-header-hidden><thead><tr><th width="333">Method Name</th><th>Invoked When</th></tr></thead><tbody><tr><td>Method Name</td><td>Invoked When</td></tr><tr><td><strong><code>onDeleteButtonInMyAccountPageTapped()</code></strong></td><td>Active user taps the Delete Account button in My Account view. Returns the currently active My Account <strong>activity</strong> instance.</td></tr></tbody></table>

### TapUICustomKeyboardListener

TapUICustomKeyboardListener bridges the custom keyboard-related events between TapTalk.io and the client app when UI implementation type is used. TapTalk.io will request custom keyboard items from the client app through this listener when a chat room is opened by the user. TapUICustomKeyboardListener can be implemented using the **TapUI** class.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapUI;
import io.taptalk.TapTalk.Listener.TapUICustomKeyboardListener;
import io.taptalk.TapTalk.Model.TAPRoomModel;
import io.taptalk.TapTalk.Model.TAPUserModel;
import io.taptalk.TapTalk.Model.TAPCustomKeyboardItemModel;

...

TapUI.getInstance().addCustomKeyboardListener(new TapUICustomKeyboardListener() {
    @Override
    public List<TAPCustomKeyboardItemModel> setCustomKeyboardItems(TAPRoomModel room, TAPUserModel activeUser, @Nullable TAPUserModel recipientUser) {
        // Return items here if you wish to use custom keyboard in chat room
        return null;
    }

    @Override
    public void onCustomKeyboardItemTapped(Activity activity, TAPCustomKeyboardItemModel customKeyboardItem, TAPRoomModel room, TAPUserModel activeUser, @Nullable TAPUserModel recipientUser) {
        // Do an action when user taps a custom keyboard item
    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Listener.TapUICustomKeyboardListener
import io.taptalk.TapTalk.Model.TAPRoomModel
import io.taptalk.TapTalk.Model.TAPUserModel
import io.taptalk.TapTalk.Model.TAPCustomKeyboardItemModel

...

TapUI.getInstance().addCustomKeyboardListener(object : TapCustomKeyboardListener() {
    override fun setCustomKeyboardItems(
        room: TAPRoomModel?,
        activeUser: TAPUserModel?,
        recipientUser: TAPUserModel?
    ): List<TAPCustomKeyboardItemModel>? {
        // Return items here if you wish to use custom keyboard in chat room
        return null
    }

    override fun onCustomKeyboardItemTapped(
        activity: Activity?,
        customKeyboardItem: TAPCustomKeyboardItemModel?,
        room: TAPRoomModel?,
        activeUser: TAPUserModel?,
        recipientUser: TAPUserModel?
    ) {
        // Do an action when user taps a custom keyboard item
    }
})
```

{% endtab %}
{% endtabs %}

To use custom keyboard in the chat room, return a list of **TAPCustomKeyboardItemModel** on the `setCustomKeyboardItems()` method in this listener. See the example below:

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapUI;
import io.taptalk.TapTalk.Listener.TapUICustomKeyboardListener;
import io.taptalk.TapTalk.Model.TAPRoomModel;
import io.taptalk.TapTalk.Model.TAPUserModel;
import io.taptalk.TapTalk.Model.TAPCustomKeyboardItemModel;

...

TapUI.getInstance().addCustomKeyboardListener(new TapUICustomKeyboardListener() {
    @Override
    public List<TAPCustomKeyboardItemModel> setCustomKeyboardItems(TAPRoomModel room, TAPUserModel activeUser, @Nullable TAPUserModel recipientUser) {
        List<TAPCustomKeyboardItemModel> customKeyboardItems = new ArrayList<>();
        TAPCustomKeyboardItemModel customKeyboardItem1 = new TAPCustomKeyboardItemModel(
            "customKeyboardItem1",
            getDrawable(R.drawable.keyboard_icon_1),
            "Hello, " + room.getRoomName()
        );
        TAPCustomKeyboardItemModel customKeyboardItem2 = new TAPCustomKeyboardItemModel(
                "customKeyboardItem2",
                "https://www.yoururl.com/image2.png",
                "Hello, my name is " + activeUser.getName()
        );
        customKeyboardItems.add(customKeyboardItem1);
        customKeyboardItems.add(customKeyboardItem2);
        return customKeyboardItems;
    }

    @Override
    public void onCustomKeyboardItemTapped(Activity activity, TAPCustomKeyboardItemModel customKeyboardItem, TAPRoomModel room, TAPUserModel activeUser, @Nullable TAPUserModel recipientUser) {
        if (customKeyboardItem.getItemID().equals("customKeyboardItem1")) {
            // Custom keyboard item 1 was tapped by user
        }
        else if (customKeyboardItem.getItemID().equals("customKeyboardItem2")) {
            // Custom keyboard item 2 was tapped by user
        }
    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Listener.TapUICustomKeyboardListener
import io.taptalk.TapTalk.Model.TAPRoomModel
import io.taptalk.TapTalk.Model.TAPUserModel
import io.taptalk.TapTalk.Model.TAPCustomKeyboardItemModel

...

TapUI.getInstance().addCustomKeyboardListener(object : TapCustomKeyboardListener() {
    override fun setCustomKeyboardItems(
        room: TAPRoomModel?,
        activeUser: TAPUserModel?,
        recipientUser: TAPUserModel?
    ): List<TAPCustomKeyboardItemModel> {
        val customKeyboardItems = ArrayList<TAPCustomKeyboardItemModel>()
        val customKeyboardItem1 = TAPCustomKeyboardItemModel(
            "customKeyboardItem1",
            getDrawable(R.drawable.keyboard_icon_1),
            "Hello, " + room.getRoomName()
        )
        val customKeyboardItem2 = TAPCustomKeyboardItemModel(
            "customKeyboardItem2",
            "https://www.yoururl.com/image2.png",
            "Hello, my name is " + activeUser!!.name
        )
        customKeyboardItems.add(customKeyboardItem1)
        customKeyboardItems.add(customKeyboardItem2)
        return customKeyboardItems
    }

    override fun onCustomKeyboardItemTapped(
        activity: Activity?,
        customKeyboardItem: TAPCustomKeyboardItemModel?,
        room: TAPRoomModel?,
        activeUser: TAPUserModel?,
        recipientUser: TAPUserModel?
    ) {
        if (customKeyboardItem?.itemID == "customKeyboardItem1") {
            // Custom keyboard item 1 was tapped by user
        }
        else if (customKeyboardItem?.itemID == "customKeyboardItem2") {
            // Custom keyboard item 2 was tapped by user
        }
    }
})
```

{% endtab %}
{% endtabs %}

| Method Name                        | Invoked When                                                                                                                                                                                                         |
| ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`setCustomKeyboardItems()`**     | Chat room is opened. TapTalk.io will request custom keyboard items from the client app to be displayed in the chat room. Returns **room**, **active user**, and the **recipient user** (only for personal chat room) |
| **`onCustomKeyboardItemTapped()`** | A custom keyboard item in a chat room is tapped by the user. Returns the **activity** instance, custom keyboard **item**, **room**, **active user**, and **recipient user** (only for personal chat room)            |

### TapCoreMessageListener

TapCoreMessageListener listens to message-related events, such as receiving new or updated message. TapCoreMessageListener can be registered through the **TapCoreMessageManager** class.JavaKotlin

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Listener.TapCoreMessageListener;
import io.taptalk.TapTalk.Model.TAPMessageModel;

...

TapCoreMessageManager.getInstance().addMessageListener(new TapCoreMessageListener() {
    @Override
    public void onReceiveNewMessage(TAPMessageModel message) {

    }

    @Override
    public void onReceiveUpdatedMessage(TAPMessageModel message) {

    }
    
    @Override
    public void onMessageDeleted(TAPMessageModel message) {
    
    }

    @Override
    public void onRequestMessageFileUpload(TAPMessageModel message, Uri fileUri) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Listener.TapCoreMessageListener
import io.taptalk.TapTalk.Model.TAPMessageModel

...

TapCoreMessageManager.getInstance().addMessageListener(object : TapCoreMessageListener() {
    override fun onReceiveNewMessage(message: TAPMessageModel?) {
        
    }

    override fun onReceiveUpdatedMessage(message: TAPMessageModel?) {
        
    }

    override fun onMessageDeleted(message: TAPMessageModel?) {
        
    }

    override fun onRequestMessageFileUpload(message: TAPMessageModel?, fileUri: Uri?) {
        
    }
})
```

{% endtab %}
{% endtabs %}

| Method Name                        | Invoked When                                                                                                                                                           |
| ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`onReceiveNewMessage()`**        | A new message is received. Returns the newly received **message**.                                                                                                     |
| **`onReceiveUpdatedMessage()`**    | An updated message is received. Returns the updated **message**.                                                                                                       |
| **`onMessageDeleted()`**           | A message is deleted. Returns the deleted **message**.                                                                                                                 |
| **`onRequestMessageFileUpload()`** | Active user sends a message with file, such as image, video, or document. Returns the **message** to be sent and the **uri** of the file to be uploaded by the client. |

{% hint style="info" %}
**Note:** the callback `onRequestMessageFileUpload()` will only be invoked when the user calls `setUploadMessageFileToExternalServerEnabled(true)` in **TapCoreMessageManager**. Enabling this will prevent the SDK from uploading message files, which are image, video, or document, to TapTalk servers, means the message will not be sent until the client returns the uploaded file's URL to the SDK through the `onFileUploadCompleted` method in **TapCoreMessageManager**.
{% endhint %}

### TapCoreRoomListListener

Changes to a chat room's state, such as pin and mute events are notified through TapCoreRoomListListener. An instance of TapCoreRoomListListener can be registered from the **TapCoreRoomListManager** class.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreRoomListManager;
import io.taptalk.TapTalk.Listener.TapCoreRoomListListener;

...

TapCoreRoomListManager.getInstance().addCoreRoomListListener(new TapCoreRoomListListener() {
    @Override
    public void onChatRoomMuted(@NonNull String roomID, long expiryTime) {
        
    }

    @Override
    public void onChatRoomUnmuted(@NonNull String roomID) {
        
    }

    @Override
    public void onChatRoomPinned(@NonNull String roomID) {
        
    }

    @Override
    public void onChatRoomUnpinned(@NonNull String roomID) {
        
    }
    
    @Override
    public void onChatRoomDeleted(@NonNull String roomID) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreRoomListManager
import io.taptalk.TapTalk.Listener.TapCoreRoomListListener

...

TapCoreRoomListManager.getInstance().addCoreRoomListListener(object : TapCoreRoomListListener() {
    override fun onChatRoomMuted(roomID: String, expiryTime: Long) {

    }

    override fun onChatRoomUnmuted(roomID: String) {

    }

    override fun onChatRoomPinned(roomID: String) {

    }

    override fun onChatRoomUnpinned(roomID: String) {

    }
    
    override fun onChatRoomDeleted(roomID: String) {

    }
})
```

{% endtab %}
{% endtabs %}

| Method Name                | Invoked When                                                                                           |
| -------------------------- | ------------------------------------------------------------------------------------------------------ |
| **`onChatRoomMuted()`**    | The active user muted a chat room. Returns the **room ID** and **mute expiry time** of the muted room. |
| **`onChatRoomUnmuted()`**  | The active user unmuted a chat room. Returns the **room ID** of the unmuted room.                      |
| **`onChatRoomPinned()`**   | The active user pinned a chat room. Returns the **room ID** of the pinned room.                        |
| **`onChatRoomUnpinned()`** | The active user unpinned a chat room. Returns the **room ID** of the unpinned room.                    |
| **`onChatRoomDeleted()`**  | The active user deleted a chat room. Returns the **room ID** of the deleted room.                      |

### TapCoreChatRoomListener

Room status events such as typing events and online status are notified through TapCoreChatRoomListener. An instance of TapCoreChatRoomListener can be registered from the **TapCoreContactManager** class.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager;
import io.taptalk.TapTalk.Listener.TapCoreChatRoomListener;
import io.taptalk.TapTalk.Model.TAPUserModel;

...

TapCoreChatRoomManager.getInstance().addChatRoomListener(new TapCoreChatRoomListener() {
    @Override
    public void onReceiveStartTyping(String roomID, TAPUserModel user) {
    
    }

    @Override
    public void onReceiveStopTyping(String roomID, TAPUserModel user) {
    
    }

    @Override
    public void onReceiveOnlineStatus(TAPUserModel user, Boolean isOnline, Long lastActive) {
    
    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager
import io.taptalk.TapTalk.Listener.TapCoreChatRoomListener
import io.taptalk.TapTalk.Model.TAPUserModel

...

TapCoreChatRoomManager.getInstance().addChatRoomListener(object : TapCoreChatRoomListener() {
    override fun onReceiveStartTyping(roomID: String?, user: TAPUserModel?) {

    }

    override fun onReceiveStopTyping(roomID: String?, user: TAPUserModel?) {

    }

    override fun onReceiveOnlineStatus(user: TAPUserModel?, isOnline: Boolean?, lastActive: Long?) {

    }
})
```

{% endtab %}
{% endtabs %}

| Method Name                   | Invoked When                                                                                                                              |
| ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| **`onReceiveStartTyping()`**  | Another user starts typing a message in a chat room. Returns the **room ID** and typing **user**.                                         |
| **`onReceiveStopTyping()`**   | Another user stops typing a message in a chat room. Returns the **room ID** and typing **user**.                                          |
| **`onReceiveOnlineStatus()`** | Another user comes online or offline. Returns the updated **user**, **online status**, and the updated user's last active **time stamp**. |

### TapCoreContactListener

Contact related events such as block/unblock are notified through TapCoreContactListener. An instance of TapCoreContactListener can be registered from the **TapCoreContactManager** class.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreContactManager;
import io.taptalk.TapTalk.Listener.TapCoreContactListener;
import io.taptalk.TapTalk.Model.TAPUserModel;

...

TapCoreContactManager.getInstance().addContactListener(new TapCoreContactListener() {
    @Override
    public void onContactBlocked(TAPUserModel user) {
    
    }

    @Override
    public void onContactUnblocked(TAPUserModel user) {
    
    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreContactManager
import io.taptalk.TapTalk.Listener.TapCoreContactListener
import io.taptalk.TapTalk.Model.TAPUserModel

...

TapCoreContactManager.getInstance().addContactListener(object : TapCoreContactListener() {
    override fun onContactBlocked(user: TAPUserModel) {

    }

    override fun onContactUnblocked(user: TAPUserModel) {

    }
})
```

{% endtab %}
{% endtabs %}

| Method Name                | Invoked When                                                       |
| -------------------------- | ------------------------------------------------------------------ |
| **`onContactBlocked()`**   | Active user blocks another user. Returns the blocked **user**.     |
| **`onContactUnblocked()`** | Active user unblocks another user. Returns the unblocked **user**. |


# Push Notification

Push notification is a very important aspect of a chat application. Taptalk.io provides a convenient way to implement push notifications so you can easily manage them according to your needs. If you implement Taptalk.io with the UI implementation method, incoming notifications will be handled within our library and will be automatically shown to the user. If you prefer having full control over the push notifications, the core implementation method can be used.

Before you get a notification from your message, you must ensure that the following steps are setup properly in your application. The first step is to create your project on Firebase Console and have the **google-service.json** file in your application project. The next step is to register the FCM Server Key and Sender ID on the Taptalk.io dashboard.

### Step 1: Add Firebase Cloud Messaging and Google Play Service Dependencies

Implement Google Play Service dependency to your build.grade project file.

{% tabs %}
{% tab title="build.gradle (Project)" %}

```groovy
dependencies {
    classpath 'com.google.gms:google-services:$gms_version'
}
```

{% endtab %}
{% endtabs %}

Apply google play service plugin and implement firebase messaging dependency to your **app-level** build.gradle

{% tabs %}
{% tab title="app module build.gradle" %}

```groovy
plugins {
    id 'com.google.gms.google-services'
}

dependencies {
   implementation("com.google.firebase:firebase-messaging:$firebase_version")
}
```

{% endtab %}
{% endtabs %}

If you have implemented your own push notification to your app, you may add this code in your **FirebaseMessagingService** class to let Taptalk handle the chat notification.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Helper.TapTalk;
import io.taptalk.TapTalk.Listener.TapCommonListener;

...

public class YourFirebaseMessagingService extends FirebaseMessagingService {

  @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        super.onMessageReceived(remoteMessage);
        if (TapTalk.isTapTalkNotification(remoteMessage)) {
            TapTalk.handleTapTalkPushNotification(remoteMessage);
        }
        else {
            // Your own notification here 
        }
    }

    @Override
    public void onNewToken(String s) {
        super.onNewToken(s);
        TapTalk.saveFirebaseToken(s);
        TapTalk.updateFirebaseTokenToServer(new TapCommonListener() {
            @Override
            public void onSuccess(String successMessage) {
                // Successfully updated token
            }
    
            @Override
            public void onError(String errorCode, String errorMessage) {
            
            }
        });
    }
}
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Helper.TapTalk
import io.taptalk.TapTalk.Listener.TapCommonListener

...

class YourFirebaseMessagingService : FirebaseMessagingService() {
    override fun onMessageReceived(remoteMessage: RemoteMessage?) {
        super.onMessageReceived(remoteMessage)
        if (TapTalk.isTapTalkNotification(remoteMessage!!)) {
            TapTalk.handleTapTalkPushNotification(remoteMessage)
        }
        else {
            // Your own notification here
        }
    }

    override fun onNewToken(s: String?) {
        super.onNewToken(s)
        TapTalk.saveFirebaseToken(s)
        TapTalk.updateFirebaseTokenToServer(object : TapCommonListener() {
            override fun onSuccess(successMessage: String?) {
                // Successfully updated token
            }
        
            override fun onError(errorCode: String?, errorMessage: String?) {
        
            }
        })
    }
}
```

{% endtab %}
{% endtabs %}

Otherwise, if you don't handle your own app notification, you can add Taptalk default Firebase Service to your Manifest file.AndroidManifest.xml

{% tabs %}
{% tab title="AndroidManifest.xml" %}

```xml
<service android:name="io.taptalk.TapTalk.Firebase.TapFirebaseMessagingService">
     <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
     </intent-filter>
</service>
```

{% endtab %}
{% endtabs %}

### Step 2: Create Project and Get google-service.json File

Before getting notifications, you are required to add firebase to your android project by having a **google-service.json** file. If the file is already in the folder in your project, no additional steps are needed and you can skip *Step 1*. If it isn't, you can easily add the file to your project in the way below.

There are 2 options to add the google-service.json file, the first is through the **Firebase Console**. You will be asked to create and register your project to get the google-service.json file. The second option is using **Firebase Assistant** where you have to add the plugin in your Android Studio then log in with a google account to connect and configure. For the second option, the google-service.json file will not be needed to be added manually, Firebase Assistant will help you to add it to your project. For further instruction for generating google-service.json file, [check out the complete documentation](https://firebase.google.com/docs/android/setup#console).

After adding firebase to your account, if you are using UI implementation method, the process of activating notification is complete. But if you are using core or combined implementation, you can override the `onNotificationReceived` method in [TapListener](/powertalk-chat-sdk-documentation/powertalk-android/event-listener#taplistener) to implement your own push notification style, or you can use TapTalk's default notification like below.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Listener.TapListener;
import io.taptalk.TapTalk.Model.TAPMessageModel;

...

TapListener tapListener = new TapListener() {
    @Override
    public void onNotificationReceived(TAPMessageModel message) {
        // Implement your notification here
        super.onNotificationReceived(message); // Using super will show TapTalk's default notification
    }
};
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Listener.TapListener
import io.taptalk.TapTalk.Model.TAPMessageModel

...

var tapListener: TapListener = object : TapListener() {
    override fun onNotificationReceived(message: TAPMessageModel?) {
        // Implement your notification here
        super.onNotificationReceived(message) // Using super will show TapTalk's default notification
    }
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Note**: TapTalk will also show its default notification if your do not override the `onNotificationReceived` method in TapListener
{% endhint %}

If you are using TapTalk's default chat notification, TapTalk's chat room will be opened when the user taps the push notification from the phone. Note that your application's main activity will not be present when this happens, and **the application will exit once the user closes the chat room**. To prevent this, you can override the `onTaskRootChatRoomClosed` method in [TapListener](/powertalk-chat-sdk-documentation/powertalk-android/event-listener#taplistener) to open your application's main activity when the user closes the chat room as shown below.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Listener.TapListener;

...

TapListener tapListener = new TapListener() {
    @Override
    public void onTaskRootChatRoomClosed(Activity activity) {
        // Open your application's main activity here
        Intent intent = new Intent(activity, YourMainActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        activity.startActivity(intent);
    }
};
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Listener.TapListener

...

var tapListener: TapListener = object : TapListener() {
    override fun onTaskRootChatRoomClosed(activity: Activity?) {
        // Open your application's main activity here
        val intent = Intent(activity!!, YourMainActivity::class.java)
        intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
        activity.startActivity(intent)
    }
}
```

{% endtab %}
{% endtabs %}

### Step 3: Register the FCM Server Key and Sender ID to Taptalk.io Dashboard

1\. Go to [TapTalk.io Dashboard page](https://taptalk.io/), and login to your dashboard.\
2\. Select Tab **Development** -> **Push Certificates**

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MHq0o6h5nJjAcCeUo92%2F-MHq3dauh77tCrQvMe_c%2F42dbd28-Screenly_-_12.1_Development_-_Push_Certificates_-_Enabled_-_Empty_State2x.png?alt=media\&token=1666e198-67a1-4f02-b33c-6fbb2ac53a61)

3\. Next, select **Add FCM Key**

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MHq0o6h5nJjAcCeUo92%2F-MHq49_le255fN1VLOCz%2F77599eb-Screenly_-_12.2.5_Development_-_Push_Certificates_-_Add_FCM_Key2x.png?alt=media\&token=8f740ba2-c117-4f80-831c-39f94454b75b)

4\. Fill in the FCM Server Key and FCM Sender ID field and click **Save**

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MHq0o6h5nJjAcCeUo92%2F-MHq4MObAplFBmYfFnJs%2Fab7299f-Screenly_-_12.3_Development_-_Push_Certificates_-_Filled2x.png?alt=media\&token=72cd03c3-a972-4c6d-8851-f28da8056b38)

5\. Finally the FCM Server Key and FCM Sender ID will be saved to your project and will be used for push notifications in your application.


# General

### Get TapTalk Implementation Type

You can check the TapTalk.io implementation type used in your application by calling `getTapTalkImplementationType()`.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Helper.TapTalk;
import io.taptalk.TapTalk.Helper.TapTalk.TapTalkImplementationType;

...

TapTalkImplementationType implementationType = TapTalk.getTapTalkImplementationType();
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Helper.TapTalk
import io.taptalk.TapTalk.Helper.TapTalk.TapTalkImplementationType

...

var implementationType = TapTalk.getTapTalkImplementationType()
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**IMPLEMENTATION\_TYPE**

TapTalk implementation consists of 3 types which are:

* TapTalkImplementationTypeUI: used for implementation with only TapUI
* TapTalkImplementationTypeCore: used for implementation with only TapCore
* TapTalkImplementationTypeCombine: used for implementation with both of TapCore and TapUI combined
  {% endhint %}

### Update Application Badge Count

Calling `updateApplicationBadgeCount()` will refresh the number of unread messages in the application and trigger the callback `onTapTalkUnreadChatRoomBadgeCountUpdated()` present in [TapListener](/powertalk-chat-sdk-documentation/powertalk-android/event-listener#taplistener).

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Helper.TapTalk;

...

TapTalk.updateApplicationBadgeCount();
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Helper.TapTalk

...

TapTalk.updateApplicationBadgeCount()
```

{% endtab %}
{% endtabs %}

### Remote Configs

A TapTalk.io project owns a remote configuration, which consists of 3 configuration types: **Core Configs**, **Project Configs**, and **Custom Configs**. A configuration value can be obtained with the respective configuration type's getter method, and will return a **Map** object. To get a specific value, call the `get()` method from the returned Map with the respective key. The value obtained will always be in a **String** format and should be converted each according to their uses. Each configuration type will be explained below.

### Core Configs

| Config Key             | Value                                                                        |
| ---------------------- | ---------------------------------------------------------------------------- |
| chatMediaMaxFileSize   | Number of maximum allowed chat media file size in bytes                      |
| roomPhotoMaxFileSize   | Number of maximum allowed group chat room profile picture file size in bytes |
| userPhotoMaxFileSize   | Number of maximum allowed user profile picture file size in bytes            |
| groupMaxParticipants   | Number of maximum allowed participants in a group chat room                  |
| channelMaxParticipants | Number of maximum allowed participants in a channel                          |

Below is an example to get the value of chatMediaMaxFileSize:

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Helper.TapTalk;

...

Map<String, String> coreConfigs = TapTalk.getCoreConfigs();
String maxFileSizeString = coreConfigs.get("chatMediaMaxFileSize");
long maxFileSizeValue = Long.valueOf(maxFileSize);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Helper.TapTalk

...

val coreConfigs = TapTalk.getCoreConfigs()
val maxFileSizeString = coreConfigs["chatMediaMaxFileSize"]
val maxFileSizeValue = maxFileSize?.toLong()
```

{% endtab %}
{% endtabs %}

### Project Configs

| Config Key         | Value                                                                                                                                           |
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| usernameIgnoreCase | <p><strong>"0"</strong> if username in the project is case sensitive<br><strong>"1"</strong> if username in the project is case insensitive</p> |

An example to obtain usernameIgnoreCase value:

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Helper.TapTalk;

...

Map<String, String> projectConfigs = TapTalk.getProjectConfigs(); 
String usernameIgnoreCase = projectConfigs.get("usernameIgnoreCase");
boolean isUsernameIgnoreCase;
if (usernameIgnoreCase.equals("0")) {
    isUsernameIgnoreCase = false;
}
else if (usernameIgnoreCase.equals("1")) {
    isUsernameIgnoreCase = true;
}
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Helper.TapTalk

...

val projectConfigs = TapTalk.getProjectConfigs()
val usernameIgnoreCase = projectConfigs["usernameIgnoreCase"]
val isUsernameIgnoreCase: Boolean
if (usernameIgnoreCase == "0") {
    isUsernameIgnoreCase = false
}
else if (usernameIgnoreCase == "1") {
    isUsernameIgnoreCase = true
}
```

{% endtab %}
{% endtabs %}

### Custom Configs

Custom config values are specified by the user, and can be customized through the TapTalk.io Dashboard. To get the project's custom configs, call the `getCustomConfigs()` method.JavaKotlin

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Helper.TapTalk;

...

Map<String, String> customConfigs = TapTalk.getCustomConfigs();
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Helper.TapTalk

...

val customConfigs = TapTalk.getCustomConfigs()
```

{% endtab %}
{% endtabs %}

### Refresh Remote Configs

To refresh remote configs with the latest updated values, call the `refreshRemoteConfigs()` method in TapTalk.io class.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Helper.TapTalk;
import io.taptalk.TapTalk.Listener.TapCommonListener;

...

TapTalk.refreshRemoteConfigs(new TapCommonListener() {
    @Override
    public void onSuccess(String successMessage) {
        // Updated configs successfully
    }

    @Override
    public void onError(String errorCode, String errorMessage) {
        
    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Helper.TapTalk
import io.taptalk.TapTalk.Listener.TapCommonListener

...

TapTalk.refreshRemoteConfigs(object : TapCommonListener() {
    override fun onSuccess(successMessage: String?) {
        // Updated configs successfully
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

### Enable / Disable Auto Contact Sync

If you are using UI implementation method in your application, TapTalk.io provides a feature to automatically sync your user's phone contacts with their TapTalk.io contacts. You can choose to enable or disable auto contact sync by calling these methods. If auto contact sync is enabled, TapTalk.io will automatically sync your user's phone contacts and add them to TapTalk.io contacts if their phone number is registered to TapTalk.io when the application is opened. Please note that the **default value** is **enabled**.JavaKotlin

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Helper.TapTalk;

...

@Override
public void onCreate() {
    ...
    
    // Call this method to enable or disable auto contact sync
    // The default value is set to enabled if you do not set this method
    TapTalk.setAutoContactSyncEnabled(IS_ENABLED);
}
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Helper.TapTalk

...

override fun onCreate(savedInstanceState: Bundle?) {
    ...
    
    // Call this method to enable or disable auto contact sync
    // The default value is set to enabled if you do not set this method
    TapTalk.setAutoContactSyncEnabled(IS_ENABLED)
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`IS_ENABLED`**: (boolean) set to true to enable auto contact sync
{% endhint %}

### Get Auto Contact Sync Status

Use this method to obtain auto contact sync status. This method will return `true` if auto contact sync is enabled.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Helper.TapTalk;

...

boolean isAutoContactSyncEnabled = TapTalk.isAutoContactSyncEnabled();
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Helper.TapTalk

...

val isAutoContactSyncEnabled = TapTalk.isAutoContactSyncEnabled()
```

{% endtab %}
{% endtabs %}

### Get Current Activity / Fragment in TapUI

You can obtain the currently showing room list fragment, chat activity, or any TapTalk activity from **TapUI** using the following methods:

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapUI;
import io.taptalk.TapTalk.View.Fragment.TapUIRoomListFragment;
import io.taptalk.TapTalk.View.Activity.TapUIChatActivity;

...

// Obtain TapUIRoomListFragment
TapUIRoomListFragment currentTapTalkRoomListFragment = TapUI.getInstance().getCurrentTapTalkRoomListFragment();

// Obtain currently showing TapUIChatActivity
TapUIChatActivity currentTapTalkChatActivity = TapUI.getInstance().getCurrentTapTalkChatActivity();

// Obtain any AppCompatActivity in the foreground
AppCompatActivity currentForegroundTapTalkActivity = TapUI.getInstance().getCurrentForegroundTapTalkActivity();
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapUI
import io.taptalk.TapTalk.View.Fragment.TapUIRoomListFragment
import io.taptalk.TapTalk.View.Activity.TapUIChatActivity

...

// Obtain TapUIRoomListFragment
val currentTapTalkRoomListFragment = TapUI.getInstance().getCurrentTapTalkRoomListFragment()

// Obtain currently showing TapUIChatActivity
val currentTapTalkChatActivity = TapUI.getInstance().getCurrentTapTalkChatActivity()

// Obtain any AppCompatActivity in the foreground
val currentForegroundTapTalkActivity = TapUI.getInstance().getCurrentForegroundTapTalkActivity()
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
Note: the methods above may return `null` if the selected activity or fragment is not found.
{% endhint %}

### Set Image Compression Quality

You can customize the compression quality of images used for upload and download. The range of the compression quality is set between 10 and 100. The higher the quality, the better the images will look, but they will also take more storage space as their size increases.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Helper.TapTalk;

...

TapTalk.setImageCompressionQuality(IMAGE_COMPRESSION_QUALITY);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Helper.TapTalk

...

TapTalk.setImageCompressionQuality(IMAGE_COMPRESSION_QUALITY)
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`IMAGE_COMPRESSION_QUALITY`**: (int) image compression quality between 10 to 100
{% endhint %}

### Smart Local Cache Management

In order to optimize storage usage and performance, TapTalk.io cleans any local data of messages that are older than 1 month. This cleanup runs on a scheduled interval. Deleted messages can later be retrieved from the server when required.

### Encrypted Chat

TapTalk.io SDK encrypts all message contents before sending them to the server to protect any sensitive content contained in the messages. All messages received and stored in the server will stay encrypted. Messages will be decrypted once fetched in end user's local device in order to show their contents. TapTalk.io uses **AES Crypt** combined with secure local password to encrypt and decrypt message contents.


# User

You can obtain current TapTalk.io active user data by using these methods:

### Get TapTalk.io Active User

Obtain current TapTalk.io active user from cache by calling `getTaptalkActiveUser()`.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Helper.TapTalk;
import io.taptalk.TapTalk.Model.TAPUserModel;

...

TAPUserModel activeUser = TapTalk.getTapTalkActiveUser();
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Helper.TapTalk
import io.taptalk.TapTalk.Model.TAPUserModel

...

val activeUser = TapTalk.getTapTalkActiveUser()
```

{% endtab %}
{% endtabs %}

### Refresh TapTalk.io Active User

You can retrieve the latest TapTalk.io active user data from the server with the `refreshActiveUser()` method.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Helper.TapTalk;
import io.taptalk.TapTalk.Listener.TapCommonListener;

...

TapTalk.refreshActiveUser(new TapCommonListener() {
    @Override
    public void onSuccess(String successMessage) {
        // Successfully updated active user data
        TAPUserModel activeUser = TapTalk.getTapTalkActiveUser();
    }

    @Override
    public void onError(String errorCode, String errorMessage) {
    
    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Helper.TapTalk;
import io.taptalk.TapTalk.Listener.TapCommonListener;

...

TapTalk.refreshActiveUser(object : TapCommonListener() {
    override fun onSuccess(successMessage: String?) {
        // Successfully updated active user data
        val activeUser = TapTalk.getTapTalkActiveUser()
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

### Update Active User Bio

You are able to update the active user's bio with a custom string by calling `updateActiveUserBio()` from **TapCoreContactManager** class.

Successful update will be reflected in the **bio** field of the updated active user's data (`TAPUserModel.getBio()`).

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreContactManager;
import io.taptalk.TapTalk.Listener.TapCoreGetContactListener;
import io.taptalk.TapTalk.Model.TAPUserModel;

...

TapCoreContactManager.getInstance().updateActiveUserBio(BIO_STRING, new TapCoreGetContactListener() {
    @Override
    public void onSuccess(TAPUserModel user) {
        // Successfully updated active user bio
    }

    @Override
    public void onError(String errorCode, String errorMessage) {
    
    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreContactManager
import io.taptalk.TapTalk.Listener.TapCoreGetContactListener
import io.taptalk.TapTalk.Model.TAPUserModel

...

TapCoreContactManager.getInstance().updateActiveUserBio(BIO_STRING, object : TapCoreGetContactListener() {
    override fun onSuccess(user: TAPUserModel?) {
        // Successfully loaded latest user data 
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
BIO\_STRING: (String) custom string for active user bio
{% endhint %}


# Room List

You can implement Room List with [TapUI](/powertalk-chat-sdk-documentation/powertalk-android/room-list/room-list-tapui) or [TapCore](/powertalk-chat-sdk-documentation/powertalk-android/room-list/tapcore).


# Room List - TapUI

If you are using UI implementation type, you can use the method below to open TapTalk.io's chat room list activity.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapUI;

...

TapUI.getInstance().openRoomList(CONTEXT);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapUI

...

TapUI.getInstance().openRoomList(CONTEXT)
```

{% endtab %}
{% endtabs %}

You may also open a specified chat room directly after the room list by passing a room model or room ID parameter. Passing roomID may require additional time to load chat room data after the room list page is opened.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapUI;
import io.taptalk.TapTalk.Model.TAPRoomModel;

...

// Opens room list, and then chat room with provided room model
TapUI.getInstance().openRoomList(CONTEXT, ROOM);

// Opens room list, then loads chat room data and opens it when successful
TapUI.getInstance().openRoomList(CONTEXT, ROOM_ID);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapUI
import io.taptalk.TapTalk.Model.TAPRoomModel

...

// Opens room list, and then chat room with provided room model
TapUI.getInstance().openRoomList(CONTEXT, ROOM);

// Opens room list, then loads chat room data and opens it when successful
TapUI.getInstance().openRoomList(CONTEXT, ROOM_ID);
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`CONTEXT`**: (Context) your Application or Activity context\
**`ROOM`**: (TAPRoomModel) selected room model to be opened\
**`ROOM_ID`**: (String) ID of the selected room model
{% endhint %}

Another option to use the chat room list as a fragment is also available:

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapUI;
import io.taptalk.TapTalk.View.Fragment.TapUIMainRoomListFragment;

...

private TapUIMainRoomListFragment roomListFragment;

roomListFragment = TapUI.getInstance().getRoomListFragment();

getSupportFragmentManager()
    .beginTransaction()
    .show(roomListFragment)
    .commit();
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapUI
import io.taptalk.TapTalk.View.Fragment.TapUIMainRoomListFragment

...

var roomListFragment = TapUI.getInstance().getRoomListFragment();

getSupportFragmentManager()
    .beginTransaction()
    .show(roomListFragment)
    .commit()
```

{% endtab %}
{% endtabs %}


# Room List - TapCore

If you are using core implementation type, the application's chat room list can be managed with the **TapCoreRoomListManager** class using the following methods:

| TapTalk Room List Method                                                                                                   | Description                                                                                       |
| -------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
| [Get Updated Room List](/powertalk-chat-sdk-documentation/powertalk-android/room-list/tapcore#get-updated-room-list)       | Call this method to fetch the latest room list data from the server and update to the local cache |
| [Get Room List From Cache](/powertalk-chat-sdk-documentation/powertalk-android/room-list/tapcore#get-room-list-from-cache) | Call this method to retrieve list of room data obtained from the local cache                      |
| [Fetch New Message](#fetch-new-message)                                                                                    | Call this method to fetch new/updated messages that have not yet been received by the device      |
| [Search Local Room List](#search-local-room-list)                                                                          | Call this method to search room lists from the device's local storage with a keyword              |
| [Mark Chat Room as Unread](#mark-chat-room-as-unread)                                                                      | Add the chat room ID to the marked as unread chat room list                                       |
| [Remove Unread Mark from Chat Room](#mark-chat-room-as-unread-1)                                                           | Remove chat room ID from the marked as unread chat room list​                                     |
| [Get Marked as Unread Chat Room List](#mark-chat-room-as-unread-1)                                                         | Retrieve the list of chat room IDs that has been marked as unread                                 |
| [Mute/Unmute Chat Room](#mute-unmute-chat-room)                                                                            | Mute selected chat rooms until a specified time                                                   |
| [Get Muted Chat Rooms](#get-muted-chat-rooms)                                                                              | Retrieve the list of muted chat room IDs and their respective mute expiry time                    |
| [Pin/Unpin Chat Room](#pin-unpin-chat-room)                                                                                | Add or remove the chat room ID to pinned chat room list                                           |
| [Get Pinned Chat Rooms](#get-pinned-chat-rooms)                                                                            | Retrieve list of pinned chat room IDs from the server                                             |

### Get Updated Room List

Call this method to retrieve the latest room list data from the server and update to the local cache.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreRoomListManager;
import io.taptalk.TapTalk.Listener.TapCoreGetRoomListListener;
import io.taptalk.TapTalk.Model.TAPRoomListModel;

...

TapCoreRoomListManager.getInstance().getUpdatedRoomList(new TapCoreGetRoomListListener() {
    @Override
    public void onSuccess(List<TAPRoomListModel> roomLists) {
        // Returns latest updated room lists
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreRoomListManager
import io.taptalk.TapTalk.Listener.TapCoreGetRoomListListener
import io.taptalk.TapTalk.Model.TAPRoomListModel

...

TapCoreRoomListManager.getInstance().getUpdatedRoomList(object : TapCoreGetRoomListListener() {
    override fun onSuccess(roomLists: List<TAPRoomListModel>?) {
        // Returns latest updated room lists
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

### Get Room List From Cache

Call this method to retrieve list of room data obtained from the local cache.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreRoomListManager;
import io.taptalk.TapTalk.Listener.TapCoreGetRoomListListener;
import io.taptalk.TapTalk.Model.TAPRoomListModel;

...

TapCoreRoomListManager.getInstance().getRoomListFromCache(new TapCoreGetRoomListListener() {
    @Override
    public void onSuccess(List<TAPRoomListModel> roomLists) {
        // Returns room lists obtained from cache
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreRoomListManager
import io.taptalk.TapTalk.Listener.TapCoreGetRoomListListener
import io.taptalk.TapTalk.Model.TAPRoomListModel

...

TapCoreRoomListManager.getInstance().getRoomListFromCache(object : TapCoreGetRoomListListener() {
    override fun onSuccess(roomLists: List<TAPRoomListModel>?) {
        // Returns room lists obtained from cache
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

### Fetch New Message

Call this method to fetch new/updated messages that have not yet been received by the device. Can be used to retrieve pending messages when the device goes back online after an offline state.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreRoomListManager;
import io.taptalk.TapTalk.Listener.TapCoreGetMessageListener;
import io.taptalk.TapTalk.Model.TAPMessageModel;

...

TapCoreRoomListManager.getInstance().fetchNewMessage(new TapCoreGetMessageListener() {
    @Override
    public void onSuccess(List<TAPMessageModel> messages) {
        // Returns list of messages received by the user while the device is offline
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreRoomListManager
import io.taptalk.TapTalk.Listener.TapCoreGetMessageListener
import io.taptalk.TapTalk.Model.TAPMessageModel

...

TapCoreRoomListManager.getInstance().fetchNewMessage(object : TapCoreGetMessageListener() {
    override fun onSuccess(messages: List<TAPMessageModel>?) {
        // Returns list of messages received by the user while the device is offline
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

### Search Local Room List

Call this method to search room lists from the device's local storage with a keyword. Provided keyword will be used to filter **room name** in the search result.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreRoomListManager;
import io.taptalk.TapTalk.Listener.TapCoreGetRoomListListener;
import io.taptalk.TapTalk.Model.TAPRoomListModel;

...

TapCoreRoomListManager.getInstance().searchLocalRoomListWithKeyword(KEYWORD, new TapCoreGetRoomListListener() {
    @Override
    public void onSuccess(List<TAPRoomListModel> roomLists) {
        // Returns filtered room lists obtained from cache
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreRoomListManager
import io.taptalk.TapTalk.Listener.TapCoreGetRoomListListener
import io.taptalk.TapTalk.Model.TAPRoomListModel

...

TapCoreRoomListManager.getInstance().searchLocalRoomListWithKeyword(KEYWORD, object : TapCoreGetRoomListListener() {
    override fun onSuccess(roomLists: List<TAPRoomListModel>?) {
        // Returns filtered room lists obtained from cache
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`KEYWORD`**: (String) search keyword to filter room name
{% endhint %}

### Mark Chat Room as Unread

Call this method to add the selected chat room ID to the marked as unread chat room list.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreRoomListManager;
import io.taptalk.TapTalk.Listener.TapCommonListener;

...

// Mark single chat room as unread
TapCoreRoomListManager.getInstance().markChatRoomAsUnread(ROOM_ID, new TapCommonListener() {
    @Override
    public void onSuccess(String successMessage) {
        // Successfully marked chat room as unread
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});

// Mark multiple chat rooms as unread
TapCoreRoomListManager.getInstance().markChatRoomsAsUnread(ROOM_IDS, new TapCommonListener() {
    @Override
    public void onSuccess(String successMessage) {
        // Successfully marked chat rooms as unread
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreRoomListManager
import io.taptalk.TapTalk.Listener.TapCommonListener

...

// Mark single chat room as unread
TapCoreRoomListManager.getInstance().markChatRoomAsUnread(ROOM_ID, object : TapCommonListener() {
    override fun onSuccess(successMessage: String?) {
        // Successfully marked chat room as unread
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})

// Mark multiple chat rooms as unread
TapCoreRoomListManager.getInstance().markChatRoomsAsUnread(ROOM_IDS, object : TapCommonListener() {
    override fun onSuccess(successMessage: String?) {
        // Successfully marked chat rooms as unread
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`ROOM_ID`**: (String) ID of the target room\
**`ROOM_IDS`**: (List\<String>) list containing IDs of target rooms
{% endhint %}

### Remove Unread Mark from Chat Room

Call this method to remove the selected chat room ID from the marked as unread chat room list.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreRoomListManager;
import io.taptalk.TapTalk.Listener.TapCommonListener;

...

// Remove unread mark from single chat room
TapCoreRoomListManager.getInstance().removeUnreadMarkFromChatRoom(ROOM_ID, new TapCommonListener() {
    @Override
    public void onSuccess(String successMessage) {
        // Successfully removed unread mark from chat room
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});

// Remove unread mark from multiple chat rooms
TapCoreRoomListManager.getInstance().removeUnreadMarkFromChatRooms(ROOM_IDS, new TapCommonListener() {
    @Override
    public void onSuccess(String successMessage) {
        // Successfully removed unread mark from chat rooms
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreRoomListManager
import io.taptalk.TapTalk.Listener.TapCommonListener

...

// Remove unread mark from single chat room
TapCoreRoomListManager.getInstance().removeUnreadMarkFromChatRoom(ROOM_ID, object : TapCommonListener() {
    override fun onSuccess(successMessage: String?) {
        // Successfully removed unread mark from chat room
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})

// Remove unread mark from multiple chat rooms
TapCoreRoomListManager.getInstance().removeUnreadMarkFromChatRooms(ROOM_IDS, object : TapCommonListener() {
    override fun onSuccess(successMessage: String?) {
        // Successfully removed unread mark from chat rooms
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`ROOM_ID`**: (String) ID of the target room\
**`ROOM_IDS`**: (List\<String>) list containing IDs of target rooms
{% endhint %}

### Get Marked as Unread Chat Room List

Call this method to retrieve the list of chat room IDs that has been marked as unread.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreRoomListManager;
import io.taptalk.TapTalk.Listener.TapCoreGetStringArrayListener;

...

TapCoreRoomListManager.getInstance().getMarkedAsUnreadChatRoomList(new TapCoreGetStringArrayListener() {
    @Override
    public void onSuccess(ArrayList<String> arrayList) {
        // Returns list of roomID that has been marked as unread
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreRoomListManager
import io.taptalk.TapTalk.Listener.TapCoreGetStringArrayListener

...

TapCoreRoomListManager.getInstance().getMarkedAsUnreadChatRoomList(object : TapCoreGetStringArrayListener() {
    override fun onSuccess(arrayList: ArrayList<String>) {
        // Returns list of roomID that has been marked as unread
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
});
```

{% endtab %}
{% endtabs %}

### Mute/Unmute Chat Room

Call these methods to mute the selected chat rooms until a specified time. Active user will not receive notifications from muted chat rooms.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreRoomListManager;
import io.taptalk.TapTalk.Listener.TapCommonListener;

...

// Mute a single chat room
TapCoreRoomListManager.getInstance().muteChatRoom(ROOM_ID, EXPIRED_AT, new TapCommonListener() {
    @Override
    public void onSuccess(String successMessage) {
        // Successfully muted chat room
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});

// Mute multiple chat rooms
TapCoreRoomListManager.getInstance().muteChatRooms(ROOM_IDS, EXPIRED_AT, new TapCommonListener() {
    @Override
    public void onSuccess(String successMessage) {
        // Successfully muted chat rooms
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreRoomListManager
import io.taptalk.TapTalk.Listener.TapCommonListener

...

// Mute a single chat room
TapCoreRoomListManager.getInstance().muteChatRoom(ROOM_ID, EXPIRED_AT, object : TapCommonListener() {
    override fun onSuccess(successMessage: String?) {
        // Successfully muted chat room
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})

// Mute multiple chat rooms
TapCoreRoomListManager.getInstance().muteChatRooms(ROOM_IDS, EXPIRED_AT, object : TapCommonListener() {
    override fun onSuccess(successMessage: String?) {
        // Successfully muted chat rooms
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`ROOM_ID`**: (String) ID of the target room\
**`ROOM_IDS`**: (List\<String>) list containing IDs of target rooms\
**`EXPIRED_AT`**: (Long) chat room will stay muted until this time, fill with 0L to mute the room forever or until the room is unmuted
{% endhint %}

To return chat rooms to its normal state and continue retrieving notifications, use `unmuteChatRoom()` method.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreRoomListManager;
import io.taptalk.TapTalk.Listener.TapCommonListener;

...

// Unmute a single chat room
TapCoreRoomListManager.getInstance().unmuteChatRoom(ROOM_ID, new TapCommonListener() {
    @Override
    public void onSuccess(String successMessage) {
        // Successfully unmuted chat room
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});

// Unmute multiple chat rooms
TapCoreRoomListManager.getInstance().unmuteChatRooms(ROOM_IDS, new TapCommonListener() {
    @Override
    public void onSuccess(String successMessage) {
        // Successfully unmuted chat rooms
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreRoomListManager
import io.taptalk.TapTalk.Listener.TapCommonListener

...

// Unmute a single chat room
TapCoreRoomListManager.getInstance().unmuteChatRoom(ROOM_ID, object : TapCommonListener() {
    override fun onSuccess(successMessage: String?) {
        // Successfully unmuted chat room
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})

// Unmute multiple chat rooms
TapCoreRoomListManager.getInstance().unmuteChatRooms(ROOM_IDS, object : TapCommonListener() {
    override fun onSuccess(successMessage: String?) {
        // Successfully unmuted chat rooms
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`ROOM_ID`**: (String) ID of the target room\
**`ROOM_IDS`**: (List\<String>) list containing IDs of target rooms
{% endhint %}

### Get Muted Chat Rooms

Retrieve the list of muted chat room IDs and their respective mute expiry time.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreRoomListManager;
import io.taptalk.TapTalk.Listener.TapCoreGetMutedChatRoomListener;
import io.taptalk.TapTalk.Model.ResponseModel.TapMutedRoomListModel;

...

TapCoreRoomListManager.getInstance().getMutedChatRoomList(new TapCoreGetMutedChatRoomListener() {
    @Override
    public void onSuccess(@NonNull ArrayList<TapMutedRoomListModel> mutedRoomList) {
        // Returns list of TapMutedRoomListModel which contains 
        // roomID and expiry time of the muted chat rooms
    }
    
    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreRoomListManager
import io.taptalk.TapTalk.Listener.TapCoreGetMutedChatRoomListener
import io.taptalk.TapTalk.Model.ResponseModel.TapMutedRoomListModel

...

TapCoreRoomListManager.getInstance().getMutedChatRoomList(ROOM_ID, object : TapCoreGetMutedChatRoomListener() {
    override fun onSuccess(mutedRoomList: ArrayList<TapMutedRoomListModel>) {
        // Returns list of TapMutedRoomListModel which contains 
        // roomID and expiry time of the muted chat rooms
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

### Pin/Unpin Chat Room

You may call `pinChatRoom()` to add or remove the chat room ID to pinned chat room list. Chat rooms pinned by the user are generally shown on top of the chat room list. You can later retrieve the list of pinned chat room IDs with `getPinnedChatRoomIDs()`.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreRoomListManager;
import io.taptalk.TapTalk.Listener.TapCommonListener;

...

// Pin a single chat room
TapCoreRoomListManager.getInstance().pinChatRoom(ROOM_ID, new TapCommonListener() {
    @Override
    public void onSuccess(String successMessage) {
        // Successfully pinned chat room
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});

// Pin multiple chat rooms
TapCoreRoomListManager.getInstance().pinChatRooms(ROOM_IDS, new TapCommonListener() {
    @Override
    public void onSuccess(String successMessage) {
        // Successfully pinned chat rooms
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreRoomListManager
import io.taptalk.TapTalk.Listener.TapCommonListener

...

// Pin a single chat room
TapCoreRoomListManager.getInstance().pinChatRoom(ROOM_ID, object : TapCommonListener() {
    override fun onSuccess(successMessage: String?) {
        // Successfully pinned chat room
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})

// Pin multiple chat rooms
TapCoreRoomListManager.getInstance().pinChatRooms(ROOM_IDS, object : TapCommonListener() {
    override fun onSuccess(successMessage: String?) {
        // Successfully pinned chat rooms
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

Use `unpinChatRoom()` to remove existing pinned chat room ID from the pinned chat room list.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreRoomListManager;
import io.taptalk.TapTalk.Listener.TapCommonListener;

...

// Unpin a single chat room
TapCoreRoomListManager.getInstance().unpinChatRoom(ROOM_ID, new TapCommonListener() {
    @Override
    public void onSuccess(String successMessage) {
        // Successfully unpinned chat room
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});

// Unpin multiple chat rooms
TapCoreRoomListManager.getInstance().unpinChatRooms(ROOM_IDS, new TapCommonListener() {
    @Override
    public void onSuccess(String successMessage) {
        // Successfully unpinned chat rooms
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreRoomListManager
import io.taptalk.TapTalk.Listener.TapCommonListener

...

// Unpin a single chat room
TapCoreRoomListManager.getInstance().unpinChatRoom(ROOM_ID, object : TapCommonListener() {
    override fun onSuccess(successMessage: String?) {
        // Successfully unpinned chat room
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})

// Unpin multiple chat rooms
TapCoreRoomListManager.getInstance().unpinChatRooms(ROOM_IDS, object : TapCommonListener() {
    override fun onSuccess(successMessage: String?) {
        // Successfully unpinned chat rooms
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`ROOM_ID`**: (String) ID of the target room\
**`ROOM_IDS`**: (List\<String>) list containing IDs of target rooms
{% endhint %}

### Get Pinned Chat Rooms

You can retrieve the list of the active user's pinned chat room IDs from the server with `getPinnedChatRoomIDs()`.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreRoomListManager;
import io.taptalk.TapTalk.Listener.TapCoreGetStringArrayListener;

...

TapCoreRoomListManager.getInstance().getPinnedChatRoomIDs(new TapCoreGetStringArrayListener() {
    @Override
    public void onSuccess(@NonNull ArrayList<String> pinnedRoomIDs) {
        // Returns list of roomID of the active user's pinned chat rooms
    }
    
    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreRoomListManager
import io.taptalk.TapTalk.Listener.TapCoreGetStringArrayListener

...

TapCoreRoomListManager.getInstance().getPinnedChatRoomIDs(ROOM_ID, object : TapCoreGetStringArrayListener() {
    override fun onSuccess(pinnedRoomIDs: ArrayList<String>) {
        // Returns list of roomID of the active user's pinned chat rooms
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}


# Chat Room and Messages

You can implement manage chat room and messages with [TapUI](/powertalk-chat-sdk-documentation/powertalk-android/group-chat/tapui) or [TapCore](/powertalk-chat-sdk-documentation/powertalk-android/group-chat/tapcore).


# Chat Room and Messages - TapUI

The following methods from the **TapUI** class can be used to open a chat room when UI implementation type is used.

| TapTalk UI Chat Room Method                                                                                                                                                             | Description                                                                                                                                |
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| [Open Chat Room With User Model](#open-chat-room-with-user-model)                                                                                                                       | Opens a chat room using the recipient user model. This method will directly open the chat room activity.                                   |
| [Open Chat Room with TapTalk.io User ID](#open-chat-room-with-taptalk.io-user-id)                                                                                                       | Opens a chat room using TapTalk.io user ID of the recipient user. This method will directly open the chat room activity.                   |
| [Open Chat Room with Client User ID](#open-chat-room-with-client-user-id)                                                                                                               | Opens a chat room using client user ID of the recipient user. This method will directly open the chat room activity.                       |
| [Open Room with Room Model](/powertalk-chat-sdk-documentation/powertalk-android/group-chat/tapui#open-room-with-room-model)                                                             | Opens a chat room using an available room model. This method will directly open the chat room activity.                                    |
| [Open Room with Room Model & Scroll to Selected Message](/powertalk-chat-sdk-documentation/powertalk-android/group-chat/tapui#open-room-with-room-model-and-scroll-to-selected-message) | Opens a chat room using an available room model. This method will directly open the chat room and scroll the view to the selected message. |
| [Open Saved Messages Chat Room](#open-saved-messages-chat-room)                                                                                                                         | Opens of the active user's Saved Messages chat room. This method will directly open the chat room activity.                                |

### Open Chat Room With User Model

Opens a chat room using the recipient user model. This method will directly open the chat room activity.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapUI;
import io.taptalk.TapTalk.Model.TAPUserModel;

...

TapUI.getInstance().openChatRoomWithOtherUser(CONTEXT, RECIPIENT_USER);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapUI
import io.taptalk.TapTalk.Model.TAPUserModel

...

TapUI.getInstance().openChatRoomWithOtherUser(CONTEXT, RECIPIENT_USER)
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`CONTEXT`**: (Context) your Application or Activity context\
**`RECIPIENT_USER`**: (TAPUserModel) the recipient user to chat with
{% endhint %}

### Open Chat Room with TapTalk.io User ID

Opens a chat room using client user ID of the recipient user. This method will directly open the chat room activity.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapUI;
import io.taptalk.TapTalk.Listener.TapCommonListener;

...

TapUI.getInstance().openChatRoomWithUserID(
    CONTEXT,
    USER_ID,
    PREFILLED_TEXT,
    CUSTOM_QUOTE_TITLE,
    CUSTOM_QUOTE_CONTENT,
    CUSTOM_QUOTE_IMAGE_URL,
    USER_INFO,
    new TapCommonListener() {
        @Override
        public void onSuccess(String successMessage) {
            // Chat room opened successfully
        }
    
        @Override
        public void onError(String errorCode, String errorMessage) {
    
        }
    }
);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapUI
import io.taptalk.TapTalk.Listener.TapCommonListener

...

TapUI.getInstance().openChatRoomWithUserID(
    CONTEXT,
    USER_ID,
    PREFILLED_TEXT,
    CUSTOM_QUOTE_TITLE,
    CUSTOM_QUOTE_CONTENT,
    CUSTOM_QUOTE_IMAGE_URL,
    USER_INFO,
    object : TapCommonListener() {
        override fun onSuccess(successMessage: String?) {
            // Chat room opened successfully
        }
    
        override fun onError(errorCode: String?, errorMessage: String?) {
    
        }
    }
)
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`CONTEXT`**: (Context) your Application or Activity context\
**`USER_ID`**: (String) Taptalk.io User ID of the recipient user\
**`PREFILLED_TEXT`**: (String) if not empty, the active user's chat composer will be filled with this predefined message when the chat room is opened (existing draft will be replaced)\
**`CUSTOM_QUOTE_TITLE`**: (String) title of custom quote data\
**`CUSTOM_QUOTE_CONTENT`**: (String) content / subtitle of custom quote data\
**`CUSTOM_QUOTE_IMAGE_URL`**: (String) image URL string of custom quote\
**`USER_INFO`**: (HashMap\<String , Object>) client-specified data or details of the custom quote
{% endhint %}

### Open Chat Room with Client User ID

Opens a chat room using client user ID (XCUserID) of the recipient user. This method will directly open the chat room activity.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapUI;
import io.taptalk.TapTalk.Listener.TapCommonListener;

...

TapUI.getInstance().openChatRoomWithXCUserID(
    CONTEXT,
    XC_USER_ID,
    PREFFILED_TEXT,
    CUSTOM_QUOTE_TITLE,
    CUSTOM_QUOTE_CONTENT,
    CUSTOM_QUOTE_IMAGE_URL,
    USER_INFO,
    new TapCommonListener() {
        @Override
        public void onSuccess(String successMessage) {
            // Chat room opened successfully
        }
    
        @Override
        public void onOpenRoomFailed(String errorMessage) {
    
        }
    }
);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapUI
import io.taptalk.TapTalk.Listener.TapCommonListener

...

TapUI.getInstance().openChatRoomWithXCUserID(
    CONTEXT,
    XC_USER_ID,
    PREFFILED_TEXT,
    CUSTOM_QUOTE_TITLE,
    CUSTOM_QUOTE_CONTENT,
    CUSTOM_QUOTE_IMAGE_URL,
    USER_INFO,
    object : TapCommonListener() {
        override fun onSuccess(successMessage: String?) {
            // Chat room opened successfully
        }
    
        fun onOpenRoomFailed(errorMessage: String) {
    
        }
    }
)
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`CONTEXT`**: (Context) your Application or Activity context\
**`XC_USER_ID`**: (String) Client User ID of the recipient user\
**`PREFILLED_TEXT`**: (String) if not empty, the active user's chat composer will be filled with this predefined message when the chat room is opened (existing draft will be replaced)\
**`CUSTOM_QUOTE_TITLE`**: (String) title of custom quote data\
**`CUSTOM_QUOTE_CONTENT`**: (String) content / subtitle of custom quote data\
**`CUSTOM_QUOTE_IMAGE_URL`**: (String) image URL string of custom quote\
**`USER_INFO`**: (HashMap\<String , Object>) client-specified data or details of the custom quote
{% endhint %}

### Open Room with Room Model

Opens a chat room using an available room model. This method will directly open the chat room activity.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapUI;
import io.taptalk.TapTalk.Model.TAPRoomModel;

...

TapUI.getInstance().openChatRoomWithRoomModel(CONTEXT, ROOM);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapUI
import io.taptalk.TapTalk.Model.TAPRoomModel

...

TapUI.getInstance().openChatRoomWithRoomModel(CONTEXT, ROOM)
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`CONTEXT`**: (Context) your Application or Activity context\
**`ROOM`**: (TAPRoomModel) existing chat room data to open
{% endhint %}

The `openChatRoomWithRoomModel()` method with extra parameters below is used when you wish to set a predefined quote for the user in the opened chat room.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapUI;
import io.taptalk.TapTalk.Model.TAPRoomModel;

...

TapUI.getInstance().openChatRoomWithRoomModel(
    CONTEXT,
    ROOM,
    PREFILLED_TEXT,
    CUSTOM_QUOTE_TITLE,
    CUSTOM_QUOTE_CONTENT,
    CUSTOM_QUOTE_IMAGE_URL,
    USER_INFO
);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapUI;
import io.taptalk.TapTalk.Model.TAPRoomModel;

...

TapUI.getInstance().openChatRoomWithRoomModel(
    CONTEXT,
    ROOM,
    PREFILLED_TEXT,
    CUSTOM_QUOTE_TITLE,
    CUSTOM_QUOTE_CONTENT,
    CUSTOM_QUOTE_IMAGE_URL,
    USER_INFO
)
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`CONTEXT`**: (Context) your Application or Activity context\
**`ROOM`**: (TAPRoomModel) existing chat room data to open\
**`PREFILLED_TEXT`**: (String) if not empty, the active user's chat composer will be filled with this predefined message when the chat room is opened (existing draft will be replaced)\
**`CUSTOM_QUOTE_TITLE`**: (String) title of custom quote data\
**`CUSTOM_QUOTE_CONTENT`**: (String) content / subtitle of custom quote data\
**`CUSTOM_QUOTE_IMAGE_URL_STRING`**: (String) image URL string of custom quote\
**`USER_INFO`**: (HashMap\<String , Object>) client-specified data or details of the custom quote
{% endhint %}

### Open Room with Room Model & Scroll to Selected Message

Opens a chat room using an available room model. This method will directly open the chat room and scroll the view to the selected message.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapUI;
import io.taptalk.TapTalk.Model.TAPRoomModel;

...

TapUI.getInstance().openChatRoomWithRoomModel(
    CONTEXT,
    ROOM,
    SCROLL_TO_MESSAGE_WITH_LOCAL_ID
);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapUI
import io.taptalk.TapTalk.Model.TAPRoomModel

...

TapUI.getInstance().openChatRoomWithRoomModel(
    CONTEXT,
    ROOM,
    SCROLL_TO_MESSAGE_WITH_LOCAL_ID
)
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`CONTEXT`**: (Context) your Application or Activity context\
**`ROOM`**: (TAPRoomModel) existing chat room data to open\
**`SCROLL_TO_MESSAGE_WITH_LOCAL_ID`**: (String) scrolls the view to the message with the specified local ID when the chat room is opened
{% endhint %}

### Open Saved Messages Chat Room

Opens of the active user's Saved Messages chat room. This method will directly open the chat room activity.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapUI;

...

TapUI.getInstance().openSavedMessagesChatRoom(CONTEXT);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapUI

...

TapUI.getInstance().openSavedMessagesChatRoom(CONTEXT)
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`CONTEXT`**: (Context) your Application or Activity context
{% endhint %}


# Chat Room and Messages - TapCore

If you are using core implementation method, you can use the methods from the **TapCoreChatRoomManager** and **TapCoreMessageManager** class to manage chat room and messages.

| **TapTalk Chat Method**                                                                                                                       | **Description**                                                                                         |
| --------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| [Get Active Chat Room](/powertalk-chat-sdk-documentation/powertalk-android/group-chat/tapcore#get-active-chat-room)                           | Returns the room model of the currently active chat room.                                               |
| [Get Personal Chat Room with Recipient User](#get-personal-chat-room-with-recipient-user)                                                     | Create new personal chat room with recipient user, or obtain chat room data if it already exists        |
| [Get Personal Chat Room with Recipient User ID](#get-personal-chat-room-with-recipient-user-id)                                               | Create new personal chat room with recipient user ID, or obtain chat room data if it already exists.    |
| [Get Local Chat Room Data](#get-local-chat-room-data)                                                                                         | Obtain locally saved chat room details with a roomID.                                                   |
| [Create Group Chat Room](/powertalk-chat-sdk-documentation/powertalk-android/group-chat/tapcore#create-group-chat-room)                       | Create a new group chat room with selected group name.                                                  |
| [Create Group Chat Room with Picture](/powertalk-chat-sdk-documentation/powertalk-android/group-chat/tapcore#create-group-chat-room-1)        | Create a new group chat room with selected group name and group picture.                                |
| [Get Chat Room Data](/powertalk-chat-sdk-documentation/powertalk-android/group-chat/tapcore#get-group-chat-room)                              | Get room details from selected room ID.                                                                 |
| [Update Group Chat Room Details](/powertalk-chat-sdk-documentation/powertalk-android/group-chat/tapcore#update-group-chat-room-details)       | Update existing group chat room data.                                                                   |
| [Update Group Image](/powertalk-chat-sdk-documentation/powertalk-android/group-chat/tapcore#update-group-image)                               | Update group picture with current selected image.                                                       |
| [Delete Local Group Chat Room](#delete-local-group-chat-room)                                                                                 | Delete group chat room from the device's local storage.                                                 |
| [Delete Group Chat Room](/powertalk-chat-sdk-documentation/powertalk-android/group-chat/tapcore#delete-group-chat-room)                       | Delete group chat room and clear all chat data and participants.                                        |
| [Leave Group Chat](/powertalk-chat-sdk-documentation/powertalk-android/group-chat/tapcore#leave-group-chat)                                   | Leave from selected group chat.                                                                         |
| [Add Members to Group Chat](/powertalk-chat-sdk-documentation/powertalk-android/group-chat/tapcore#add-members-to-group-chat)                 | Add selected member(s) to current group chat room.                                                      |
| [Remove Members from Group Chat](/powertalk-chat-sdk-documentation/powertalk-android/group-chat/tapcore#remove-members-from-group-chat)       | Remove selected member(s) from current group chat room.                                                 |
| [Promote Group Admin](/powertalk-chat-sdk-documentation/powertalk-android/group-chat/tapcore#promote-group-admin)                             | Promote selected member(s) as admin(s) to the current group chat room.                                  |
| [Demote Group Admin](/powertalk-chat-sdk-documentation/powertalk-android/group-chat/tapcore#demote-group-admin)                               | Demote selected admin(s) to member(s) to the current group chat room.                                   |
| [Get Saved Messages Chat Room](#get-saved-messages-chat-room)                                                                                 | Obtain Saved Messages chat room data                                                                    |
| [Start Typing](/powertalk-chat-sdk-documentation/powertalk-android/group-chat/tapcore#send-start-typing)                                      | Notify that the active user has started typing in the selected room.                                    |
| [Stop Typing](/powertalk-chat-sdk-documentation/powertalk-ios/group-chat/group-chat-tapcore#send-stop-typing)                                 | Notify that the active user has stopped typing in the selected room.                                    |
| [Send Text Message](/powertalk-chat-sdk-documentation/powertalk-android/group-chat/tapcore#send-text-message)                                 | Send a new text message to the selected chat room.                                                      |
| [Send Location Message](/powertalk-chat-sdk-documentation/powertalk-android/group-chat/tapcore#send-location-message)                         | Send a new message with location to the selected chat room.                                             |
| [Send Image Message](/powertalk-chat-sdk-documentation/powertalk-android/group-chat/tapcore#send-image-message)                               | Send a new image message to the selected chat room.                                                     |
| [Send Video Message](/powertalk-chat-sdk-documentation/powertalk-android/group-chat/tapcore#send-video-message)                               | Send a new video message to the selected chat room.                                                     |
| [Send File Message](/powertalk-chat-sdk-documentation/powertalk-android/group-chat/tapcore#send-file-message)                                 | Send a new file message to the selected chat room.                                                      |
| [Send Voice Message](#send-voice-message)                                                                                                     | Send a new voice message to the selected chat room.                                                     |
| [Send Link Message](#send-link-message)                                                                                                       | Send a new link message to the selected chat room.                                                      |
| [Forward Message](#forward-a-message)                                                                                                         | Forward existing messages to the selected chat room.                                                    |
| [Construct Message Model](/powertalk-chat-sdk-documentation/powertalk-android/group-chat/tapcore#construct-taptalk-io-message-model)          | Construct a customized TapTalk.io message model.                                                        |
| [Send a Custom Message](/powertalk-chat-sdk-documentation/powertalk-android/group-chat/tapcore#send-a-custom-message)                         | Send a new custom message to the room defined in the message model.                                     |
| [Edit Message](#edit-message)                                                                                                                 | Edit the contents of the selected message.                                                              |
| [Delete Message](#delete-message)                                                                                                             | Delete the selected message from the server.                                                            |
| [Delete Message from Local Cache](/powertalk-chat-sdk-documentation/powertalk-android/group-chat/tapcore#delete-message-from-local-cache)     | Delete the selected message from local storage.                                                         |
| [Cancel Message File Upload](/powertalk-chat-sdk-documentation/powertalk-android/group-chat/tapcore#cancel-message-file-upload)               | Cancel image, video, or file upload on the selected pending message.                                    |
| [Download Message File](/powertalk-chat-sdk-documentation/powertalk-android/group-chat/tapcore#download-message-file)                         | Start a file download from the selected file, image, or video message.                                  |
| [Cancel Message File Download](/powertalk-chat-sdk-documentation/powertalk-android/group-chat/tapcore#cancel-message-file-download)           | Cancel image, video, or file download on the selected message.                                          |
| [Upload Image](#upload-image)                                                                                                                 | Upload an image file to TapTalk.io server without sending message.                                      |
| [Upload Video](#upload-video)                                                                                                                 | Upload a video file to TapTalk.io server without sending message.                                       |
| [Upload File](#upload-file)                                                                                                                   | Upload a document to TapTalk.io server without sending message.                                         |
| [Mark Message as Delivered](#mark-message-as-delivered)                                                                                       | Mark message as delivered by the active user.                                                           |
| [Mark Message as Read](/powertalk-chat-sdk-documentation/powertalk-android/group-chat/tapcore#mark-message-as-read)                           | Mark message as read by the active user.                                                                |
| [Mark All Chat Room Messages as Read](#mark-message-as-read-1)                                                                                | Mark all unread messages in a chat room as read.                                                        |
| [Get Local Messages from Chat Room](/powertalk-chat-sdk-documentation/powertalk-android/group-chat/tapcore#get-local-messages-from-chat-room) | Retrieve messages from chat room that are already stored in the device's local storage.                 |
| [Get Older Messages from Chat Room](/powertalk-chat-sdk-documentation/powertalk-android/group-chat/tapcore#get-older-messages-from-chat-room) | Retrieve messages that are older than the provided timestamp from the server to the selected chat room. |
| [Get Newer Messages from Chat Room](/powertalk-chat-sdk-documentation/powertalk-android/group-chat/tapcore#get-newer-messages-from-chat-room) | Retrieve newer messages from the server to the selected chat room                                       |
| [Get All Messages from Chat Room](/powertalk-chat-sdk-documentation/powertalk-android/group-chat/tapcore#get-all-messages-from-chat-room)     | Retrieve all available messages from the selected chat room.                                            |
| [Get Unread Messages from Chat Room](#get-unread-messages-from-chat-room)                                                                     | Retrieve unread messages from the device's local storage.                                               |
| [Get Media Messages from Chat Room](#get-media-messages-from-chat-room)                                                                       | Retrieve media messages from the device's local storage.                                                |
| [Search Local Message](#search-local-room-list)                                                                                               | Call this method to search messages from the device's local storage with a keyword.                     |
| [Star/Unstar Message](#star-unstar-messages)                                                                                                  | Set message as starred or remove star from message for the active user.                                 |
| [Get Starred Messages](#star-unstar-messages-1)                                                                                               | Retrieve list of messages marked as starred in a chat room.                                             |
| [Pin/Unpin Message](#pin-unpin-message)                                                                                                       | Set message as pinned or remove pin from message for all room participants.                             |
| [Get Pinned Messages](#get-pinned-message-list)                                                                                               | Retrieve list of pinned messages in a chat room.                                                        |
| [Get Shared Content Messages](#get-shared-content-messages)                                                                                   | Retrieve image, video, file, and link messages from a chat room.                                        |
| [Delete All Chat Room Messages](#delete-all-chat-room-messages)                                                                               | Clear all existing messages in a selected chat room for the active user.                                |
| [Create Scheduled Message](#create-scheduled-message)                                                                                         | Schedule a message to be delivered at a specified time.                                                 |
| [Get Scheduled Messages](#get-scheduled-messages)                                                                                             | Retrieve list of created scheduled messages in a chat room.                                             |
| [Send Scheduled Messages Now](#send-scheduled-message-now)                                                                                    | Send a previously created scheduled message immediately to the recipient.                               |
| [Edit Scheduled Message Time](#edit-scheduled-message-time)                                                                                   | Change the deliver time of a previously created scheduled message.                                      |
| [Edit Scheduled Message Content](#edit-scheduled-message-time)                                                                                | Update the contents of a scheduled message that has not been delivered.                                 |
| [Delete Scheduled Message](#delete-scheduled-message)                                                                                         | Delete a scheduled message that has not been delivered.                                                 |
| [Get Message Details](#get-message-details)                                                                                                   | Retrieve info about a message's recipients that has read or received the message.                       |
| [Get Message Total Read Count](#get-message-total-read-count)                                                                                 | Retrieve a message's total read count from a non-personal room.                                         |

### Get Active Chat Room

Returns the room model (TAPRoomModel) of the currently active chat room.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager;
import io.taptalk.TapTalk.Model.TAPRoomModel;

TAPRoomModel activeRoom = TapCoreChatRoomManager.getInstance().getActiveChatRoom();
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager
import io.taptalk.TapTalk.Model.TAPRoomModel

val room = TapCoreChatRoomManager.getInstance().activeChatRoom
```

{% endtab %}
{% endtabs %}

### Get Personal Chat Room with Recipient User

Create new personal chat room with recipient user, or obtain chat room data if it already exists.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager;
import io.taptalk.TapTalk.Listener.TapCoreGetRoomListener;
import io.taptalk.TapTalk.Model.TAPRoomModel;

...

TapCoreChatRoomManager.getInstance().getPersonalChatRoom(RECIPIENT_USER, new TapCoreGetRoomListener() {
    @Override
    public void onSuccess(TAPRoomModel room) {
        // Open chat room here
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager
import io.taptalk.TapTalk.Listener.TapCoreGetRoomListener
import io.taptalk.TapTalk.Model.TAPRoomModel

...

TapCoreChatRoomManager.getInstance().getPersonalChatRoom(RECIPIENT_USER, object : TapCoreGetRoomListener() {
    override fun onSuccess(room: TAPRoomModel?) {
        // Open chat room here
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`RECIPIENT_USER`**: (TAPUserModel) recipient user data
{% endhint %}

### Get Personal Chat Room with Recipient User ID

Create new personal chat room with recipient user ID, or obtain chat room data if it already exists.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager;
import io.taptalk.TapTalk.Listener.TapCoreGetRoomListener;
import io.taptalk.TapTalk.Model.TAPRoomModel;

...

TapCoreChatRoomManager.getInstance().getPersonalChatRoom(RECIPIENT_ID, new TapCoreGetRoomListener() {
    @Override
    public void onSuccess(TAPRoomModel room) {
        // Open chat room here
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager
import io.taptalk.TapTalk.Listener.TapCoreGetRoomListener
import io.taptalk.TapTalk.Model.TAPRoomModel

...

TapCoreChatRoomManager.getInstance().getPersonalChatRoom(RECIPIENT_ID, object : TapCoreGetRoomListener() {
    override fun onSuccess(room: TAPRoomModel?) {
        // Open chat room here
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`RECIPIENT_ID`**: (String) user ID of recipient
{% endhint %}

### Get Local Chat Room Data

Obtain locally saved chat room details with a roomID. Returns the saved room model or null if it does not exist.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager;
import io.taptalk.TapTalk.Model.TAPRoomModel;

...

TAPRoomModel room = TapCoreChatRoomManager.getInstance().getLocalChatRoomData(ROOM_ID);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager
import io.taptalk.TapTalk.Model.TAPRoomModel

...

val room = TapCoreChatRoomManager.getInstance().getLocalChatRoomData(ROOM_ID)
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`ROOM_ID`**: (String) selected room's ID
{% endhint %}

### Create Group Chat Room

Create a new group chat room with selected group name.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager;
import io.taptalk.TapTalk.Listener.TapCoreGetRoomListener;
import io.taptalk.TapTalk.Model.TAPRoomModel;

...

TapCoreChatRoomManager.getInstance().createGroupChatRoom(
    GROUP_NAME,
    PARTICIPANT_LIST,
    new TapCoreGetRoomListener() {
        @Override
        public void onSuccess(TAPRoomModel room) {
            // Group chat room created successfully            
        }
    
        @Override
        public void onError(String errorCode, String errorMessage) {
    
        }
    }
);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager;
import io.taptalk.TapTalk.Listener.TapCoreGetRoomListener;
import io.taptalk.TapTalk.Model.TAPRoomModel;

...

TapCoreChatRoomManager.getInstance().createGroupChatRoom(
    GROUP_NAME,
    PARTICIPANT_LIST,
    object : TapCoreGetRoomListener() {
        override fun onSuccess(room: TAPRoomModel?) {
            // Group chat room created successfully            
        }
    
        override fun onError(errorCode: String?, errorMessage: String?) {
    
        }
    }
)
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`GROUP_NAME`**: (String) your group name\
**`PARTICIPANT_LIST`**: (List\<String>) list of the group participant's user IDs
{% endhint %}

### Create Group Chat Room

Create a new group chat room with selected group name and group picture.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager;
import io.taptalk.TapTalk.Listener.TapCoreCreateGroupWithPictureListener;
import io.taptalk.TapTalk.Model.TAPRoomModel;

...

TapCoreChatRoomManager.getInstance().createGroupChatRoomWithPicture(
    GROUP_NAME,
    PARTICIPANT_LIST,
    IMAGE_URI,
    new TapCoreCreateGroupWithPictureListener() {
        @Override
        public void onSuccess(TAPRoomModel room, boolean isPictureUploadSuccess) {
            // Group chat room created successfully            
        }
    
        @Override
        public void onError(String errorCode, String errorMessage) {
    
        }
    }
);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager
import io.taptalk.TapTalk.Listener.TapCoreCreateGroupWithPictureListener
import io.taptalk.TapTalk.Model.TAPRoomModel

...

TapCoreChatRoomManager.getInstance().createGroupChatRoomWithPicture(
    GROUP_NAME,
    PARTICIPANT_LIST,
    IMAGE_URI,
    object : TapCoreCreateGroupWithPictureListener() {
        override fun onSuccess(room: TAPRoomModel?, isPictureUploadSuccess: Boolean) {
            // Group chat room created successfully            
        }
    
        override fun onError(errorCode: String?, errorMessage: String?) {
    
        }
    }
)
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`GROUP_NAME`**: (String) name of the group chat room to create\
**`PARTICIPANT_LIST`**: (List) list of the group participant's user IDs\
**`IMAGE_URI`**: (Uri) picture to be uploaded as the group's profile
{% endhint %}

### Get Chat Room Data

Get room details from selected room ID.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager;
import io.taptalk.TapTalk.Listener.TapCoreGetRoomListener;
import io.taptalk.TapTalk.Model.TAPRoomModel;

...

TapCoreChatRoomManager.getInstance().getChatRoomData(ROOM_ID, new TapCoreGetRoomListener() {
    @Override
    public void onSuccess(TAPRoomModel room) {
        // Open chat room here
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager
import io.taptalk.TapTalk.Listener.TapCoreGetRoomListener
import io.taptalk.TapTalk.Model.TAPRoomModel

...

TapCoreChatRoomManager.getInstance().getChatRoomData(ROOM_ID, object : TapCoreGetRoomListener() {
    override fun onSuccess(room: TAPRoomModel?) {
        // Open chat room here
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`ROOM_ID`**: (String) selected room's ID
{% endhint %}

### Update Group Chat Room Details

Create a new Update existing group chat room data.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager;
import io.taptalk.TapTalk.Listener.TapCoreGetRoomListener;
import io.taptalk.TapTalk.Model.TAPRoomModel;

...

TapCoreChatRoomManager.getInstance().updateGroupChatRoomDetails(GROUP_ID, GROUP_NAME, new TapCoreGetRoomListener() {
    @Override
    public void onSuccess(TAPRoomModel room) {
        // Updated group chat room successfully         
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager
import io.taptalk.TapTalk.Listener.TapCoreGetRoomListener
import io.taptalk.TapTalk.Model.TAPRoomModel

...

TapCoreChatRoomManager.getInstance().updateGroupChatRoomDetails(GROUP_ID, GROUP_NAME, object : TapCoreGetRoomListener() {
    override fun onSuccess(room: TAPRoomModel?) {
        // Updated group chat room successfully         
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`GROUP_ID`**: (String) room ID of group\
**`GROUP_NAME`**: (String) name of group
{% endhint %}

### Update Group Image

Update group picture with current selected image.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager
import io.taptalk.TapTalk.Listener.TapCoreGetRoomListener
import io.taptalk.TapTalk.Model.TAPRoomModel

...

TapCoreChatRoomManager.getInstance().updateGroupPicture(GROUP_ID, IMAGE_URI, new TapCoreGetRoomListener() {
    @Override
    public void onSuccess(TAPRoomModel room) {
        // Updated group chat room successfully
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager
import io.taptalk.TapTalk.Listener.TapCoreGetRoomListener
import io.taptalk.TapTalk.Model.TAPRoomModel

...

TapCoreChatRoomManager.getInstance().updateGroupPicture(GROUP_ID, IMAGE_URI, object : TapCoreGetRoomListener() {
    override fun onSuccess(room: TAPRoomModel?) {
        // Updated group chat room successfully
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`GROUP_ID`**: (String) room ID of the selected group\
**`IMAGE_URI`**: (Uri) new picture for the group's profile
{% endhint %}

### Delete Local Group Chat Room

Delete group chat room from the device's local storage and clear all chat data and participants. Locally deleted room data will still be accessible from the server if the user remains a participant in the room.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager;
import io.taptalk.TapTalk.Listener.TapCommonListener;

...

TapCoreChatRoomManager.getInstance().deleteLocalGroupChatRoom(ROOM_ID, new TapCommonListener() {
    @Override
    public void onSuccess(String successMessage) {
        // Deleted group chat room successfully
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager
import io.taptalk.TapTalk.Listener.TapCommonListener

...

TapCoreChatRoomManager.getInstance().deleteLocalGroupChatRoom(ROOM_ID, object : TapCommonListener() {
    override fun onSuccess(successMessage: String?) {
        // Deleted group chat room successfully
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`ROOM_ID`**: (String) group room ID to be deleted
{% endhint %}

### Delete Group Chat Room

Delete group chat room and clear all chat data and participants.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager;
import io.taptalk.TapTalk.Listener.TapCommonListener;
import io.taptalk.TapTalk.Model.TAPRoomModel;

...

TapCoreChatRoomManager.getInstance().deleteGroupChatRoom(GROUP_CHAT_MODEL, new TapCommonListener() {
    @Override
    public void onSuccess(String successMessage) {
        // Deleted group chat room successfully
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager;
import io.taptalk.TapTalk.Listener.TapCommonListener;
import io.taptalk.TapTalk.Model.TAPRoomModel;

...

TapCoreChatRoomManager.getInstance().deleteGroupChatRoom(GROUP_CHAT_MODEL, object : TapCommonListener() {
    override fun onSuccess(successMessage: String?) {
        // Deleted group chat room successfully
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`GROUP_CHAT_MODEL`**: (TAPRoomModel) a room model of the group to delete
{% endhint %}

### Leave Group Chat

Leave from selected group chat.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager;
import io.taptalk.TapTalk.Listener.TapCommonListener;

...

TapCoreChatRoomManager.getInstance().leaveGroupChatRoom(GROUP_ID, new TapCommonListener() {
    @Override
    public void onSuccess(String successMessage) {
        // Left chat room successfully
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager
import io.taptalk.TapTalk.Listener.TapCommonListener

...

TapCoreChatRoomManager.getInstance().leaveGroupChatRoom(GROUP_ID, object : TapCommonListener() {
    override fun onSuccess(successMessage: String?) {
        // Left chat room successfully
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`GROUP_ID`**: (String) room ID of the selected group
{% endhint %}

### Add Members to Group Chat

Add selected member(s) to current group chat room.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager;
import io.taptalk.TapTalk.Listener.TapCoreGetRoomListener;
import io.taptalk.TapTalk.Model.TAPRoomModel;

...

TapCoreChatRoomManager.getInstance().addGroupChatMembers(GROUP_ID, USER_IDs, new TapCoreGetRoomListener() {
    @Override
    public void onSuccess(TAPRoomModel room) {
        // Added group members successfully
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager
import io.taptalk.TapTalk.Listener.TapCoreGetRoomListener
import io.taptalk.TapTalk.Model.TAPRoomModel

...

TapCoreChatRoomManager.getInstance().addGroupChatMembers(GROUP_ID, USER_IDs, object : TapCoreGetRoomListener() {
    override fun onSuccess(room: TAPRoomModel?) {
        // Added group members successfully
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`GROUP_ID`**: (String) room ID of the selected group\
**`USER_IDs`**: (List\<String>) list of the user IDs to add to the group
{% endhint %}

### Remove Members from Group Chat

Remove selected member(s) from current group chat room.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager;
import io.taptalk.TapTalk.Listener.TapCoreGetRoomListener;
import io.taptalk.TapTalk.Model.TAPRoomModel;

...

TapCoreChatRoomManager.getInstance().removeGroupChatMembers(GROUP_ID, USER_IDs, new TapCoreGetRoomListener() {
    @Override
    public void onSuccess(TAPRoomModel room) {
        // Removed members successfully    
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager
import io.taptalk.TapTalk.Listener.TapCoreGetRoomListener
import io.taptalk.TapTalk.Model.TAPRoomModel

...

TapCoreChatRoomManager.getInstance().removeGroupChatMembers(GROUP_ID, USER_IDs, object : TapCoreGetRoomListener() {
    override fun onSuccess(room: TAPRoomModel?) {
        // Removed members successfully    
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`GROUP_ID`**: (String) room ID of the selected group\
**`USER_IDs`**: (List\<String>) list of the user IDs to add to the group
{% endhint %}

### Promote Group Admin

Promote selected member(s) as admin(s) to the current group chat room.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager;
import io.taptalk.TapTalk.Listener.TapCoreGetRoomListener;
import io.taptalk.TapTalk.Model.TAPRoomModel;

...

TapCoreChatRoomManager.getInstance().promoteGroupAdmins(GROUP_ID, USER_IDs, new TapCoreGetRoomListener() {
    @Override
    public void onSuccess(TAPRoomModel room) {
        // Promoted admins successfully 
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager
import io.taptalk.TapTalk.Listener.TapCoreGetRoomListener
import io.taptalk.TapTalk.Model.TAPRoomModel

...

TapCoreChatRoomManager.getInstance().promoteGroupAdmins(GROUP_ID, USER_IDs, object : TapCoreGetRoomListener() {
    override fun onSuccess(room: TAPRoomModel?) {
        // Promoted admins successfully 
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`GROUP_ID`**: (String) room ID of the selected group\
**`USER_IDs`**: (List\<String>) list of the user IDs to add to the group
{% endhint %}

### Demote Group Admin

Demote selected admin(s) to member(s) to the current group chat room.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager
import io.taptalk.TapTalk.Listener.TapCoreGetRoomListener
import io.taptalk.TapTalk.Model.TAPRoomModel

...

  TapCoreChatRoomManager.getInstance().demoteGroupAdmins(GROUP_ID, USER_IDs, new TapCoreGetRoomListener() {
    @Override
    public void onSuccess(TAPRoomModel room) {
        // Demoted admins successfully 
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager
import io.taptalk.TapTalk.Listener.TapCoreGetRoomListener
import io.taptalk.TapTalk.Model.TAPRoomModel

...

TapCoreChatRoomManager.getInstance().demoteGroupAdmins(GROUP_ID, USER_IDs, object : TapCoreGetRoomListener() {
    override fun onSuccess(room: TAPRoomModel?) {
        // Demoted admins successfully 
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`GROUP_ID`**: (String) room ID of the selected group\
**`USER_IDs`**: (List\<String>) list of the user IDs to add to the group
{% endhint %}

### Get Saved Messages Chat Room

Obtain Saved Messages chat room data.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager;
import io.taptalk.TapTalk.Listener.TapCoreGetRoomListener;
import io.taptalk.TapTalk.Model.TAPRoomModel;

...

TapCoreChatRoomManager.getInstance(instanceKey).getSavedMessagesChatRoom(new TapCoreGetRoomListener() {
    @Override
    public void onSuccess(TAPRoomModel room) {
        // Open chat room here
    }
    
    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager
import io.taptalk.TapTalk.Listener.TapCoreGetRoomListener
import io.taptalk.TapTalk.Model.TAPRoomModel

...

TapCoreChatRoomManager.getInstance().getSavedMessagesChatRoom(object : TapCoreGetRoomListener() {
    override fun onSuccess(room: TAPRoomModel?) {
        // Open chat room here
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

### Send Start Typing

Notify that the active user has started typing in the selected room.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager;

...

TapCoreChatRoomManager.getInstance().sendStartTypingEmit(ROOM_ID);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager

...

TapCoreChatRoomManager.getInstance().sendStartTypingEmit(ROOM_ID)
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`ROOM_ID`**: (String) ID of the room where the user starts typing in
{% endhint %}

### Send Stop Typing

Notify that the active user has stopped typing in the selected room.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager;

...

TapCoreChatRoomManager.getInstance().sendStopTypingEmit(ROOM_ID);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager

...

TapCoreChatRoomManager.getInstance().sendStopTypingEmit(ROOM_ID)
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`ROOM_ID`**: (String) ID of the room where the user starts typing in
{% endhint %}

### Send Text Message

To send a text message to a chat room, use the `sendTextMessage()` method from the **TapCoreMessageManager** class.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Listener.TapCoreSendMessageListener;
import io.taptalk.TapTalk.Model.TAPMessageModel;
import io.taptalk.TapTalk.Model.TAPRoomModel;

...

TapCoreMessageManager.getInstance().sendTextMessage(
    MESSAGE_BODY,
    ROOM,
    new TapCoreSendMessageListener() {
        @Override
        public void onStart(TAPMessageModel message) {
            // Message was constructed
        }
    
        @Override
        public void onSuccess(TAPMessageModel message) {
            // Message was sent successfully
        }
    
        @Override
        public void onError(@Nullable TAPMessageModel message, String errorCode, String errorMessage) {
          
        }
    }
);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Listener.TapCoreSendMessageListener
import io.taptalk.TapTalk.Model.TAPMessageModel
import io.taptalk.TapTalk.Model.TAPRoomModel

...

TapCoreMessageManager.getInstance().sendTextMessage(
    MESSAGE_BODY,
    ROOM,
    object : TapCoreSendMessageListener() {
        override fun onStart(message: TAPMessageModel?) {
            // Message was constructed
        }
    
        override fun onSuccess(message: TAPMessageModel?) {
            // Message was sent successfully
        }
    
        override fun onError(message: TAPMessageModel?, errorCode: String?, errorMessage: String?) {
    
        }
    }
)
```

{% endtab %}
{% endtabs %}

Use the `sendTextMessage()` method with extra parameter to send a text message with quote.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Listener.TapCoreSendMessageListener;
import io.taptalk.TapTalk.Model.TAPMessageModel;
import io.taptalk.TapTalk.Model.TAPRoomModel;

...

TapCoreMessageManager.getInstance().sendTextMessage(
    MESSAGE_BODY,
    ROOM,
    QUOTED_MESSAGE,
    new TapCoreSendMessageListener() {
        @Override
        public void onStart(TAPMessageModel message) {
            // Message was constructed
        }
    
        @Override
        public void onSuccess(TAPMessageModel message) {
            // Message was sent successfully
        }
    
        @Override
        public void onError(@Nullable TAPMessageModel message, String errorCode, String errorMessage) {
          
        }
    }
);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Listener.TapCoreSendMessageListener
import io.taptalk.TapTalk.Model.TAPMessageModel
import io.taptalk.TapTalk.Model.TAPRoomModel

...

TapCoreMessageManager.getInstance().sendTextMessage(
    MESSAGE_BODY,
    ROOM,
    QUOTED_MESSAGE,
    object : TapCoreSendMessageListener() {
        override fun onStart(message: TAPMessageModel?) {
            // Message was constructed
        }
    
        override fun onSuccess(message: TAPMessageModel?) {
            // Message was sent successfully
        }
    
        override fun onError(message: TAPMessageModel?, errorCode: String?, errorMessage: String?) {
    
        }
    }
)
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`MESSAGE_BODY`**: (String) content of the message\
**`ROOM`**: (TAPRoomModel) the destination room where the message will be sent\
**`QUOTED_MESSAGE`**: (TAPMessageModel) quote containing another existing message
{% endhint %}

### Send Location Message

You can send a location embedded in a chat message using `sendLocationMessage()`. This method takes latitude, longitude, and address text as parameters.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Listener.TapCoreSendMessageListener;
import io.taptalk.TapTalk.Model.TAPMessageModel;
import io.taptalk.TapTalk.Model.TAPRoomModel;

...

TapCoreMessageManager.getInstance().sendLocationMessage(
    LATITUDE,
    LONGITUDE,
    ADDRESS,
    ROOM,
    new TapCoreSendMessageListener() {
        @Override
        public void onStart(TAPMessageModel message) {
            // Message was constructed
        }
    
        @Override
        public void onSuccess(TAPMessageModel message) {
            // Message was sent successfully
        }
    
        @Override
        public void onError(@Nullable TAPMessageModel message, String errorCode, String errorMessage) {
          
        }
    }
);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Listener.TapCoreSendMessageListener
import io.taptalk.TapTalk.Model.TAPMessageModel
import io.taptalk.TapTalk.Model.TAPRoomModel

...

TapCoreMessageManager.getInstance().sendLocationMessage(
    LATITUDE,
    LONGITUDE,
    ADDRESS,
    ROOM,
    object : TapCoreSendMessageListener() {
        override fun onStart(message: TAPMessageModel?) {
            // Message was constructed
        }
    
        override fun onSuccess(message: TAPMessageModel?) {
            // Message was sent successfully
        }
    
        override fun onError(message: TAPMessageModel?, errorCode: String?, errorMessage: String?) {
    
        }
    }
)
```

{% endtab %}
{% endtabs %}

Use the `sendLocationMessage()` method with extra parameter to send a location message with quote.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Listener.TapCoreSendMessageListener;
import io.taptalk.TapTalk.Model.TAPMessageModel;
import io.taptalk.TapTalk.Model.TAPRoomModel;

...

TapCoreMessageManager.getInstance().sendLocationMessage(
    LATITUDE,
    LONGITUDE,
    ADDRESS,
    ROOM,
    QUOTED_MESSAGE,
    new TapCoreSendMessageListener() {
        @Override
        public void onStart(TAPMessageModel message) {
            // Message was constructed
        }
    
        @Override
        public void onSuccess(TAPMessageModel message) {
            // Message was sent successfully
        }
    
        @Override
        public void onError(@Nullable TAPMessageModel message, String errorCode, String errorMessage) {
          
        }
    }
);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Listener.TapCoreSendMessageListener
import io.taptalk.TapTalk.Model.TAPMessageModel
import io.taptalk.TapTalk.Model.TAPRoomModel

...

TapCoreMessageManager.getInstance().sendLocationMessage(
    LATITUDE,
    LONGITUDE,
    ADDRESS,
    ROOM,
    QUOTED_MESSAGE,
    object : TapCoreSendMessageListener() {
        override fun onStart(message: TAPMessageModel?) {
            // Message was constructed
        }
    
        override fun onSuccess(message: TAPMessageModel?) {
            // Message was sent successfully
        }
    
        override fun onError(message: TAPMessageModel?, errorCode: String?, errorMessage: String?) {
    
        }
    }
)
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`LATITUDE`**: (Double) latitude of the shared location\
**`LONGITUDE`**: (Double) longitude of the shared location\
**`ADDRESS`**: (String) text data containing the location address\
**`ROOM`**: (TAPRoomModel) the destination room where the message will be sent\
**`QUOTED_MESSAGE`**: (TAPMessageModel) quote containing another existing message
{% endhint %}

### Send Image Message

To send an image to a chat room, you can use `sendImageMessage()` method by providing either `IMAGE_URI`, `BITMAP`, or `IMAGE_URL` as parameter.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Listener.TapCoreSendMessageListener;
import io.taptalk.TapTalk.Model.TAPMessageModel;
import io.taptalk.TapTalk.Model.TAPRoomModel;

...

// Send image with file Uri or Bitmap
TapCoreMessageManager.getInstance().sendImageMessage(
    IMAGE_URI or BITMAP,
    CAPTION,
    ROOM,
    new TapCoreSendMessageListener() {
        @Override
        public void onStart(TAPMessageModel message) {
            // Message was constructed
        }
      
        @Override
        public void onProgress(TAPMessageModel message, int percentage, long bytes) {
            // Image upload is in progress
        }
    
        @Override
        public void onSuccess(TAPMessageModel message) {
            // Message was sent successfully
        }
    
        @Override
        public void onError(@Nullable TAPMessageModel message, String errorCode, String errorMessage) {
          
        }
    }
);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Listener.TapCoreSendMessageListener
import io.taptalk.TapTalk.Model.TAPMessageModel
import io.taptalk.TapTalk.Model.TAPRoomModel

...

// Send image with file Uri or Bitmap
TapCoreMessageManager.getInstance().sendImageMessage(
    IMAGE_URI or BITMAP,
    CAPTION,
    ROOM,
    object : TapCoreSendMessageListener() {
        override fun onStart(message: TAPMessageModel?) {
            // Message was constructed
        }
    
        override fun onProgress(message: TAPMessageModel?, percentage: Int, bytes: Long) {
            // Image upload is in progress
        }
    
        override fun onSuccess(message: TAPMessageModel?) {
            // Message was sent successfully
        }
    
        override fun onError(message: TAPMessageModel?, errorCode: String?, errorMessage: String?) {
    
        }
    }
)
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Listener.TapCoreSendMessageListener;
import io.taptalk.TapTalk.Model.TAPMessageModel;
import io.taptalk.TapTalk.Model.TAPRoomModel;

...

// Send image with remote image URL
TapCoreMessageManager.getInstance().sendImageMessage(
    IMAGE_URL,
    CAPTION,
    ROOM,
    FETCH_METADATA,
    new TapCoreSendMessageListener() {
        @Override
        public void onTemporaryMessageCreated(TAPMessageModel message) {
            // Temporary message will be created while fetching metadata
            // This callback will be called when FETCH_METADATA is true
        }
        
        @Override
        public void onStart(TAPMessageModel message) {
            // Message was constructed
        }
      
        // onProgress is not called when remote URL is provided
    
        @Override
        public void onSuccess(TAPMessageModel message) {
            // Message was sent successfully
        }
    
        @Override
        public void onError(@Nullable TAPMessageModel message, String errorCode, String errorMessage) {
          
        }
    }
);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Listener.TapCoreSendMessageListener
import io.taptalk.TapTalk.Model.TAPMessageModel
import io.taptalk.TapTalk.Model.TAPRoomModel

...

// Send image with remote image URL
TapCoreMessageManager.getInstance().sendImageMessage(
    IMAGE_URL,
    CAPTION,
    ROOM,
    FETCH_METADATA,
    object : TapCoreSendMessageListener() {
        override fun onTemporaryMessageCreated(message: TAPMessageModel?) {
            // Temporary message will be created while fetching metadata
            // This callback will be called when FETCH_METADATA is true
        }
        
        override fun onStart(message: TAPMessageModel?) {
            // Message was constructed
        }
    
        // onProgress is not called when remote URL is provided
    
        override fun onSuccess(message: TAPMessageModel?) {
            // Message was sent successfully
        }
    
        override fun onError(message: TAPMessageModel?, errorCode: String?, errorMessage: String?) {
    
        }
    }
)
```

{% endtab %}
{% endtabs %}

Use the `sendImageMessage()` method with extra parameter to send an image message with quote.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Listener.TapCoreSendMessageListener;
import io.taptalk.TapTalk.Model.TAPMessageModel;
import io.taptalk.TapTalk.Model.TAPRoomModel;

...

// Send image with file Uri or Bitmap and quoted message
TapCoreMessageManager.getInstance().sendImageMessage(
    IMAGE_URI or BITMAP,
    CAPTION,
    ROOM,
    QUOTED_MESSAGE,
    new TapCoreSendMessageListener() {
        @Override
        public void onStart(TAPMessageModel message) {
            // Message was constructed
        }
      
        @Override
        public void onProgress(TAPMessageModel message, int percentage, long bytes) {
            // Image upload is in progress
        }
    
        @Override
        public void onSuccess(TAPMessageModel message) {
            // Message was sent successfully
        }
    
        @Override
        public void onError(@Nullable TAPMessageModel message, String errorCode, String errorMessage) {
          
        }
    }
);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Listener.TapCoreSendMessageListener
import io.taptalk.TapTalk.Model.TAPMessageModel
import io.taptalk.TapTalk.Model.TAPRoomModel

...

// Send image with file Uri or Bitmap and quoted message
TapCoreMessageManager.getInstance().sendImageMessage(
    IMAGE_URI,
    CAPTION,
    ROOM,
    QUOTED_MESSAGE,
    object : TapCoreSendMessageListener() {
        override fun onStart(message: TAPMessageModel?) {
            // Message was constructed
        }
    
        override fun onProgress(message: TAPMessageModel?, percentage: Int, bytes: Long) {
            // Image upload is in progress
        }
    
        override fun onSuccess(message: TAPMessageModel?) {
            // Message was sent successfully
        }
    
        override fun onError(message: TAPMessageModel?, errorCode: String?, errorMessage: String?) {
    
        }
    }
)
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Listener.TapCoreSendMessageListener;
import io.taptalk.TapTalk.Model.TAPMessageModel;
import io.taptalk.TapTalk.Model.TAPRoomModel;

...

// Send image with remote image URL and quoted message
TapCoreMessageManager.getInstance().sendImageMessage(
    IMAGE_URL,
    CAPTION,
    ROOM,
    QUOTED_MESSAGE,
    FETCH_METADATA,
    new TapCoreSendMessageListener() {
        @Override
        public void onTemporaryMessageCreated(TAPMessageModel message) {
            // Temporary message will becreated while fetching metadata
            // This callback will be called when FETCH_METADATA is true
        }
        
        @Override
        public void onStart(TAPMessageModel message) {
            // Message was constructed
        }
      
        // onProgress is not called when remote URL is provided
    
        @Override
        public void onSuccess(TAPMessageModel message) {
            // Message was sent successfully
        }
    
        @Override
        public void onError(@Nullable TAPMessageModel message, String errorCode, String errorMessage) {
          
        }
    }
);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Listener.TapCoreSendMessageListener;
import io.taptalk.TapTalk.Model.TAPMessageModel;
import io.taptalk.TapTalk.Model.TAPRoomModel;

...

// Send image with remote image URL and quoted message
TapCoreMessageManager.getInstance().sendImageMessage(
    IMAGE_URL,
    CAPTION,
    ROOM,
    QUOTED_MESSAGE,
    FETCH_METADATA,
    object : TapCoreSendMessageListener() {
        override fun onTemporaryMessageCreated(message: TAPMessageModel?) {
            // Temporary message will be created while fetching metadata
            // This callback will be called when FETCH_METADATA is true
        }
        
        override fun onStart(message: TAPMessageModel?) {
            // Message was constructed
        }
    
        // onProgress is not called when remote URL is provided
    
        override fun onSuccess(message: TAPMessageModel?) {
            // Message was sent successfully
        }
    
        override fun onError(message: TAPMessageModel?, errorCode: String?, errorMessage: String?) {
    
        }
    }
)
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`IMAGE_URI`**: (Uri) local Uri of the image file\
**`BITMAP`**: (Bitmap) bitmap file of the image\
**`IMAGE_URL`**: (String) remote URL of the image file\
**`CAPTION`**: (String) caption for the image\
**`ROOM`**: (TAPRoomModel) the destination room where the message will be sent\
**`QUOTED_MESSAGE`**: (TAPMessageModel) quote containing another existing message\
**`FETCH_METADATA`**: (boolean) inserts metadata from remote URL to the constructed message when true
{% endhint %}

### Send Video Message

To send a video to a chat room, you can use `sendVideoMessage()` method by providing `VIDEO_URI` or `VIDEO_URL`.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Listener.TapCoreSendMessageListener;
import io.taptalk.TapTalk.Model.TAPMessageModel;
import io.taptalk.TapTalk.Model.TAPRoomModel;

...

// Send video with file Uri
TapCoreMessageManager.getInstance().sendVideoMessage(
    VIDEO_URI,
    CAPTION,
    ROOM,
    new TapCoreSendMessageListener() {
        @Override
        public void onStart(TAPMessageModel message) {
            // Message was constructed
        }
      
        @Override
        public void onProgress(TAPMessageModel message, int percentage, long bytes) {
            // Video upload is in progress
        }
    
        @Override
        public void onSuccess(TAPMessageModel message) {
            // Message was sent successfully
        }
    
        @Override
        public void onError(@Nullable TAPMessageModel message, String errorCode, String errorMessage) {
          
        }
    }
);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Listener.TapCoreSendMessageListener
import io.taptalk.TapTalk.Model.TAPMessageModel
import io.taptalk.TapTalk.Model.TAPRoomModel

...

// Send video with file Uri
TapCoreMessageManager.getInstance().sendVideoMessage(
    VIDEO_URI,
    CAPTION,
    ROOM,
    object : TapCoreSendMessageListener() {
        override fun onStart(message: TAPMessageModel?) {
            // Message was constructed
        }
    
        override fun onProgress(message: TAPMessageModel?, percentage: Int, bytes: Long) {
            // Video upload is in progress
        }
    
        override fun onSuccess(message: TAPMessageModel?) {
            // Message was sent successfully
        }
    
        override fun onError(message: TAPMessageModel?, errorCode: String?, errorMessage: String?) {
    
        }
    }
)
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="Java" %}

<pre class="language-java"><code class="lang-java">import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Listener.TapCoreSendMessageListener;
import io.taptalk.TapTalk.Model.TAPMessageModel;
import io.taptalk.TapTalk.Model.TAPRoomModel;

...

// Send video with remote video URL
<strong>TapCoreMessageManager.getInstance().sendVideoMessage(
</strong><strong>    CONTEXT,
</strong><strong>    VIDEO_URL,
</strong><strong>    CAPTION,
</strong><strong>    ROOM,
</strong><strong>    FETCH_METADATA,
</strong><strong>    new TapCoreSendMessageListener() {
</strong>        @Override
        public void onTemporaryMessageCreated(TAPMessageModel message) {
            // Temporary message will be created while fetching metadata
            // This callback will be called when FETCH_METADATA is true
        }
        
        @Override
        public void onStart(TAPMessageModel message) {
            // Message was constructed
        }
      
        // onProgress is not called when remote URL is provided
    
        @Override
        public void onSuccess(TAPMessageModel message) {
            // Message was sent successfully
        }
    
        @Override
        public void onError(@Nullable TAPMessageModel message, String errorCode, String errorMessage) {
          
        }
    }
);
</code></pre>

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Listener.TapCoreSendMessageListener
import io.taptalk.TapTalk.Model.TAPMessageModel
import io.taptalk.TapTalk.Model.TAPRoomModel

...

// Send video with remote video URL
TapCoreMessageManager.getInstance().sendVideoMessage(
    CONTEXT,
    VIDEO_URL,
    CAPTION,
    ROOM,
    FETCH_METADATA,
    object : TapCoreSendMessageListener() {
        override fun onTemporaryMessageCreated(message: TAPMessageModel?) {
            // Temporary message will be created while fetching metadata
            // This callback will be called when FETCH_METADATA is true
        }
        
        override fun onStart(message: TAPMessageModel?) {
            // Message was constructed
        }
    
        // onProgress is not called when remote URL is provided
    
        override fun onSuccess(message: TAPMessageModel?) {
            // Message was sent successfully
        }
    
        override fun onError(message: TAPMessageModel?, errorCode: String?, errorMessage: String?) {
    
        }
    }
)
```

{% endtab %}
{% endtabs %}

Use the `sendVideoMessage()` method with extra parameter to send a video message with quote.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Listener.TapCoreSendMessageListener;
import io.taptalk.TapTalk.Model.TAPMessageModel;
import io.taptalk.TapTalk.Model.TAPRoomModel;

...

// Send video with file Uri and quoted message
TapCoreMessageManager.getInstance().sendVideoMessage(
    VIDEO_URI,
    CAPTION,
    ROOM,
    QUOTED_MESSAGE,
    new TapCoreSendMessageListener() {
        @Override
        public void onStart(TAPMessageModel message) {
            // Message was constructed
        }
      
        @Override
        public void onProgress(TAPMessageModel message, int percentage, long bytes) {
            // Video upload is in progress
        }
    
        @Override
        public void onSuccess(TAPMessageModel message) {
            // Message was sent successfully
        }
    
        @Override
        public void onError(@Nullable TAPMessageModel message, String errorCode, String errorMessage) {
          
        }
    }
);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Listener.TapCoreSendMessageListener
import io.taptalk.TapTalk.Model.TAPMessageModel
import io.taptalk.TapTalk.Model.TAPRoomModel

...

// Send video with file Uri and quoted message
TapCoreMessageManager.getInstance().sendVideoMessage(
    VIDEO_URI,
    CAPTION,
    ROOM,
    QUOTED_MESSAGE,
    object : TapCoreSendMessageListener() {
        override fun onStart(message: TAPMessageModel?) {
            // Message was constructed
        }
    
        override fun onProgress(message: TAPMessageModel?, percentage: Int, bytes: Long) {
            // Video upload is in progress
        }
    
        override fun onSuccess(message: TAPMessageModel?) {
            // Message was sent successfully
        }
    
        override fun onError(message: TAPMessageModel?, errorCode: String?, errorMessage: String?) {
    
        }
    }
)
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="Java" %}

<pre class="language-java"><code class="lang-java">import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Listener.TapCoreSendMessageListener;
import io.taptalk.TapTalk.Model.TAPMessageModel;
import io.taptalk.TapTalk.Model.TAPRoomModel;

...

// Send video with remote video URL and quoted message
<strong>TapCoreMessageManager.getInstance().sendVideoMessage(
</strong><strong>    CONTEXT,
</strong><strong>    VIDEO_URL,
</strong><strong>    CAPTION,
</strong><strong>    ROOM,
</strong><strong>    QUOTED_MESSAGE,
</strong><strong>    FETCH_METADATA,
</strong><strong>    new TapCoreSendMessageListener() {
</strong>        @Override
        public void onTemporaryMessageCreated(TAPMessageModel message) {
            // Temporary message will be created while fetching metadata
            // This callback will be called when FETCH_METADATA is true
        }
        
        @Override
        public void onStart(TAPMessageModel message) {
            // Message was constructed
        }
      
        // onProgress is not called when remote URL is provided
    
        @Override
        public void onSuccess(TAPMessageModel message) {
            // Message was sent successfully
        }
    
        @Override
        public void onError(@Nullable TAPMessageModel message, String errorCode, String errorMessage) {
          
        }
    }
);
</code></pre>

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Listener.TapCoreSendMessageListener
import io.taptalk.TapTalk.Model.TAPMessageModel
import io.taptalk.TapTalk.Model.TAPRoomModel

...

// Send video with remote video URL and quoted message
TapCoreMessageManager.getInstance().sendVideoMessage(
    CONTEXT,
    VIDEO_URL,
    CAPTION,
    ROOM,
    QUOTED_MESSAGE,
    FETCH_METADATA,
    object : TapCoreSendMessageListener() {
        override fun onTemporaryMessageCreated(message: TAPMessageModel?) {
            // Temporary message will becreated while fetching metadata
            // This callback will be called when FETCH_METADATA is true
        }
        
        override fun onStart(message: TAPMessageModel?) {
            // Message was constructed
        }
    
        // onProgress is not called when remote URL is provided
    
        override fun onSuccess(message: TAPMessageModel?) {
            // Message was sent successfully
        }
    
        override fun onError(message: TAPMessageModel?, errorCode: String?, errorMessage: String?) {
    
        }
    }
)
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`CONTEXT`**: (Context) your Application or Activity context\
**`VIDEO_URI`**: (Uri) local Uri of the video file\
**`VIDEO_URL`**: (String) remote URL of the video file\
**`CAPTION`**: (String) caption for the video\
**`ROOM`**: (TAPRoomModel) the destination room where the message will be sent\
**`QUOTED_MESSAGE`**: (TAPMessageModel) quote containing another existing message\
**`FETCH_METADATA`**: (boolean) inserts metadata from remote URL to the constructed message when true
{% endhint %}

### Send File Message

You can also send a file to a chat room using the `sendFileMessage()` method with a provided `FILE`, `URI`, or `FILE_URL`.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Listener.TapCoreSendMessageListener;
import io.taptalk.TapTalk.Model.TAPMessageModel;
import io.taptalk.TapTalk.Model.TAPRoomModel;

...

// Send file with File object or Uri
TapCoreMessageManager.getInstance().sendFileMessage(
    FILE or URI,
    ROOM,
    new TapCoreSendMessageListener() {
        @Override
        public void onStart(TAPMessageModel message) {
            // Message was constructed
        }
      
        @Override
        public void onProgress(TAPMessageModel message, int percentage, long bytes) {
            // File upload is in progress
        }
    
        @Override
        public void onSuccess(TAPMessageModel message) {
            // Message was sent successfully
        }
    
        @Override
        public void onError(@Nullable TAPMessageModel message, String errorCode, String errorMessage) {
          
        }
    }
);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Listener.TapCoreSendMessageListener
import io.taptalk.TapTalk.Model.TAPMessageModel
import io.taptalk.TapTalk.Model.TAPRoomModel

...

// Send file with File object or Uri
TapCoreMessageManager.getInstance().sendFileMessage(
    FILE or URI,
    ROOM,
    object : TapCoreSendMessageListener() {
        override fun onStart(message: TAPMessageModel?) {
            // Message was constructed
        }
    
        override fun onProgress(message: TAPMessageModel?, percentage: Int, bytes: Long) {
            // File upload is in progress
        }
    
        override fun onSuccess(message: TAPMessageModel?) {
            // Message was sent successfully
        }
    
        override fun onError(message: TAPMessageModel?, errorCode: String?, errorMessage: String?) {
    
        }
    }
)
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Listener.TapCoreSendMessageListener;
import io.taptalk.TapTalk.Model.TAPMessageModel;
import io.taptalk.TapTalk.Model.TAPRoomModel;

...

// Send file with remote file URL
TapCoreMessageManager.getInstance().sendFileMessage(
    FILE_URL,
    CAPTION,
    ROOM,
    FETCH_METADATA,
    new TapCoreSendMessageListener() {
        @Override
        public void onTemporaryMessageCreated(TAPMessageModel message) {
            // Temporary message will be created while fetching metadata
            // This callback will be called when FETCH_METADATA is true
        }
        
        @Override
        public void onStart(TAPMessageModel message) {
            // Message was constructed
        }
      
        // onProgress is not called when remote URL is provided
    
        @Override
        public void onSuccess(TAPMessageModel message) {
            // Message was sent successfully
        }
    
        @Override
        public void onError(@Nullable TAPMessageModel message, String errorCode, String errorMessage) {
          
        }
    }
);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Listener.TapCoreSendMessageListener
import io.taptalk.TapTalk.Model.TAPMessageModel
import io.taptalk.TapTalk.Model.TAPRoomModel

...

// Send file with remote file URL
TapCoreMessageManager.getInstance().sendFileMessage(
    FILE_URL,
    CAPTION,
    ROOM,
    FETCH_METADATA,
    object : TapCoreSendMessageListener() {
        override fun onTemporaryMessageCreated(message: TAPMessageModel?) {
            // Temporary message will be created while fetching metadata
            // This callback will be called when FETCH_METADATA is true
        }
        
        override fun onStart(message: TAPMessageModel?) {
            // Message was constructed
        }
    
        // onProgress is not called when remote URL is provided
    
        override fun onSuccess(message: TAPMessageModel?) {
            // Message was sent successfully
        }
    
        override fun onError(message: TAPMessageModel?, errorCode: String?, errorMessage: String?) {
    
        }
    }
)
```

{% endtab %}
{% endtabs %}

Use the `sendFileMessage()` method with extra parameters to send a file message with quote and/or caption.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Listener.TapCoreSendMessageListener;
import io.taptalk.TapTalk.Model.TAPMessageModel;
import io.taptalk.TapTalk.Model.TAPRoomModel;

...

// Send file with File object or Uri and quoted message and caption
TapCoreMessageManager.getInstance().sendFileMessage(
    FILE or URI,
    ROOM,
    QUOTED_MESSAGE,
    CAPTION,
    new TapCoreSendMessageListener() {
        @Override
        public void onStart(TAPMessageModel message) {
            // Message was constructed
        }
      
        @Override
        public void onProgress(TAPMessageModel message, int percentage, long bytes) {
            // File upload is in progress
        }
    
        @Override
        public void onSuccess(TAPMessageModel message) {
            // Message was sent successfully
        }
    
        @Override
        public void onError(@Nullable TAPMessageModel message, String errorCode, String errorMessage) {
          
        }
    }
);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Listener.TapCoreSendMessageListener
import io.taptalk.TapTalk.Model.TAPMessageModel
import io.taptalk.TapTalk.Model.TAPRoomModel

...

// Send file with File object or Uri and quoted message and caption
TapCoreMessageManager.getInstance().sendFileMessage(
    FILE or URI,
    ROOM,
    QUOTED_MESSAGE,
    CAPTION,
    object : TapCoreSendMessageListener() {
        override fun onStart(message: TAPMessageModel?) {
            // Message was constructed
        }
    
        override fun onProgress(message: TAPMessageModel?, percentage: Int, bytes: Long) {
            // File upload is in progress
        }
    
        override fun onSuccess(message: TAPMessageModel?) {
            // Message was sent successfully
        }
    
        override fun onError(message: TAPMessageModel?, errorCode: String?, errorMessage: String?) {

        }
    }
)
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Listener.TapCoreSendMessageListener;
import io.taptalk.TapTalk.Model.TAPMessageModel;
import io.taptalk.TapTalk.Model.TAPRoomModel;

...

// Send file with remote file URL, quoted message, caption, file name, mime type
TapCoreMessageManager.getInstance().sendFileMessage(
    FILE_URL,
    CAPTION,
    ROOM,
    QUOTED_MESSAGE,
    FILE_NAME,
    MIME_TYPE,
    FETCH_METADATA,
    new TapCoreSendMessageListener() {
    @Override
    public void onTemporaryMessageCreated(TAPMessageModel message) {
        // Temporary message will be created while fetching metadata
        // This callback will be called when FETCH_METADATA is true
    }
    
    @Override
    public void onStart(TAPMessageModel message) {
        // Message was constructed
    }
  
    // onProgress is not called when remote URL is provided

    @Override
    public void onSuccess(TAPMessageModel message) {
        // Message was sent successfully
    }

    @Override
    public void onError(@Nullable TAPMessageModel message, String errorCode, String errorMessage) {
      
    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Listener.TapCoreSendMessageListener
import io.taptalk.TapTalk.Model.TAPMessageModel
import io.taptalk.TapTalk.Model.TAPRoomModel

...

// Send file with remote file URL, quoted message, caption, file name, mime type
TapCoreMessageManager.getInstance().sendFileMessage(
    FILE_URL,
    CAPTION,
    ROOM,
    QUOTED_MESSAGE,
    FILE_NAME,
    MIME_TYPE,
    FETCH_METADATA,
    object : TapCoreSendMessageListener() {
        override fun onTemporaryMessageCreated(message: TAPMessageModel?) {
            // Temporary message was created while fetching metadata
            // This callback will be called when FETCH_METADATA is true
        }
        
        override fun onStart(message: TAPMessageModel?) {
            // Message was constructed
        }
    
        // onProgress is not called when remote URL is provided
    
        override fun onSuccess(message: TAPMessageModel?) {
            // Message was sent successfully
        }
    
        override fun onError(message: TAPMessageModel?, errorCode: String?, errorMessage: String?) {

        }
    }
)
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`FILE`**: (File) file to be sent, can also be replaced with **`URI`**\
**`URI`**: (Uri) path of the file to be sent\
**`FILE_URL`**: (String) file to be sent, can also be replaced with **`URI`**\
**`CAPTION`**: (String) caption for the file\
**`ROOM`**: (TAPRoomModel) the destination room where the message will be sent\
**`QUOTED_MESSAGE`**: (TAPMessageModel) quote containing another existing message\
**`FETCH_METADATA`**: (boolean) inserts metadata from remote URL to the constructed message when true
{% endhint %}

### Send Voice Message

You can also send a voice note to a chat room using the `sendVoiceMessage()` method with a provided `FILE` or `URI`.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Listener.TapCoreSendMessageListener;
import io.taptalk.TapTalk.Model.TAPMessageModel;
import io.taptalk.TapTalk.Model.TAPRoomModel;

...

TapCoreMessageManager.getInstance().sendVoiceMessage(
    FILE or URI,
    ROOM,
    new TapCoreSendMessageListener() {
        @Override
        public void onStart(TAPMessageModel message) {
            // Message was constructed
        }
      
        @Override
        public void onProgress(TAPMessageModel message, int percentage, long bytes) {
            // File upload is in progress
        }
    
        @Override
        public void onSuccess(TAPMessageModel message) {
            // Message was sent successfully
        }
    
        @Override
        public void onError(@Nullable TAPMessageModel message, String errorCode, String errorMessage) {
          
        }
    }
);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Listener.TapCoreSendMessageListener
import io.taptalk.TapTalk.Model.TAPMessageModel
import io.taptalk.TapTalk.Model.TAPRoomModel

...

TapCoreMessageManager.getInstance().sendVoiceMessage(
    FILE or URI,
    ROOM,
    object : TapCoreSendMessageListener() {
        override fun onStart(message: TAPMessageModel?) {
            // Message was constructed
        }
    
        override fun onProgress(message: TAPMessageModel?, percentage: Int, bytes: Long) {
            // File upload is in progress
        }
    
        override fun onSuccess(message: TAPMessageModel?) {
            // Message was sent successfully
        }
    
        override fun onError(message: TAPMessageModel?, errorCode: String?, errorMessage: String?) {
    
        }
    }
)
```

{% endtab %}
{% endtabs %}

Use the `sendVoiceMessage()` method with extra parameter to send a file message with quote.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Listener.TapCoreSendMessageListener;
import io.taptalk.TapTalk.Model.TAPMessageModel;
import io.taptalk.TapTalk.Model.TAPRoomModel;

...

TapCoreMessageManager.getInstance().sendVoiceMessage(
    FILE,
    ROOM,
    QUOTED_MESSAGE,
    new TapCoreSendMessageListener() {
        @Override
        public void onStart(TAPMessageModel message) {
            // Message was constructed
        }
      
        @Override
        public void onProgress(TAPMessageModel message, int percentage, long bytes) {
            // File upload is in progress
        }
    
        @Override
        public void onSuccess(TAPMessageModel message) {
            // Message was sent successfully
        }
    
        @Override
        public void onError(@Nullable TAPMessageModel message, String errorCode, String errorMessage) {
          
        }
    }
);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Listener.TapCoreSendMessageListener
import io.taptalk.TapTalk.Model.TAPMessageModel
import io.taptalk.TapTalk.Model.TAPRoomModel

...

TapCoreMessageManager.getInstance().sendVoiceMessage(
    FILE,
    ROOM,
    QUOTED_MESSAGE,
    object : TapCoreSendMessageListener() {
        override fun onStart(message: TAPMessageModel?) {
            // Message was constructed
        }
    
        override fun onProgress(message: TAPMessageModel?, percentage: Int, bytes: Long) {
            // File upload is in progress
        }
    
        override fun onSuccess(message: TAPMessageModel?) {
            // Message was sent successfully
        }
    
        override fun onError(message: TAPMessageModel?, errorCode: String?, errorMessage: String?) {
    
        }
    }
)
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`FILE`**: (File) voice file to be sent, can also be replaced with **`URI`**\
**`URI`**: (Uri) path of the file to be sent\
**`ROOM`**: (TAPRoomModel) the destination room where the message will be sent\
**`QUOTED_MESSAGE`**: (TAPMessageModel) quote containing another existing message
{% endhint %}

### Send Link Message

You can send a link message, which is usually composed of a text message with URL on the body, using the `sendLinkMessage()` method.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Listener.TapCoreSendMessageListener;
import io.taptalk.TapTalk.Model.TAPMessageModel;
import io.taptalk.TapTalk.Model.TAPRoomModel;

...

TapCoreMessageManager.getInstance().sendLinkMessage(
    MESSAGE_BODY,
    ROOM,
    URLS,
    TITLE,
    DESCRIPTION,
    IMAGE,
    new TapCoreSendMessageListener() {
        @Override
        public void onStart(TAPMessageModel message) {
            // Message was constructed
        }
    
        @Override
        public void onSuccess(TAPMessageModel message) {
            // Message was sent successfully
        }
    
        @Override
        public void onError(@Nullable TAPMessageModel message, String errorCode, String errorMessage) {
          
        }
    }
);

// With additional metadata parameters
TapCoreMessageManager.getInstance().sendLinkMessage(
    MESSAGE_BODY,
    ROOM,
    URLS,
    TITLE,
    DESCRIPTION,
    IMAGE,
    SITE_NAME,
    TYPE,
    new TapCoreSendMessageListener() {
        @Override
        public void onStart(TAPMessageModel message) {
            // Message was constructed
        }
    
        @Override
        public void onSuccess(TAPMessageModel message) {
            // Message was sent successfully
        }
    
        @Override
        public void onError(@Nullable TAPMessageModel message, String errorCode, String errorMessage) {
          
        }
    }
);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Listener.TapCoreSendMessageListener
import io.taptalk.TapTalk.Model.TAPMessageModel
import io.taptalk.TapTalk.Model.TAPRoomModel

...

TapCoreMessageManager.getInstance().sendLinkMessage(
    MESSAGE_BODY,
    ROOM,
    URLS,
    TITLE,
    DESCRIPTION,
    IMAGE,
    object : TapCoreSendMessageListener() {
        override fun onStart(message: TAPMessageModel?) {
            // Message was constructed
        }
    
        override fun onSuccess(message: TAPMessageModel?) {
            // Message was sent successfully
        }
    
        override fun onError(message: TAPMessageModel?, errorCode: String?, errorMessage: String?) {
    
        }
    }
)
    
// With additional metadata parameters
TapCoreMessageManager.getInstance().sendLinkMessage(
    MESSAGE_BODY,
    ROOM,
    URLS,
    TITLE,
    DESCRIPTION,
    IMAGE,
    SITE_NAME,
    TYPE,
    object : TapCoreSendMessageListener() {
        override fun onStart(message: TAPMessageModel?) {
            // Message was constructed
        }
    
        override fun onSuccess(message: TAPMessageModel?) {
            // Message was sent successfully
        }
    
        override fun onError(message: TAPMessageModel?, errorCode: String?, errorMessage: String?) {
    
        }
    }
)
```

{% endtab %}
{% endtabs %}

Use the `sendLinkMessage()` method with extra parameters to send a link message with quote.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Listener.TapCoreSendMessageListener;
import io.taptalk.TapTalk.Model.TAPMessageModel;
import io.taptalk.TapTalk.Model.TAPRoomModel;

...

TapCoreMessageManager.getInstance().sendLinkMessage(
    MESSAGE_BODY,
    ROOM,
    QUOTED_MESSAGE,
    URLS,
    TITLE,
    DESCRIPTION,
    IMAGE,
    new TapCoreSendMessageListener() {
        @Override
        public void onStart(TAPMessageModel message) {
            // Message was constructed
        }
    
        @Override
        public void onSuccess(TAPMessageModel message) {
            // Message was sent successfully
        }
    
        @Override
        public void onError(@Nullable TAPMessageModel message, String errorCode, String errorMessage) {
          
        }
    }
);
    
// With additional metadata parameters
TapCoreMessageManager.getInstance().sendLinkMessage(
    MESSAGE_BODY,
    ROOM,
    QUOTED_MESSAGE,
    URLS,
    TITLE,
    DESCRIPTION,
    IMAGE,
    SITE_NAME,
    TYPE,
    new TapCoreSendMessageListener() {
        @Override
        public void onStart(TAPMessageModel message) {
            // Message was constructed
        }
    
        @Override
        public void onSuccess(TAPMessageModel message) {
            // Message was sent successfully
        }
    
        @Override
        public void onError(@Nullable TAPMessageModel message, String errorCode, String errorMessage) {
          
        }
    }
);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Listener.TapCoreSendMessageListener
import io.taptalk.TapTalk.Model.TAPMessageModel
import io.taptalk.TapTalk.Model.TAPRoomModel

...

TapCoreMessageManager.getInstance().sendLinkMessage(
    MESSAGE_BODY,
    ROOM,
    QUOTED_MESSAGE,
    URLS,
    TITLE,
    DESCRIPTION,
    IMAGE,
    object : TapCoreSendMessageListener() {
        override fun onStart(message: TAPMessageModel?) {
            // Message was constructed
        }
    
        override fun onSuccess(message: TAPMessageModel?) {
            // Message was sent successfully
        }
    
        override fun onError(message: TAPMessageModel?, errorCode: String?, errorMessage: String?) {
    
        }
    }
)
    
// With additional metadata parameters
TapCoreMessageManager.getInstance().sendLinkMessage(
    MESSAGE_BODY,
    ROOM,
    QUOTED_MESSAGE,
    URLS,
    TITLE,
    DESCRIPTION,
    IMAGE,
    SITE_NAME,
    TYPE,
    object : TapCoreSendMessageListener() {
        override fun onStart(message: TAPMessageModel?) {
            // Message was constructed
        }
    
        override fun onSuccess(message: TAPMessageModel?) {
            // Message was sent successfully
        }
    
        override fun onError(message: TAPMessageModel?, errorCode: String?, errorMessage: String?) {
    
        }
    }
)
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`MESSAGE_BODY`**: (String) content of the message\
**`ROOM`**: (TAPRoomModel) the destination room where the message will be sent\
**`QUOTED_MESSAGE`**: (TAPMessageModel) quote containing another existing message\
**`URLS`**: (List\<String>) list of URLs contained in the message\
**`TITLE`**: (String) `og:title` metadata of the specified URL\
**`DESCRIPTION`**: (String) `og:description` metadata of the specified URL\
**`IMAGE`**: (String) `og:image` metadata of the specified URL\
**`SITE_NAME`**: (String) `og:site_name` metadata of the specified URL\
**`TYPE`**: (String) `og:type` metadata of the specified URL
{% endhint %}

### Forward Message

To forward existing messages to chat room, call the `sendForwardedMessage()` method. You may also use `sendForwardedMessages()` to forward multiple messages at once, or `sendForwardedMessageToMultipleRooms()` or `sendForwardedMessagesToMultipleRooms()` to forward messages to multiple rooms at once.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Listener.TapCoreSendMessageListener;
import io.taptalk.TapTalk.Model.TAPMessageModel;
import io.taptalk.TapTalk.Model.TAPRoomModel;

...

// Forward a message
TapCoreMessageManager.getInstance().sendForwardedMessage(
    MESSAGE_TO_FORWARD,
    ROOM,
    new TapCoreSendMessageListener() {
    @Override
    public void onStart(TAPMessageModel message) {
        // New message to be forwarded was constructed
    }

    @Override
    public void onSuccess(TAPMessageModel message) {
        // Message was sent successfully
    }

    @Override
    public void onError(@Nullable TAPMessageModel message, String errorCode, String errorMessage) {
      
    }
});

// Forward multiple messages at once
TapCoreMessageManager.getInstance().sendForwardedMessages(
    MESSAGES_TO_FORWARD,
    ROOM,
    new TapCoreSendMessageListener() {
        @Override
        public void onStart(TAPMessageModel message) {
            // New message to be forwarded was constructed
        }
    
        @Override
        public void onSuccess(TAPMessageModel message) {
            // Message was sent successfully
        }
    
        @Override
        public void onError(@Nullable TAPMessageModel message, String errorCode, String errorMessage) {
          
        }
    }
);
    
// Forward a message to multiple chat rooms
TapCoreMessageManager.getInstance().sendForwardedMessageToMultipleRooms(
    MESSAGE_TO_FORWARD,
    ROOMS,
    new TapCoreSendMessageListener() {
        @Override
        public void onStart(TAPMessageModel message) {
            // New message to be forwarded was constructed
        }
    
        @Override
        public void onSuccess(TAPMessageModel message) {
            // Message was sent successfully
        }
    
        @Override
        public void onError(@Nullable TAPMessageModel message, String errorCode, String errorMessage) {
          
        }
    }
);

// Forward multiple messages to multiple chat rooms at once
TapCoreMessageManager.getInstance().sendForwardedMessagesToMultipleRooms(
    MESSAGES_TO_FORWARD,
    ROOMS,
    new TapCoreSendMessageListener() {
        @Override
        public void onStart(TAPMessageModel message) {
            // New message to be forwarded was constructed
        }
    
        @Override
        public void onSuccess(TAPMessageModel message) {
            // Message was sent successfully
        }
    
        @Override
        public void onError(@Nullable TAPMessageModel message, String errorCode, String errorMessage) {
          
        }
    }
);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Listener.TapCoreSendMessageListener
import io.taptalk.TapTalk.Model.TAPMessageModel
import io.taptalk.TapTalk.Model.TAPRoomModel

...

// Forward a message
TapCoreMessageManager.getInstance().sendForwardedMessage(
    MESSAGE_TO_FORWARD,
    ROOM,
    object : TapCoreSendMessageListener() {
        override fun onStart(message: TAPMessageModel?) {
            // New message to be forwarded was constructed
        }
    
        override fun onSuccess(message: TAPMessageModel?) {
            // Message was sent successfully
        }
    
        override fun onError(message: TAPMessageModel?, errorCode: String?, errorMessage: String?) {
    
        }
    }
)
    
// Forward multiple messages at once
TapCoreMessageManager.getInstance().sendForwardedMessages(
    MESSAGES_TO_FORWARD,
    ROOM,
    object : TapCoreSendMessageListener() {
        override fun onStart(message: TAPMessageModel?) {
            // New message to be forwarded was constructed
        }
    
        override fun onSuccess(message: TAPMessageModel?) {
            // Message was sent successfully
        }
    
        override fun onError(message: TAPMessageModel?, errorCode: String?, errorMessage: String?) {
    
        }
    }
)

// Forward a message to multiple chat rooms
TapCoreMessageManager.getInstance().sendForwardedMessageToMultipleRooms(
    MESSAGE_TO_FORWARD,
    ROOMS,
    object : TapCoreSendMessageListener() {
        override fun onStart(message: TAPMessageModel?) {
            // New message to be forwarded was constructed
        }
    
        override fun onSuccess(message: TAPMessageModel?) {
            // Message was sent successfully
        }
    
        override fun onError(message: TAPMessageModel?, errorCode: String?, errorMessage: String?) {
    
        }
    }
)

// Forward multiple messages to multiple chat rooms at once
TapCoreMessageManager.getInstance().sendForwardedMessagesToMultipleRooms(
    MESSAGES_TO_FORWARD,
    ROOMS,
    object : TapCoreSendMessageListener() {
        override fun onStart(message: TAPMessageModel?) {
            // New message to be forwarded was constructed
        }
    
        override fun onSuccess(message: TAPMessageModel?) {
            // Message was sent successfully
        }
    
        override fun onError(message: TAPMessageModel?, errorCode: String?, errorMessage: String?) {
    
        }
    }
)
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`MESSAGE_TO_FORWARD`**: (TAPMessageModel) existing message to be forwarded\
**`MESSAGES_TO_FORWARD`**: (List\<TAPMessageModel>) list of messages to be forwarded\
**`ROOM`**: (TAPRoomModel) the destination room where the message will be forwarded\
**`ROOMS`**: (List\<TAPRoomModel>) list of destination rooms where the message will be forwarded
{% endhint %}

### Construct TapTalk.io Message Model

You can construct your own customized message model to be used in chat as shown below.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Model.TAPMessageModel;
import io.taptalk.TapTalk.Model.TAPRoomModel;

...

// Create custom message
TAPMessageModel customMessage = TapCoreMessageManager.getInstance().constructTapTalkMessageModel(
    MESSAGE_BODY,
    ROOM,
    MESSAGE_TYPE,
    MESSAGE_DATA
);

// Create custom message with quote
TAPMessageModel customMessageWithQuote = TapCoreMessageManager.getInstance().constructTapTalkMessageModelWithQuote(
    MESSAGE_BODY,
    ROOM,
    MESSAGE_TYPE,
    MESSAGE_DATA,
    QUOTED_MESSAGE
);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Model.TAPMessageModel
import io.taptalk.TapTalk.Model.TAPRoomModel

...

// Create custom message
val customMessage = TapCoreMessageManager.getInstance().constructTapTalkMessageModel(
    MESSAGE_BODY,
    ROOM,
    MESSAGE_TYPE,
    MESSAGE_DATA
)

// Create custom message with quote
val customMessageWithQuote = TapCoreMessageManager.getInstance().constructTapTalkMessageModelWithQuote(
    MESSAGE_BODY,
    ROOM,
    MESSAGE_TYPE.toInt(),
    MESSAGE_DATA,
    QUOTED_MESSAGE
)
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`MESSAGE_BODY`**: (String) content of the message\
**`ROOM`**: (TAPRoomModel) the destination room where the message will be sent\
**`MESSAGE_TYPE`**: (Integer) type of your custom message, check the [Message Type page](/powertalk-chat-sdk-documentation/powertalk-android/message-type) for more information\
**`MESSAGE_DATA`**: (HashMap\<String, Object>) custom data for the message (optional)\
**`QUOTED_MESSAGE`**: (TAPMessageModel) quote of the new message model containing another existing message
{% endhint %}

{% hint style="info" %}
**Note**: you are free to put any data that you need for your custom message in the **`MESSAGE_DATA`**&#x70;arameter, to obtain message data from a **TAPMessageModel**, use the **`TAPMessageModel.getData()`**&#x6D;ethod
{% endhint %}

### Send a Custom Message

To send a custom message that you just created above, call the `sendCustomMessage()` method with the custom message as a parameter.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Listener.TapCoreSendMessageListener;
import io.taptalk.TapTalk.Model.TAPMessageModel;

...

TapCoreMessageManager.getInstance().sendCustomMessage(CUSTOM_MESSAGE, new TapCoreSendMessageListener() {
    @Override
    public void onStart(TAPMessageModel message) {
        // Message is being processed
    }

    @Override
    public void onSuccess(TAPMessageModel message) {
        // Message was sent successfully
    }

    @Override
    public void onError(@Nullable TAPMessageModel message, String errorCode, String errorMessage) {
      
    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Listener.TapCoreSendMessageListener
import io.taptalk.TapTalk.Model.TAPMessageModel

...

TapCoreMessageManager.getInstance().sendCustomMessage(CUSTOM_MESSAGE, object : TapCoreSendMessageListener() {
    override fun onStart(message: TAPMessageModel?) {
        // Message is being processed
    }

    override fun onSuccess(message: TAPMessageModel?) {
        // Message was sent successfully
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`CUSTOM_MESSAGE`**: (TAPMessageModel) the message to be sent, see the [Construct TapTalk.io Message Model](/powertalk-chat-sdk-documentation/powertalk-android/group-chat/tapcore#construct-taptalk-io-message-model) section to construct a custom message
{% endhint %}

### Edit Message

To update the contents of a message, you may use the `editMessage()` method from **TapCoreMessageManager** class. Editing is currently available for text message, and image or video message caption.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Listener.TapCoreSendMessageListener;
import io.taptalk.TapTalk.Model.TAPMessageModel;

...

TapCoreMessageManager.getInstance().editMessage(MESSAGE_MODEL, UPDATED_TEXT, new TapCoreSendMessageListener() {
    @Override
    public void onStart(TAPMessageModel message) {
        // Message is being processed
    }

    @Override
    public void onSuccess(TAPMessageModel message) {
        // Message was edited successfully
    }

    @Override
    public void onError(@Nullable TAPMessageModel message, String errorCode, String errorMessage) {
      
    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Listener.TapCoreSendMessageListener
import io.taptalk.TapTalk.Model.TAPMessageModel

...

TapCoreMessageManager.getInstance().deleteMessage(MESSAGE_MODEL, UPDATED_TEXT, object : TapCoreSendMessageListener() {
    override fun onStart(message: TAPMessageModel?) {
        // Message is being processed
    }

    override fun onSuccess(message: TAPMessageModel?) {
        // Message was sent successfully
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`MESSAGE_MODEL`**: (TAPMessageModel) the message to be updated\
**`UPDATED_TEXT`**: (String) new text to replace the body and caption of the message
{% endhint %}

### Delete Message

To delete a message permanently from the server, call `deleteMessage()` from **TapCoreMessageManager** class. When the message is successfully deleted, **TapCoreMessageListener** will invoke **onMessageDeleted()** callback.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Model.TAPMessageModel;

...

TapCoreMessageManager.getInstance().deleteMessage(MESSAGE_MODEL);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Model.TAPMessageModel

...

TapCoreMessageManager.getInstance().deleteMessage(MESSAGE_MODEL)
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`MESSAGE_MODEL`**: (TAPMessageModel) the message to be deleted
{% endhint %}

### Delete Message from Local Cache

To delete a message from local cache, call `deleteLocalMessage()` from **TapCoreMessageManager** class.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;

...

TapCoreMessageManager.getInstance().deleteLocalMessage(MESSAGE_LOCAL_ID);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager

...

TapCoreMessageManager.getInstance().deleteLocalMessage(MESSAGE_LOCAL_ID)
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`MESSAGE_LOCAL_ID`**: (String) local ID of the message to delete
{% endhint %}

### Cancel Message File Upload

Messages such as **Image**, **Video**, and **File** messages requires a file upload completion before the message is sent. To cancel an ongoing file upload of a message, call the `cancelMessageFileUpload()` method.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Model.TAPMessageModel;

...

TapCoreMessageManager.getInstance().cancelMessageFileUpload(MESSAGE);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Model.TAPMessageModel

...

TapCoreMessageManager.getInstance().cancelMessageFileUpload(MESSAGE)
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`MESSAGE`**: (TAPMessageModel) pending message with ongoing file upload
{% endhint %}

### Download Message File

To start a file download from a **File**, **Image**, or **Video** message, you can use the `downloadMessageFile()` method.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Listener.TapCoreFileDownloadListener;
import io.taptalk.TapTalk.Model.TAPMessageModel;

...

TapCoreMessageManager.getInstance().downloadMessageFile(MESSAGE, new TapCoreFileDownloadListener() {
    @Override
    public void onSuccess(TAPMessageModel message, File file) {
        // File downloaded successfully
    }

    @Override
    public void onProgress(TAPMessageModel message, int percentage, long bytes) {
        // File download is in progress
    }

    @Override
    public void onError(TAPMessageModel message, String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Listener.TapCoreFileDownloadListener
import io.taptalk.TapTalk.Model.TAPMessageModel

...

TapCoreMessageManager.getInstance().downloadMessageFile(MESSAGE, object : TapCoreFileDownloadListener() {
    override fun onSuccess(message: TAPMessageModel?, file: File) {
        // File downloaded successfully
    }

    override fun onProgress(message: TAPMessageModel?, percentage: Int, bytes: Long) {
        // File download is in progress
    }

    override fun onError(message: TAPMessageModel?, errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`MESSAGE`**: (TAPMessageModel) existing message to download the file from
{% endhint %}

### Cancel Message File Download

You can cancel download message with type such as **Image**, **Video**, and **File** by calling the `cancelMessageFileDownload()` method.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Model.TAPMessageModel;

...

TapCoreMessageManager.getInstance().cancelMessageFileDownload(MESSAGE);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Model.TAPMessageModel

...

TapCoreMessageManager.getInstance().cancelMessageFileDownload(MESSAGE)
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`MESSAGE`**: (TAPMessageModel) selected message with ongoing file download
{% endhint %}

### Upload Image

You can upload an image file to TapTalk.io server without sending message. The response will return the uploaded file ID and URL.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Listener.TapCoreFileUploadListener;

...

TapCoreMessageManager.getInstance(instanceKey).uploadImage(CONTEXT, IMAGE_URI, new TapCoreFileUploadListener() {
    @Override
    public void onStart(File file, Uri uri) {
        // Returns the compressed image file and uri before upload is started
    }  
    
    @Override
    public void onProgress(int percentage, long bytes) {
        // File upload in in progress
    }
    
    @Override
    public void onSuccess(String fileID, String fileURL) {
        // Successfully uploaded file
    }
    
    @Override
    public void onError(String errorCode, String errorMessage) {
        
    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Listener.TapCoreFileUploadListener

...

TapCoreMessageManager.getInstance(instanceKey).uploadImage(CONTEXT, IMAGE_URI, object : TapCoreFileUploadListener() {
    override fun onStart(file: File, uri: Uri) {
        // Returns the compressed image file and uri before upload is started
    }
    
    override fun onProgress(percentage: Int, bytes: Long) {
        // File upload in in progress
    }
    
    override fun onSuccess(fileID: String, fileURL: String) {
        // Successfully uploaded file
    }
    
    override fun onError(errorCode: String, errorMessage: String) {

    }
})
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`CONTEXT`**: (Context) your Application or Activity context\
**`IMAGE_URI`**: (Uri) local Uri of the image file
{% endhint %}

### Upload Video

You can upload a video file to TapTalk.io server without sending message. The response will return the uploaded file ID and URL.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Listener.TapCoreFileUploadListener;

...

TapCoreMessageManager.getInstance(instanceKey).uploadVideo(CONTEXT, VIDEO_URI, new TapCoreFileUploadListener() {
    @Override
    public void onStart(File file, Uri uri) {
        // Returns the file and uri before upload is started
    }
    
    @Override
    public void onProgress(int percentage, long bytes) {
        // File upload in in progress
    }
    
    @Override
    public void onSuccess(String fileID, String fileURL) {
        // Successfully uploaded file
    }
    
    @Override
    public void onError(String errorCode, String errorMessage) {
        
    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Listener.TapCoreFileUploadListener

...

TapCoreMessageManager.getInstance(instanceKey).uploadVideo(CONTEXT, VIDEO_URI, object : TapCoreFileUploadListener() {
    override fun onStart(file: File, uri: Uri) {
        // Returns the file and uri before upload is started
    }
    
    override fun onProgress(percentage: Int, bytes: Long) {
        // File upload in in progress
    }
    
    override fun onSuccess(fileID: String, fileURL: String) {
        // Successfully uploaded file
    }
    
    override fun onError(errorCode: String, errorMessage: String) {

    }
})
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`CONTEXT`**: (Context) your Application or Activity context\
**`VIDEO_URI`**: (Uri) local Uri of the video file
{% endhint %}

### Upload File

You can also upload other formats of file/document to TapTalk.io server without sending message. The response will return the uploaded file ID and URL.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Listener.TapCoreFileUploadListener;

...

TapCoreMessageManager.getInstance(instanceKey).uploadFile(CONTEXT, FILE_URI, new TapCoreFileUploadListener() {
    @Override
    public void onStart(File file, Uri uri) {
        // Returns the file and uri before upload is started
    }
    
    @Override
    public void onProgress(int percentage, long bytes) {
        // File upload in in progress
    }
    
    @Override
    public void onSuccess(String fileID, String fileURL) {
        // Successfully uploaded file
    }
    
    @Override
    public void onError(String errorCode, String errorMessage) {
        
    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Listener.TapCoreFileUploadListener

...

TapCoreMessageManager.getInstance(instanceKey).uploadFile(CONTEXT, FILE_URI, object : TapCoreFileUploadListener() {
    override fun onStart(file: File, uri: Uri) {
        // Returns the file and uri before upload is started
    }
    
    override fun onProgress(percentage: Int, bytes: Long) {
        // File upload in in progress
    }
    
    override fun onSuccess(fileID: String, fileURL: String) {
        // Successfully uploaded file
    }
    
    override fun onError(errorCode: String, errorMessage: String) {

    }
})
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`CONTEXT`**: (Context) your Application or Activity context\
**`FILE_URI`**: (Uri) local Uri of the file
{% endhint %}

### Mark Message as Delivered

To manually mark a message as delivered, call the `markMessageAsDelivered()` method.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Model.TAPMessageModel;

...

TapCoreMessageManager.getInstance().markMessageAsDelivered(MESSAGE);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Model.TAPMessageModel

...

TapCoreMessageManager.getInstance().markMessageAsDelivered(MESSAGE)
```

{% endtab %}
{% endtabs %}

### Mark Message as Read

To manually mark a message as read, call the `markMessageAsRead()` method. You can also mark multiple messages as read at once using `markMessagesAsRead()`.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Listener.TapCoreUpdateMessageStatusListener;
import io.taptalk.TapTalk.Model.TAPMessageModel;

...

// Mark single message as read with message model
TapCoreMessageManager.getInstance().markMessageAsRead(MESSAGE);


// Mark single message as read with message ID
TapCoreMessageManager.getInstance().markMessageAsRead(MESSAGE_ID);


// Mark multiple messages as read with list of message IDs
TapCoreMessageManager.getInstance().markMessagesAsRead(MESSAGE_IDS);


// Mark multiple messages as read with list of message IDs and completion listener
TapCoreMessageManager.getInstance().markMessagesAsRead(MESSAGE_IDS, new TapCoreUpdateMessageStatusListener() {
    @Override
    public void onSuccess(List<String> updatedMessageIDs) {
        // updatedMessageIDs contains message IDs that were successfully marked as read
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});

```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Listener.TapCoreUpdateMessageStatusListener
import io.taptalk.TapTalk.Model.TAPMessageModel

...

// Mark single message as read with message model
TapCoreMessageManager.getInstance().markMessageAsRead(MESSAGE)


// Mark single message as read with message ID
TapCoreMessageManager.getInstance().markMessageAsRead(MESSAGE_ID)


// Mark multiple messages as read with list of message IDs
TapCoreMessageManager.getInstance().markMessagesAsRead(MESSAGE_IDS)


// Mark multiple messages as read with list of message IDs and completion listener
TapCoreMessageManager.getInstance().markMessagesAsRead(MESSAGE_IDS, object : TapCoreUpdateMessageStatusListener() {
    override fun onSuccess(updatedMessageIDs: List<String>?) {
        // updatedMessageIDs contains message IDs that were successfully marked as read
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`MESSAGE`**: (TAPMessageModel) existing message to be marked as read\
**`MESSAGE_ID`**: (String) message ID from an existing message to be marked as read\
**`MESSAGE_IDS`**: (String) message ID from an existing message to be marked as read
{% endhint %}

### Mark All Chat Room Messages as Read

To quickly mark all unread messages in a chat room as read, call `markAllMessageInRoomAsRead()` method.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Listener.TapCoreUpdateMessageStatusListener;

...

// Mark all unread messages in specified chat room as read
TapCoreMessageManager.getInstance().markAllMessagesInRoomAsRead(ROOM_ID);


// Mark all unread messages in specified chat room as read with completion listener
TapCoreMessageManager.getInstance().markAllMessagesInRoomAsRead(ROOM_ID, new TapCoreUpdateMessageStatusListener() {
    @Override
    public void onSuccess(List<String> updatedMessageIDs) {
        // updatedMessageIDs contains message IDs that were successfully marked as read
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});

```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Listener.TapCoreUpdateMessageStatusListener

...

// Mark all unread messages in specified chat room as read
TapCoreMessageManager.getInstance().markAllMessagesInRoomAsRead(ROOM_ID)


// Mark all unread messages in specified chat room as read with completion listener
TapCoreMessageManager.getInstance().markAllMessagesInRoomAsRead(ROOM_ID, object : TapCoreUpdateMessageStatusListener() {
    override fun onSuccess(updatedMessageIDs: List<String>?) {
        // updatedMessageIDs contains message IDs that were successfully marked as read
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`ROOM_ID`**: (String) room ID of the messages to be marked as read
{% endhint %}

### Get Local Messages from Chat Room

In a chat room, you can retrieve messages that are already stored in the device's local storage by calling `getLocalMessages()` method.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Listener.TapCoreGetMessageListener;
import io.taptalk.TapTalk.Model.TAPMessageModel;

...

TapCoreMessageManager.getInstance().getLocalMessages(ROOM_ID, new TapCoreGetMessageListener() {
    @Override
    public void onSuccess(List<TAPMessageModel> messages) {
        // Retrieved messages successfully
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Listener.TapCoreGetMessageListener
import io.taptalk.TapTalk.Model.TAPMessageModel

...

TapCoreMessageManager.getInstance().getLocalMessages(ROOM_ID, object : TapCoreGetMessageListener() {
    override fun onSuccess(messages: List<TAPMessageModel>?) {
        // Retrieved messages successfully
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`ROOM_ID`**: (String) the room ID to retrieve the messages for
{% endhint %}

Retrieving local messages is fast and reliable, but may not contain all messages available in the selected chat room. To obtain more messages that are available from the server, you may use `getOlderMessagesBeforeTimestamp()` and `getNewerMessagesAfterTimestamp()` methods.

### Get Older Messages from Chat Room

To retrieve older messages in a chat room from the server, use the `getOlderMessagesBeforeTimestamp()` method.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Listener.TapCoreGetOlderMessageListener;
import io.taptalk.TapTalk.Model.TAPMessageModel;

...

TapCoreMessageManager.getInstance().getOlderMessagesBeforeTimestamp(
    ROOM_ID,
    MAX_CREATED_TIMESTAMP,
    NUMBER_OF_ITEMS,
    new TapCoreGetOlderMessageListener() {
        @Override
        public void onSuccess(List<TAPMessageModel> messages, Boolean hasMoreData) {
            // hasMoreData will return true if more messages that have not been retrieved remain in the chat room
        }
    
        @Override
        public void onError(String errorCode, String errorMessage) {
    
        }
    }
);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Listener.TapCoreGetOlderMessageListener
import io.taptalk.TapTalk.Model.TAPMessageModel

...

TapCoreMessageManager.getInstance().getOlderMessagesBeforeTimestamp(
    ROOM_ID,
    MAX_CREATED_TIMESTAMP,
    NUMBER_OF_ITEMS,
    object : TapCoreGetOlderMessageListener() {
        override fun onSuccess(messages: List<TAPMessageModel>, hasMoreData: Boolean?) {
            // hasMoreData will return true if more messages that have not been retrieved remain in the chat room
        }
    
        override fun onError(errorCode: String?, errorMessage: String?) {
    
        }
    }
)
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`ROOM_ID`**: (String) the room ID to retrieve the messages for\
**`MAX_CREATED_TIMESTAMP`**: (long) the maximum created time of the messages to retrieve, in milliseconds\
**`NUMBER_OF_ITEMS`**: (int) maximum limit of the number of messages to retrieve
{% endhint %}

### Get Newer Messages from Chat Room

To retrieve newer messages in a chat room from the server, use the `getNewerMessagesAfterTimestamp()` method.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Listener.TapCoreGetMessageListener;
import io.taptalk.TapTalk.Model.TAPMessageModel;

...

TapCoreMessageManager.getInstance().getNewerMessagesAfterTimestamp(
    ROOM_ID,
    MIN_CREATED_TIMESTAMP,
    LAST_UPDATE_TIMESTAMP,
    new TapCoreGetMessageListener() {
        @Override
        public void onSuccess(List<TAPMessageModel> messages) {
            // Retrieved messages successfully
        }
    
        @Override
        public void onError(String errorCode, String errorMessage) {
    
        }
    }
);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Listener.TapCoreGetMessageListener
import io.taptalk.TapTalk.Model.TAPMessageModel

...

TapCoreMessageManager.getInstance().getNewerMessagesAfterTimestamp(
    ROOM_ID,
    MIN_CREATED_TIMESTAMP,
    LAST_UPDATE_TIMESTAMP,
    object : TapCoreGetMessageListener() {
        override fun onSuccess(messages: List<TAPMessageModel>?) {
            // Retrieved messages successfully
        }
    
        override fun onError(errorCode: String?, errorMessage: String?) {
    
        }
    }
)
```

{% endtab %}
{% endtabs %}

You can also call `getNewerMessages()` without providing `MIN_CREATED_TIMESTAMP` and `LAST_UPDATE_TIMESTAMP`, only providing `ROOM_ID` as the parameter. With this method, `MIN_CREATED_TIMESTAMP` will automatically be set to the oldest existing message's created time in the room, and `LAST_UPDATE_TIMESTAMP` will be obtained from local cache.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Listener.TapCoreGetMessageListener;
import io.taptalk.TapTalk.Model.TAPMessageModel;

...

TapCoreMessageManager.getInstance().getNewerMessages(ROOM_ID, new TapCoreGetMessageListener() {
    @Override
    public void onSuccess(List<TAPMessageModel> messages) {
        // Retrieved messages successfully
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Listener.TapCoreGetMessageListener
import io.taptalk.TapTalk.Model.TAPMessageModel

...

TapCoreMessageManager.getInstance().getNewerMessages(ROOM_ID, object : TapCoreGetMessageListener() {
    override fun onSuccess(messages: List<TAPMessageModel>?) {
        // Retrieved messages successfully
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`ROOM_ID`**: (String) the room ID to retrieve the messages for\
**`MIN_CREATED_TIMESTAMP`**: (long) the minimum created time of the messages to retrieve, in millisecond\
**`LAST_UPDATE_TIMESTAMP`**: (long) the minimum updated time of the messages to retrieve, in milliseconds\
**`NUMBER_OF_ITEMS`**: (int) maximum limit of the number of messages to retrieve
{% endhint %}

### Get All Messages from Chat Room

You may also retrieve all available messages from a chat room using the `getAllMessagesFromRoom()` method.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Listener.TapCoreGetAllMessageListener;
import io.taptalk.TapTalk.Model.TAPMessageModel;

...

TapCoreMessageManager.getInstance().getAllMessagesFromRoom(ROOM_ID, new TapCoreGetAllMessageListener() {
    @Override
    public void onGetLocalMessagesCompleted(List<TAPMessageModel> messages) {
        // Retrieved local messages from room
    }
    
    @Override
    public void onGetAllMessagesCompleted(List<TAPMessageModel> allMessages, List<TAPMessageModel> olderMessages, List<TAPMessageModel> newerMessages) {
        // Successfully retrieved all messages from room
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Listener.TapCoreGetAllMessageListener
import io.taptalk.TapTalk.Model.TAPMessageModel

...

TapCoreMessageManager.getInstance().getAllMessagesFromRoom(ROOM_ID, object : TapCoreGetAllMessageListener() {
    override fun onGetLocalMessagesCompleted(messages: List<TAPMessageModel>?) {
        // Retrieved local messages from room
    }
    
    override fun onGetAllMessagesCompleted(allMessages: List<TAPMessageModel>?, olderMessages: List<TAPMessageModel>?, newerMessages: List<TAPMessageModel>?) {
        // Successfully retrieved all messages from room
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`ROOM_ID`**: (String) the room ID to retrieve the messages from
{% endhint %}

`getAllMessagesFromRoom()` is convenient to obtain all existing chat room messages since the beginning of the room creation, but the process **will take longer** depending on the number of messages contained in the selected room.\
\
`TapCoreGetAllMessageListener` will trigger two callbacks sequentially during the process of retrieving messages:\
• `onGetLocalMessagesCompleted()` will be triggered first once local messages are retrieved, the process will then continue to retrieve more messages from the server.\
• `onGetAllMessagesCompleted()` will be triggered after all messages from the server are successfully retrieved, this callback contains three parameters containing all messages, older messages (that did not exist in local storage), and newer messages that have recently been updated), the latter two parameters might be empty depending on the situation.

### Get Unread Messages from Chat Room

You can retrieve unread messages from the device's local storage by calling `getUnreadMessagesFromRoom()` method.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Listener.TapCoreGetMessageListener;
import io.taptalk.TapTalk.Model.TAPMessageModel;

...

TapCoreMessageManager.getInstance().getUnreadMessagesFromRoom(ROOM_ID, new TapCoreGetMessageListener() {
    @Override
    public void onSuccess(List<TAPMessageModel> messages) {
        // Retrieved messages successfully
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Listener.TapCoreGetMessageListener
import io.taptalk.TapTalk.Model.TAPMessageModel

...

TapCoreMessageManager.getInstance().getUnreadMessagesFromRoom(ROOM_ID, object : TapCoreGetMessageListener() {
    override fun onSuccess(messages: List<TAPMessageModel>?) {
        // Retrieved messages successfully
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`ROOM_ID`**: (String) the room ID to retrieve the messages from
{% endhint %}

### Get Media Messages from Chat Room

You can also retrieve media messages from the device's local storage, which consists of **image**, **video**, and **documents**, by calling `getMediaMessagesFromRoom()` method.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Listener.TapCoreGetMessageListener;
import io.taptalk.TapTalk.Model.TAPMessageModel;

...

TapCoreMessageManager.getInstance().getUnreadMessagesFromRoom(
    ROOM_ID,
    LAST_TIMESTAMP,
    NUMBER_OF_ITEM,
    new TapCoreGetMessageListener() {
        @Override
        public void onSuccess(List<TAPMessageModel> messages) {
            // Retrieved messages successfully
        }
    
        @Override
        public void onError(String errorCode, String errorMessage) {
    
        }
    }
);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Listener.TapCoreGetMessageListener
import io.taptalk.TapTalk.Model.TAPMessageModel

...

TapCoreMessageManager.getInstance().getMediaMessagesFromRoom(
    ROOM_ID,
    LAST_TIMESTAMP,
    NUMBER_OF_ITEM,
    object : TapCoreGetMessageListener() {
        override fun onSuccess(messages: List<TAPMessageModel>?) {
            // Retrieved messages successfully
        }
    
        override fun onError(errorCode: String?, errorMessage: String?) {
    
        }
    }
)
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`ROOM_ID`**: (String) the room ID to retrieve the messages from\
**`LAST_TIMESTAMP`**: (long)  the maximum created time of the messages to retrieve, in milliseconds\
**`NUMBER_OF_ITEM`**: (int) maximum limit of the number of messages to retrieve
{% endhint %}

### Search Local Message

Call this method to search messages from the device's local storage with a keyword. Provided keyword will be used to filter **message body** in the search result.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Listener.TapCoreGetMessageListener;
import io.taptalk.TapTalk.Model.TAPMessageModel;

...

TapCoreMessageManager.getInstance().searchLocalMessageWithKeyword(KEYWORD, new TapCoreGetMessageListener() {
    @Override
    public void onSuccess(List<TAPMessageModel> messages) {
        // Returns filtered messages obtained from local storage
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Listener.TapCoreGetMessageListener
import io.taptalk.TapTalk.Model.TAPMessageModel

...

TapCoreMessageManager.getInstance().searchLocalMessageWithKeyword(KEYWORD, object : TapCoreGetMessageListener() {
    override fun onSuccess(messages: List<TAPMessageModel>?) {
        // Returns filtered messages obtained from local storage
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`KEYWORD`**: (String) search keyword to filter message body
{% endhint %}

### Star/Unstar Messages

You may use these methods to mark a message or multiple messages as starred, or remove messages from the starred list. Only the active user can retrieve his/her own starred messages.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Listener.TapCoreGetStringArrayListener;

...

// Star single message
TapCoreMessageManager.getInstance().starMessage(ROOM_ID, MESSAGE_ID, new TapCoreGetStringArrayListener() {
    @Override
    public void onSuccess(ArrayList<String> arrayList) {
        // Returns list of messageID of starred messages
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});

// Star multiple messages
TapCoreMessageManager.getInstance().starMessages(ROOM_ID, MESSAGE_IDS, new TapCoreGetStringArrayListener() {
    @Override
    public void onSuccess(ArrayList<String> arrayList) {
        // Returns list of messageID of starred messages
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});

// Unstar single message
TapCoreMessageManager.getInstance().unstarMessage(ROOM_ID, MESSAGE_ID, new TapCoreGetStringArrayListener() {
    @Override
    public void onSuccess(ArrayList<String> arrayList) {
        // Returns list of messageID of unstarred messages
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});

// Unstar multiple messages
TapCoreMessageManager.getInstance().unstarMessages(ROOM_ID, MESSAGE_IDS, new TapCoreGetStringArrayListener() {
    @Override
    public void onSuccess(ArrayList<String> arrayList) {
        // Returns list of messageID of unstarred messages
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Listener.TapCoreGetStringArrayListener

...

// Star single message
TapCoreMessageManager.getInstance().starMessage(ROOM_ID, MESSAGE_ID, object : TapCoreGetStringArrayListener() {
    override fun onSuccess(arrayList: ArrayList<String>) {
        // Returns list of messageID of starred messages
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
});

// Star multiple messages
TapCoreMessageManager.getInstance().starMessages(ROOM_ID, MESSAGE_IDS, object : TapCoreGetStringArrayListener() {
    override fun onSuccess(arrayList: ArrayList<String>) {
        // Returns list of messageID of starred messages
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
});

// Unstar single message
TapCoreMessageManager.getInstance().unstarMessage(ROOM_ID, MESSAGE_ID, object : TapCoreGetStringArrayListener() {
    override fun onSuccess(arrayList: ArrayList<String>) {
        // Returns list of messageID of unstarred messages
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
});

// Unstar multiple messages
TapCoreMessageManager.getInstance().unstarMessages(ROOM_ID, MESSAGE_IDS, object : TapCoreGetStringArrayListener() {
    override fun onSuccess(arrayList: ArrayList<String>) {
        // Returns list of messageID of unstarred messages
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
});
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`ROOM_ID`**: (String) room ID, can be obtained from the message's room model\
**`MESSAGE_ID`**: (String) unique server ID from the message\
**`MESSAGE_IDS`**: (List\<String>) list containing message IDs to be starred/unstarred
{% endhint %}

### Get Starred Messages

You can use the method below get a list of message IDs marked as starred by the user.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Listener.TapCoreGetStringArrayListener;

...

TapCoreMessageManager.getInstance().getStarredMessageIds(ROOM_ID, new TapCoreGetStringArrayListener() {
    @Override
    public void onSuccess(ArrayList<String> arrayList) {
        // Returns list of messageID of starred messages
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Listener.TapCoreGetStringArrayListener

...

TapCoreMessageManager.getInstance().getStarredMessageIds(ROOM_ID, object : TapCoreGetStringArrayListener() {
    override fun onSuccess(arrayList: ArrayList<String>) {
        // Returns list of messageID of starred messages
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
});
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`ROOM_ID`**: (String) ID of the target room
{% endhint %}

A method to obtain the full message model list of the starred messages with pagination is also provided.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Listener.TapCoreGetOlderMessageListener;
import io.taptalk.TapTalk.Model.TAPMessageModel;

...

TapCoreMessageManager.getInstance().getStarredMessages(
    ROOM_ID,
    PAGE_NUMBER,
    NUMBER_OF_ITEMS,
    new TapCoreGetOlderMessageListener() {
        @Override
        public void onSuccess(List<TAPMessageModel> messages, Boolean hasMoreData) {
            // hasMoreData will return true if the room has remaining starred messages that have not been retrieved
        }
    
        @Override
        public void onError(String errorCode, String errorMessage) {
    
        }
    }
);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Listener.TapCoreGetOlderMessageListener
import io.taptalk.TapTalk.Model.TAPMessageModel

...

TapCoreMessageManager.getInstance().getStarredMessages(
    ROOM_ID,
    PAGE_NUMBER,
    NUMBER_OF_ITEMS,
    object : TapCoreGetOlderMessageListener() {
        override fun onSuccess(messages: List<TAPMessageModel>, hasMoreData: Boolean?) {
            // hasMoreData will return true if the room has remaining starred messages that have not been retrieved
        }
    
        override fun onError(errorCode: String?, errorMessage: String?) {
    
        }
    }
)
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`ROOM_ID`**: (String) ID of the target room\
**`PAGE_NUMBER`**: (int) the number of page to retrieve the items\
**`NUMBER_OF_ITEMS`**: (int) number of items to be retrieved
{% endhint %}

### Pin/Unpin Message

You may use these methods to pin or unpin a message or multiple messages in a chat room. Every participant in the room can retrieve the chat room's pinned messages.&#x20;

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Listener.TapCoreGetStringArrayListener;

...

// Pin single message
TapCoreMessageManager.getInstance().pinMessage(ROOM_ID, MESSAGE_ID, new TapCoreGetStringArrayListener() {
    @Override
    public void onSuccess(ArrayList<String> arrayList) {
        // Returns list of messageID of pinned messages
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});

// Pin multiple messages
TapCoreMessageManager.getInstance().pinMessage(ROOM_ID, MESSAGE_IDS, new TapCoreGetStringArrayListener() {
    @Override
    public void onSuccess(ArrayList<String> arrayList) {
        // Returns list of messageID of pinned messages
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});

// Unpin single message
TapCoreMessageManager.getInstance().unpinMessage(ROOM_ID, MESSAGE_ID, new TapCoreGetStringArrayListener() {
    @Override
    public void onSuccess(ArrayList<String> arrayList) {
        // Returns list of messageID of unpinned messages
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});

// Unpin multiple messages
TapCoreMessageManager.getInstance().unpinMessage(ROOM_ID, MESSAGE_IDS, new TapCoreGetStringArrayListener() {
    @Override
    public void onSuccess(ArrayList<String> arrayList) {
        // Returns list of messageID of unpinned messages
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Listener.TapCoreGetStringArrayListener

...

// Pin single message
TapCoreMessageManager.getInstance().pinMessage(ROOM_ID, MESSAGE_ID, object : TapCoreGetStringArrayListener() {
    override fun onSuccess(arrayList: ArrayList<String>) {
        // Returns list of messageID of pinned messages
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
});

// Pin multiple messages
TapCoreMessageManager.getInstance().pinMessage(ROOM_ID, MESSAGE_IDS, object : TapCoreGetStringArrayListener() {
    override fun onSuccess(arrayList: ArrayList<String>) {
        // Returns list of messageID of pinned messages
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
});

// Unpin single message
TapCoreMessageManager.getInstance().unpinMessage(ROOM_ID, MESSAGE_ID, object : TapCoreGetStringArrayListener() {
    override fun onSuccess(arrayList: ArrayList<String>) {
        // Returns list of messageID of unpinned messages
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
});

// Unpin multiple messages
TapCoreMessageManager.getInstance().unpinMessage(ROOM_ID, MESSAGE_IDS, object : TapCoreGetStringArrayListener() {
    override fun onSuccess(arrayList: ArrayList<String>) {
        // Returns list of messageID of unpinned messages
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
});
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`ROOM_ID`**: (String) room ID, can be obtained from the message's room model\
**`MESSAGE_ID`**: (String) unique server ID from the message\
**`MESSAGE_IDS`**: (List\<String>) list containing message IDs to be pinned/unpinned
{% endhint %}

### Get Pinned Messages

You can use the method below get a list of message IDs of pinned messages in a chat room.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Listener.TapCoreGetStringArrayListener;

...

TapCoreMessageManager.getInstance().getPinnedMessageIDs(ROOM_ID, new TapCoreGetStringArrayListener() {
    @Override
    public void onSuccess(ArrayList<String> arrayList) {
        // Returns list of messageID of pinned messages
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Listener.TapCoreGetStringArrayListener

...

TapCoreMessageManager.getInstance().getPinnedMessageIDs(ROOM_ID, object : TapCoreGetStringArrayListener() {
    override fun onSuccess(arrayList: ArrayList<String>) {
        // Returns list of messageID of pinned messages
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
});
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`ROOM_ID`**: (String) ID of the target room
{% endhint %}

A method to obtain the full message model list of the pinned messages with pagination is also provided.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Listener.TapCoreGetOlderMessageListener;
import io.taptalk.TapTalk.Model.TAPMessageModel;

...

TapCoreMessageManager.getInstance().getPinnedMessages(
    ROOM_ID,
    PAGE_NUMBER,
    NUMBER_OF_ITEMS,
    new TapCoreGetOlderMessageListener() {
        @Override
        public void onSuccess(List<TAPMessageModel> messages, Boolean hasMoreData) {
            // hasMoreData will return true if the room has remaining pinned messages that have not been retrieved
        }
    
        @Override
        public void onError(String errorCode, String errorMessage) {
    
        }
    }
);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Listener.TapCoreGetOlderMessageListener
import io.taptalk.TapTalk.Model.TAPMessageModel

...

TapCoreMessageManager.getInstance().getPinnedMessages(
    ROOM_ID,
    PAGE_NUMBER,
    NUMBER_OF_ITEMS,
    object : TapCoreGetOlderMessageListener() {
        override fun onSuccess(messages: List<TAPMessageModel>, hasMoreData: Boolean?) {
            // hasMoreData will return true if the room has remaining pinned messages that have not been retrieved
        }
    
        override fun onError(errorCode: String?, errorMessage: String?) {
    
        }
    }
)
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`ROOM_ID`**: (String) ID of the target room\
**`PAGE_NUMBER`**: (int) the number of page to retrieve the items\
**`NUMBER_OF_ITEMS`**: (int) number of items to be retrieved
{% endhint %}

### Get Shared Content Messages

You can retrieve media-type messages, consisting of image, video, file, and link messages from a chat room by using `getSharedContentMessages` method.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Listener.TapCoreGetSharedContentMessageListener;
import io.taptalk.TapTalk.Model.TAPMessageModel;

...

TapCoreMessageManager.getInstance().getSharedContentMessages(
    ROOM,
    MIN_CREATED_TIMESTAMP,
    MAX_CREATED_TIMESTAMP,
    new TapCoreGetSharedContentMessageListener() {
        @Override
        public void onSuccess(List<TAPMessageModel> mediaMessages, List<TAPMessageModel> fileMessages, List<TAPMessageModel> linkMessages) {
            // mediaMessages contains image and video messages
            // fileMessages contains file/document messages
            // linkMessages contains link messages
        }
    
        @Override
        public void onError(String errorCode, String errorMessage) {
    
        }
    }
);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Listener.TapCoreGetSharedContentMessageListener
import io.taptalk.TapTalk.Model.TAPMessageModel

...

TapCoreMessageManager.getInstance().getSharedContentMessages(
    ROOM,
    MIN_CREATED_TIMESTAMP,
    MAX_CREATED_TIMESTAMP,
    object : TapCoreGetSharedContentMessageListener() {
        override fun onSuccess(mediaMessages: List<TAPMessageModel>, fileMessages: List<TAPMessageModel>, linkMessages: List<TAPMessageModel>) {
            // mediaMessages contains image and video messages
            // fileMessages contains file/document messages
            // linkMessages contains link messages
        }
    
        override fun onError(errorCode: String?, errorMessage: String?) {
    
        }
    }
)
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`ROOM`**: (TAPRoomModel) room to retrieve the messages from\
**`MIN_CREATED_TIMESTAMP`**: (long) smallest created time of the messages to retrieve, use 0L to retrieve up to the oldest message in the room\
**`MAX_CREATED_TIMESTAMP`**: (long) largest created time of the messages to retrieve, use current timestamp to retrieve up to the newest message in the room
{% endhint %}

### Delete All Chat Room Messages

Use the **`deleteAllChatRoomMessages()`** method from the **TapCoreChatRoomManager** class to clear all existing messages in a selected chat room for the active user. The selected messages will only be deleted for the active user, and will not affect the other participants in the selected room.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Listener.TapCommonListener;

...

TapCoreChatRoomManager.getInstance().deleteAllChatRoomMessages(ROOM_ID, new TapCommonListener() {
    @Override
    public void onSuccess(String successMessage) {
        // Successfully deleted all messages in the chat room
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Listener.TapCommonListener

...

TapCoreChatRoomManager.getInstance().deleteAllChatRoomMessages(ROOM_ID, object : TapCommonListener() {
    override fun onSuccess(successMessage: String?) {
        // Successfully deleted all messages in the chat room
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`ROOM_ID`**: (String) ID of the specified room to delete the messages from
{% endhint %}

### Create Scheduled Message

You can schedule a constructed message model to be delivered at a specified time to a chat room.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager;
import io.taptalk.TapTalk.Listener.TapCoreCreateScheduledMessageListener;
import io.taptalk.TapTalk.Model.TAPMessageModel;
import io.taptalk.TapTalk.Model.ResponseModel.TapScheduledMessageModel;

...

TAPMessageModel constructedMessage = TapCoreMessageManager.getInstance().constructTapTalkMessageModel(
    MESSAGE_BODY,
    ROOM,
    MESSAGE_TYPE,
    MESSAGE_DATA
);
    
TapCoreChatRoomManager.getInstance().createScheduledMessage(constructedMessage, TIMESTAMP, new TapCoreCreateScheduledMessageListener() {
    @Override
    public void onSuccess(TapScheduledMessageModel scheduledMessage) {
        // Successfully created a scheduled message
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager
import io.taptalk.TapTalk.Listener.TapCoreCreateScheduledMessageListener
import io.taptalk.TapTalk.Model.TAPMessageModel
import io.taptalk.TapTalk.Model.ResponseModel.TapScheduledMessageModel

...

val constructedMessage = TapCoreMessageManager.getInstance().constructTapTalkMessageModel(
    MESSAGE_BODY,
    ROOM,
    MESSAGE_TYPE,
    MESSAGE_DATA
)
        
TapCoreChatRoomManager.getInstance().createScheduledMessage(constructedMessage, TIMESTAMP, object : TapCoreCreateScheduledMessageListener() {
    override fun onSuccess(scheduledMessage: TapScheduledMessageModel) {
        // Successfully created a scheduled message
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`MESSAGE_BODY`**: (String) content of the message\
**`ROOM`**: (TAPRoomModel) the destination room where the message will be sent\
**`MESSAGE_TYPE`**: (Integer) type of your custom message, check the [Message Type page](/powertalk-chat-sdk-documentation/powertalk-android/message-type) for more information\
**`MESSAGE_DATA`**: (HashMap\<String, Object>) custom data for the message (optional)\
**`QUOTED_MESSAGE`**: (TAPMessageModel) quote of the new message model containing another existing message\
**`TIMESTAMP`**: (long) time when the message will be delivered to the destination room (long value)
{% endhint %}

### Get Scheduled Messages

You may then retrieve the list of created scheduled messages that have not yet been delivered in a chat room.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager;
import io.taptalk.TapTalk.Listener.TapCoreGetScheduledMessagesListener;
import io.taptalk.TapTalk.Model.ResponseModel.TapScheduledMessageModel;

...

TapCoreChatRoomManager.getInstance().getScheduledMessages(ROOM_ID, new TapCoreGetScheduledMessagesListener() {
    @Override
    public void onSuccess(List<TapScheduledMessageModel> scheduledMessages) {
        // Successfully retrieved scheduled messages
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager
import io.taptalk.TapTalk.Listener.TapCoreGetScheduledMessagesListener
import io.taptalk.TapTalk.Model.ResponseModel.TapScheduledMessageModel

...

TapCoreChatRoomManager.getInstance().getScheduledMessages(ROOM_ID, object : TapCoreGetScheduledMessagesListener() {
    override fun onSuccess(scheduledMessages: List<TapScheduledMessageModel>) {
        // Successfully retrieved scheduled messages
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`ROOM_ID`**: (String) ID of the destination chat room
{% endhint %}

### Send Scheduled Message Now

You may also send a previously created scheduled message immediately to the recipient.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager;
import io.taptalk.TapTalk.Listener.TapCoreGetIntegerArrayListener;

...

// Send a scheduled message immediately
TapCoreChatRoomManager.getInstance().sendScheduledMessageNow(SCHEDULED_MESSAGE_ID, ROOM_ID, new TapCoreGetIntegerArrayListener() {
    @Override
    public void onSuccess(ArrayList<Integer> sentIDs) {
        // Successfully sent scheduled message
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});

// Send multiple scheduled messages immediately
TapCoreChatRoomManager.getInstance().sendScheduledMessagesNow(SCHEDULED_MESSAGE_IDS, ROOM_ID, new TapCoreGetIntegerArrayListener() {
    @Override
    public void onSuccess(ArrayList<Integer> sentIDs) {
        // Successfully sent scheduled messages
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager
import io.taptalk.TapTalk.Listener.TapCoreGetIntegerArrayListener

...

// Send a scheduled message immediately
TapCoreChatRoomManager.getInstance().sendScheduledMessageNow(SCHEDULED_MESSAGE_ID, ROOM_ID, object : TapCoreGetIntegerArrayListener() {
    override fun onSuccess(sentIDs: ArrayList<Int>) {
        // Successfully sent scheduled message
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})

// Send multiple scheduled messages immediately
TapCoreChatRoomManager.getInstance().sendScheduledMessagesNow(SCHEDULED_MESSAGE_IDS, ROOM_ID, object : TapCoreGetIntegerArrayListener() {
    override fun onSuccess(sentIDs: ArrayList<Int>) {
        // Successfully sent scheduled messages
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`SCHEDULED_MESSAGE_ID`**: (Integer) ID of the previously created scheduled message\
**`SCHEDULED_MESSAGE_IDS`**: (List\<Integer>) list of scheduled message IDs\
**`ROOM_ID`**: (String) ID of the destination chat room
{% endhint %}

### Edit Scheduled Message Time

To change the deliver time of a previously created scheduled message, use the **`editScheduledMessageTime`** method from **TAPCoreMessageManager**.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager;
import io.taptalk.TapTalk.Listener.TapCommonListener;

...

TapCoreChatRoomManager.getInstance().editScheduledMessageTime(SCHEDULED_MESSAGE_ID, TIMESTAMP, new TapCommonListener() {
    @Override
    public void onSuccess(String successMessage) {
        // Successfully edited scheduled message
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager
import io.taptalk.TapTalk.Listener.TapCommonListener

...

TapCoreChatRoomManager.getInstance().editScheduledMessageTime(SCHEDULED_MESSAGE_ID, TIMESTAMP, object : TapCommonListener() {
    override fun onSuccess(successMessage: String) {
        // Successfully edited scheduled message
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`SCHEDULED_MESSAGE_ID`**: (Integer) ID of the previously created scheduled message\
**`TIMESTAMP`**: (long) time when the message will be delivered to the destination room (long value)
{% endhint %}

### Edit Scheduled Message Content

You may also update the contents of a scheduled message that was previously created before it is delivered to the recipient.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager;
import io.taptalk.TapTalk.Listener.TapCommonListener;
import io.taptalk.TapTalk.Model.TAPMessageModel;

...

// Edit message with updated message model
TapCoreChatRoomManager.getInstance().editScheduledMessageContent(SCHEDULED_MESSAGE_ID, UPDATED_MESSAGE, new TapCommonListener() {
    @Override
    public void onSuccess(String successMessage) {
        // Successfully edited scheduled message
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});

// Edit text content of the existing message
TapCoreChatRoomManager.getInstance().editScheduledMessageContent(SCHEDULED_MESSAGE_ID, PREVIOUS_MESSAGE, UPDATED_TEXT, new TapCommonListener() {
    @Override
    public void onSuccess(String successMessage) {
        // Successfully edited scheduled message
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager
import io.taptalk.TapTalk.Listener.TapCommonListener
import io.taptalk.TapTalk.Model.TAPMessageModel

...

// Edit message with updated message model
TapCoreChatRoomManager.getInstance().editScheduledMessageContent(SCHEDULED_MESSAGE_ID, UPDATED_MESSAGE, object : TapCommonListener() {
    override fun onSuccess(successMessage: String) {
        // Successfully edited scheduled message
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})

// Edit text content of the existing message
TapCoreChatRoomManager.getInstance().editScheduledMessageContent(SCHEDULED_MESSAGE_ID, PREVIOUS_MESSAGE, UPDATED_TEXT, object : TapCommonListener() {
    override fun onSuccess(successMessage: String) {
        // Successfully edited scheduled message
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`SCHEDULED_MESSAGE_ID`**: (Integer) ID of the previously created scheduled message\
**`UPDATED_MESSAGE`**: (TAPMessageModel) message model with updated values\
**`PREVIOUS_MESSAGE`**: (TAPMessageModel) existing message model to be edited\
**`UPDATED_TEXT`**: (String) text content to update the message model
{% endhint %}

### Delete Scheduled Message

To cancel sending a scheduled message that has not been delivered, you can delete it using **`deleteScheduledMessage`** method.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager;
import io.taptalk.TapTalk.Listener.TapCoreGetIntegerArrayListener;

...

// Delete a scheduled message
TapCoreChatRoomManager.getInstance().deleteScheduledMessage(SCHEDULED_MESSAGE_ID, ROOM_ID, new TapCoreGetIntegerArrayListener() {
    @Override
    public void onSuccess(ArrayList<Integer> deletedIDs) {
        // Successfully deleted scheduled message
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});

// Delete multiple scheduled messages
TapCoreChatRoomManager.getInstance().deleteScheduledMessages(SCHEDULED_MESSAGE_IDS, ROOM_ID, new TapCoreGetIntegerArrayListener() {
    @Override
    public void onSuccess(ArrayList<Integer> deletedIDs) {
        // Successfully deleted scheduled messages
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager
import io.taptalk.TapTalk.Listener.TapCoreGetIntegerArrayListener

...

// Delete a scheduled message
TapCoreChatRoomManager.getInstance().deleteScheduledMessage(SCHEDULED_MESSAGE_ID, ROOM_ID, object : TapCoreGetIntegerArrayListener() {
    override fun onSuccess(deletedIDs: ArrayList<Int>) {
        // Successfully deleted scheduled message
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})

// Delete multiple scheduled messages
TapCoreChatRoomManager.getInstance().deleteScheduledMessages(SCHEDULED_MESSAGE_IDS, ROOM_ID, object : TapCoreGetIntegerArrayListener() {
    override fun onSuccess(deletedIDs: ArrayList<Int>) {
        // Successfully deleted scheduled messages
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`SCHEDULED_MESSAGE_ID`**: (Integer) ID of the previously created scheduled message\
**`SCHEDULED_MESSAGE_IDS`**: (List\<Integer>) list of scheduled message IDs\
**`ROOM_ID`**: (String) ID of the destination chat room
{% endhint %}

### Get Message Details

You can retrieve info about a message's recipients that has read or received the message.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Listener.TapCoreGetMessageDetailsListener;
import io.taptalk.TapTalk.Model.TAPMessageModel;
import io.taptalk.TapTalk.Model.ResponseModel.TapMessageRecipientModel;

...

TapCoreMessageManager.getInstance().getMessageDetails(MESSAGE_ID, new TapCoreGetMessageDetailsListener() {
    @Override
    public void onSuccess(TAPMessageModel message, List<TapMessageRecipientModel> deliveredTo, List<TapMessageRecipientModel> readBy) {
        // Successfully retrieved message info
        // message: the message model
        // deliveredTo: list of recipients that has received the message
        // readBy: list of recipients that has read the message
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Listener.TapCoreGetMessageDetailsListener
import io.taptalk.TapTalk.Model.TAPMessageModel
import io.taptalk.TapTalk.Model.ResponseModel.TapMessageRecipientModel

...

TapCoreMessageManager.getInstance().getMessageDetails(MESSAGE_ID, object : TapCoreGetMessageDetailsListener() {
    override fun onSuccess(message: TAPMessageModel, deliveredTo: List<TapMessageRecipientModel>?, readBy: List<TapMessageRecipientModel>?) {
        // Successfully retrieved message info
        // message: the message model
        // deliveredTo: list of recipients that has received the message
        // readBy: list of recipients that has read the message
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`MESSAGE_ID`**: (String) unique server ID from the message
{% endhint %}

### Get Message Total Read Count

You can also retrieve a message's total read count from a non-personal room.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Listener.TapCoreGetIntegerListener;

...

TapCoreMessageManager.getInstance().getMessageTotalRead(MESSAGE_ID, new TapCoreGetIntegerListener() {
    @Override
    public void onSuccess(int readCount) {
        // Successfully retrieved message read count
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Listener.TapCoreGetIntegerListener

...

TapCoreMessageManager.getInstance().getMessageTotalRead(MESSAGE_ID, object : TapCoreGetIntegerListener() {
    override fun onSuccess(readCount: Int) {
        // Successfully retrieved message read count
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`MESSAGE_ID`**: (String) unique server ID from the message
{% endhint %}


# Contact

If your application is using the core implementation type, you can use the **TapCoreContactManager** class to manage your user's contacts.

| TapTalk Contact Method                                                                                                                                   | Description                                                                      |
| -------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
| [Get All User Contacts](#get-all-user-contacts)                                                                                                          | Get all of the user's contact data from local storage                            |
| [Fetch All User Contacts from Server](#fetch-all-user-contacts-from-server)                                                                              | Fetch the user's latest contact data from TapTalk.io server                      |
| [Get Contact Detail Info with TapTalk User ID](/powertalk-chat-sdk-documentation/powertalk-android/contact#get-contact-detail-info-with-taptalk-user-id) | Get a detailed contact info with selected TapTalk.io user ID                     |
| [Get Contact Detail Info with Client User ID](/powertalk-chat-sdk-documentation/powertalk-android/contact#get-contact-detail-info-with-client-user-id)   | Get a detailed contact info with selected Client user ID (xcUserID)              |
| [Add User to Contact with User ID](/powertalk-chat-sdk-documentation/powertalk-android/contact#add-user-to-contact-with-user-id)                         | Add a user with selected TapTalk.io user ID to the active user's contacts        |
| [Add User to Contact with Phone Number](/powertalk-chat-sdk-documentation/powertalk-android/contact#add-user-to-contact-with-phone-number)               | Add a user with selected phone number to the active user's contacts              |
| [Remove User from Contact](/powertalk-chat-sdk-documentation/powertalk-android/contact#remove-user-from-contact)                                         | Remove a user with selected TapTalk.io user ID from the active user's contacts   |
| [Save User Data](/powertalk-chat-sdk-documentation/powertalk-android/contact#save-user-data)                                                             | Save or update existing user data to local cache                                 |
| [Search Local Contact](#search-local-message)                                                                                                            | Search the active user's contacts from the device's local storage with a keyword |
| [Report User](#report-user)                                                                                                                              | Submit a report for a selected user.                                             |
| [Report Message](#report-message)                                                                                                                        | Submit a report for a selected message.                                          |
| [Block User](#block-user)                                                                                                                                | Block a user from sending or receiving messages.                                 |
| [Unblock User](#unblock-user)                                                                                                                            | Unblock a blocked user.                                                          |
| [Get Blocked User List](#get-blocked-user-list)                                                                                                          | Retrieve a list of blocked users.                                                |
| [Get Blocked User IDs](#get-blocked-user-ids)                                                                                                            | Retrieve a list of IDs from blocked users.                                       |
| [Get Groups in Common](#get-groups-in-common)                                                                                                            | Retrieve the list of groups in common with another user.                         |

### Get All User Contacts

Get all of the user's contact data from TapTalk.io.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreContactManager;
import io.taptalk.TapTalk.Listener.TapCoreGetMultipleContactListener;
import io.taptalk.TapTalk.Model.TAPUserModel;

...

TapCoreContactManager.getInstance().getAllUserContacts(new TapCoreGetMultipleContactListener() {
    @Override
    public void onSuccess(List<TAPUserModel> users) {
        // Returns a list of the active user's TapTalk.io contacts
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreContactManager
import io.taptalk.TapTalk.Listener.TapCoreGetMultipleContactListener
import io.taptalk.TapTalk.Model.TAPUserModel

...

TapCoreContactManager.getInstance().getAllUserContacts(object : TapCoreGetMultipleContactListener() {
    override fun onSuccess(users: List<TAPUserModel>?) {
        // Returns a list of the active user's TapTalk.io contacts
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

### Fetch All User Contacts from Server

Calling `fetchAllUserContactsFromServer` will fetch the user's latest contact data from TapTalk.io server and syncs it to the device's local storage.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreContactManager;
import io.taptalk.TapTalk.Listener.TapCoreGetMultipleContactListener;
import io.taptalk.TapTalk.Model.TAPUserModel;

...

TapCoreContactManager.getInstance().fetchAllUserContactsFromServer(new TapCoreGetMultipleContactListener() {
    @Override
    public void onSuccess(List<TAPUserModel> users) {
        // Returns a list of the active user's TapTalk.io contacts
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreContactManager
import io.taptalk.TapTalk.Listener.TapCoreGetMultipleContactListener
import io.taptalk.TapTalk.Model.TAPUserModel

...

TapCoreContactManager.getInstance().fetchAllUserContactsFromServer(object : TapCoreGetMultipleContactListener() {
    override fun onSuccess(users: List<TAPUserModel>?) {
        // Returns a list of the active user's TapTalk.io contacts
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

### Get Contact Detail Info with TapTalk User ID

Get a detailed contact info with selected TapTalk.io user ID.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreContactManager;
import io.taptalk.TapTalk.Listener.TapCoreGetContactListener;
import io.taptalk.TapTalk.Model.TAPUserModel;

...

TapCoreContactManager.getInstance().getUserDataWithUserID(USER_ID, new TapCoreGetContactListener() {
    @Override
    public void onSuccess(TAPUserModel user) {
        // Returns detailed user info
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreContactManager
import io.taptalk.TapTalk.Listener.TapCoreGetContactListener
import io.taptalk.TapTalk.Model.TAPUserModel

...

TapCoreContactManager.getInstance().getUserDataWithUserID(USER_ID, object : TapCoreGetContactListener() {
    override fun onSuccess(user: TAPUserModel?) {
        // Returns detailed user info
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
`USER_ID`: (String) Taptalk.io User ID of the selected user
{% endhint %}

### Get Contact Detail Info with Client User ID

Get a detailed contact info with selected Client user ID (XCUserID).

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreContactManager;
import io.taptalk.TapTalk.Listener.TapCoreGetContactListener;
import io.taptalk.TapTalk.Model.TAPUserModel;

...

TapCoreContactManager.getInstance().getUserDataWithXCUserID(XC_USER_ID, new TapCoreGetContactListener() {
    @Override
    public void onSuccess(TAPUserModel user) {
        // Returns detailed user info
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreContactManager
import io.taptalk.TapTalk.Listener.TapCoreGetContactListener
import io.taptalk.TapTalk.Model.TAPUserModel

...

TapCoreContactManager.getInstance().getUserDataWithXCUserID(XC_USER_ID, object : TapCoreGetContactListener() {
    override fun onSuccess(user: TAPUserModel?) {
        // Returns detailed user info
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
`XC_USER_ID`: (String) Client User ID of the selected user
{% endhint %}

### Add User to Contact with User ID

Add a user with selected TapTalk.io user ID to the active user's contacts.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreContactManager;
import io.taptalk.TapTalk.Listener.TapCoreGetContactListener;
import io.taptalk.TapTalk.Model.TAPUserModel;

...

TapCoreContactManager.getInstance().addToTapTalkContactsWithUserID(USER_ID, new TapCoreGetContactListener() {
    @Override
    public void onSuccess(TAPUserModel user) {
        // Added to contacts successfully
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreContactManager
import io.taptalk.TapTalk.Listener.TapCoreGetContactListener
import io.taptalk.TapTalk.Model.TAPUserModel

...

TapCoreContactManager.getInstance().addToTapTalkContactsWithUserID(USER_ID, object : TapCoreGetContactListener() {
    override fun onSuccess(user: TAPUserModel?) {
        // Added to contacts successfully
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
`USER_ID`: (String) Taptalk.io User ID of the contact to be added
{% endhint %}

### Add User to Contact with Phone Number

Add a user with selected phone number to the active user's contacts.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreContactManager;
import io.taptalk.TapTalk.Listener.TapCoreGetContactListener;
import io.taptalk.TapTalk.Model.TAPUserModel;

...

TapCoreContactManager.getInstance().addToTapTalkContactsWithPhoneNumber(PHONE_NUMBER, new TapCoreGetContactListener() {
    @Override
    public void onSuccess(TAPUserModel user) {
        // Added to contacts successfully
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreContactManager
import io.taptalk.TapTalk.Listener.TapCoreGetContactListener
import io.taptalk.TapTalk.Model.TAPUserModel

...

TapCoreContactManager.getInstance().addToTapTalkContactsWithPhoneNumber(PHONE_NUMBER, object : TapCoreGetContactListener() {
    override fun onSuccess(user: TAPUserModel?) {
        // Added to contacts successfully
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
`PHONE_NUMBER`: (String) phone number of the contact to be added
{% endhint %}

### Remove User from Contact

Remove a user with selected TapTalk.io user ID from the active user's contacts.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreContactManager;
import io.taptalk.TapTalk.Listener.TapCommonListener;

...

TapCoreContactManager.getInstance().removeFromTapTalkContacts(USER_ID, new TapCommonListener() {
    @Override
    public void onSuccess(String successMessage) {
        // Removed from contacts successfully
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreContactManager
import io.taptalk.TapTalk.Listener.TapCommonListener

...

TapCoreContactManager.getInstance().removeFromTapTalkContacts(USER_ID, object : TapCommonListener() {
    override fun onSuccess(successMessage: String?) {
        // Removed from contacts successfully
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
`USER_ID`: (String) Taptalk.io User ID of the contact to remove
{% endhint %}

### Save User Data

Save or update existing user data to local cache.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreContactManager;
import io.taptalk.TapTalk.Model.TAPUserModel;

...

TapCoreContactManager.getInstance().saveUserData(USER);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreContactManager
import io.taptalk.TapTalk.Model.TAPUserModel

...

TapCoreContactManager.getInstance().saveUserData(USER)
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
`USER`: (TAPUserModel) the user data model to be saved
{% endhint %}

### Search Local Contact

Call this method to search the active user's contacts from the device's local storage with a keyword. Provided keyword will be used to filter the contacts' **full name** in the search result.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreContactManager;
import io.taptalk.TapTalk.Listener.TapCoreGetMultipleContactListener;
import io.taptalk.TapTalk.Model.TAPUserModel;

...

TapCoreContactManager.getInstance().searchLocalContactByName(KEYWORD, new TapCoreGetMultipleContactListener() {
    @Override
    public void onSuccess(List<TAPUserModel> users) {
        // Returns filtered contacts
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreContactManager
import io.taptalk.TapTalk.Listener.TapCoreGetMultipleContactListener
import io.taptalk.TapTalk.Model.TAPUserModel

...

TapCoreContactManager.getInstance().searchLocalContactByName(KEYWORD, object : TapCoreGetMultipleContactListener() {
    override fun onSuccess(users: List<TAPUserModel>?) {
        // Returns filtered contacts
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`KEYWORD`**: (String) search keyword to filter full name
{% endhint %}

### Report User

You may call this method to submit a report for a selected user. Submitted reports can then be viewed through the dashboard.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreContactManager;
import io.taptalk.TapTalk.Listener.TapCommonListener;

...

TapCoreContactManager.getInstance().reportUser(
    USER_ID,
    CATEGORY,
    IS_OTHER_CATEGORY,
    REASON,
    new TapCommonListener() {
        @Override
        public void onSuccess(String successMessage) {
            // Successfully reported user
        }
    
        @Override
        public void onError(String errorCode, String errorMessage) {
    
        }
    }
);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreContactManager
import io.taptalk.TapTalk.Listener.TapCommonListener

...

TapCoreContactManager.getInstance().reportUser(
    USER_ID,
    IS_OTHER_CATEGORY,
    REASON,
    object : TapCommonListener() {
        override fun onSuccess(successMessage: String?) {
            // Successfully reported user
        }
    
        override fun onError(errorCode: String?, errorMessage: String?) {
    
        }
    }
)
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`USER_ID`**: (String) ID of the user to report\
**`CATEGORY`**: (String) Category of the violation. max length is 100 characters\
**`IS_OTHER_CATEGORY`**: (Boolean) If the category is other than the predefined categories\
**`REASON`**: (String) reason why the user is reported
{% endhint %}

### Report Message

You may call this method to submit a report for a selected message. Submitted reports can then be viewed through the dashboard.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreContactManager;
import io.taptalk.TapTalk.Listener.TapCommonListener;

...

TapCoreContactManager.getInstance().reportMessage(
    MESSAGE_ID,
    ROOM_ID,
    CATEGORY,
    IS_OTHER_CATEGORY,
    REASON,
    new TapCommonListener() {
        @Override
        public void onSuccess(String successMessage) {
            // Successfully reported message
        }
    
        @Override
        public void onError(String errorCode, String errorMessage) {
    
        }
    }
);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreContactManager
import io.taptalk.TapTalk.Listener.TapCommonListener

...

TapCoreContactManager.getInstance().reportMessage(
    MESSAGE_ID,
    ROOM_ID,
    IS_OTHER_CATEGORY,
    REASON,
    object : TapCommonListener() {
        override fun onSuccess(successMessage: String?) {
            // Successfully reported message
        }
    
        override fun onError(errorCode: String?, errorMessage: String?) {
    
        }
    }
)
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`MESSAGE_ID`**: (String) unique server ID of the message to report\
**`ROOM_ID`**: (String) ID of the room where the message belongs to\
**`CATEGORY`**: (String) Category of the violation. max length is 100 characters\
**`IS_OTHER_CATEGORY`**: (Boolean) If the category is other than the predefined categories\
**`REASON`**: (String) reason why the message is reported
{% endhint %}

### Block User

You may block a user to stop conversation flow with the blocked user. Blocked users will not be able to send and receive message, or retrieve profile info from the active user.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreContactManager;
import io.taptalk.TapTalk.Listener.TapCoreGetContactListener;
import io.taptalk.TapTalk.Model.TAPUserModel;

...

TapCoreContactManager.getInstance().blockUser(USER_ID, new TapCoreGetContactListener() {
    @Override
    public void onSuccess(TAPUserModel user) {
        // Successfully blocked user
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreContactManager
import io.taptalk.TapTalk.Listener.TapCoreGetContactListener
import io.taptalk.TapTalk.Model.TAPUserModel

...

TapCoreContactManager.getInstance().blockUser(USER_ID, object : TapCoreGetContactListener() {
    override fun onSuccess(user: TAPUserModel?) {
        // Successfully blocked user
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`USER_ID`**: (String) ID of the user to block
{% endhint %}

### Unblock User

You may unblock a blocked user to let them send and receive message from the active user.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreContactManager;
import io.taptalk.TapTalk.Listener.TapCoreGetContactListener;
import io.taptalk.TapTalk.Model.TAPUserModel;

...

TapCoreContactManager.getInstance().unblockUser(USER_ID, new TapCoreGetContactListener() {
    @Override
    public void onSuccess(TAPUserModel user) {
        // Successfully unblocked user
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreContactManager
import io.taptalk.TapTalk.Listener.TapCoreGetContactListener
import io.taptalk.TapTalk.Model.TAPUserModel

...

TapCoreContactManager.getInstance().unblockUser(USER_ID, object : TapCoreGetContactListener() {
    override fun onSuccess(user: TAPUserModel?) {
        // Successfully unblocked user
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`USER_ID`**: (String) ID of the user to unblock
{% endhint %}

### Get Blocked User List

You may call this method to retrieve a list of blocked users.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreContactManager;
import io.taptalk.TapTalk.Listener.TapCoreGetMultipleContactListener;
import io.taptalk.TapTalk.Model.TAPUserModel;

...

TapCoreContactManager.getInstance().getBlockedUserList(new TapCoreGetMultipleContactListener() {
    @Override
    public void onSuccess(List<TAPUserModel> blockedUsers) {
         // Successfully retrieved blocked users
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreContactManager
import io.taptalk.TapTalk.Listener.TapCoreGetMultipleContactListener
import io.taptalk.TapTalk.Model.TAPUserModel

...

TapCoreContactManager.getInstance().getBlockedUserList(object : TapCoreGetMultipleContactListener() {
    override fun onSuccess(blockedUsers: List<TAPUserModel>) {
         // Successfully retrieved blocked users
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

### Get Blocked User IDs

You may call this method to retrieve a list of IDs from blocked users.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreContactManager;
import io.taptalk.TapTalk.Listener.TapCoreGetStringArrayListener;

...

TapCoreContactManager.getInstance().getBlockedUserIDs(new TapCoreGetStringArrayListener() {
    @Override
    public void onSuccess(ArrayList<String> blockedUserIDs) {
         // Successfully retrieved blocked user IDs
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreContactManager
import io.taptalk.TapTalk.Listener.TapCoreGetStringArrayListener

...

TapCoreContactManager.getInstance().getBlockedUserIDs(object : TapCoreGetStringArrayListener() {
    override fun onSuccess(blockedUserIDs: ArrayList<String>) {
        // Successfully retrieved blocked user IDs
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

### Get Groups in Common

You may use **`getGroupsInCommon`** method to retrieve the list of groups in common with another user.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreContactManager;
import io.taptalk.TapTalk.Listener.TapCoreGetRoomArrayListener;
import io.taptalk.TapTalk.Model.TAPRoomModel;

...

TapCoreContactManager.getInstance().getGroupsInCommon(USER_ID, new TapCoreGetRoomArrayListener() {
    @Override
    public void onSuccess(ArrayList<TAPRoomModel> rooms) {
        // Successfully retrieved rooms
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreContactManager
import io.taptalk.TapTalk.Listener.TapCoreGetRoomArrayListener
import io.taptalk.TapTalk.Model.TAPRoomModel

...

TapCoreContactManager.getInstance().getGroupsInCommon(USER_ID, object : TapCoreGetRoomArrayListener() {
    override fun onSuccess(rooms: ArrayList<TAPRoomModel>) {
        // Successfully retrieved rooms
    }

    override fun onError(errorCode: String?, errorMessage: String?) {

    }
})
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`USER_ID`**: (String) ID of the other user
{% endhint %}


# Message Type

TapTalk.io use a predefined type for each chat message bubble as shown below:

| **TapTalk Chat Message Type Name** | **Type** | **Description**                                        |
| ---------------------------------- | -------- | ------------------------------------------------------ |
| TYPE\_TEXT                         | 1001     | Used for text message bubble.                          |
| TYPE\_IMAGE                        | 1002     | Used for image message bubble.                         |
| TYPE\_VIDEO                        | 1003     | Used for video message bubble.                         |
| TYPE\_FILE                         | 1004     | Used for file message bubble.                          |
| TYPE\_LOCATION                     | 1005     | Used for location message bubble.                      |
| TYPE\_CONTACT\*                    | 1006     | Used for contact message bubble \*(not yet available). |
| TYPE\_STICKER\*                    | 1007     | Used for sticker message bubble \*(not yet available). |
| TYPE\_LINK                         | 1010     | Used for message bubble that contains URL.             |
| TYPE\_SYSTEM\_MESSAGE              | 9001     | Used for system message bubble                         |
| TYPE\_UNREAD\_MESSAGE\_IDENTIFIER  | 9002     | Used to mark the start of unread messages in chat room |

{% hint style="info" %}
**TapTalk.io Chat Message Type**

1xxx for Standard Message Bubble\
9xxx for System Message Bubble\
3xxx for User Customized Message Bubble

If you wish to create custom message bubble, please set your customized chat message bubble type with **3** as prefix (e.g. 3001).
{% endhint %}

{% hint style="info" %}
You can add your own customized chat message bubble by following the instructions in [Customized Chat Message Bubble Page](/powertalk-chat-sdk-documentation/powertalk-android/customize-chat-message-bubble).
{% endhint %}


# Customize UI Appearance

If you are using the default interface from TapTalk.io UI implementation type, you can customize the appearance of the chat UI. To do this, open your application's `colors.xml` or `styles.xml` file and override the values present in TapTalk.io library's `values.xml` file.

### Customize Default Color Theme

To customize the chat UI's color theme, open your `colors.xml` file and add override following values with your own colors:

{% tabs %}
{% tab title="colors.xml" %}

```xml
<!--TapTalk Default Colors-->
<color name="tapColorPrimaryExtraLight">@color/yourExtraLightColor</color>
<color name="tapColorPrimaryLight">@color/yourLightColor</color>
<color name="tapColorPrimary">@color/yourPrimaryLightColor</color>
<color name="tapColorPrimaryDark">@color/yourDarkColor</color>
<color name="tapColorAccent">@color/yourAccentColor</color>
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
**Note**: you can override the default color values partially, but it is recommended to change all of them accordingly to make sure the color theme within the chat UI matches
{% endhint %}

### Customize General Colors

The following are the values used as general component colors, present in `colors.xml`

{% tabs %}
{% tab title="colors.xml" %}

```xml
<!--Light text color on dark background-->
<color name="tapColorTextLight">@color/yourLightTextColor</color>

<!--Medium text color generally used on subtitles or placeholders-->
<color name="tapColorTextMedium">@color/yourMediumTextColor</color>

<!--Dark text color on light background-->
<color name="tapColorTextDark">@color/yourDarkTextColor</color>

<!--Identifies successful actions-->
<color name="tapColorSuccess">@color/yourSuccessTextColor</color>

<!--Identifies errors or destructive actions-->
<color name="tapColorError">@color/yourErrorTextColor</color>

<!--Primary colored icons used on light background-->
<color name="tapColorPrimaryIcon">@color/yourPrimaryIconColor</color>

<!--White icons used on colored background-->
<color name="tapColorWhiteIcon">@color/yourCustomLightIconColor</color>

<!--Default color for gray icons-->
<color name="tapColorGrayIcon">@color/yourGrayIconColor</color>

<!--Default icon color for successful actions-->
<color name="tapColorSuccessIcon">@color/yourSuccessIconColor</color>

<!--Default icon color for errors or destructive actions-->
<color name="tapColorDestructiveIcon">@color/yourDestructiveIconColor</color>
```

{% endtab %}
{% endtabs %}

### Customize Component Colors

The following are the values used as specific component colors, present in `colors.xml`.

#### Default Components

{% tabs %}
{% tab title="colors.xml" %}

```xml
<color name="tapDefaultNavBarBackgroundColor">@color/yourColor</color>
<color name="tapDefaultBackgroundColor">@color/yourColor</color>
```

{% endtab %}
{% endtabs %}

#### Chat Bubble

{% tabs %}
{% tab title="colors.xml" %}

```xml
<color name="tapDefaultRightBubbleBackgroundColor">@color/yourColor</color>
<color name="tapDefaultRightBubbleDarkBackgroundColor">@color/yourColor</color>
<color name="tapDefaultLeftBubbleBackgroundColor">@color/yourColor</color>
<color name="tapDefaultLeftBubbleDarkBackgroundColor">@color/yourColor</color>
```

{% endtab %}
{% endtabs %}

#### Text Field

{% tabs %}
{% tab title="colors.xml" %}

```xml
<color name="tapTextFieldCursorColor">@color/yourColor</color>
<color name="tapTextFieldBorderActiveColor">@color/yourColor</color>
<color name="tapTextFieldBorderInactiveColor">@color/yourColor</color>
<color name="tapTextFieldBorderErrorColor">@color/yourColor</color>
```

{% endtab %}
{% endtabs %}

#### Button

{% tabs %}
{% tab title="colors.xml" %}

```xml
<color name="tapButtonInactiveBackgroundGradientLightColor">@color/yourColor</color>
<color name="tapButtonInactiveBackgroundGradientDarkColor">@color/yourColor</color>
<color name="tapButtonInactiveBorderColor">@color/yourColor</color>
<color name="tapButtonActiveBackgroundGradientLightColor">@color/yourColor</color>
<color name="tapButtonActiveBackgroundGradientDarkColor">@color/yourColor</color>
<color name="tapButtonActiveBorderColor">@color/yourColor</color>
<color name="tapButtonDestructiveBackgroundColor">@color/yourColor</color>
<color name="tapButtonIconColor">@color/yourColor</color>
<color name="tapButtonIconPrimaryColor">@color/yourColor</color>
<color name="tapButtonIconDestructiveColor">@color/yourColor</color>
```

{% endtab %}
{% endtabs %}

#### Switch

{% tabs %}
{% tab title="colors.xml" %}

```xml
<color name="tapSwitchActiveBackgroundColor">@color/yourColor</color>
<color name="tapSwitchInactiveBackgroundColor">@color/yourColor</color>
```

{% endtab %}
{% endtabs %}

#### Popup Dialog

{% tabs %}
{% tab title="colors.xml" %}

```xml
<color name="tapPopupDialogPrimaryButtonBackgroundSuccessColor">@color/yourColor</color>
<color name="tapPopupDialogPrimaryButtonBackgroundErrorColor">@color/yourColor</color>
<color name="tapPopupDialogSecondaryButtonBackgroundColor">@color/yourColor</color>
```

{% endtab %}
{% endtabs %}

#### Unread Badge

{% tabs %}
{% tab title="colors.xml" %}

```xml
<color name="tapUnreadBadgeBackgroundColor">@color/yourColor</color>
<color name="tapUnreadBadgeInactiveBackgroundColor">@color/yourColor</color>
```

{% endtab %}
{% endtabs %}

#### Chat Room Page

{% tabs %}
{% tab title="colors.xml" %}

```xml
<color name="tapChatComposerBackgroundColor">@color/yourColor</color>
<color name="tapQuoteLayoutDecorationBackgroundColor">@color/yourColor</color>
<color name="tapRightBubbleBackgroundColor">@color/yourColor</color>
<color name="tapLeftBubbleBackgroundColor">@color/yourColor</color>
<color name="tapRightBubbleQuoteBackgroundColor">@color/yourColor</color>
<color name="tapLeftBubbleQuoteBackgroundColor">@color/yourColor</color>
<color name="tapRightBubbleQuoteDecorationBackgroundColor">@color/yourColor</color>
<color name="tapLeftBubbleQuoteDecorationBackgroundColor">@color/yourColor</color>
<color name="tapRightFileButtonBackgroundColor">@color/yourColor</color>
<color name="tapLeftFileButtonBackgroundColor">@color/yourColor</color>
<color name="tapSystemMessageBackgroundColor">@color/yourColor</color>
<color name="tapUnreadIdentifierBackgroundColor">@color/yourColor</color>
<color name="tapFileProgressBackgroundColorWhite">@color/yourColor</color>
<color name="tapFileProgressBackgroundColorPrimary">@color/yourColor</color>
<color name="tapDeletedChatRoomInfoBackgroundColor">@color/yourColor</color>
<color name="tapChatRoomBackgroundColor">@color/yourColor</color>
```

{% endtab %}
{% endtabs %}

#### Media Preview

{% tabs %}
{% tab title="colors.xml" %}

```xml
<color name="tapSelectedMediaPreviewThumbnailBorderColor">@color/yourColor</color>
<color name="tapMediaPreviewWarningBackgroundColor">@color/yourColor</color>
```

{% endtab %}
{% endtabs %}

#### Search

{% tabs %}
{% tab title="colors.xml" %}

```xml
<color name="tapSearchConnectionLostInfoBackgroundColor">@color/yourColor</color>
```

{% endtab %}
{% endtabs %}

#### Default Avatar Background Color

{% tabs %}
{% tab title="colors.xml" %}

```xml
<color name="tapDefaultAvatarBackgroundColor1">@color/yourColor</color>
<color name="tapDefaultAvatarBackgroundColor2">@color/yourColor</color>
<color name="tapDefaultAvatarBackgroundColor3">@color/yourColor</color>
<color name="tapDefaultAvatarBackgroundColor4">@color/yourColor</color>
<color name="tapDefaultAvatarBackgroundColor5">@color/yourColor</color>
<color name="tapDefaultAvatarBackgroundColor6">@color/yourColor</color>
<color name="tapDefaultAvatarBackgroundColor7">@color/yourColor</color>
<color name="tapDefaultAvatarBackgroundColor8">@color/yourColor</color>
```

{% endtab %}
{% endtabs %}

### Customize Icon Colors

To customize specific icon colors, you can override the following values in your `colors.xml` file.

#### Default Icons

{% tabs %}
{% tab title="colors.xml" %}

```xml
<color name="tapIconLoadingProgressPrimary">@color/yourColor</color>
<color name="tapIconLoadingProgressWhite">@color/yourColor</color>
<color name="tapIconChevronRightPrimary">@color/yourColor</color>
<color name="tapIconChevronRightGray">@color/yourColor</color>
<color name="tapIconChecklist">@color/yourColor</color>
<color name="tapIconCircleSelectionActive">@color/yourColor</color>
<color name="tapIconCircleSelectionInactive">@color/yourColor</color>
<color name="tapIconLoadingPopupSuccess">@color/yourColor</color>
<color name="tapIconSearchConnectionLost">@color/yourColor</color>
<color name="tapIconMessageSending">@color/yourColor</color>
<color name="tapIconMessageFailed">@color/yourColor</color>
<color name="tapIconMessageSent">@color/yourColor</color>
<color name="tapIconMessageDelivered">@color/yourColor</color>
<color name="tapIconMessageRead">@color/yourColor</color>
<color name="tapIconMessageDeleted">@color/yourColor</color>
<color name="tapIconRemoveItem">@color/yourColor</color>
<color name="tapIconRemoveItemBackground">@color/yourColor</color>
```

{% endtab %}
{% endtabs %}

#### Navigation Bar Icons

{% tabs %}
{% tab title="colors.xml" %}

```xml
<color name="tapIconNavigationBarBackButton">@color/yourColor</color>
<color name="tapIconTransparentBackgroundBackButton">@color/yourColor</color>
<color name="tapIconNavBarCloseButton">@color/yourColor</color>
<color name="tapIconNavBarMagnifier">@color/yourColor</color>
<color name="tapIconSearchBarMagnifier">@color/yourColor</color>
<color name="tapIconClearTextButton">@color/yourColor</color>
```

{% endtab %}
{% endtabs %}

#### Room List Page Icons

{% tabs %}
{% tab title="colors.xml" %}

```xml
<color name="tapIconRoomListSettingUp">@color/yourColor</color>
<color name="tapIconRoomListSetupSuccess">@color/yourColor</color>
<color name="tapIconRoomListSetupFailure">@color/yourColor</color>
<color name="tapIconRoomListRetrySetupButton">@color/yourColor</color>
<color name="tapIconRoomListMuted">@color/yourColor</color>
<color name="tapIconStartNewChatButton">@color/yourColor</color>
```

{% endtab %}
{% endtabs %}

#### New Chat Page Icons

{% tabs %}
{% tab title="colors.xml" %}

```xml
<color name="tapIconMenuNewContact">@color/yourColor</color>
<color name="tapIconMenuScanQRCode">@color/yourColor</color>
<color name="tapIconMenuCreateNewGroup">@color/yourColor</color>
```

{% endtab %}
{% endtabs %}

#### Chat / Group Profile Page Icons

{% tabs %}
{% tab title="colors.xml" %}

```xml
<color name="tapIconChatProfileMenuNotificationActive">@color/yourColor</color>
<color name="tapIconChatProfileMenuNotificationInactive">@color/yourColor</color>
<color name="tapIconChatProfileMenuConversationColor">@color/yourColor</color>
<color name="tapIconChatProfileMenuBlockUser">@color/yourColor</color>
<color name="tapIconChatProfileMenuSearchChat">@color/yourColor</color>
<color name="tapIconChatProfileMenuClearChat">@color/yourColor</color>
<color name="tapIconGroupProfileMenuViewMembers">@color/yourColor</color>
<color name="tapIconGroupMemberProfileMenuAddToContacts">@color/yourColor</color>
<color name="tapIconGroupMemberProfileMenuSendMessage">@color/yourColor</color>
<color name="tapIconGroupMemberProfileMenuPromoteAdmin">@color/yourColor</color>
<color name="tapIconGroupMemberProfileMenuDemoteAdmin">@color/yourColor</color>
<color name="tapIconGroupMemberProfileMenuRemoveMember">@color/yourColor</color>
```

{% endtab %}
{% endtabs %}

#### Media / Image Detail Preview Icons

{% tabs %}
{% tab title="colors.xml" %}

```xml
<color name="tapIconMediaPreviewAdd">@color/yourColor</color>
<color name="tapIconMediaPreviewWarning">@color/yourColor</color>
<color name="tapIconMediaPreviewThumbnailWarning">@color/yourColor</color>
<color name="tapIconMediaPreviewThumbnailWarningBackground">@color/yourColor</color>
<color name="tapIconSaveImage">@color/yourColor</color>
<color name="tapIconMediaListVideo">@color/yourColor</color>
```

{% endtab %}
{% endtabs %}

#### Bottom Sheet Icons

{% tabs %}
{% tab title="colors.xml" %}

```xml
<color name="tapIconLongPressActionCopy">@color/yourColor</color>
<color name="tapIconLongPressActionReply">@color/yourColor</color>
<color name="tapIconLongPressActionForward">@color/yourColor</color>
<color name="tapIconLongPressActionDelete">@color/yourColor</color>
<color name="tapIconLongPressActionCallNumber">@color/yourColor</color>
<color name="tapIconLongPressActionSmsNumber">@color/yourColor</color>
<color name="tapIconLongPressActionOpenLink">@color/yourColor</color>
<color name="tapIconLongPressActionComposeEmail">@color/yourColor</color>
<color name="tapIconLongPressActionSaveToGallery">@color/yourColor</color>
<color name="tapIconAttachDocuments">@color/yourColor</color>
<color name="tapIconAttachCamera">@color/yourColor</color>
<color name="tapIconAttachGallery">@color/yourColor</color>
<color name="tapIconAttachAudio">@color/yourColor</color>
<color name="tapIconAttachContact">@color/yourColor</color>
<color name="tapIconAttachLocation">@color/yourColor</color>
```

{% endtab %}
{% endtabs %}

#### Chat Room Page Icons

{% tabs %}
{% tab title="colors.xml" %}

```xml
<color name="tapIconChatComposerSend">@color/yourColor</color>
<color name="tapIconChatComposerSendInactive">@color/yourColor</color>
<color name="tapIconChatComposerBurgerMenu">@color/yourColor</color>
<color name="tapIconChatComposerShowKeyboard">@color/yourColor</color>
<color name="tapIconChatComposerSendBackground">@color/yourColor</color>
<color name="tapIconChatComposerSendBackgroundInactive">@color/yourColor</color>
<color name="tapIconChatComposerBurgerMenuBackground">@color/yourColor</color>
<color name="tapIconChatComposerShowKeyboardBackground">@color/yourColor</color>
<color name="tapIconChatComposerAttach">@color/yourColor</color>
<color name="tapIconFileWhite">@color/yourColor</color>
<color name="tapIconFileUploadDownloadWhite">@color/yourColor</color>
<color name="tapIconFileCancelUploadDownloadWhite">@color/yourColor</color>
<color name="tapIconFileRetryUploadDownloadWhite">@color/yourColor</color>
<color name="tapIconFilePrimary">@color/yourColor</color>
<color name="tapIconFileUploadDownloadPrimary">@color/yourColor</color>
<color name="tapIconFileCancelUploadDownloadPrimary">@color/yourColor</color>
<color name="tapIconFileRetryUploadDownloadPrimary">@color/yourColor</color>
<color name="tapIconFilePlayMedia">@color/yourColor</color>
<color name="tapIconDeletedRightMessageBubble">@color/yourColor</color>
<color name="tapIconDeletedLeftMessageBubble">@color/yourColor</color>
<color name="tapIconChatRoomUnreadButton">@color/yourColor</color>
<color name="tapIconChatRoomUnreadIdentifier">@color/yourColor</color>
<color name="tapIconChatRoomScrollToBottom">@color/yourColor</color>
<color name="tapIconChatRoomScrollToBottomBackground">@color/yourColor</color>
<color name="tapIconUserStatusActive">@color/yourColor</color>
<color name="tapIconChatRoomCancelQuote">@color/yourColor</color>
<color name="tapIconDeletedChatRoom">@color/yourColor</color>
<color name="tapIconQuotedFileBackground">@color/yourColor</color>
<color name="tapIconLocationBubbleMarker">@color/yourColor</color>
```

{% endtab %}
{% endtabs %}

#### Location Picker Icons

```xml
<color name="tapIconLocationPickerMarker">@color/yourColor</color>
<color name="tapIconLocationPickerRecenter">@color/yourColor</color>
<color name="tapIconLocationPickerRecenterBackground">@color/yourColor</color>
<color name="tapIconLocationPickerSendLocation">@color/yourColor</color>
<color name="tapIconLocationPickerSendLocationBackground">@color/yourColor</color>
<color name="tapIconLocationPickerAddressActive">@color/yourColor</color>
<color name="tapIconLocationPickerAddressInactive">@color/yourColor</color>
```

#### Scan Result

{% tabs %}
{% tab title="colors.xml" %}

```xml
<color name="tapIconCloseScanResult">@color/yourColor</color>
<color name="tapIconCloseScanResultBackground">@color/yourColor</color>
```

{% endtab %}
{% endtabs %}

### Customize Font Style

To use your application's font resource in the chat UI, override the following values in your application's `styles.xml` file.

{% tabs %}
{% tab title="styles.xml" %}

```xml
<style name="tapFontFamilyLight">
    <item name="android:fontFamily">@font/your_light_font</item>
</style>

<style name="tapFontFamilyRegular">
    <item name="android:fontFamily">@font/your_regular_font</item>
</style>

<style name="tapFontFamilyMedium">
    <item name="android:fontFamily">@font/your_medium_font</item>
</style>

<style name="tapFontFamilyBold">
    <item name="android:fontFamily">@font/your_bold_font</item>
</style>

<style name="tapFontFamilyItalic">
    <item name="android:fontFamily">@font/your_italic_font</item>
</style>
```

{% endtab %}
{% endtabs %}

You can also override the following styles to customize specific text styles to your liking, or you you may also override their respective color value in `colors.xml` if you wish to change only the color of the text.

#### Default Font Styles

{% tabs %}
{% tab title="styles.xml" %}

```xml
<style name="tapTitleLabelStyle"></style>
<style name="tapNavBarTitleLabelStyle"></style>
<style name="tapNavBarButtonLabelStyle"></style>
<style name="tapFormLabelStyle"></style>
<style name="tapFormDescriptionLabelStyle"></style>
<style name="tapFormErrorInfoLabelStyle"></style>
<style name="tapFormTextFieldStyle"></style>
<style name="tapFormTextFieldPlaceholderStyle"></style>
<style name="tapClickableLabelStyle"></style>
<style name="tapClickableDestructiveLabelStyle"></style>
<style name="tapButtonLabelStyle"></style>
<style name="tapButtonInactiveLabelStyle"></style>
<style name="tapInfoLabelTitleStyle"></style>
<style name="tapInfoLabelSubtitleStyle"></style>
<style name="tapInfoLabelBodyStyle"></style>
<style name="tapPopupLoadingLabelStyle"></style>
<style name="tapSearchConnectionLostTitleStyle"></style>
<style name="tapSearchConnectionLostDescriptionStyle"></style>
<style name="tapDefaultRoomAvatarSmallFontStyle"></style>
<style name="tapDefaultRoomAvatarMediumFontStyle"></style>
<style name="tapDefaultRoomAvatarLargeFontStyle"></style>
<style name="tapDefaultRoomAvatarExtraLargeFontStyle"></style>
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="colors.xml" %}

```xml
<color name="tapTitleLabelColor">@color/yourColor</color>
<color name="tapNavBarTitleLabelColor">@color/yourColor</color>
<color name="tapNavBarButtonLabelColor">@color/yourColor</color>
<color name="tapFormLabelColor">@color/yourColor</color>
<color name="tapFormDescriptionLabelColor">@color/yourColor</color>
<color name="tapFormErrorInfoLabelColor">@color/yourColor</color>
<color name="tapFormTextFieldColor">@color/yourColor</color>
<color name="tapFormTextFieldPlaceholderColor">@color/yourColor</color>
<color name="tapClickableLabelColor">@color/yourColor</color>
<color name="tapClickableDestructiveLabelColor">@color/yourColor</color>
<color name="tapButtonLabelColor">@color/yourColor</color>
<color name="tapButtonInactiveLabelColor">@color/yourColor</color>
<color name="tapInfoLabelTitleColor">@color/yourColor</color>
<color name="tapInfoLabelSubtitleColor">@color/yourColor</color>
<color name="tapInfoLabelBodyColor">@color/yourColor</color>
<color name="tapPopupLoadingLabelColor">@color/yourColor</color>
<color name="tapSearchConnectionLostTitleColor">@color/yourColor</color>
<color name="tapSearchConnectionLostDescriptionColor">@color/yourColor</color>
<color name="tapDefaultRoomAvatarSmallFontColor">@color/yourColor</color>
<color name="tapDefaultRoomAvatarMediumFontColor">@color/yourColor</color>
<color name="tapDefaultRoomAvatarLargeFontColor">@color/yourColor</color>
<color name="tapDefaultRoomAvatarExtraLargeFontColor">@color/yourColor</color>
```

{% endtab %}
{% endtabs %}

#### Search Bar Font Styles

{% tabs %}
{% tab title="styles.xml" %}

```xml
<style name="tapSearchBarTextStyle"></style>
<style name="tapNavBarSearchTextStyle"></style>
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="colors.xml" %}

```xml
<color name="tapSearchBarTextColor">@color/yourColor</color>
<color name="tapSearchBarTextPlaceholderColor">@color/yourColor</color>
<color name="tapSearchBarCancelButtonColor">@color/yourColor</color>
<color name="tapNavBarSearchTextColor">@color/yourColor</color>
```

{% endtab %}
{% endtabs %}

#### Popup Dialog

{% tabs %}
{% tab title="styles.xml" %}

```xml
<style name="tapPopupDialogTitleStyle"></style>
<style name="tapPopupDialogBodyStyle"></style>
<style name="tapPopupDialogButtonTextPrimaryStyle"></style>
<style name="tapPopupDialogButtonTextSecondaryStyle"></style>
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="colors.xml" %}

```xml
<color name="tapPopupDialogTitleColor">@color/yourColor</color>
<color name="tapPopupDialogBodyColor">@color/yourColor</color>
<color name="tapPopupDialogButtonTextPrimaryColor">@color/yourColor</color>
<color name="tapPopupDialogButtonTextSecondaryColor">@color/yourColor</color>
```

{% endtab %}
{% endtabs %}

#### Bottom Sheet Font Styles

{% tabs %}
{% tab title="styles.xml" %}

```xml
<style name="tapActionSheetDefaultLabelStyle"></style>
<style name="tapActionSheetDestructiveLabelStyle"></style>
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="colors.xml" %}

```xml
<color name="tapActionSheetDefaultLabelColor">@color/yourColor</color>
<color name="tapActionSheetDestructiveLabelColor">@color/yourColor</color>
```

{% endtab %}
{% endtabs %}

#### List Section Header Font Styles

{% tabs %}
{% tab title="styles.xml" %}

```xml
<style name="tapSectionHeaderLabelStyle"></style>
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="colors.xml" %}

```xml
<color name="tapSectionHeaderLabelColor">@color/yourColor</color>
```

{% endtab %}
{% endtabs %}

#### Contact List Font Styles

{% tabs %}
{% tab title="styles.xml" %}

```xml
<style name="tapContactListNameStyle"></style>
<style name="tapContactListUsernameStyle"></style>
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="colors.xml" %}

```xml
<color name="tapContactListNameColor">@color/yourColor</color>
<color name="tapContactListNameHighlightedColor">@color/yourColor</color>
<color name="tapContactListUsernameColor">@color/yourColor</color>
```

{% endtab %}
{% endtabs %}

#### Room List Page Font Styles

{% tabs %}
{% tab title="styles.xml" %}

```xml
<style name="tapRoomListNameStyle"></style>
<style name="tapRoomListNameHighlightedStyle"></style>
<style name="tapRoomListMessageStyle"></style>
<style name="tapRoomListMessageHighlightedStyle"></style>
<style name="tapGroupRoomListSenderNameStyle"></style>
<style name="tapRoomListTimeStyle"></style>
<style name="tapRoomListUnreadBadgeLabelStyle"></style>
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="colors.xml" %}

```xml
<color name="tapRoomListNameColor">@color/yourColor</color>
<color name="tapRoomListNameHighlightedColor">@color/yourColor</color>
<color name="tapRoomListMessageColor">@color/yourColor</color>
<color name="tapRoomListMessageHighlightedColor">@color/yourColor</color>
<color name="tapRoomListTimeColor">@color/yourColor</color>
<color name="tapGroupRoomListSenderNameColor">@color/yourColor</color>
<color name="tapRoomListUnreadBadgeLabelColor">@color/yourColor</color>
```

{% endtab %}
{% endtabs %}

#### New Chat Page Font Styles

{% tabs %}
{% tab title="styles.xml" %}

```xml
<style name="tapNewChatMenuLabelStyle"></style>
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="colors.xml" %}

```xml
<color name="tapNewChatMenuLabelColor">@color/yourColor</color>
```

{% endtab %}
{% endtabs %}

#### Chat / Group Profile Page Font Styles

{% tabs %}
{% tab title="styles.xml" %}

```xml
<style name="tapChatProfileRoomNameStyle"></style>
<style name="tapChatProfileMenuLabelStyle"></style>
<style name="tapChatProfileMenuDestructiveLabelStyle"></style>
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="colors.xml" %}

```xml
<color name="tapChatProfileRoomNameColor">@color/yourColor</color>
<color name="tapChatProfileMenuLabelColor">@color/yourColor</color>
<color name="tapChatProfileMenuDestructiveLabelColor">@color/yourColor</color>
```

{% endtab %}
{% endtabs %}

#### Media Font Styles

{% tabs %}
{% tab title="styles.xml" %}

```xml
<style name="tapMediaListInfoLabelStyle"></style>
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="colors.xml" %}

```xml
<color name="tapMediaListInfoLabelColor">@color/yourColor</color>
```

{% endtab %}
{% endtabs %}

#### New Contact Page Font Styles

{% tabs %}
{% tab title="styles.xml" %}

```xml
<style name="tapSearchNewContactResultNameStyle"></style>
<style name="tapSearchNewContactResultUsernameStyle"></style>
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="colors.xml" %}

```xml
<color name="tapSearchNewContactResultNameColor">@color/yourColor</color>
<color name="tapSearchNewContactResultUsernameColor">@color/yourColor</color>
```

{% endtab %}
{% endtabs %}

#### Gallery Picker Page Font Styles

{% tabs %}
{% tab title="styles.xml" %}

```xml
<style name="tapAlbumNameLabelStyle"></style>
<style name="tapAlbumCountLabelStyle"></style>
<style name="tapGalleryPickerCancelButtonStyle"></style>
<style name="tapGalleryPickerContinueButtonStyle"></style>
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="colors.xml" %}

```xml
<color name="tapAlbumNameLabelColor">@color/yourColor</color>
<color name="tapAlbumCountLabelColor">@color/yourColor</color>
<color name="tapGalleryPickerCancelButtonColor">@color/yourColor</color>
<color name="tapGalleryPickerContinueButtonColor">@color/yourColor</color>
```

{% endtab %}
{% endtabs %}

#### Chat Room Page Font Styles

{% tabs %}
{% tab title="style.xml" %}

```xml
<style name="tapChatRoomNameLabelStyle"></style>
<style name="tapChatRoomStatusLabelStyle"></style>
<style name="tapChatComposerTextFieldStyle"></style>
<style name="tapCustomKeyboardItemLabelStyle"></style>
<style name="tapQuoteLayoutTitleLabelStyle"></style>
<style name="tapQuoteLayoutContentLabelStyle"></style>
<style name="tapRightBubbleMessageBodyStyle"></style>
<style name="tapLeftBubbleMessageBodyStyle"></style>
<style name="tapRightBubbleDeletedMessageBodyStyle"></style>
<style name="tapLeftBubbleDeletedMessageBodyStyle"></style>
<style name="tapRightBubbleQuoteTitleStyle"></style>
<style name="tapLeftBubbleQuoteTitleStyle"></style>
<style name="tapRightBubbleQuoteContentStyle"></style>
<style name="tapLeftBubbleQuoteContentStyle"></style>
<style name="tapRightFileBubbleNameStyle"></style>
<style name="tapLeftFileBubbleNameStyle"></style>
<style name="tapRightFileBubbleInfoStyle"></style>
<style name="tapLeftFileBubbleInfoStyle"></style>
<style name="tapLeftBubbleSenderNameStyle"></style>
<style name="tapBubbleMessageStatusStyle"></style>
<style name="tapBubbleMediaInfoStyle"></style>
<style name="tapSystemMessageBodyStyle"></style>
<style name="tapChatRoomUnreadBadgeLabelStyle"></style>
<style name="tapUnreadMessageIdentifierStyle"></style>
<style name="tapUnreadMessageButtonLabelStyle"></style>
<style name="tapDeletedChatRoomInfoTitleStyle"></style>
<style name="tapDeletedChatRoomInfoContentStyle"></style>
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="colors.xml" %}

```xml
<color name="tapChatRoomNameLabelColor">@color/yourColor</color>
<color name="tapChatRoomStatusLabelColor">@color/yourColor</color>
<color name="tapChatComposerTextFieldColor">@color/yourColor</color>
<color name="tapChatComposerTextFieldPlaceholderColor">@color/yourColor</color>
<color name="tapCustomKeyboardItemLabelColor">@color/yourColor</color>
<color name="tapQuoteLayoutTitleLabelColor">@color/yourColor</color>
<color name="tapQuoteLayoutContentLabelColor">@color/yourColor</color>
<color name="tapRightBubbleMessageBodyColor">@color/yourColor</color>
<color name="tapLeftBubbleMessageBodyColor">@color/yourColor</color>
<color name="tapRightBubbleMessageBodyURLColor">@color/yourColor</color>
<color name="tapLeftBubbleMessageBodyURLColor">@color/yourColor</color>
<color name="tapRightBubbleMessageBodyURLHighlightedColor">@color/yourColor</color>
<color name="tapLeftBubbleMessageBodyURLHighlightedColor">@color/yourColor</color>
<color name="tapRightBubbleDeletedMessageBodyColor">@color/yourColor</color>
<color name="tapLeftBubbleDeletedMessageBodyColor">@color/yourColor</color>
<color name="tapRightBubbleQuoteTitleColor">@color/yourColor</color>
<color name="tapLeftBubbleQuoteTitleColor">@color/yourColor</color>
<color name="tapRightBubbleQuoteContentColor">@color/yourColor</color>
<color name="tapLeftBubbleQuoteContentColor">@color/yourColor</color>
<color name="tapRightFileBubbleNameColor">@color/yourColor</color>
<color name="tapLeftFileBubbleNameColor">@color/yourColor</color>
<color name="tapRightFileBubbleInfoColor">@color/yourColor</color>
<color name="tapLeftFileBubbleInfoColor">@color/yourColor</color>
<color name="tapLeftBubbleSenderNameColor">@color/yourColor</color>
<color name="tapBubbleMessageStatusColor">@color/yourColor</color>
<color name="tapBubbleMediaInfoColor">@color/yourColor</color>
<color name="tapSystemMessageBodyColor">@color/yourColor</color>
<color name="tapChatRoomUnreadBadgeLabelColor">@color/yourColor</color>
<color name="tapUnreadMessageIdentifierColor">@color/yourColor</color>
<color name="tapUnreadMessageButtonLabelColor">@color/yourColor</color>
<color name="tapDeletedChatRoomInfoTitleColor">@color/yourColor</color>
<color name="tapDeletedChatRoomInfoContentColor">@color/yourColor</color>
```

{% endtab %}
{% endtabs %}

#### Location Picker Font Styles

{% tabs %}
{% tab title="styles.xml" %}

```xml
<style name="tapLocationPickerTextFieldStyle"></style>
<style name="tapLocationPickerTextFieldClearButtonStyle"></style>
<style name="tapLocationPickerSearchResultStyle"></style>
<style name="tapLocationPickerAddressStyle"></style>
<style name="tapLocationPickerSendLocationLabelButtonStyle"></style>
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="colors.xml" %}

```xml
<color name="tapLocationPickerTextFieldColor">@color/yourColor</color>
<color name="tapLocationPickerTextFieldPlaceholderColor">@color/yourColor</color>
<color name="tapLocationPickerTextFieldClearButtonColor">@color/yourColor</color>
<color name="tapLocationPickerSearchResultColor">@color/yourColor</color>
<color name="tapLocationPickerAddressColor">@color/yourColor</color>
<color name="tapLocationPickerAddressPlaceholderColor">@color/yourColor</color>
<color name="tapLocationPickerSendLocationLabelButtonColor">@color/yourColor</color>
```

{% endtab %}
{% endtabs %}

#### Send Media Preview Font Styles

{% tabs %}
{% tab title="styles.xml" %}

```xml
<style name="tapMediaPreviewCancelButtonStyle"></style>
<style name="tapMediaPreviewItemCountStyle"></style>
<style name="tapMediaPreviewCaptionStyle"></style>
<style name="tapMediaPreviewCaptionLetterCountStyle"></style>
<style name="tapMediaPreviewSendLabelButtonStyle"></style>
<style name="tapMediaPreviewWarningTitleStyle"></style>
<style name="tapMediaPreviewWarningBodyStyle"></style>
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="XML/HTML/SVG" %}

```xml
<color name="tapMediaPreviewCancelButtonColor">@color/yourColor</color>
<color name="tapMediaPreviewItemCountColor">@color/yourColor</color>
<color name="tapMediaPreviewCaptionColor">@color/yourColor</color>
<color name="tapMediaPreviewCaptionPlaceholderColor">@color/yourColor</color>
<color name="tapMediaPreviewCaptionLetterCountColor">@color/yourColor</color>
<color name="tapMediaPreviewSendLabelButtonColor">@color/yourColor</color>
<color name="tapMediaPreviewWarningTitleColor">@color/yourColor</color>
<color name="tapMediaPreviewWarningBodyColor">@color/yourColor</color>
```

{% endtab %}
{% endtabs %}

#### Image Detail Preview Font Styles

{% tabs %}
{% tab title="styles.xml" %}

```xml
<style name="tapImageDetailSenderNameStyle"></style>
<style name="tapImageDetailMessageStatusStyle"></style>
<style name="tapImageDetailCaptionStyle"></style>
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="colors.xml" %}

```xml
<color name="tapImageDetailSenderNameColor">@color/yourColor</color>
<color name="tapImageDetailMessageStatusColor">@color/yourColor</color>
<color name="tapImageDetailCaptionColor">@color/yourColor</color>
```

{% endtab %}
{% endtabs %}

#### Group Chat Font Styles

{% tabs %}
{% tab title="styles.xml" %}

```xml
<style name="tapSelectedMemberListNameStyle"></style>
<style name="tapGroupMemberCountStyle"></style>
<style name="tapGroupMemberListRoleStyle"></style>
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="colors.xml" %}

```xml
<color name="tapSelectedMemberListColor">@color/yourColor</color>
<color name="tapGroupMemberCountColor">@color/yourColor</color>
<color name="tapGroupMemberListRoleColor">@color/yourColor</color>
```

{% endtab %}
{% endtabs %}

#### Video Player Font Styles

{% tabs %}
{% tab title="styles.xml" %}

```xml
<style name="tapVideoPlayerTimeLabelStyle"></style>
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="colors.xml" %}

```xml
<color name="tapVideoPlayerTimeLabelColor">@color/yourColor</color>
```

{% endtab %}
{% endtabs %}


# Customize Chat Features

If you are using the default interface from TapTalk.io UI implementation type, you can choose to enable or disable the available chat features that we provided by using the **TapUI** class.

### Show / Hide Action Bar

By default, TapTalk activities will follow your project's app theme to show/hide action bar in activities, but you can show or hide action bar in TapTalk activities using the following methods:

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapUI;

...

// Show/hide action bar for all TapTalk activities
TapUI.getInstance().setAllTapTalkActivityActionBarEnabled(ENABLED);

// Show/hide action bar for TapTalk chat activity
TapUI.getInstance().setTapTalkChatActivityActionBarEnabled(ENABLED);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapUI

...

// Show/hide action bar for all TapTalk activities
TapUI.getInstance().setAllTapTalkActivityActionBarEnabled(ENABLED)

// Show/hide action bar for TapTalk chat activity
TapUI.getInstance().setTapTalkChatActivityActionBarEnabled(ENABLED)
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Note:**

• Calling `setAllTapTalkActivityActionBarEnabled` will enable/disable action bar in all TapTalk activities.

• Calling `setTapTalkChatActivityActionBarEnabled` will only enable/disable action bar in TapTalk default chat room (**TapUIChatActivity**).

• Setting `setAllTapTalkActivityActionBarEnabled` to `true` and `setTapTalkChatActivityActionBarEnabled` to `false` will **disable** action bar in TapTalk default chat room, but **enable** it in other TapTalk activities, and vice versa.
{% endhint %}

### Enable / Disable Message Read Status

You can choose to enable or disable read status of messages in room list and chat room. When disabled, read messages will show as delivered instead. Read status is enabled by default.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapUI;

...

TapUI.getInstance().setReadStatusVisible(VISIBLE);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapUI

...

TapUI.getInstance().setReadStatusVisible(VISIBLE)
```

{% endtab %}
{% endtabs %}

### Enable / Disable Add Contact Feature

You can also choose to enable or disable the user from adding another user as TapTalk contact.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapUI;

...

TapUI.getInstance().setAddContactEnabled(ENABLED);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapUI

...

TapUI.getInstance().setAddContactEnabled(ENABLED)
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Note:** Disabling add contact feature will also hide the following:

• Add to Contacts button in chat room

• Add to Contacts button in user profile

• New Contact button in start new chat page

• Scan QR Code button in start new chat page
{% endhint %}

### Customize Room List Features

The following features in TapTalk default room list can be customized:

• Close Room List Button

• Search Chat

• My Account

• Start New Chat

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapUI;

...

TapUI.getInstance().setCloseButtonInRoomListVisible(VISIBLE);

TapUI.getInstance().setSearchChatBarInRoomListVisible(VISIBLE);

TapUI.getInstance().setMyAccountButtonInRoomListVisible(VISIBLE);

TapUI.getInstance().setNewChatButtonInRoomListVisible(VISIBLE);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapUI

...

TapUI.getInstance().setCloseButtonInRoomListVisible(VISIBLE)

TapUI.getInstance().setSearchChatBarInRoomListVisible(VISIBLE)

TapUI.getInstance().setMyAccountButtonInRoomListVisible(VISIBLE)

TapUI.getInstance().setNewChatButtonInRoomListVisible(VISIBLE)
```

{% endtab %}
{% endtabs %}

### Customize Chat Room Features

The following features in TapTalk default chat room can be customized:

• User / Group Profile Button

• Add to Contacts

• Mention Username

• Send Voice Note

• Link Preview in Message Bubble

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapUI;

...

TapUI.getInstance().setProfileButtonInChatRoomVisible(VISIBLE);

TapUI.getInstance().setAddToContactsButtonInChatRoomVisible(VISIBLE);

TapUI.getInstance().setMentionUsernameEnabled(ENABLED);

TapUI.getInstance().setSendVoiceNoteMenuEnabled(ENABLED);

TapUI.getInstance().setLinkPreviewInMessageEnabled(ENABLED);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapUI

...

TapUI.getInstance().setProfileButtonInChatRoomVisible(VISIBLE)

TapUI.getInstance().setAddToContactsButtonInChatRoomVisible(VISIBLE)

TapUI.getInstance().setMentionUsernameEnabled(ENABLED)

TapUI.getInstance().setSendVoiceNoteMenuEnabled(ENABLED)

TapUI.getInstance().setLinkPreviewInMessageEnabled(ENABLED)
```

{% endtab %}
{% endtabs %}

### Customize Chat Room Attachments

You can choose to enable or disable message attachments in chat room as follows:

• Documents

• Camera

• Gallery

• Location (requires Google Places API Key)

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapUI;

...

TapUI.getInstance().setDocumentAttachmentEnabled(ENABLED);

TapUI.getInstance().setCameraAttachmentEnabled(ENABLED);

TapUI.getInstance().setGalleryAttachmentEnabled(ENABLED);

TapUI.getInstance().setLocationAttachmentEnabled(ENABLED);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapUI

...

TapUI.getInstance().setDocumentAttachmentEnabled(ENABLED)

TapUI.getInstance().setCameraAttachmentEnabled(ENABLED)

TapUI.getInstance().setGalleryAttachmentEnabled(ENABLED)

TapUI.getInstance().setLocationAttachmentEnabled(ENABLED)
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Note:** Location attachment will be disabled by default when Google Places API Key is not set from **TapTalk** class.
{% endhint %}

### Customize Chat Bubble Long Press Action

You can choose to enable or disable long press action menus in chat room as follows:

• Reply Message

• Forward Message

• Edit Message

• Delete Message

• Delete Others' Message by Admin

• Message Info

• Save Media to Gallery

• Open Link

• Compose Email

• Dial Number

• Send SMS

• View Profile

• Send Message

• Report Message (disabled by default)

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapUI;

...

TapUI.getInstance().setReplyMessageMenuEnabled(ENABLED);

TapUI.getInstance().setForwardMessageMenuEnabled(ENABLED);

TapUI.getInstance().setEditMessageMenuEnabled(ENABLED);

TapUI.getInstance().setDeleteMessageMenuEnabled(ENABLED);

TapUI.getInstance().setAllowDeleteOthersMessageForAdminEnabled(ENABLED);

TapUI.getInstance().setMessageInfoMenuEnabled(ENABLED);

TapUI.getInstance().setSaveMediaToGalleryMenuEnabled(ENABLED);

TapUI.getInstance().setOpenLinkMenuEnabled(ENABLED);

TapUI.getInstance().setComposeEmailMenuEnabled(ENABLED);

TapUI.getInstance().setDialNumberMenuEnabled(ENABLED);

TapUI.getInstance().setSendSMSMenuEnabled(ENABLED);

TapUI.getInstance().setViewProfileMenuEnabled(ENABLED);

TapUI.getInstance().setSendMessageMenuEnabled(ENABLED);

TapUI.getInstance().setReportMessageMenuEnabled(ENABLED);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapUI

...

TapUI.getInstance().setReplyMessageMenuEnabled(ENABLED)

TapUI.getInstance().setForwardMessageMenuEnabled(ENABLED)

TapUI.getInstance().setEditMessageMenuEnabled(ENABLED)

TapUI.getInstance().setDeleteMessageMenuEnabled(ENABLED)

TapUI.getInstance().setMessageInfoMenuEnabled(ENABLED)

TapUI.getInstance().setSaveMediaToGalleryMenuEnabled(ENABLED)

TapUI.getInstance().setOpenLinkMenuEnabled(ENABLED)

TapUI.getInstance().setComposeEmailMenuEnabled(ENABLED)

TapUI.getInstance().setDialNumberMenuEnabled(ENABLED)

TapUI.getInstance().setSendSMSMenuEnabled(ENABLED)

TapUI.getInstance().setViewProfileMenuEnabled(ENABLED)

TapUI.getInstance().setSendMessageMenuEnabled(ENABLED)

TapUI.getInstance().setReportMessageMenuEnabled(ENABLED)
```

{% endtab %}
{% endtabs %}

### Customize Start New Chat Features

If `setNewChatButtonInRoomListVisible` is enabled (default), you can also customize the availability of its contents:

• Add New Contact (add contact by search)

• Scan QR Code (add contact by scanning QR code)

• Create new group

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapUI;

...

TapUI.getInstance().setNewContactMenuButtonVisible(VISIBLE);

TapUI.getInstance().setScanQRMenuButtonVisible(VISIBLE);

TapUI.getInstance().setNewGroupMenuButtonVisible(VISIBLE);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapUI

...

TapUI.getInstance().setNewContactMenuButtonVisible(VISIBLE)

TapUI.getInstance().setScanQRMenuButtonVisible(VISIBLE)

TapUI.getInstance().setNewGroupMenuButtonVisible(VISIBLE)
```

{% endtab %}
{% endtabs %}

### Customize My Account Page

You can choose to show or hide the logout and delete account button in TapTalk My Account page.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapUI

...

TapUI.getInstance().setLogoutButtonVisible(VISIBLE);

TapUI.getInstance().setDeleteAccountButtonVisible(VISIBLE);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapUI

...

TapUI.getInstance().setLogoutButtonVisible(VISIBLE)

TapUI.getInstance().setDeleteAccountButtonVisible(VISIBLE)
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
Delete account button is hidden and does nothing if pressed by default, its action needs to be handled manually using [**TapUIMyAccountListener**](/powertalk-chat-sdk-documentation/powertalk-android/event-listener#tapuimyaccountlistener).
{% endhint %}

### Customize User Profile Page

You can choose to show or hide the add to contacts & report/block button in TapTalk Chat Profile page.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapUI;

...

TapUI.getInstance().setAddToContactsButtonInChatProfileVisible(VISIBLE);

TapUI.getInstance().setReportButtonInChatProfileVisible(VISIBLE);

TapUI.getInstance().setReportButtonInUserProfileVisible(VISIBLE);

TapUI.getInstance().setReportButtonInGroupProfileVisible(VISIBLE);

TapUI.getInstance().setBlockUserMenuEnabled(ENABLED);

TapUI.getInstance().setGroupInCommonMenuEnabled(ENABLED);

TapUI.getInstance().setSharedMediaMenuEnabled(ENABLED);

TapUI.getInstance().setSharedMediaMediasTabVisible(VISIBLE);

TapUI.getInstance().setSharedMediaLinksTabVisible(VISIBLE);

TapUI.getInstance().setSharedMediaDocumentsTabVisible(VISIBLE);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapUI

...

TapUI.getInstance().setAddToContactsButtonInChatProfileVisible(VISIBLE)

TapUI.getInstance().setReportButtonInChatProfileVisible(VISIBLE)

TapUI.getInstance().setReportButtonInUserProfileVisible(VISIBLE)

TapUI.getInstance().setReportButtonInGroupProfileVisible(VISIBLE)

TapUI.getInstance().setBlockUserMenuEnabled(ENABLED)

TapUI.getInstance().setGroupInCommonMenuEnabled(ENABLED)

TapUI.getInstance().setSharedMediaMenuEnabled(ENABLED)

TapUI.getInstance().setSharedMediaMediasTabVisible(VISIBLE)

TapUI.getInstance().setSharedMediaLinksTabVisible(VISIBLE)

TapUI.getInstance().setSharedMediaDocumentsTabVisible(VISIBLE)
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
The report button is hidden by default, and the report button in group profile currently does nothing by default when pressed, its action needs to be handled manually using [**TapUIChatProfileListener**](/powertalk-chat-sdk-documentation/powertalk-android/event-listener#tapuichatprofilelistener).
{% endhint %}

### Customize Star Message Menu

To enable or disable star message menu in chat room and chat profile page, you may call `setStarMessageMenuEnabled()` method from **TapUI** class. This feature is enabled by default.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapUI;

...

TapUI.getInstance().setStarMessageMenuEnabled(ENABLED);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapUI

...

TapUI.getInstance().setStarMessageMenuEnabled(ENABLED)
```

{% endtab %}
{% endtabs %}

### Customize Room List Item Swipe Menu&#x20;

User is able to swipe an item in the room list page to quickly complete some actions. To enable/disable this feature, you may call the following methods below.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapUI;

...

// Enable/disable mark as read swipe menu action
TapUI.getInstance().setMarkAsReadRoomListSwipeMenuEnabled(ENABLED);

// Enable/disable mark as unread swipe menu action
TapUI.getInstance().setMarkAsUnreadRoomListSwipeMenuEnabled(ENABLED);

// Enable/disable pin and unpin swipe menu action
TapUI.getInstance().setPinRoomListSwipeMenuEnabled(ENABLED);

// Enable/disable mute and unmute swipe menu action
TapUI.getInstance().setMuteRoomListSwipeMenuEnabled(ENABLED);

// Enable/disable delete chat swipe menu action
TapUI.getInstance().setDeleteRoomListSwipeMenuEnabled(ENABLED);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapUI

...

// Enable/disable mark as read swipe menu action
TapUI.getInstance().setMarkAsReadRoomListSwipeMenuEnabled(ENABLED)

// Enable/disable mark as unread swipe menu action
TapUI.getInstance().setMarkAsUnreadRoomListSwipeMenuEnabled(ENABLED)

// Enable/disable pin and unpin swipe menu action
TapUI.getInstance().setPinRoomListSwipeMenuEnabled(ENABLED)

// Enable/disable mute and unmute swipe menu action
TapUI.getInstance().setMuteRoomListSwipeMenuEnabled(ENABLED)

// Enable/disable delete chat swipe menu action
TapUI.getInstance().setDeleteRoomListSwipeMenuEnabled(ENABLED)
```

{% endtab %}
{% endtabs %}

### Customize Saved Messages Feature

To enable or disable Saved Messages feature, call the `setSavedMessagesMenuEnabled()` from **TapUI**. This feature is enabled by default. Disabling this feature when the user has previously used it will not remove the user's existing messages that has been sent to the Saved Messages chat room.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapUI;

...

TapUI.getInstance().setSavedMessagesMenuEnabled(ENABLED);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapUI

...

TapUI.getInstance().setSavedMessagesMenuEnabled(ENABLED)
```

{% endtab %}
{% endtabs %}

### Customize Pin Message Menu

To enable or disable pin message menu in chat room, you may call `setPinMessageMenuEnabled()` method from **TapUI** class. This feature is enabled by default.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapUI;

...

TapUI.getInstance().setPinMessageMenuEnabled(ENABLED);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapUI

...

TapUI.getInstance().setPinMessageMenuEnabled(ENABLED)
```

{% endtab %}
{% endtabs %}

### Enable / Disable In-App Browser

To choose whether to open message urls with in-app browser or the device's browser app, you may call `setOpenLinkWithExternalBrowserEnabled()` method from **TapUI** class. TapTalk.io's in-app browser will be used by default.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapUI;

...

TapUI.getInstance().setOpenLinkWithExternalBrowserEnabled(ENABLED);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapUI

...

TapUI.getInstance().setOpenLinkWithExternalBrowserEnabled(ENABLED)
```

{% endtab %}
{% endtabs %}


# Customize Chat Message Bubble

When TapTalk.io framework is integrated to your app with the UI implementation method, you can add customized chat message bubbles to be used in chat.

### Adding a Custom Chat Bubble

You can check the following example to add a custom bubble to your chat.

#### 1. Create an XML layout file for the custom bubble

First, create a new XML layout resource file for your custom bubble, we will name it `my_custom_bubble_layout.xml`. You are free to customize the custom bubble layout as you wish. In this example, we will be using a simple image and text bubble.<br>

{% tabs %}
{% tab title="my\_custom\_bubble\_layout.xml" %}

```xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginStart="16dp"
    android:layout_marginEnd="16dp"
    android:layout_marginBottom="8dp"
    android:background="@color/tapWhite">

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:adjustViewBounds="true"
        android:src="@mipmap/ic_launcher"
        app:layout_constraintTop_toTopOf="parent" />
    
    <!--We are using TapTalk'io's default message body style for this TextView-->
    <TextView
        android:id="@+id/textView"
        style="@style/tapLeftBubbleMessageBodyStyle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="8dp"
        app:layout_constraintTop_toBottomOf="@id/imageView"
        tools:text="Message body" />

</android.support.constraint.ConstraintLayout>
```

{% endtab %}
{% endtabs %}

![my\_custom\_bubble\_layout.xml](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MITU-amd75K7ni1ppWQ%2F-MITUeTY7darodJ5FFO8%2F5e41486-cb1.png?alt=media\&token=df8430d0-1804-4f4f-b7c2-21c8409057c6)

{% hint style="info" %}
**Note:** TapTalk.io's default message bubble layouts generally have a `8dp` bottom margin and no top margin.
{% endhint %}

#### 2. Create a custom listener

In order to listen to event callbacks that happens in your custom bubble, we will create a custom interface that extends **TapTalkBaseCustomInterface**. We will name this interface `MyCustomBubbleListener`.

{% tabs %}
{% tab title="MyCustomBubbleListener.java" %}

```java
import io.taptalk.TapTalk.Interface.TapTalkBaseCustomInterface;
import io.taptalk.TapTalk.Model.TAPMessageModel;

...

public interface MyCustomBubbleListener extends TapTalkBaseCustomInterface {

    // Use this to notify that the user tapped your custom bubble
    void onBubbleTapped(TAPMessageModel message);
}
```

{% endtab %}

{% tab title="MyCustomBubbleListener.kt" %}

```kotlin
import io.taptalk.TapTalk.Interface.TapTalkBaseCustomInterface
import io.taptalk.TapTalk.Model.TAPMessageModel

...

interface MyCustomBubbleListener : TapTalkBaseCustomInterface {

    // Use this to notify that the user tapped your custom bubble
    fun onBubbleTapped(message: TAPMessageModel)
}
```

{% endtab %}
{% endtabs %}

#### 3. Create a custom bubble ViewHolder

To display your custom bubble layout in a chat room, you will need to create a custom ViewHolder that extends **TAPBaseChatViewHolder**. We will name this class `MyCustomBubbleViewHolder`.

{% tabs %}
{% tab title="MyCustomBubbleListener.java" %}

```java
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import io.taptalk.TapTalk.Model.TAPMessageModel;
import io.taptalk.TapTalk.View.Adapter.TAPBaseChatViewHolder;

public class MyCustomBubbleViewHolder extends TAPBaseChatViewHolder {

    private ImageView imageView;
    private TextView textView;

    private MyCustomBubbleListener listener; // The listener that you just created above will be used here

    // Add MyCustomBubbleListener to the constructor parameter
    MyCustomBubbleViewHolder(ViewGroup parent, int itemLayoutId, MyCustomBubbleListener listener) {
        super(parent, itemLayoutId);

        // Bind views on constructor
        imageView = itemView.findViewById(R.id.imageView);
        textView = itemView.findViewById(R.id.textView);

        // Pass the listener from parameter
        this.listener = listener;
    }

    @Override
    protected void onBind(TAPMessageModel message, int index) {
        super.onBind(message, index);

        // Set message text
        textView.setText(message.getBody());

        // Set click listener
        imageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // Trigger listener and pass the clicked message
                listener.onBubbleTapped(message);
            }
        });
    }
}
```

{% endtab %}

{% tab title="MyCustomBubbleListener.kt" %}

```kotlin
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import io.taptalk.TapTalk.Model.TAPMessageModel
import io.taptalk.TapTalk.View.Adapter.TAPBaseChatViewHolder

class MyCustomBubbleViewHolder internal constructor(
    parent: ViewGroup,
    itemLayoutId: Int,
    private val listener: MyCustomBubbleListener
) : TAPBaseChatViewHolder(parent, itemLayoutId) {

    private val imageView: ImageView = itemView.findViewById(R.id.imageView)
    private val textView: TextView = itemView.findViewById(R.id.textView)

    override fun onBind(message: TAPMessageModel?, index: Int) {
        super.onBind(message, index)
          
        // Set message text
        textView.text = message!!.body
          
        // Pass the listener from parameter
        imageView.setOnClickListener { 
            // Trigger listener and pass the clicked message
            listener.onBubbleTapped(message)
        }
    }
}
```

{% endtab %}
{% endtabs %}

#### 4. Create a custom bubble class

Using all the things you have created above, we will create a custom bubble class that extends **TAPBaseCustomBubble**. This class instance will then be added to the custom bubble list.

{% tabs %}
{% tab title="MyCustomBubbleClass.java" %}

```java
import android.view.ViewGroup;

import io.taptalk.TapTalk.Helper.TAPBaseCustomBubble;
import io.taptalk.TapTalk.Model.TAPUserModel;
import io.taptalk.TapTalk.View.Adapter.TAPMessageAdapter;

public class MyCustomBubbleClass extends TAPBaseCustomBubble<MyCustomBubbleViewHolder, MyCustomBubbleListener> {

    public MyCustomBubbleClass(int customBubbleLayoutRes, int messageType, MyCustomBubbleListener listener) {
        super(customBubbleLayoutRes, messageType, listener);
    }

    @Override
    public MyCustomBubbleViewHolder createCustomViewHolder(ViewGroup viewGroup, TAPMessageAdapter tapMessageAdapter, TAPUserModel tapUserModel, MyCustomBubbleListener listener) {
        return new MyCustomBubbleViewHolder(viewGroup, getCustomBubbleLayoutRes(), listener);
    }
}
```

{% endtab %}

{% tab title="MyCustomBubbleClass.kt" %}

```kotlin
import android.view.ViewGroup

import io.taptalk.TapTalk.Helper.TAPBaseCustomBubble
import io.taptalk.TapTalk.Model.TAPUserModel
import io.taptalk.TapTalk.View.Adapter.TAPMessageAdapter

class MyCustomBubbleClass(
    customBubbleLayoutRes: Int,
    messageType: Int,
    listener: MyCustomBubbleListener
) : TAPBaseCustomBubble<MyCustomBubbleViewHolder, MyCustomBubbleListener>(
    customBubbleLayoutRes,
    messageType,
    listener
) {

    override fun createCustomViewHolder(
        viewGroup: ViewGroup,
        tapMessageAdapter: TAPMessageAdapter,
        tapUserModel: TAPUserModel,
        listener: MyCustomBubbleListener
    ): MyCustomBubbleViewHolder {
        return MyCustomBubbleViewHolder(viewGroup, customBubbleLayoutRes, listener)
    }
}
```

{% endtab %}
{% endtabs %}

#### 5. Add your custom bubble class

To add your custom bubble to TapTalk.io, use the **TapUI** class and call the `addCustomBubble()` method. This is typically done in your Application class, after `init()` has already been called.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Helper.TapTalk;
import io.taptalk.TapTalk.Manager.TapUI;
import io.taptalk.TapTalk.Model.TAPMessageModel;

...

TapTalk.init(...);

// Insert the XML layout resource, message type, and your custom listener as parameter
TapUI.getInstance().addCustomBubble(new MyCustomBubbleClass(
    R.layout.my_custom_bubble_layout,
    3001,
    new MyCustomBubbleListener() {
        @Override
        public void onBubbleTapped(TAPMessageModel message) {
            // My custom bubble was tapped by user
        }
    }
));
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Helper.TapTalk
import io.taptalk.TapTalk.Manager.TapUI
import io.taptalk.TapTalk.Model.TAPMessageModel

...

TapTalk.init(...)

// Insert the XML layout resource, message type, and your custom listener as parameter
TapUI.getInstance().addCustomBubble(MyCustomBubbleClass(
    R.layout.my_custom_bubble_layout,
    3001,
    object : MyCustomBubbleListener() {
        fun onBubbleTapped(message: TAPMessageModel) {
            // My custom bubble was tapped by user
        }
    }
))
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
**Note:** Please note that the message type for custom bubbles should start with 3 as the prefix. For more information, check the [message type page](/powertalk-chat-sdk-documentation/powertalk-ios/message-type).
{% endhint %}

After completing all the steps above, your custom bubble will be ready to use.

### Showing Your Custom Bubble in Chat

You can use your customized chat bubble in a chat room by constructing a custom **TAPMessageModel** with [`constructTapTalkMessageModel()`](broken://pages/-MITd810gfX-Tnf3zLdP#construct-taptalk-io-message-model) method, then sending the constructed message to the chat room with [`sendCustomMessage()`](broken://pages/-MITd810gfX-Tnf3zLdP#send-a-custom-message). Both methods can be accessed from the **TapCoreMessageManager** class.

To construct a message, you are required to have a **TAPRoomModel** as a parameter. You can use [`getPersonalChatRoom()`](broken://pages/-MITd810gfX-Tnf3zLdP#get-personal-chat-room-with-recipient-user) or [`getGroupChatRoom()`](/powertalk-chat-sdk-documentation/powertalk-android/group-chat/tapcore#get-group-chat-room) method in **TapCoreChatRoomManager** class to obtain a chat room model.

Below is an example to send a custom message with the steps mentioned above.

{% tabs %}
{% tab title="Java" %}

```java
import io.taptalk.TapTalk.Manager.TapCoreMessageManager;
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager;
import io.taptalk.TapTalk.Listener.TapCoreGetRoomListener;
import io.taptalk.TapTalk.Listener.TapCoreSendMessageListener;
import io.taptalk.TapTalk.Model.TAPMessageModel;
import io.taptalk.TapTalk.Model.TAPRoomModel;

...

// First, we will retrieve a TAPRoomModel required to construct a message
TapCoreChatRoomManager.getInstance().getPersonalChatRoom(RECIPIENT_USER, new TapCoreGetRoomListener() {
    @Override
    public void onSuccess(TAPRoomModel room) {
        // Retrieved room data successfully, we will use this room to construct a TAPMessageModel
        TAPMessageModel customBubbleMessage = TapCoreMessageManager.getInstance().constructTapTalkMessageModel(
            "This is a custom message", // MESSAGE_BODY
            room,                       // ROOM
            3001,                       // MESSAGE_TYPE
            null                        // MESSAGE_DATA
        );
      
        // We will then send the constructed message to its corresponding chat room
        TapCoreMessageManager.getInstance().sendCustomMessage(customBubbleMessage, new TapCoreSendMessageListener() {
            @Override
            public void onSuccess(TAPMessageModel message) {
                // Custom message was sent successfully
            }

            @Override
            public void onError(String errorCode, String errorMessage) {
                
            }
        });
    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import io.taptalk.TapTalk.Manager.TapCoreMessageManager
import io.taptalk.TapTalk.Manager.TapCoreChatRoomManager
import io.taptalk.TapTalk.Listener.TapCoreGetRoomListener
import io.taptalk.TapTalk.Listener.TapCoreSendMessageListener
import io.taptalk.TapTalk.Model.TAPMessageModel
import io.taptalk.TapTalk.Model.TAPRoomModel

...

// First, we will retrieve a TAPRoomModel required to construct a message
TapCoreChatRoomManager.getInstance().getPersonalChatRoom(RECIPIENT_USER, object : TapCoreGetRoomListener() {
    override fun onSuccess(room: TAPRoomModel?) {
        // Retrieved room data successfully, we will use this room to construct a TAPMessageModel
        val customBubbleMessage = TapCoreMessageManager.getInstance().constructTapTalkMessageModel(
            "This is a custom message", // MESSAGE_BODY
            room!!,                     // ROOM
            3001,                       // MESSAGE_TYPE
            null                        // MESSAGE_DATA
        )
      
        // We will then send the constructed message to its corresponding chat room
        TapCoreMessageManager.getInstance().sendCustomMessage(customBubbleMessage, object : TapCoreSendMessageListener() {
            override fun onSuccess(message: TAPMessageModel?) {
                // Custom message was sent successfully
            }

            override fun onError(errorCode: String?, errorMessage: String?) {
                
            }
        })
    }
})
```

{% endtab %}
{% endtabs %}


# Customize Navigation Bar

When TapTalk.io framework is integrated to your app with the UI/combine implementation method, you can customize chat room's navigation bar layout to your preferences.

### Customize Chat Room Navigation Bar

You can follow the steps below to customize chat rooms' navigation bar layout in your app.

#### 1. Create your custom navigation bar XML layout

{% tabs %}
{% tab title="your\_custom\_navbar\_layout.xml" %}

```xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize">

    <!--Customize and add more layouts here-->

</android.support.constraint.ConstraintLayout>
```

{% endtab %}
{% endtabs %}

#### 2. Create your custom navigation bar fragment

Create a new fragment file inside your project folder, and set it to extend `TapBaseChatRoomCustomNavigationBarFragment`**.**

Then override `onCreateView()` and return your custom layout.

{% tabs %}
{% tab title="YourCustomNavBarFragment.java" %}

```java
import io.taptalk.TapTalk.View.Fragment.TapBaseChatRoomCustomNavigationBarFragment;

public class MeetTalkChatRoomNavigationBarFragment extends TapBaseChatRoomCustomNavigationBarFragment {
    
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        // Return your custom layout
        return inflater.inflate(R.layout.your_custom_navbar_layout, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        // Setup your views here
    }
}
```

{% endtab %}

{% tab title="YourCustomNavBarFragment.kt" %}

```kotlin
import io.taptalk.TapTalk.View.Fragment.TapBaseChatRoomCustomNavigationBarFragment

class MeetTalkChatRoomNavigationBarFragment : TapBaseChatRoomCustomNavigationBarFragment() {

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        // Return your custom layout
        return inflater.inflate(R.layout.your_custom_navbar_layout, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        // Setup your views here
    }
}
```

{% endtab %}
{% endtabs %}

#### 3. Implement callbacks from base navigation fragment class to update UI

`TapBaseChatRoomCustomNavigationBarFragment` class is a helper fragment class that implements `TapCoreChatRoomListener` to listen to chat room related callbacks from PowerTalk SDK.

The class will then handle and redirect the callbacks to the following functions, which provide the required data that you can make use of for your own custom navbar class to display and update UI elements in the custom navigation bar.

You can override the callbacks functions from the `TapBaseChatRoomCustomNavigationBarFragment` class to your own custom navbar class:

{% tabs %}
{% tab title="YourCustomNavBarFragment.java" %}

```java
import io.taptalk.TapTalk.View.Fragment.TapBaseChatRoomCustomNavigationBarFragment;
import io.taptalk.TapTalk.Model.TAPMessageModel;
import io.taptalk.TapTalk.Model.TAPOnlineStatusModel;
import io.taptalk.TapTalk.Model.TAPRoomModel;
import io.taptalk.TapTalk.Model.TAPUserModel;

public class MeetTalkChatRoomNavigationBarFragment extends TapBaseChatRoomCustomNavigationBarFragment {
    
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        // Return your custom layout
        return inflater.inflate(R.layout.your_custom_navbar_layout, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        // Setup your views here
    }
    
    // Override callback methods from TapBaseChatRoomCustomNavigationBarFragment below
    
    @Override
    public void onReceiveUpdatedChatRoomData(TAPRoomModel room, @Nullable TAPUserModel recipientUser, TAPOnlineStatusModel onlineStatus) {
        // This callback is called when PowerTalk SDK receives updated chat room data through server or socket
        // Here you can update the display of your custom view given the updated data
        // Please note that recipientUser's value could be null at some cirscumstances, such in a group room
    }

    @Override
    public void onReceiveStartTyping(String roomID, TAPUserModel user) {
        // This callback is called when a participant in the current room starts typing
        // Here you can optionally show typing view in your custom navbar
    }

    @Override
    public void onReceiveStopTyping(String roomID, TAPUserModel user) {
        // This callback is called when a participant in the current room stops typing
        // Here you can optionally hide typing view in your custom navbar
    }

    @Override
    public void onReceiveOnlineStatus(TAPUserModel user, Boolean isOnline, Long lastActive) {
        // This callback is called when a participant's online status in the current room is updated
        // Here you can optionally update online status view in your custom navbar
    }

    @Override
    public void onShowMessageSelection(List<TAPMessageModel> selectedMessages) {
        // This callback is called when user opens a multiple message selection in the chat room, such as selecting forward messages
    }

    @Override
    public void onHideMessageSelection() {    
        // This callback is called when multiple message selection in the chat room is closed
    }
}
```

{% endtab %}

{% tab title="YourCustomNavBarFragment.kt" %}

```kotlin
import io.taptalk.TapTalk.View.Fragment.TapBaseChatRoomCustomNavigationBarFragment
import io.taptalk.TapTalk.Model.TAPMessageModel
import io.taptalk.TapTalk.Model.TAPOnlineStatusModel
import io.taptalk.TapTalk.Model.TAPRoomModel
import io.taptalk.TapTalk.Model.TAPUserModel

class MeetTalkChatRoomNavigationBarFragment : TapBaseChatRoomCustomNavigationBarFragment() {

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        // Return your custom layout
        return inflater.inflate(R.layout.your_custom_navbar_layout, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        // Setup your views here
    }
    
    // Override callback methods from TapBaseChatRoomCustomNavigationBarFragment below

    override fun onReceiveUpdatedChatRoomData(room: TAPRoomModel?, recipientUser: TAPUserModel?, onlineStatus: TAPOnlineStatusModel?) {
        // This callback is called when PowerTalk SDK receives updated chat room data through server or socket
        // Here you can update the display of your custom view given the updated data
        // Please note that recipientUser's value could be null at some cirscumstances, such in a group room
    }

    override fun onReceiveStartTyping(roomID: String, user: TAPUserModel) {
        // This callback is called when a participant in the current room starts typing
        // Here you can optionally show typing view in your custom navbar
    }

    override fun onReceiveStopTyping(roomID: String, user: TAPUserModel) {
        // This callback is called when a participant in the current room stops typing
        // Here you can optionally hide typing view in your custom navbar
    }

    override fun onReceiveOnlineStatus(user: TAPUserModel, isOnline: Boolean, lastActive: Long) {
        // This callback is called when a participant's online status in the current room is updated
        // Here you can optionally update online status view in your custom navbar
   }

    override fun onShowMessageSelection(selectedMessages: List<TAPMessageModel>) {
        // This callback is called when user opens a multiple message selection in the chat room, such as selecting forward messages
    }

    override fun onHideMessageSelection() {
        // This callback is called when multiple message selection in the chat room is closed
    }
}
```

{% endtab %}
{% endtabs %}

#### 4. Make use of base navigation bar manager properties

`TapBaseChatRoomCustomNavigationBarFragment` also provides some properties that you can make use of to display UI elements in your custom navbar class.

You can call any of these properties provided below to help displaying your custom navbar.

```java
// Room data of the currently open chat room
TAPRoomModel room;

// Other user's data in personal chat room
// Value could be null when currently active room is not personal
TAPUserModel recipientUser;

// Online status data of the recipient user
// Value could be null when currently active room is not personal
TAPOnlineStatusModel onlineStatus;

// Linked HashMap containing currently typing users in the chat room
LinkedHashMap<String, TAPUserModel> typingUsers;
```

The values of the properties above will also be updated when any related callbacks from PowerTalk SDK is received.

#### 5. Implement TapUIChatRoomCustomNavigationBarListener

After you finished setting up your custom-made navigation bar, you will need to implement a listener from TapUI that will be invoked when the user opens a chat room. You can then return your custom navigation bar fragment through the callback function.

To do this, call the **`addChatRoomCustomNavigationBarListener`** method from **TapUI** class after you have initialized TapTalk. You can check the example below:

{% tabs %}
{% tab title="Application.java" %}

```java
import io.taptalk.TapTalk.Helper.TapTalk;
import io.taptalk.TapTalk.Manager.TapUI;
import io.taptalk.TapTalk.Listener.TapUIChatRoomCustomNavigationBarListener;
import io.taptalk.TapTalk.View.Fragment.TapBaseChatRoomCustomNavigationBarFragment;
import io.taptalk.TapTalk.Model.TAPRoomModel;
import io.taptalk.TapTalk.Model.TAPUserModel;

public class YourApplication extends Application {
    
    @Override
    public void onCreate() {
        super.onCreate();
        
        TapTalk.init(...);
        
        // Implement listener
        TapUI.getInstance().addChatRoomCustomNavigationBarListener(new TapUIChatRoomCustomNavigationBarListener() {
            @Override
            public TapBaseChatRoomCustomNavigationBarFragment setCustomChatRoomNavigationBar(
                Activity activity, 
                TAPRoomModel room, 
                TAPUserModel activeUser, 
                @Nullable TAPUserModel recipientUser
            ) {
                // Return your custom navigation bar fragment
                return new YourCustomNavBarFragment();
            }
        });
    }
}
```

{% endtab %}

{% tab title="Application.kt" %}

<pre class="language-kotlin"><code class="lang-kotlin">import io.taptalk.TapTalk.Helper.TapTalk
import io.taptalk.TapTalk.Manager.TapUI
import io.taptalk.TapTalk.Listener.TapUIChatRoomCustomNavigationBarListener
import io.taptalk.TapTalk.View.Fragment.TapBaseChatRoomCustomNavigationBarFragment
import io.taptalk.TapTalk.Model.TAPRoomModel
import io.taptalk.TapTalk.Model.TAPUserModel

class YourApplication : Application() {

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        // Return your custom layout
        return inflater.inflate(R.layout.your_custom_navbar_layout, container, false)
    }

    override fun onCreate() {
        super.onCreate()
        
        TapTalk.init(...)
        
        // Implement listener
        TapUI.getInstance().addChatRoomCustomNavigationBarListener(object : TapUIChatRoomCustomNavigationBarListener() {
<strong>            override fun setCustomChatRoomNavigationBar(
</strong>                activity: Activity,
                room: TAPRoomModel,
                activeUser: TAPUserModel,
                recipientUser: TAPUserModel?
            ): TapBaseChatRoomCustomNavigationBarFragment {
                // Return your custom navigation bar fragment
                return new YourCustomNavBarFragment();
            }
        });
    }
}
</code></pre>

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**`setCustomChatRoomNavigationBar`** callback from `TapUIChatRoomCustomNavigationBarListener` returns a `TapBaseChatRoomCustomNavigationBarFragment` as a value. If you do not implement this callback or return a `null`, PowerTalk SDK will display the default chat room navigation bar.
{% endhint %}


# Deep Linking

You may set up a deep link for your preferred URL so that when users taps the defined URL from anywhere outside your app in their Android device, they will be redirected to your app for a smoother experience.

In this example, we will explain how to set up deep linking to open TapTalk.io's room list or a specific chat room page when user taps a specific link from their device.

### Step 1: Define a URL to open your app

To start, choose a URL from your domain that will be used to open your app. In this example, we will try using [**https://web.taptalk.io/chat**](https://web.taptalk.io/chat).

{% hint style="warning" %}
You should use your own specified URL, the URL above is only meant as an example to make it easier to follow the guide.
{% endhint %}

### Step 2:  Specify an Activity to handle Deep Link

To be able to open your app from a URL, you will need to add an intent filter to your specified activity's tag inside the **AndroidManifest.xml** file. In this example, a new activity named **TapDeepLinkActivity** will be created specifically to handle deep links. You may also use an existing activity, such as your app's main activity, if you wish.

After you locate your chosen activity tag in the Manifest, add the following intent filter inside the `<activity>` tag. The previously defined URL as will be added as data for the intent filter.

{% code title="AndroidManifest.xml" %}

```xml
<application
    android:name=".YourApplication"
    ...
    
    <activity
        android:name="com.example.app.activity.TapDeepLinkActivity"
        android:exported="true"
        android:launchMode="singleTask">
        <intent-filter android:autoVerify="true">
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data android:scheme="https" />
            <data android:host="web.taptalk.io" />
            <data android:pathPrefix="/chat" />
        </intent-filter>
    </activity>

</application>
```

{% endcode %}

From [**Android Developer**](https://developer.android.com/training/app-links/deep-linking):

To create a link to your app content, add an intent filter that contains these elements and attribute values in your manifest:

• [`<action>`](https://developer.android.com/guide/topics/manifest/action-element)

Specify the [`ACTION_VIEW`](https://developer.android.com/reference/android/content/Intent#ACTION_VIEW) intent action so that the intent filter can be reached from Google Search.

• [`<data>`](https://developer.android.com/guide/topics/manifest/data-element)

Add one or more [`<data>`](https://developer.android.com/guide/topics/manifest/data-element) tags, each of which represents a URI format that resolves to the activity. At minimum, the [`<data>`](https://developer.android.com/guide/topics/manifest/data-element) tag must include the [`android:scheme`](https://developer.android.com/guide/topics/manifest/data-element#scheme) attribute.

You can add more attributes to further refine the type of URI that the activity accepts. For example, you might have multiple activities that accept similar URIs, but which differ simply based on the path name. In this case, use the [`android:path`](https://developer.android.com/guide/topics/manifest/data-element#path) attribute or its `pathPattern` or `pathPrefix` variants to differentiate which activity the system should open for different URI paths.

• [`<category>`](https://developer.android.com/guide/topics/manifest/category-element)

Include the [`BROWSABLE`](https://developer.android.com/reference/android/content/Intent#CATEGORY_BROWSABLE) category. It is required in order for the intent filter to be accessible from a web browser. Without it, clicking a link in a browser cannot resolve to your app.

Also include the [`DEFAULT`](https://developer.android.com/reference/android/content/Intent#CATEGORY_DEFAULT) category. This allows your app to respond to implicit intents. Without this, the activity can be started only if the intent specifies your app component name.

### Step 3: Opening a Specific Activity from Deep Link

The TapDeepLinkActivity from this example will act as a bridge to open TapTalk.io's room list page, or a specified chat room.

When the activity is launched from an intent filter, you can obtain the required data from the incoming Intent from the Activity.

The example snippet below will show how to open a chat room from the specified roomID from the URL (i.e. [https://web.taptalk.io/chat/roomID](https://web.taptalk.io/chat)), or open the room list page when no roomID is specified&#x20;

{% tabs %}
{% tab title="Java" %}
{% code title="TapDeepLinkActivity.java" %}

```java
package com.example.app.activity;

import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;

import androidx.appcompat.app.AppCompatActivity;

import java.util.List;

import io.taptalk.TapTalk.Helper.TapTalk;
import io.taptalk.TapTalk.Listener.TapCommonListener;
import io.taptalk.TapTalk.Manager.TapUI;

public class TapDeepLinkActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        handleIntent();
        finish();
    }

    private void handleIntent() {
        Intent intent = getIntent();
        if (intent != null && intent.getData() != null) {
            Uri data = intent.getData();
            if (data.getHost().equals("web.taptalk.io")) {
                if (TapTalk.isAuthenticated()) {
                    List<String> pathSegments = data.getPathSegments();

                    if (pathSegments != null && !pathSegments.isEmpty()) {
                        // Get room ID from last path segment
                        String roomID = pathSegments.get(pathSegments.size() - 1);
                        openRoomList(roomID);
                    }
                    else {
                        // Fallback if room ID is not found
                        openRoomList("");
                    }
                }
                else {
                    // TapTalk not authenticated
                    // You may authenticate or open fallback activity
                    TapTalk.authenticateWithAuthTicket(AUTH_TICKET, true, new TapCommonListener() {
                        @Override
                        public void onSuccess(String successMessage) {
                            // Authentication success
                            handleIntent();
                        }

                        @Override
                        public void onError(String errorCode, String errorMessage) {
                            // Authentication success
                            openFallbackActivity();
                        }
                    });
                }
            }
            else {
                // Fallback if tapped url is not chat
                openFallbackActivity();
            }
        }
        else {
            // Fallback if data is null
            openFallbackActivity();
        }
    }

    private void openRoomList(String roomID) {
        // openRoomList with roomID parameter will open selected chat room after room list
        TapUI.getInstance().openRoomList(this, roomID);
    }

    private void openFallbackActivity() {
        Intent intent = new Intent(this, MainActivity.class);
        startActivity(intent);
    }
}
```

{% endcode %}
{% endtab %}

{% tab title="Kotlin" %}
{% code title="TapDeepLinkActivity.kt" %}

```kotlin
package com.example.app.activity

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.content.Intent
import io.taptalk.TapTalk.Helper.TapTalk
import io.taptalk.TapTalk.Listener.TapCommonListener
import io.taptalk.TapTalk.Manager.TapUI

class TapDeepLinkActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        handleIntent()
        finish()
    }

    private fun handleIntent() {
        if (intent != null && intent.data != null) {
            val data = intent.data
            if (data!!.host == "web.taptalk.io") {
                if (TapTalk.isAuthenticated()) {
                    val pathSegments = data.pathSegments
                    if (!pathSegments.isNullOrEmpty()) {
                        // Get room ID from last path segment
                        val roomID = pathSegments[pathSegments.size - 1]
                        openRoomList(roomID)
                    }
                    else {
                        // Fallback if room ID is not found
                        openRoomList("")
                    }
                }
                else {
                    // TapTalk not authenticated
                    // You may authenticate or open fallback activity
                    TapTalk.authenticateWithAuthTicket(
                        AUTH_TICKET,
                        true,
                        object : TapCommonListener() {
                            override fun onSuccess(successMessage: String) {
                                // Authentication success
                                handleIntent()
                            }

                            override fun onError(errorCode: String, errorMessage: String) {
                                // Authentication success
                                openFallbackActivity()
                            }
                        }
                    )
                }
            }
            else {
                // Fallback if tapped url is not chat
                openFallbackActivity()
            }
        }
        else {
            // Fallback if data is null
            openFallbackActivity()
        }
    }

    private fun openRoomList(roomID: String) {
        // openRoomList with roomID parameter will open selected chat room after room list
        TapUI.getInstance().openRoomList(this, roomID)
    }

    private fun openFallbackActivity() {
        val intent = Intent(this, MainActivity::class.java)
        startActivity(intent)
    }
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

{% hint style="info" %}
You can also try using the above snippet for your own preferred Activity.
{% endhint %}

### Step 4: Handling Deep Link for Android 12+

Starting in Android 12 (API level 31), a generic web intent resolves to an activity in your app **only if your app is approved for the specific domain** contained in that web intent. If your app isn't approved for the domain, the web intent resolves to the user's default browser app instead.

To handle this change, we will need to create an assetlinks.json file and place it under the **.well-known/** directory of your host.

#### Creating the assetlinks.json file

You may create the file manually, create an empty file and name it assetlinks.json. The file should contain the following:

{% code title="assetlinks.json" %}

```json
[
  {
    "relation": ["delegate_permission/common.handle_all_urls"],
    "target": {
      "namespace": "android_app",
      "package_name": "com.example.yourapppackagename",
      "sha256_cert_fingerprints":
      ["<Your App’s SHA256 fingerprint>"]
    }
  },
  {
    "relation": ["delegate_permission/common.handle_all_urls"],
    "target": {
      "namespace": "android_app",
      "package_name": "com.example.yourapppackagename.debug",
      "sha256_cert_fingerprints":
      ["<Your App’s SHA256 fingerprint>"]
    }
  }
]
```

{% endcode %}

The above example shows the contents of **assetlinks.json** file addressing your application for both debug and release build. Change the `package_name` and `sha256_cert_fingerprints` value respectively according to your application.

`package_name` can be obtained from the **`applicationId`** in your **build.grade (:app)** file.

One way to obtain SHA-256 fingerprint for your app is through running **`gradle signingReport`** from Android Studio.

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2FQVhrxiygG49JRhmRiEvM%2Fimage.png?alt=media\&token=f9f2c975-12ca-4856-a04b-a206d4819c72)![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LfVupFSqh_qZAY9OiCO%2Fuploads%2F2RBzT9dszmPPCYSGG9FN%2Fimage.png?alt=media\&token=deacdc7a-c60a-4cb5-9d82-38aa8b87b8ce)

Click on the gear icon on the top right of Android Studio, then select Run Anything, and type **gradle signingReport**, then press Enter. *(menu location may vary according to version)*

Android Studio will then execute a signingReport task. When it is finished, you can see all your app variants' fingerprints in the Debug tab at the bottom of the Android Studio window. Paste the SHA-256 value of your selected app variant to the **assetlinks.json** file.

#### Deploying the assetlinks.json file

After generating the file, deploy it to the host under a .well\_known directory. For this specific example, the file will be located at <https://web.taptalk.io/.well-known/assetlinks.json>

[Google provides some useful information](https://developer.android.com/training/app-links/verify-site-associations#publish-json) to watch out for when hosting this file:

* The assetlinks.json file must be accessible *without any redirects (no 301 or 302 redirects)* and must be accessible by bots (your robots.txt must allow crawling /.well-known/assetlinks.json).
* The assetlinks.json file must be served with content-type application/json.
* The assetlinks.json file must be accessible over an HTTPS connection, regardless of whether the app's intent filters declare HTTPS as the data scheme.

Once all the steps above are successfully done, your app should be approved for your domain, and should be able to handle deep linking. You can try tapping the specified url from a test device to open your app.


# Error Codes

TapTalk.io SDK has two different types of error codes, which are:

[Server Error Codes](/powertalk-chat-sdk-documentation/powertalk-ios/error-codes#server-error-codes): This error caused by server-side issues.\
[Client Error Codes](/powertalk-chat-sdk-documentation/powertalk-ios/error-codes#client-error-codes): This error caused by client-side issues such as invalid parameters and validation handling.

### Server Error Codes

Server-side error codes generally contain five-digit integers beginning with **4xx** and **5xx**.<br>

| **Error Codes** | **Description**                                                                                                                         |
| --------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| 40001           | HTTP request header validation failed.                                                                                                  |
| 40002           | API request parameter validation failed.                                                                                                |
| 40101           | The request failed because HTTP request header Authorization is not provided when required.                                             |
| 40102           | The request failed because HTTP request header Authorization format is invalid.                                                         |
| 40103           | The request failed because the server failed to parse the token or the token is not found or invalid. Client should get a new token.    |
| 40104           | The request failed because the token has expired. Client should get a new token.                                                        |
| 40105           | The request failed because the token owner does not belong to the client's info. Client should get a new token.                         |
| 40106           | The request failed because the user is not found for the specified token.                                                               |
| 49101           | The authentication request failed because the app key is not provided.                                                                  |
| 49102           | The authentication request failed because server failed to parse the app key, or the app key is invalid.                                |
| 49103           | The authentication request failed because the provided app key is not found.                                                            |
| 49104           | The authentication request failed because the provided app key is not intended to be used with the client's platform.                   |
| 49106           | The authentication request failed because the app key has expired.                                                                      |
| 49201           | The authentication request failed because the app is not enabled by the customer.                                                       |
| 49202           | The authentication request failed because the app is not available because either the app, project, or customer is currently suspended. |
| 49203           | The authentication request failed because the app is not found.                                                                         |
| 50001           | The authentication request failed because an error occurred while validating the app key.                                               |

### Client Error Codes

Client-side error codes generally contain five-digit integers beginning with **9xx**.

| **Error Codes** | **Description**                                                                         |
| --------------- | --------------------------------------------------------------------------------------- |
| 90001           | The request failed because TapTalk.io active user is not found.                         |
| 90002           | The request failed because access token is not available, authentication is needed.     |
| 90003           | The request failed because user already connected to TapTalk.io.                        |
| 90004           | The request failed because the device is not connected to the server.                   |
| 90005           | The request failed because provided authentication ticket is invalid.                   |
| 90006           | The request failed because user is not authenticated.                                   |
| 90101           | The request failed because the selected group chat has already been deleted.            |
| 90102           | The request failed because another admin needs to be assigned before leaving the group. |
| 90301           | The request failed because file URI data was not found.                                 |
| 90302           | The request failed because maximum file size was exceeded.                              |
| 90303           | The server failed to process the file upload due to user cancellation.                  |
| 90304           | The request failed because image compression was unsuccessful.                          |
| 90305           | The request failed because an invalid message type was provided.                        |
| 90306           | The request failed because media caption exceeds the character limit.                   |


# PowerTalk iOS

TapTalk.io helps you to implement real-time chat with any type of your client app with speed and efficiency. Our iOS SDK provides you with various methods to initialize, configure, and build the chat from the client-side - no server-side implementation is required because our reliable infra management service is delivered with the SDK. This page presents a brief overview of the SDK’s structure and abilities, then lets you go through the preliminary steps of implementing the SDK in your own app.


# Get Started

## Configure and Initialize TapTalk.io iOS SDK

#### **Step 1: Create a new application from your dashboard**

**1.** Login to [TapTalk.io Dashboard](https://taptalk.io/), then choose **Development** -> **Apps**

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MHKsq4vOlouRa03adbb%2F-MHKvQJYwokZj2SvRd6U%2F08a4ad0-Screenly_-_9.0_Development_-_Apps_-_Empty_State2x.png?alt=media\&token=6f629f44-d932-400f-984d-2fb1a1f0e408)

**2**. Click **New App** Button, input **App Name** and choose **Platform**, and then click **Create New App** Button.

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MHKsq4vOlouRa03adbb%2F-MHKxC_cD1-kv3lPxiSk%2F58201a8-Screenly_-_9.1.0_Development_-_Apps_-_New_App_-_Empty_State2x.png?alt=media\&token=ab2fe069-a0b6-4d22-86d3-fdd8e51c235f)

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MHKsq4vOlouRa03adbb%2F-MHKxGJV7RBtqLBu8UwT%2Ff2a1418-Screenly_-_9.1.1_Development_-_Apps_-_New_App_-_Filled2x.png?alt=media\&token=5b628aa3-05ec-47e9-98ef-dbc2c23de5bc)

**3.** A pop-up dialog will be shown with provided **App Key ID** & **App Key Secret**

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MHKsq4vOlouRa03adbb%2F-MHKxQLyhxLOunGM05hx%2Ff869a40-Screenly_-_9.1.3_Development_-_Apps_-_New_App_-_Your_App_Key_-_Dismiss2x.png?alt=media\&token=b7bfb1cb-65ff-47e6-beda-69011f5addb8)

{% hint style="warning" %}
**Note:** Please remember to save your **App Key ID** & your **App Key Secret** because it will only be shown once and will be used in [TapTalk.io initialization](/powertalk-chat-sdk-documentation/powertalk-ios/get-started#step-5-initialize-taptalk-io-in-your-application-class)
{% endhint %}

#### Step 2: Install TapTalk.io SDK

You can install the TapTalk.io iOS SDK using [CocoaPods](https://cocoapods.org/) like the following. If you are new to CocoaPods, you can see more information in [Cocoapods guides](https://guides.cocoapods.org/using/getting-started.html). To create a **Podfile**, open a terminal window, navigate to your project directory, and then create a **Podfile** by running the following command:

{% tabs %}
{% tab title="Terminal" %}

```bash
$ pod init
```

{% endtab %}
{% endtabs %}

Then **Podfile** will be created in your project directory. Open the **Podfile** and add the following lines to the **Podfile**.

{% tabs %}
{% tab title="Podfile" %}

```ruby
# Please make sure you define platform on your Podfile
# Make sure to use ios 11.0 for minimum deployment target

platform :ios, '11.0'
use_modular_headers!

target "YourProjectName" do
    pod 'TapTalk'
end
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %} <mark style="color:red;">**Note**</mark><mark style="color:red;">:</mark> <mark style="color:red;"></mark><mark style="color:red;">**For SDK version 1.4.1 and above,**</mark><mark style="color:red;">**&#x20;**</mark><mark style="color:red;">**`use_frameworks!`**</mark><mark style="color:red;">**&#x20;**</mark><mark style="color:red;">**can be replaced with**</mark><mark style="color:red;">**&#x20;**</mark><mark style="color:red;">**`use_modular_headers!`**</mark><mark style="color:red;">**&#x20;**</mark><mark style="color:red;">**to handle some compatibility issues.**</mark>

For versions below 1.4.1, you can replace **`use_modular_headers!`** on the code above with **`use_frameworks!`**
{% endhint %}

{% hint style="warning" %}
**Note**: Please make sure you implement ios version 11.0 \
`platform :ios, '11.0'` \
for minimum deployment target to obtain the latest update of TapTalk.io SDK
{% endhint %}

Since TapTalk.io use uses **`git-lfs`** (Git Large Files Storage) you will need to install **GIT LFS** to clone/install TapTalk.io SDK through **Cocoapods**.

{% hint style="warning" %}
**Note**: Make sure to install **`git-lfs`**&#x62;efore pod install, otherwise the pod install / pod update will return an error
{% endhint %}

Easiest way to install [git-lfs](https://git-lfs.github.com) is using [brew](https://brew.sh):

{% tabs %}
{% tab title="Terminal" %}

```bash
brew install git-lfs
git lfs install
```

{% endtab %}
{% endtabs %}

Next, after the **`git-lfs`** is installed, install the TapTalk.io SDK through CocoaPods.

{% tabs %}
{% tab title="Terminal" %}

```bash
$ pod install
```

{% endtab %}
{% endtabs %}

#### Step 3: Grant permission in your application project

To make sure TapTalk.io has all permission to access the user's media, file, location, and contact, the application needs to ask for permission. Go to your **info.plist**, and add the following key-value pairs.

<table data-header-hidden><thead><tr><th width="339">Information Property Key</th><th>Information Property Value</th></tr></thead><tbody><tr><td><strong>Information Property Key</strong></td><td><strong>Information Property Value</strong></td></tr><tr><td>Privacy - Camera Usage Description</td><td>$(PRODUCT_NAME) needs to request access to your camera to send image messages and take profile picture.</td></tr><tr><td>Privacy - Contacts Usage Description</td><td>$(PRODUCT_NAME) need your permission to access your contact, we will sync your contact to our server and automatically find your friend so it is easier for you to find your friends.</td></tr><tr><td>Privacy - Photo Library Additions Usage Description</td><td>$(PRODUCT_NAME) needs to request access to your photo library to save photos.</td></tr><tr><td>Privacy - Photo Library Usage Description</td><td>$(PRODUCT_NAME) needs to request access to your photo library to send image messages and select profile picture.</td></tr><tr><td>Privacy - Location When In Use Usage Description</td><td>$(PRODUCT_NAME) needs to request access to your location to send location messages.</td></tr><tr><td>Privacy - Microphone Usage Description</td><td>$(PRODUCT_NAME) needs to request access to your microphone to record audio to send voice messages.</td></tr></tbody></table>

{% hint style="info" %}
**Note:** You can change **Information Property Value** with your preferred message, the string value will be displayed when the application requests the permission.
{% endhint %}

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MHKsq4vOlouRa03adbb%2F-MHLISj3JHnpzjIeKv5r%2F8b43524-Screen_Shot_2019-08-28_at_13.57.43.png?alt=media\&token=b918d137-bd53-43fc-84df-ae605c44b0c9)

#### Step 4: Enable background modes

Background modes is required to handle background process in TapTalk.io. It is used to run some processes in the background before the app is killed. For more information about the processes, check out the [background process section](/powertalk-chat-sdk-documentation/powertalk-ios/background-process-in-taptalk.io).\
To enable **background modes**, go to **Target** -> **Capabilities**, then turn **Background Modes** toggle to **ON**, next select **Background fetch** and **Remote notifications**

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MHKsq4vOlouRa03adbb%2F-MHLIm1-VkzIwjxQilqS%2Feaab744-Screen_Shot_2019-08-28_at_13.37.54.png?alt=media\&token=02281a47-665d-4403-8062-8fb0fe48c64b)

After you turn on the **Background Modes**, **Required background modes** key will be added automatically in your **Info.plist** as shown below.

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MHKsq4vOlouRa03adbb%2F-MHLItjSE_HAsYniTXmS%2F979a00b-Screen_Shot_2019-08-28_at_13.44.36.png?alt=media\&token=ed490114-336d-4b7c-9777-7a6ddd88a521)

#### Step 5: Initialize Taptalk.io in your Application class

In order to use TapTalk.io, you must first initialize a TapTalk.io instance by passing the `APP_KEY_ID`, `APP_KEY_SECRET`, `APP_BASE_URL`, and `IMPLEMENTATION_TYPE` assigned to your application to the `initWithAppKeyID:appKeySecret:apiURLString:implementationType:` method as a parameter. Generally, initialization is implemented in the **appDelegate** `application:didFinishLaunchingWithOptions:` method.

{% hint style="warning" %}
**Note:** To get **BASE\_URL** you can follow our documentation on [how to get Base URL](/powertalk-chat-sdk-documentation/powertalk-server-api/base-url) on TapTalk.io.
{% endhint %}

{% tabs %}
{% tab title="Objective-C" %}
{% code title="AppDelegate.m" %}

```csharp
// Import TapTalk.io
#import <TapTalk/TapTalk.h>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Initialize TapTalk.io
    [[TapTalk sharedInstance] initWithAppKeyID:APP_KEY_ID appKeySecret:APP_KEY_SECRET apiURLString:APP_BASE_URL implementationType:IMPLEMENTATION_TYPE];
  
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**APP\_KEY\_ID**: (String) application key ID\
**APP\_KEY\_SECRET**: (String) application key Secret\
**APP\_BASE\_URL**: (String) base API URL\
**IMPLEMENTATION\_TYPE**: (enum) found in TapTalkImplentationType, more detailed information below
{% endhint %}

{% hint style="info" %}
**IMPLEMENTATION\_TYPE**\
TapTalkImplementationType consists of 3 types which are:\
**`TapTalkImplementationTypeUI`**: used for implementation with only TapUI\
**`TapTalkImplementationTypeCore`**: used for implementation with only TapCore\
**`TapTalkImplementationTypeCombine`**: used for implementation with both of TapCore and TapUI combined
{% endhint %}

{% hint style="info" %}
**Note**: In the [Event Delegate](/powertalk-chat-sdk-documentation/powertalk-ios/event-delegate) page, you can find detailed information on the usages of TapTalk iOS SDK's delegates and callbacks.
{% endhint %}

You may also call `initWithAppKeyID:appKeySecret:apiURLString:implementationType:success:` to obtain callback once the initialization is finished.

{% tabs %}
{% tab title="Objective-C" %}
{% code title="AppDelegate.m" %}

```csharp
// Import TapTalk.io
#import <TapTalk/TapTalk.h>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
 
  //Initialize TapTalk.io
  [[TapTalk sharedInstance] initWithAppKeyID:APP_KEY_ID 
                                appKeySecret:APP_KEY_SECRET 
                                apiURLString:APP_BASE_URL 
                          implementationType:IMPLEMENTATION_TYPE
                                     success:^{
      // Initialization finished
  }];
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**APP\_KEY\_ID**: (String) application key ID\
**APP\_KEY\_SECRET**: (String) application key Secret\
**APP\_BASE\_URL**: (String) base API URL\
**IMPLEMENTATION\_TYPE**: (enum) found in TapTalkImplentationType, more detailed information below
{% endhint %}

{% hint style="info" %}
**IMPLEMENTATION\_TYPE**\
TapTalkImplementationType consists of 3 types which are:\
**`TapTalkImplementationTypeUI`**: used for implementation with only TapUI\
**`TapTalkImplementationTypeCore`**: used for implementation with only TapCore\
**`TapTalkImplementationTypeCombine`**: used for implementation with both of TapCore and TapUI combined
{% endhint %}

#### Step 6: Implement application delegate

To allow the iOS SDK to respond to the connection and state changes in your iOS client app, you have to implement all of our application delegate methods in your UIApplicationDelegate methods in appDelegate file. You can follow the instructions in [Implement Application Delegate page](/powertalk-chat-sdk-documentation/powertalk-ios/implement-application-delegate).

#### Step 7: Authenticate to TapTalk.io

In order to use the abilities of the iOS SDK in your client app, a TapTalk instance must be initiated in each client app through user authentication with TapTalk.io server. An authenticated user account allows the instance to communicate and interact with the server. To authenticate your user with the server, follow the instructions in [Authentication page](/powertalk-chat-sdk-documentation/powertalk-ios/authentication).

### Initialize Google Places API Key (Optional)

To enable location search result preview while sending location message, a Google Places API Key is required. To obtain the API key for your application, you can check [the documentation](https://developers.google.com/places/web-service/get-api-key) provided by Google. To initialize, insert your obtained key using the `initializeGooglePlacesApiKey()` method.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapTalk.h>
  
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    //Initialize Google Places API Key
    [[TapTalk sharedInstance] initializeGooglePlacesAPIKey:GOOGLE_PLACES_API_KEY]; 
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**GOOGLE\_PLACES\_API\_KEY**: (String) Google Places API Key
{% endhint %}

{% hint style="info" %}
Starting from version **2.16.0**, location attachment will be enabled by default even when Google Places API Key is not provided, but location search will be hidden.\
To disable location attachment, you may call:

```
[[TapUI sharedInstance] setLocationAttachmentEnabled:NO];
```

{% endhint %}

## Open Your First Room List

To open room list view, simply initialize `TAPRoomListViewController` and choose to present or push the selected controller to your current view. Here we use **TapUI** to open room list view. Creating a user interface won't be necessary, because TapTalk.io have provided an integrated user interface to be used in your application. To use TapTalk.io's chat interface, simply initialize our **TapUI** method and you are good to go. For more information about **TapUI** and **TapCore**, please see [TapUI and TapCore](/powertalk-chat-sdk-documentation/powertalk-ios/tapui-and-tapcore) page.

{% tabs %}
{% tab title="Objective-C" %}

<pre class="language-csharp" data-title="YourViewController.m"><code class="lang-csharp">#import &#x3C;TapTalk/TapUIRoomListViewController.h>
#import &#x3C;TapTalk/TapUI.h>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Initialize TapTalk.io room list view controller here
<strong>    TapUIRoomListViewController *roomListViewController = [[TapUI sharedInstance] roomListViewController]; 
</strong>    UINavigationController *roomListNavigationController = [[UINavigationController alloc] initWithRootViewController:roomListViewController];
  
    // You can choose to present or push view controller
  
    // Present room list view
    [self presentViewController:roomListViewController animated:YES completion:^{
      // Completion
    }];
  
    // Push room list view
    [self.navigationController pushViewController:roomListNavigationController animated:YES]; 
  
    // or you can add to your window root view controller
    self.window.rootViewController = roomListNavigationController;
  
}
</code></pre>

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Note:** For more information about Room List View for TapUI, please see [Room List section](/powertalk-chat-sdk-documentation/powertalk-ios/room-list).
{% endhint %}


# TapUI and TapCore

There are three options to implement TapTalk.io chat framework to your application:

* **UI implementation method**: the go-to option to quickly integrate TapTalk.io to your app, uses the default user interface that is managed by the **TapUI** class.
* **Core implementation method**: a more advanced option to integrate TapTalk.io, which gives you more control over TapTalk.io functions. This method makes use of the **TapCore** classes to manage the chat functions inside the application.
* **Combined implementation method**: an implementation method that uses both **TapUI** and **TapCore**.

### What is TapUI?

TapUI is the manager class that is used to manage the **user interface** in UI implementation method. UI implementation is made to be the **easiest** and **quickest** method for developers to implement Taptalk.io chat framework in their application. Taptalk.io provides a default chat **user interface** so you are not required to create your own chat user interface as is usually done when implementing other chat SDK. TapUI also allows you to customize the chat appearance in your application so that it is not only easy and quick in integration, but will also fit your application's appearance with our **customizable theme**.

### What is TapCore?

TapCore is the manager class to manage **chat functions** for applications that use TapTalk.io core implementation method. While UI implementation gives you easiness and quickness in integration, Core implementation will give you more control over Taptalk.io's **more advanced functions**. You can **create your own chat user interface** as you wish, and also **customize your own chat logic** according to your needs. TapCore provides you the necessities to integrate TapTalk.io chat framework to your application.


# Background Process in TapTalk.io

An application integrated with TapTalk.io framework will keep executing certain tasks even when the app is on the background if the conditions are met, this is done to make sure that the users' chat experience proceed smoothly. The background services will be automatically terminated once all the tasks are completed or reached a timeout. Please follow the following section to [enable background mode in your application](/powertalk-chat-sdk-documentation/powertalk-ios/get-started#step-4-enable-background-modes), The following are the processes that are required to run in the background:

### Pending Messages Queue

Messages that the user is going to send are placed into a queue before they are sent to the server. If the app enters the background when unsent messages exist in this queue, TapTalk.io services will keep running until all the pending messages are delivered to the server and all other tasks are completed.

### File Downloads

When a user-initiated file download from TapTalk.io, such as file message or video message, is in progress, TapTalk.io will preserve the download progress even if the app is moved to the background. The services will stop once all the file downloads and other tasks are finished.

### File Uploads

TapTalk.io background process will also be kept running in the background when user is sending messages with attachment, such as image, video, and file messages. The services will stop once all the file uploads and other tasks are finished.


# Implement Application Delegate

To allow the iOS SDK to respond to the connection and state changes in your iOS client app, you have to implement all of our application delegate methods in your **`UIApplicationDelegate`** methods in appDelegate file.

After you initialize the TapTalk.io, you have to connect and implement these methods in your **UIApplicationDelegate** methods in **appDelegate** file to make sure TapTalk.io runs smoothly in your application.

| **TapTalk Application Delegate Metho**                                                                   | **Description**                                                                                      |
| -------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- |
| `application:didFinishLaunchingWithOptions`                                                              | Tells the delegate that the launch process is almost done and the app is almost ready to run.        |
| `applicationWillResignActive:`                                                                           | Tells the delegate that the app is about to become inactive.                                         |
| `applicationDidEnterBackground:`                                                                         | Tells the delegate that the app is now in the background.                                            |
| `applicationWillEnterForeground:`                                                                        | Tells the delegate that the app is about to enter the foreground.                                    |
| `applicationDidBecomeActive:`                                                                            | Tells the delegate that the app has become active.                                                   |
| `applicationWillTerminate:`                                                                              | Tells the delegate when the app is about to terminate.                                               |
| <p><code>application:</code></p><p><code>didRegisterForRemoteNotificationsWithDeviceToken:</code></p>    | Tells the delegate that the app successfully registered with Apple Push Notification service (APNs). |
| <p><code>application:didReceiveRemoteNotification:</code></p><p><code>fetchCompletionHandler:</code></p> | Tells the app that a remote notification arrived that indicates there is data to be fetched.         |
| `handleException:`                                                                                       | Tells the delegate when application throws exception.                                                |

{% tabs %}
{% tab title="Objective-C" %}
{% code title="AppDelegate.m" %}

```csharp
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  
    //Implement TapTalk didFinishLaunchingWithOptions here    
    [[TapTalk sharedInstance] application:application didFinishLaunchingWithOptions:launchOptions];
    
    //Other code
    ...
    
    return YES;
}

- (void)applicationWillResignActive:(UIApplication *)application {
  
    //Implement TapTalk applicationWillResignActive here
    [[TapTalk sharedInstance] applicationWillResignActive:application];
  
    //Other code
    ...
}

- (void)applicationDidEnterBackground:(UIApplication *)application {
    //Implement TapTalk applicationDidEnterBackground here
    [[TapTalk sharedInstance] applicationDidEnterBackground:application];
  
    //Other code
    ...
}

- (void)applicationWillEnterForeground:(UIApplication *)application {
  
    //Implement TapTalk applicationWillEnterForeground here
    [[TapTalk sharedInstance] applicationWillEnterForeground:application];
  
    //Other code
    ...
}
  
- (void)applicationDidBecomeActive:(UIApplication *)application {
  
    //Implement TapTalk applicationDidBecomeActive here    
    [[TapTalk sharedInstance] applicationDidBecomeActive:application];
  
    //Other code
    ...
}

- (void)applicationWillTerminate:(UIApplication *)application {
  
    //Implement TapTalk applicationWillTerminate here
    [[TapTalk sharedInstance] applicationWillTerminate:application];
  
    //Other code
    ...
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

{% hint style="warning" %}
**Note:** You have to implement `application:didRegisterForRemoteNotificationsWithDeviceToken` and `application:didReceiveRemoteNotification` to handle and receive notification from TapTalk.io.
{% endhint %}

{% tabs %}
{% tab title="Objective-C" %}
{% code title="AppDelegate.m" %}

```csharp
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
  
    //Implement TapTalk application:didRegisterForRemoteNotificationsWithDeviceToken here
    [[TapTalk sharedInstance] application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
  
    //Other code
    ...
}

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler {
  
    //Implement TapTalk application:didReceiveRemoteNotification:fetchCompletionHandler here
    [[TapTalk sharedInstance] application:application didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
  
    //Other code
    ...
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

You have to add below code `NSSetUncaughtExceptionHandler(&handleExceptions);` in `application:didFinishLaunchingWithOptions:`method to register uncaught exception handler and add delegate function `handleExceptions`.

{% tabs %}
{% tab title="Objective-C" %}
{% code title="AppDelegate.m" %}

```csharp
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Register Uncaught Exception Handler
    NSSetUncaughtExceptionHandler(&handleExceptions);
}

// Add delegate function to handle exceptions
void handleExceptions(NSException *exception) {
    // Implement TapTalk.io handleException method
    [[TapTalk sharedInstance] handleException:exception];
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

{% hint style="warning" %}
**Note:** Don't forget to register for exception handler inside `application:didFinishLaunchingWithOptions:` method and implement `handleExceptions` method in **appDelegate** class to make sure TapTalk.io able to handle exceptions.
{% endhint %}


# Authentication

In order to use the abilities of the iOS SDK in your client app, a TapTalk instance must be initiated in each client app through user authentication with TapTalk.io server. An authenticated user account allows the instance to communicate and interact with the server. The following explains how to authenticate your user with the server.

![TapTalk.io's Authentication Flow](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MHKsq4vOlouRa03adbb%2F-MHLTpHao9rfmA05gZO6%2F3cee4ff-Login_Flow2x.png?alt=media\&token=e252a825-bf44-49ef-954d-f2c4a841f154)

When the user logs in to your application, your backend server will have to request an **Authentication Ticket** from TapTalk.io server. TapTalk.io server will return the requested **Authentication Ticket** and **user ID** to your backend server. The client application (iOS or Android) can then retrieve the ticket from your backend server to implement TapTalk.io's SDK by initializing the SDK using the obtained **Authentication Ticket**.

You can see the documentation on how to obtain Authentication Ticket from TapTalk.io's Server on the [Authentication in TapTalk.io's Server API page](/powertalk-chat-sdk-documentation/powertalk-server-api/authentication).

### Authenticate to TapTalk.io server with an Authentication Ticket

{% hint style="warning" %}
**Note:** authentication should only be called once before the user is logged in or when the callback tapTalkRefreshTokenExpired is triggered in [TapTalkDelegate](/powertalk-chat-sdk-documentation/powertalk-ios/event-delegate#taptalkdelegate)
{% endhint %}

{% tabs %}
{% tab title="Objective-C" %}
{% code title="AppDelegate.m" %}

```csharp
#import <TapTalk/TapTalk.h>
  
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    //Other Code
    ...
    
    [[TapTalk sharedInstance] authenticateWithAuthTicket:AUTH_TICKET connectWhenSuccess:CONNECT_WHEN_SUCCESS success:^{
        //Success connect to TapTalk.io server
    }
    failure:^(NSError *error) {
        //Failed connect to TapTalk.io server
    }];
}

```

{% endcode %}
{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
`AUTH_TICKET` : (String) an authentication ticket is required for this method\
`CONNECT_WHEN_SUCCESS`: (boolean) if set to true, application will connect to TapTalk.io server after authentication is successfully completed
{% endhint %}

### Check Authentication Status

You can check authentication status by calling **`isAuthenticated`** method

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapTalk.h>

BOOL isAuthenticated = [[TapTalk sharedInstance] isAuthenticated];
```

{% endtab %}
{% endtabs %}

### Logout and Clear TapTalk.io Data

Call this method when you need to logout and clear all local cached data from TapTalk.io.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapTalk.h>

// Call to logout and clear all local data from TapTalk.io
[[TapTalk sharedInstance] logoutAndClearAllTapTalkData];
```

{% endtab %}
{% endtabs %}

### Clear TapTalk.io Data

Call this method when you need to logout and clear all local cached data from TapTalk.io.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapTalk.h>

[[TapTalk sharedInstance] clearAllTapTalkData];
```

{% endtab %}
{% endtabs %}


# Connection

### Connect to TapTalk.io server

You can manually connect to TapTalk.io by calling this method.

{% hint style="warning" %}
**Note:** Please make sure that you have finished authentication by calling **`authenticateWithAuthTicket:connectWhenSuccess:`**&#x6D;ethod, otherwise, it will return an error
{% endhint %}

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapTalk.h>

[[TapTalk sharedInstance] connectWithCompletionHandler:^{
    // Success connect to TapTalk.io server
}];
```

{% endtab %}
{% endtabs %}

### Disconnect from TapTalk.io server

You can disconnect from TapTalk.io when the user no longer needs to receive messages from an online state. But the user can still receive push notifications for new messages when the app is closed.

When the user is disconnected from the server, all event delegates will stop receiving event callbacks from the server.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapTalk.h>

[[TapTalk sharedInstance] disconnectWithCompletionHandler:^{
    // Success disconnected from TapTalk.io server.
}];
```

{% endtab %}
{% endtabs %}

### Check Connection Status

You can check whether you are connected to TapTalk.io server by calling **`isConnected`** method.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapTalk.h>

BOOL isConnected = [[TapTalk sharedInstance] isConnected];
```

{% endtab %}
{% endtabs %}

### Enable / Disable Auto Connect

You can choose to enable or disable auto connect by calling these methods. TapTalk.io will automatically connect to the server every time the user opens the app from the background when auto connect is enabled. Please note that the **default value** is **enabled**.

{% tabs %}
{% tab title="Objective-C" %}
{% code title="AppDelegate.m" %}

```csharp
#import <TapTalk/TapTalk.h>
  
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

   //Other Code
   ...

   // Call this method to enable or disable auto connect to socket
   // The default is enabled if you do not set this method
   [[TapTalk sharedInstance] enableAutoConnect:IS_ENABLED];
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

{% hint style="info" %}

#### Parameters

`IS_ENABLED`: (BOOL) set to TRUE/YES to enable auto connect to TapTalk server
{% endhint %}

### Get Auto Connect Status

Use this method to obtain auto connect status. This method will return **`TRUE`** if auto connect is enabled

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapTalk.h>

// Call this method obtain auto connect status
// isAutoConnectEnabled will return TRUE if auto connect is enabled
BOOL isAutoConnectEnabled = [[TapTalk sharedInstance] isAutoConnectEnabled];
```

{% endtab %}
{% endtabs %}


# Event Delegate

The iOS SDK provides event delegates to listen to various events on the client app. Through these event delegates, TapTalk.io notifies the client app of events that happen on your app. You will need to register the delegate objects to receive event callbacks from TapTalk.io.

| **Event Delegate Name**                                                                                                                                     | **Description**                                                                                                |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
| [TapTalkDelegate](/powertalk-chat-sdk-documentation/powertalk-ios/event-delegate#taptalkdelegate)                                                           | Listens to general event changes in the application                                                            |
| [TapUIRoomListDelegate](/powertalk-chat-sdk-documentation/powertalk-ios/event-delegate#tapuiroomlistdelegate)                                               | Listens to UI-related events in **Room List View** when UI implementation type is used                         |
| [TapUIChatRoomDelegate](/powertalk-chat-sdk-documentation/powertalk-ios/event-delegate#tapuichatroomdelegate)                                               | Listens to UI-related events in **Chat Room View** when UI implementation type is used                         |
| [TapUIChatProfileDelegate](#tapuichatprofiledelegate)                                                                                                       | Listens to UI-related events in **Chat Profile View** when UI implementation type is used                      |
| [TapUIMyAccountDelegate](#tapuimyaccountdelegate)                                                                                                           | Listens to UI-related events in **My Account View** when UI implementation type is used                        |
| [TapUICustomKeyboardDelegate](/powertalk-chat-sdk-documentation/powertalk-ios/event-delegate#tapuicustomkeyboarddelegate)                                   | Listens to custom keyboard-related events when UI implementation type is used                                  |
| [TAPCoreMessageManagerDelegate](/powertalk-chat-sdk-documentation/powertalk-ios/event-delegate#tapcoremessagemanagerdelegate)                               | Listens to events when a new/updated message is received by the application                                    |
| [TAPCoreRoomListManagerDelegate](#tapcoreroomlistmanagerdelegate)                                                                                           | Listens to changes to chat room's state in the room list                                                       |
| [TAPCoreChatRoomManagerDelegate](/powertalk-chat-sdk-documentation/powertalk-ios/event-delegate#tapcorechatroommanagerdelegate)                             | Listens to chat room status events such as typing events and online status                                     |
| [TAPCoreContactManagerDelegate](#tapcorecontactmanagerdelegate)                                                                                             | Listens to contact related events such as block or unblock contact                                             |
| [TapUIRoomListViewControllerLifecycleDelegate](/powertalk-chat-sdk-documentation/powertalk-ios/event-delegate#tapuiroomlistviewcontrollerlifecycledelegate) | Listens to room list view controller lifecycle methods such as `viewDidLoad`, `viewWillAppear`, and many more. |

### TapTalkDelegate

General events such as notifications will be notified through `TapTalkDelegate`. A `TapTalkDelegate` instance is required when initializing TapTalk.

{% hint style="info" %}
**Note:** Make sure to add **`#import <TapTalk/TapTalk.h>`** before registering the delegate
{% endhint %}

{% tabs %}
{% tab title="Objective-C" %}
{% code title="ViewController.m" %}

```csharp
#import <TapTalk/TapTalk.h>

//Add TapTalkDelegate declaration
@interface ViewController () <TapTalkDelegate>

@end
  
@implementation ViewController
  
- (void)function {
    // Set TapTalk delegate to current
    [[TapTalk sharedInstance] setDelegate:self];
}

#pragma mark - Delegate
#pragma mark - TapTalkDelegate

- (void)tapTalkRefreshTokenExpired {
    // Authentication is needed
}

- (void)tapTalkDidTappedNotificationWithMessage:(TAPMessageModel *_Nonnull)message fromActiveController:(nullable UIViewController *)currentActiveController {
    // Handle tapped notification message
}


- (void)tapTalkUnreadChatRoomBadgeCountUpdated:(NSInteger)numberOfUnreadRooms {
    // Returns number of unread messages from the application
}

- (void)tapTalkDidRequestRemoteNotification {
    // Register for remote notification
    [[UIApplication sharedApplication] registerForRemoteNotifications];
}
  
@end
```

{% endcode %}
{% endtab %}
{% endtabs %}

| **Method Name**                                                                                                                         | **Invoked When**                                                                                                                                                                                                                                                                                                                                                                 |
| --------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`tapTalkRefreshTokenExpired`**                                                                                                        | User's refresh token has expired. Authentication with a new auth ticket is required.                                                                                                                                                                                                                                                                                             |
| **`tapTalkUnreadChatRoomBadgeCountUpdated:`**                                                                                           | <p>The number of unread messages in the application is updated. Returns the <strong>number</strong> of unread messages from the application.<br><br>Call method <code>updateApplicationBadgeCount</code> to update unread badge counter. You can see the function explanation in <a href="/powertalk-chat-sdk-documentation/powertalk-ios/general">General section page</a>.</p> |
| <p><strong><code>tapTalkDidTappedNotificationWithMessage:</code></strong></p><p><strong><code>fromActiveController:</code></strong></p> | User tapped the notification.                                                                                                                                                                                                                                                                                                                                                    |
| **`tapTalkDidRequestRemoteNotification`**                                                                                               | TapTalk.io needs to request for push notification, usually client needs to add`[UIApplication sharedApplication] registerForRemoteNotifications]`inside the method.                                                                                                                                                                                                              |

### TapUIRoomListDelegate

TapUIRoomListDelegate listens to UI-related events in **Room List View** when UI implementation type is used. You can register a TapUIRoomListDelegate instance in your application through the TapUI class as follows:

{% hint style="info" %}
**Note:** Make sure to add **`#import <TapTalk/TapUI.h>`** before registering the delegate
{% endhint %}

{% tabs %}
{% tab title="Objective-C" %}
{% code title="ViewController.m" %}

```csharp
#import <TapTalk/TapUI.h>

// Add TapUIDelegate declaration
@interface ViewController () <TapUIRoomListDelegate>

@end
  
@implementation ViewController
  
- (void)function {
    // Set TapUI delegate to current
    [[TapUI sharedInstance] setRoomListDelegate:self];
}

#pragma mark - Delegates
#pragma mark - TapUIRoomListDelegate
  
//  Called when user click the profile button on the top right side of group chat room page.
- (void)tapTalkAccountButtonTapped:(UIViewController *)currentViewController
currentShownNavigationController:(UINavigationController *)currentNavigationController {
                                   
}

@end
```

{% endcode %}
{% endtab %}
{% endtabs %}

| **Method Name**                                                                                                                        | **Invoked When**                                                                                                                                          |
| -------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <p><strong><code>tapTalkAccountButtonTapped:</code></strong></p><p><strong><code>currentShownNavigationController:</code></strong></p> | <p>My account button in top left room list view is tapped by active user.</p><p><strong><code>tapTalkUnreadChatRoomBadgeCountUpdated:</code></strong></p> |

### TapUIChatRoomDelegate

TapUIChatRoomDelegate listens to UI-related events in **Chat Room View** when UI implementation type is used. You can register a TapUIChatRoomDelegate instance in your application through the TapUI class as follows:

{% hint style="info" %}
**Note:** Make sure to add **`#import <TapTalk/TapUI.h>`** before registering the delegate
{% endhint %}

{% tabs %}
{% tab title="Objective-C" %}
{% code title="ViewController.m" %}

```csharp
#import <TapTalk/TapUI.h>

// Add TapUIDelegate declaration
@interface ViewController () <TapUIChatRoomDelegate>

@end
  
@implementation ViewController
  
- (void)function {
    // Set TapUI delegate to current
    [[TapUI sharedInstance] setChatRoomDelegate:self];
}

#pragma mark - Delegates
#pragma mark - TapUIChatRoomDelegate

// Called when a chat room is opened.
- (void)tapTalkChatRoomDidOpen:(TAPRoomModel *)room
         currentViewController:(UIViewController *)currentViewController
currentShownNavigationController:(UINavigationController *)currentNavigationController {

}

// Called when a chat room is closed.
- (void)tapTalkChatRoomDidClose:(TAPRoomModel *)room
          currentViewController:(UIViewController *)currentViewController
currentShownNavigationController:(UINavigationController *)currentNavigationController {

}

// Called when active user sends any message to a chat room.
- (void)tapTalkActiveUserDidSendMessage:(TAPMessageModel *)message
                                   room:(TAPRoomModel *)room
                  currentViewController:(UIViewController *)currentViewController
       currentShownNavigationController:(UINavigationController *)currentNavigationController {
       
 }
  
// Called when user click the profile button on the top right side of the personal chat room view.
- (void)tapTalkChatRoomProfileButtonTapped:(UIViewController *)currentViewController
                                 otherUser:(TAPUserModel *)otherUser
                                      room:(TAPRoomModel *)room
          currentShownNavigationController:(UINavigationController *)currentNavigationController {
                                   
}

// Called when user click the profile button on the top right side of the group chat room view.
- (void)tapTalkGroupChatRoomProfileButtonTapped:(UIViewController *)currentViewController
                                           room:(TAPRoomModel *)room
               currentShownNavigationController:(UINavigationController *)currentNavigationController {

}

// Called when user click the profile button on user in group.
- (void)tapTalkGroupMemberAvatarTappedWithRoom:(TAPRoomModel *)room
                                          user:(TAPUserModel *)user
              currentShownNavigationController:(UINavigationController *)currentNavigationController {
}

// Called when user click mention in the bubble chat.
- (void)tapTalkUserMentionTappedWithRoom:(TAPRoomModel *)room
                           mentionedUser:(TAPUserModel *)mentionedUser
                       isRoomParticipant:(BOOL)isRoomParticipant
                                 message:(TAPMessageModel *)message
                   currentViewController:(UIViewController *)currentViewController
        currentShownNavigationController:(UINavigationController *)currentNavigationController {
 
 }

// Called when user click the quote view that appears in the chat bubble.
- (void)tapTalkMessageQuoteTappedWithUserInfo:(NSDictionary *)userInfo {
  
}
  
@end
```

{% endcode %}
{% endtab %}
{% endtabs %}

| **Method Name**                                                                                                                                                                                                                                                                                                                                                | **Invoked When**                                                                                                                                                                                                                                                     |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`tapTalkChatRoomDidOpen:`**                                                                                                                                                                                                                                                                                                                                  | A chat room is opened. Returns the opened room, current shown view controller, and current shown navigation controller.                                                                                                                                              |
| **`tapTalkChatRoomDidClose:`**                                                                                                                                                                                                                                                                                                                                 | A chat room is closed. Returns the closed room, current shown view controller, and current shown navigation controller.                                                                                                                                              |
| **`tapTalkActiveUserDidSendMessage:`**                                                                                                                                                                                                                                                                                                                         | Active user sends any message to a chat room. Message may not yet be delivered to the room when this happens. Returned message is temporary and the values will be updated through socket once the message is delivered.                                             |
| **`tapTalkChatRoomProfileButtonTapped:`**                                                                                                                                                                                                                                                                                                                      | <p>My account button in top left room list view is tapped by active user.</p><p><strong><code>tapTalkUnreadChatRoomBadgeCountUpdated:</code></strong></p>                                                                                                            |
| **`tapTalkGroupChatRoomProfileButtonTapped:`**                                                                                                                                                                                                                                                                                                                 | Profile button in a group chat room is tapped by active user. Returns the current shown navigation controller.                                                                                                                                                       |
| **`tapTalkGroupMemberAvatarTappedWithRoom:`**                                                                                                                                                                                                                                                                                                                  | A group member's profile picture on a message bubble in group chat room is tapped by active user. Returns the current shown navigation controller.                                                                                                                   |
| <p><strong><code>tapTalkUserMentionTappedWithRoom:</code></strong></p><p><strong><code>mentionedUser:</code></strong></p><p><strong><code>isRoomParticipant:</code></strong></p><p><strong><code>message:</code></strong></p><p><strong><code>currentViewController:</code></strong></p><p><strong><code>currentShownNavigationController:</code></strong></p> | Mention in bubble chat is tapped by active user. Returns current room, mentioned user data, boolean indicating the user is in group participant or not, message data, current shown view controller, and current shown navigation controller.                        |
| **`tapTalkMessageQuoteTappedWithUserInfo:`**                                                                                                                                                                                                                                                                                                                   | <p>A quote inside a message bubble in a chat room is tapped by active user. Returns tapped message, and userInfo.</p><p>UserInfo is a dictionary object embedded inside a message containing data specified by client, and is generally null when not specified.</p> |

### TapUIChatProfileDelegate

TapUIChatProfileDelegate listens to UI-related events in **Chat Profile View** when UI implementation type is used. You can register a TapUIChatProfileDelegate instance in your application through the TapUI class as follows:

{% hint style="info" %}
**Note:** Make sure to add **`#import <TapTalk/TapUI.h>`** before registering the delegate
{% endhint %}

{% tabs %}
{% tab title="Objective-C" %}
{% code title="ViewController.m" %}

```csharp
#import <TapTalk/TapUI.h>

// Add TapUIDelegate declaration
@interface ViewController () <TapUIChatProfileDelegate>

@end
  
@implementation ViewController
  
- (void)function {
    // Set TapUI delegate to current
    [[TapUI sharedInstance] setChatProfileDelegate:self];
}

#pragma mark - Delegates
#pragma mark - TapUIChatProfileDelegate
  
// Called when user tapped Report User button in user profile
- (void)reportUserButtonDidTapped:(UIViewController *)currentViewController
                             room:(TAPRoomModel *)room
                             user:(TAPUserModel *)reportedUser {
                                   
}

// Called when user tapped Report Group button in group profile
- (void)reportGroupButtonDidTapped:(UIViewController *)currentViewController
                              room:(TAPRoomModel *)room {
                                   
}

@end
```

{% endcode %}
{% endtab %}
{% endtabs %}

### TapUIMyAccountDelegate

TapUIMyAccountDelegate listens to UI-related events in **My Account View** when UI implementation type is used. You can register a TapUIMyAccountDelegate instance in your application through the TapUI class as follows:

{% hint style="info" %}
**Note:** Make sure to add **`#import <TapTalk/TapUI.h>`** before registering the delegate
{% endhint %}

{% tabs %}
{% tab title="Objective-C" %}
{% code title="ViewController.m" %}

```csharp
#import <TapTalk/TapUI.h>

// Add TapUIDelegate declaration
@interface ViewController () <TapUIMyAccountDelegate>

@end
  
@implementation ViewController
  
- (void)function {
    // Set TapUI delegate to current
    [[TapUI sharedInstance] setMyAccountDelegate:self];
}

#pragma mark - Delegates
#pragma mark - TapUIMyAccountDelegate
  
// Called when user tapped Delete Account button in my account page
- (void)tapTalkDeleteAccountButtonTapped:(UIViewController *)currentViewController
        currentShownNavigationController:(UINavigationController *)currentNavigationController {
                                   
}

@end
```

{% endcode %}
{% endtab %}
{% endtabs %}

### TapUICustomKeyboardDelegate

TapUICustomKeyboardDelegate bridges the custom keyboard-related events between TapTalk.io and the client app when UI implementation type is used. TapTalk.io will request custom keyboard items from the client app through this listener when a chat room is opened by the user. TapUICustomKeyboardDelegate can be implemented using the TapUI class.

{% hint style="info" %}
**Note:** Make sure to add **`#import <TapTalk/TapUI.h>`** before registering the delegate
{% endhint %}

{% tabs %}
{% tab title="Objective-C" %}
{% code title="ViewController.m" %}

```csharp
#import <TapTalk/TapUI.h>

// Add TapUIChatProfileDelegate declaration
@interface ViewController () <TapUICustomKeyboardDelegate>

@end
  
@implementation ViewController
  
- (void)function {
  // Set TapUI delegate to current
  [[TapUI sharedInstance] setCustomKeyboardDelegate:self];
}

#pragma mark - Delegates
#pragma mark - TapUICustomKeyboardDelegate

- (void)customKeyboardItemTappedWithRoom:(TAPRoomModel * _Nonnull)room
                                  sender:(TAPUserModel * _Nonnull)sender
                               recipient:(TAPUserModel * _Nullable)recipient
                            keyboardItem:(TAPCustomKeyboardItemModel * _Nonnull)keyboardItem {
    // Do an action when user taps a custom keyboard item
}


- (NSArray<TAPCustomKeyboardItemModel *> *)setCustomKeyboardItemsForRoom:(TAPRoomModel * _Nonnull)room sender:(TAPUserModel * _Nonnull)sender recipient:(TAPUserModel * _Nullable)recipient {
    // Set custom keyboard option items
    // Return items here if you wish to use custom keyboard in chat room
    return [NSArray array];
}
  
@end
```

{% endcode %}
{% endtab %}
{% endtabs %}

To use custom keyboard in the chat room, return a list of **`TapCustomKeyboardItemModel`** on the **`setCustomKeyboardItemsForSender:`** method in this delegate. See the example below:

{% tabs %}
{% tab title="Objective-C" %}

```csharp
- (NSArray<TAPCustomKeyboardItemModel *> *)setCustomKeyboardItemsForRoom:(TAPRoomModel * _Nonnull)room
                                                                  sender:(TAPUserModel * _Nonnull)sender
                                                               recipient:(TAPUserModel * _Nullable)recipient {
  
    NSMutableArray *customKeyboardItemArray = [NSMutableArray array];
    
    TAPCustomKeyboardItemModel *customKeyboardItem = [TAPCustomKeyboardItemModel new];
    customKeyboardItem.itemName = @"Item 1";
    customKeyboardItem.iconURL = @"Item Icon URL 1";
    [customKeyboardItemArray addObject:customKeyboardItem];
    
    TAPCustomKeyboardItemModel *customKeyboardItem2 = [TAPCustomKeyboardItemModel new];
    customKeyboardItem2.itemName = @"Item 2";
    customKeyboardItem2.iconURL = @"Item Icon URL 2";
    [customKeyboardItemArray addObject:customKeyboardItem2];
    
    return customKeyboardItemArray;
}
```

{% endtab %}
{% endtabs %}

| **Method Name**                                                                                                                                                                                                     | **Invoked When**                                                                                                                                                                                                     |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <p><strong><code>customKeyboardItemTappedWithRoom:</code></strong></p><p><strong><code>sender:</code></strong></p><p><strong><code>recipient:</code></strong></p><p><strong><code>keyboardItem:</code></strong></p> | A custom keyboard item in a chat room is tapped by the user. Returns **custom keyboard item**, **room**, **sender user**, and **recipient user** (only for personal chat room)                                       |
| **`setCustomKeyboardItemsForRoom:sender:recipient:`**                                                                                                                                                               | Chat room is opened. TapTalk.io will request custom keyboard items from the client app to be displayed in the chat room. Returns **room**, **sender user**, and the **recipient user** (only for personal chat room) |

### TAPCoreMessageManagerDelegate

TAPCoreMessageManagerDelegate listens to events when a new/updated message is received by the application. TAPCoreMessageManagerDelegate can be registered through the TapCoreMessageManager class.

{% hint style="info" %}
**Note:** Make sure to add **`#import <TapTalk/TapCoreMessageManager.h>`** before registering the delegate
{% endhint %}

{% tabs %}
{% tab title="Objective-C" %}
{% code title="ViewController.m" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

// Add TAPCoreMessageManagerDelegate declaration
@interface ViewController () <TAPCoreMessageManagerDelegate>

@end
  
@implementation ViewController
  
- (void)function {
    // Set TAPCoreMessageManager delegate to current
    [[TAPCoreMessageManager sharedManager] setDelegate:self];
}

#pragma mark - Delegates
#pragma mark - TAPCoreMessageManagerDelegate

- (void)tapTalkDidReceiveNewMessage:(TAPMessageModel *)message {

}

- (void)tapTalkDidReceiveUpdatedMessage:(TAPMessageModel *)message {
  
}

- (void)tapTalkDidDeleteMessage:(TAPMessageModel *)message {
  
}
  
@end
```

{% endcode %}
{% endtab %}
{% endtabs %}

| **Method Name**                        | **Invoked When**                                                        |
| -------------------------------------- | ----------------------------------------------------------------------- |
| **`tapTalkDidReceiveNewMessage:`**     | A new message is received. Returns the newly received **message**.      |
| **`tapTalkDidReceiveUpdatedMessage:`** | An updated message is received. Returns the newly received **message**. |
| **`tapTalkDidDeleteMessage:`**         | A message is deleted. Returns the deleted **message**.                  |

### TAPCoreRoomListManagerDelegate

Changes to a chat room's state, such as pin and mute events are notified through TapCoreRoomListListener. An instance of TapCoreRoomListListener can be registered from the **TapCoreRoomListManager** class.

{% hint style="info" %}
**Note:** Make sure to add **`#import <TapTalk/TAPCoreRoomListManager.h>`**&#x62;efore registering the delegate
{% endhint %}

{% tabs %}
{% tab title="Objective-C" %}
{% code title="ViewController.m" %}

```csharp
#import <TapTalk/TAPCoreRoomListManager.h>

// Add TAPCoreRoomListManagerDelegate declaration
@interface ViewController () <TAPCoreRoomListManagerDelegate>

@end
  
@implementation ViewController
  
- (void)function {
    // Set TAPCoreRoomListManager delegate to current
    [[TAPCoreRoomListManager sharedManager] setDelegate:self];
}

#pragma mark - Delegates
#pragma mark - TAPCoreRoomListManagerDelegate

- (void)tapTalkDidMuteChatRoom:(NSString *)roomID expiredAt:(NSNumber *)expiredAt {

}

- (void)tapTalkDidUnmuteChatRoom:(NSString *)roomID {

}

- (void)tapTalkDidPinChatRoom:(NSString *)roomID {

}

- (void)tapTalkDidUnpinChatRoom:(NSString *)roomID {

}

- (void)tapTalkDidDeleteChatRoom:(NSString *)roomID {

}
  
@end
```

{% endcode %}
{% endtab %}
{% endtabs %}

| Method Name                     | Invoked When                                                                                           |
| ------------------------------- | ------------------------------------------------------------------------------------------------------ |
| **`tapTalkDidMuteChatRoom:`**   | The active user muted a chat room. Returns the **room ID** and **mute expiry time** of the muted room. |
| **`tapTalkDidUnmuteChatRoom:`** | The active user unmuted a chat room. Returns the **room ID** of the unmuted room.                      |
| **`tapTalkDidPinChatRoom:`**    | The active user pinned a chat room. Returns the **room ID** of the pinned room.                        |
| **`tapTalkDidUnpinChatRoom:`**  | The active user unpinned a chat room. Returns the **room ID** of the unpinned room.                    |
| **`tapTalkDidDeleteChatRoom:`** | The active user deleted a chat room. Returns the **room ID** of the deleted room.                      |

### TAPCoreChatRoomManagerDelegate

Room status events such as typing events and online status are notified through TAPCoreChatRoomManagerDelegate. An instance of TAPCoreChatRoomManagerDelegate can be registered from the **TapCoreChatRoomManager** class.

{% hint style="info" %}
**Note:** Make sure to add **`#import <TapTalk/TapCoreChatRoomManager.h>`**&#x62;efore registering the delegate
{% endhint %}

{% tabs %}
{% tab title="Objective-C" %}
{% code title="ViewController.m" %}

```csharp
#import <TapTalk/TAPCoreChatRoomManager.h>

// Add TAPCoreChatRoomManagerDelegate declaration
@interface ViewController () <TAPCoreChatRoomManagerDelegate>

@end
  
@implementation ViewController
  
- (void)function {
    // Set TAPCoreChatRoomManager delegate to current
    [[TAPCoreChatRoomManager sharedManager] setDelegate:self];
}

#pragma mark - Delegates
#pragma mark - TAPCoreChatRoomManagerDelegate

- (void)tapTalkDidStartTypingWithUser:(TAPUserModel *)user roomID:(NSString *)roomID {
  
}

- (void)tapTalkDidStopTypingWithUser:(TAPUserModel *)user roomID:(NSString *)roomID {

}

- (void)tapTalkDidReceiveOnlineStatusWithUser:(TAPUserModel *)user onlineStatus:(BOOL)isOnline lastActive:(NSNumber *)lastActive {
  
}
  
@end
```

{% endcode %}
{% endtab %}
{% endtabs %}

| **Method Name**                             | **Invoked When**                                                                                                                          |
| ------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| **`tapTalkDidStartTypingWithUser:roomID:`** | Another user starts typing a message in a chat room. Returns the **room ID** and **typing user**.                                         |
| **`tapTalkDidStopTypingWithUser:roomID:`**  | Another user stops typing a message in a chat room. Returns the **room ID** and **typing user**.                                          |
| **`tapTalkDidReceiveOnlineStatus:`**        | Another user comes online or offline. Returns the **updated user**, **online status**, and the updated user's last active **time stamp**. |

### TAPCoreContactManagerDelegate

Contact related events such as block/unblock are notified through TAPCoreContactManagerDelegate. An instance of TAPCoreContactManagerDelegate can be registered from the **TapCoreContactManager** class.

{% hint style="info" %}
**Note:** Make sure to add **`#import <TapTalk/TapCoreContactManager.h>`**&#x62;efore registering the delegate
{% endhint %}

{% tabs %}
{% tab title="Objective-C" %}
{% code title="ViewController.m" %}

```csharp
#import <TapTalk/TapCoreContactManager.h>

// Add TAPCoreContactManagerDelegate declaration
@interface ViewController () <TapCoreContactManagerDelegate>

@end
  
@implementation ViewController
  
- (void)function {
    // Set TapCoreContactManager delegate to self
    [[TapCoreContactManager sharedManager] setDelegate:self];
}

#pragma mark - Delegates
#pragma mark - TapCoreContactManagerDelegate

- (void)tapTalkDidBlockContact:(TAPUserModel *)user {
  
}

- (void)tapTalkDidUnblockContact:(TAPUserModel *)user {
  
}
  
@end
```

{% endcode %}
{% endtab %}
{% endtabs %}

| **Method Name**                 | **Invoked When**                                                   |
| ------------------------------- | ------------------------------------------------------------------ |
| **`tapTalkDidBlockContact:`**   | Active user blocks another user. Returns the blocked **user**.     |
| **`tapTalkDidUnblockContact:`** | Active user unblocks another user. Returns the unblocked **user**. |

### TapUIRoomListViewControllerLifecycleDelegate

Room list view controller lifecycle events such as `loadView`, `viewDidLoad`, `viewWillAppear` and others are notified through TAPRoomListViewControllerLifecycleDelegate.

{% hint style="info" %}
**Note:** Make sure to add **`#import <TapTalk/TapUI.h>`**&#x62;efore registering the delegate
{% endhint %}

{% tabs %}
{% tab title="Objective-C" %}
{% code title="ViewController.m" %}

```csharp
#import <TapTalk/TapUI.h>

// Add TapUIDelegate declaration
@interface ViewController () <TapUIRoomListViewControllerLifecycleDelegate>

@end
  
@implementation ViewController
  
- (void)function {
    // Set TapUI delegate to current
    [[[TapUI sharedInstance] roomListViewController] setLifecycleDelegate:self];
}

#pragma mark - Delegates
#pragma mark - TapUIRoomListViewControllerLifecycleDelegate
  
- (void)TapUIRoomListViewControllerLoadView {
  
}

- (void)TapUIRoomListViewControllerViewDidLoad {
  
}

- (void)TapUIRoomListViewControllerViewWillAppear {
  
}

- (void)TapUIRoomListViewControllerViewWillDisappear {
  
}

- (void)TapUIRoomListViewControllerViewDidAppear {
  
}

- (void)TapUIRoomListViewControllerViewDidDisappear {
  
}

- (void)TapUIRoomListViewControllerDealloc {
  
}

- (void)TapUIRoomListViewControllerDidReceiveMemoryWarning {
  
}
  
@end
```

{% endcode %}
{% endtab %}
{% endtabs %}


# Push Notification

Push notification is a very important aspect in a chat application. Taptalk.io provides a convenient way to implement push notifications so you can easily manage them according to your needs. If you implement Taptalk.io with the UI implementation method, incoming notifications will be handled within our library and will be automatically shown to the user. If you prefer having full control over the push notifications, the core implementation method can be used.

Push notification for iOS client apps are sent using **Apple Push Notification service (APNs)**. They are used for keeping your users informed with timely and relevant content, whether your client app is running in the background or inactive on a device. They can also perform the types of user interactions such as alert, sound, or badge, and include custom data your app needs to respond to the notifications.

Our iOS SDK enables you to build a client app that can receive push notifications. When a message is sent to TapTalk.io server through the SDK, the server communicates with APNs regarding the message and then APNs delivers a push notification for the message to an iOS device where your client app is installed.

### Step 1: Generating your .p8 key file

{% hint style="info" %}
Configuration with auth keys is recommended as they are the more current method for sending notifications to iOS.
{% endhint %}

A **.p8 key** file is required to send push notifications to your apps. There are some several ways to generate key for push notification, but Apple recommends to use APNs Auth Key (.p8 key file) to register for push notifications.

**1.** To generate a **.p8 key** file, go to [Apple developer account page](https://developer.apple.com/account/) , then select **Certificates, IDs & Profiles**.

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MHLfyg9-9f845ZhQihH%2F-MHM1K3FUgFsfkRCW8d1%2F42b7a4c-Screen_Shot_2019-08-19_at_11.58.10.png?alt=media\&token=b5feef10-0255-4fc8-9a83-9cfc107a35d9)

**2.** Next, select **Keys** tab.

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MHLfyg9-9f845ZhQihH%2F-MHM1bGF5370xRVjzceC%2Fa38dcd6-keys.png?alt=media\&token=8b975a7d-beb8-422f-a863-6059261d82f4)

**3.** Click **"+"** button or click **Create a key** button to add new key.

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MHLfyg9-9f845ZhQihH%2F-MHM1qPK9uC0LyyH00oW%2Fe99649f-Screen_Shot_2019-08-21_at_11.55.01.png?alt=media\&token=3e6d7104-3c09-4c8a-a277-879d47fd4e80)

**4.** In the new key page, type in your key name and check the Apple Push Notification service (APNs) box, then click **Continue**.

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MHLfyg9-9f845ZhQihH%2F-MHM1xv9KSCvpPYAoSHp%2Fbae3f0a-Screen_Shot_2019-08-21_at_11.55.43.png?alt=media\&token=1c64a1f9-7993-4b2d-ad6c-d3b873215f18)

**5.** Confirm your key information and click **Register**.

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MHLfyg9-9f845ZhQihH%2F-MHM2CsOly0Yt_mLGyIo%2F1fc0b84-Screen_Shot_2019-08-21_at_11.55.53.png?alt=media\&token=ad4ca038-b6d0-4985-9d23-5db45f289e96)

Then proceed to download the key file by clicking **Download**.

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MHLfyg9-9f845ZhQihH%2F-MHM2JfHtGEep0gbQRPu%2Ffc005ad-Push_key.png?alt=media\&token=39c49e73-d134-43d3-85c4-ab9641cbd3f9)

Please remember the Key ID provided in the information above or you can see the Key ID from the downloaded file. The Auth Key filename will look like this : AuthKey\_ABC12DE34.p8, the ABC12DE34 is the Key ID for this key, we will need this Key ID later.

### Step 2: Using .p8 key file in TapTalk.io dashboard to send push notification

**1.** Go to [TapTalk.io Dashboard page](https://taptalk.io/), and login to your dashboard.Select Tab **Development** -> **Push Certificates**\
**2.** Select Tab **Development** -> **Push Certificates**

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MHLfyg9-9f845ZhQihH%2F-MHM3-pMUJKl4Hpkj6WA%2Fac55f15-Screenly_-_12.1_Development_-_Push_Certificates_-_Enabled_-_Empty_State2x.png?alt=media\&token=361497b9-b255-4f8d-bbd6-a9765981debf)

**3.** Next, select **Add APNs Authentication Key**

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MHLfyg9-9f845ZhQihH%2F-MHM32wQQIhSApWNV_O_%2F7a20ffc-Screenly_-_12.2.1_Development_-_Push_Certificates_-_Add_APNs2x.png?alt=media\&token=6cdf1c22-8149-4655-830d-b806f29846e2)

**4.** Upload **.p8 Authentication Key**, add **APN Key ID**, add **Team ID**, and select to **show unread count** option

{% hint style="info" %}
You can find your Team ID in the Apple Member Center under the [membership tab](https://developer.apple.com/account/).
{% endhint %}

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MHLfyg9-9f845ZhQihH%2F-MHM37yKfZGFsMqhynxe%2F7ca993b-Screenly_-_12.2.3_Development_-_Push_Certificates_-_Add_APNs_-_Active2x.png?alt=media\&token=ff11f9a8-a7cc-4e8a-b190-f578a2375ff4)

{% hint style="info" %}
**Show Unread Count**

You can choose either to **show unread count by** **chat room** or **not show unread count**
{% endhint %}

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MHLfyg9-9f845ZhQihH%2F-MHM3lHfmjGIp_ZY2oyr%2F05665be-Screenly_-_12.3_Development_-_Push_Certificates_-_Filled2x.png?alt=media\&token=cfad231b-fc44-43be-bd50-73231f934c71)

### Step 3: Implement push notification in your app

**1.** The first step is to implement **`UIApplicationDelegate`** & **`TapTalkApplicationDelegate`** in your **AppDelegate** class.

{% tabs %}
{% tab title="Objective-C" %}
{% code title="AppDelegate.m" %}

```csharp
@interface AppDelegate () <TapTalkDelegate, UNUserNotificationCenterDelegate>

@end

// Implement didRegisterForRemoteNotificationsWithDeviceToken: method to tells the delegate that the app successfully registered with Apple Push Notification service (APNs).
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    //Call TapTalk didRegisterForRemoteNotificationsWithDeviceToken: method
    [[TapTalk sharedInstance] application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}

// Implement didReceiveRemoteNotification: method to tells the app that a remote notification arrived that indicates there is data to be fetched.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler {
    // Call TapTalk didReceiveRemoteNotification: method
    [[TapTalk sharedInstance] application:application didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

**2.** Request authorization to Apple Push Notification Service (APNs) by using this method in your **appDelegate** class with **`application:didFinishLaunchingWithOptions:`** method.

{% tabs %}
{% tab title="Objective-C" %}
{% code title="AppDelegate.m" %}

```csharp
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  
    //Register for notification in didFinishLaunchingWithOptions: method  
    [UNUserNotificationCenter currentNotificationCenter].delegate = self;
    UNAuthorizationOptions authOptions = UNAuthorizationOptionAlert | UNAuthorizationOptionSound | UNAuthorizationOptionBadge
      
    [[UNUserNotificationCenter currentNotificationCenter] requestAuthorizationWithOptions:authOptions completionHandler:^(BOOL granted, NSError * _Nullable error) {
    }];  
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

**3.** Implement **`UNUserNotificationCenterDelegate`** to handle notification in your **appDelegate** class.

{% tabs %}
{% tab title="Objective-C" %}
{% code title="AppDelegate.m" %}

```csharp
// Add UNUserNotificationCenterDelegate
@interface AppDelegate () <UNUserNotificationCenterDelegate>

@end

@implementation AppDelegate

#pragma mark - UNUserNotificationCenter
// Implement UNUserNotificationCenter delegate
// This method lets the app know when a notification is delivered to foreground
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler {
    // Add TapTalk.io method to handle willPresentNotification method
    [[TapTalk sharedInstance] userNotificationCenter:center willPresentNotification:notification withCompletionHandler:completionHandler];
}

// This method lets your app know which action was selected by the user for a given notification
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)())completionHandler {
    // Add TapTalk.io method to handle didReceiveNotificationResponse method
    [[TapTalk sharedInstance] userNotificationCenter:center didReceiveNotificationResponse:response withCompletionHandler:completionHandler];
}
  
@end
```

{% endcode %}
{% endtab %}
{% endtabs %}

**4.** Implement **`TapTalkDelegate`** in **appDelegate** class.

{% tabs %}
{% tab title="Objective-C" %}
{% code title="AppDelegate.m" %}

```csharp
// Add TapTalkDelegate and previous UNUserNotificationCenterDelegate
@interface AppDelegate () <UNUserNotificationCenterDelegate, TapTalkDelegate>

@end

@implementation AppDelegate

#pragma mark - Delegate
#pragma mark - TapTalkDelegate

//Implement TapTalk Delegate and add code below
- (void)tapTalkDidRequestRemoteNotification {
    // Register to receive remote notifications via Apple Push Notification service
    [[UIApplication sharedApplication] registerForRemoteNotifications];
}
  
@end
```

{% endcode %}
{% endtab %}
{% endtabs %}

### Add In-App Notification

TapTalk.io provides in-app notification handling. This following code enables you to activate and show in-app notification.

![](https://4266585843-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfVupFSqh_qZAY9OiCO%2F-MHLfyg9-9f845ZhQihH%2F-MHM54N-E4ZY08FRMWN7%2Fff558ef-Screen_-_iPhone_X_-_Notification_-_No_Image2x.png?alt=media\&token=0b2a3dd5-ddc1-4bf1-90eb-fb50ae6d38d0)

{% tabs %}
{% tab title="Objective-C" %}
{% code title="AppDelegate.m" %}

```csharp
#import <TapTalk/TapUI.h>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // To activate in-app push notification with your current window
    [[TapUI sharedInstance] activateTapTalkInAppNotification:YES];
  
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Note:** You will not receive any in-app notification if you don't implement this method.
{% endhint %}


# General

### Get TapTalk Implementation Type

You can get your current TapTalk.io implementation type by using this method.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapTalk.h>
  
// Get current used implementation Type
[[TapTalk sharedInstance] getTapTalkImplementationType];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Note:**&#x20;

TapTalkImplementationType consists of 3 types which are **:**\
`TapTalkImplementationTypeUI`: used for implementation with only TapUI`TapTalkImplementationTypeCore`: used for implementation with only TapCore`TapTalkImplementationTypeCombine`: used for implementation with both of TapCore and TapUI combined
{% endhint %}

### Check TapTalk Initialized

You can check whether TapTalk instance has completed initialization by calling the method below.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapTalk.h>
  
BOOL isInitialized = [[TapTalk sharedInstance] checkTapTalkInitialized];
```

{% endtab %}
{% endtabs %}

### Update Application Badge Count

You can get your current TapTalk.io implementation type by using this method.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapTalk.h>
  
[[TapTalk sharedInstance] updateApplicationBadgeCount];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**T**o listen to changes of application badge, please see the explanation in [event delegate page](/powertalk-chat-sdk-documentation/powertalk-ios/event-delegate) using`tapTalkUnreadChatRoomBadgeCountUpdated`method
{% endhint %}

### Remote Configs

A TapTalk.io project owns a remote configuration, which consists of 3 configuration types: **Core Configs**, **Project Configs**, and **Custom Configs**. A configuration value can be obtained with the respective configuration type's getter method, and will return a Map object. To get a specific value, call the **get** method from the returned dictionary with the respective key. The value obtained will always be in a **String** format and should be converted each according to their uses. Each configuration type will be explained below.

### Core Configs

| **Config Key**         | **Value**                                                                    |
| ---------------------- | ---------------------------------------------------------------------------- |
| chatMediaMaxFileSize   | Number of maximum allowed chat media file size in bytes                      |
| roomPhotoMaxFileSize   | Number of maximum allowed group chat room profile picture file size in bytes |
| userPhotoMaxFileSize   | Number of maximum allowed user profile picture file size in bytes            |
| groupMaxParticipants   | Number of maximum allowed participants in a group chat room                  |
| channelMaxParticipants | Number of maximum allowed participants in a channel                          |

Below is an example to get the value of chatMediaMaxFileSize:

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapTalk.h>
  
NSDictionary *coreConfigsDictionary = [[TapTalk sharedInstance] getCoreConfigs];
NSString *maxFileSizeString = [coreConfigsDictionary objectForKey:@"maxFileSize"];
NSInteger maxFileSizeValue = [maxFileSizeString integerValue];
```

{% endtab %}
{% endtabs %}

### Project Configs

| **Config Key**     | **Value**                                                                                                                                       |
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| usernameIgnoreCase | <p><strong>"0"</strong> if username in the project is case sensitive<br><strong>"1"</strong> if username in the project is case insensitive</p> |

An example to obtain usernameIgnoreCase value:

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapTalk.h>
  
NSDictionary *projectConfigsDictionary = [[TapTalk sharedInstance] getProjectConfigs];
NSString *usernameIgnoreCaseString = [projectConfigsDictionary objectForKey:@"usernameIgnoreCase"];
BOOL usernameIgnoreCase = [usernameIgnoreCaseString boolValue];
```

{% endtab %}
{% endtabs %}

### Custom Configs

Custom config values are specified by the user, and can be customized through the TapTalk.io Dashboard. To get the project's custom configs, call the **getCustomConfigs** method.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapTalk.h>
  
NSDictionary *customConfigsDictionary = [[TapTalk sharedInstance] getCustomConfigs];
```

{% endtab %}
{% endtabs %}

### Refresh Remote Configs

To refresh remote configs with the latest updated values, call the **refreshRemoteConfigs** method in TapTalk.io class.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapTalk.h>
  
[[TapTalk sharedInstance] refreshRemoteConfigs];
```

{% endtab %}
{% endtabs %}

### Enable / Disable Auto Contact Sync

If you are using UI implementation method in your application, TapTalk.io provides a feature to automatically sync your user's phone contacts with their TapTalk.io contacts. You can choose to enable or disable auto contact sync by calling these methods. If auto contact sync is enabled, TapTalk.io will automatically sync your user's phone contacts and add them to TapTalk.io contacts if their phone number is registered to TapTalk.io when the application is opened. Please note that the **default value** is **enabled**.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapTalk.h>
  
// Enable or disabled auto contact sync
// Value is enabled by default if you do not set this method
[[TapTalk sharedInstance] setAutoContactSyncEnabled:IS_ENABLED];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameter**\
`IS_ENABLED`: (BOOL) set to TRUE/YES to enable auto contact sync
{% endhint %}

### Get Auto Contact Sync Status

Use this method to obtain auto contact sync status. This method will return true if auto contact sync is enabled.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapTalk.h>
  
BOOL isAutoContactSyncEnabled = [[TapTalk sharedInstance] isAutoContactSyncEnabled];
```

{% endtab %}
{% endtabs %}

### Obtain Current Navigation Controller in TapUI

To refresh remote configs with the latest updated values, call the **refreshRemoteConfigs** method in TapTalk.If you are using TapUI and want to integrate with your app, you can get the current active view controller or navigation controller by using the following codes.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapUI.h>

// Get TapTalk.io current active view controller
UIViewController *activeViewController = [[TapUI sharedInstance] getCurrentTapTalkActiveViewController];

// Get TapTalk.io current active navigation controller
UINavigationController *activeNavigationController = [[TapUI sharedInstance] getCurrentTapTalkActiveNavigationController];
```

{% endtab %}
{% endtabs %}

### Set Image Compression Quality

You can customize the compression quality of images used for upload and download. The range of the compression quality is set between 0.1f and 1.0f. The higher the quality, the better the images will look, but they will also take more storage space as their size increases.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapTalk.h>

[[TapTalk sharedInstance] setImageCompressionQuality:IMAGE_COMPRESSION_QUALITY];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`IMAGE_COMPRESSION_QUALITY`**: (CGFloat) image compression quality between 0.1f to 1.0f
{% endhint %}

### Smart Local Cache Management

In order to optimize storage usage and performance, TapTalk.io cleans any local data of messages that are older than 1 month. This cleanup runs on a scheduled interval. Deleted messages can later be retrieved from the server when required.

### Encrypted Chat

TapTalk.io SDK encrypts all message contents before sending them to the server to protect any sensitive content contained in the messages. All messages received and stored in the server will stay encrypted. Messages will be decrypted once fetched in end user's local device in order to show their contents. TapTalk.io uses **AES Crypt** combined with secure local password to encrypt and decrypt message contents.


# User

You can obtain current TapTalk.io active user data by using these methods:

### Get TapTalk.io Active User

Obtain current TapTalk.io active user from cache.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapTalk.h>

TAPUserModel *tapTalkActiveUser = [[TapTalk sharedInstance] getTapTalkActiveUser];
```

{% endtab %}
{% endtabs %}

### Refresh TapTalk.io Active User

Obtain current Retrieve latest TapTalk.io active user data from the server.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapTalk.h>

[[TapTalk sharedInstance] refreshActiveUserWithSuccess:^{
    // Successfully updated active user data
    TAPUserModel *tapTalkActiveUser = [[TapTalk sharedInstance] getTapTalkActiveUser];
}
failure:^(NSError * _Nonnull error) {
    // Failed to update active user data
}];
```

{% endtab %}
{% endtabs %}

### Update Active User Bio

You are able to update the active user's bio with a custom string by calling `updateActiveUserBio` from **TapCoreContactManager** class.

Successful update will be reflected in the **bio** field of the updated active user's data (`TAPUserModel.bio`).

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreContactManager.h>

[[TAPCoreContactManager sharedManager] updateActiveUserBio:BIO_STRING
success:^{
    // Successfully updated active user bio
}
failure:^(NSError * _Nonnull error) {
    // Failed to update active user bio
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
BIO\_STRING: (NSString \*) custom string for active user bio
{% endhint %}


# Room List

You can implement Room List with [TapUI](/powertalk-chat-sdk-documentation/powertalk-ios/room-list/room-list-tapui) or [TapCore](/powertalk-chat-sdk-documentation/powertalk-ios/room-list/room-list-tapcore).


# Room List - TapUI

If you are using UI implementation type, you can use the method below to open TapTalk.io's chat room list view.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapUIRoomListViewController.h>
#import <TapTalk/TapUI.h>

// Initialize TapTalk.io room list view controller here
TapUIRoomListViewController *roomListViewController = [[TapUI sharedInstance] roomListViewController]; 
UINavigationController *roomListNavigationController = [[UINavigationController alloc] initWithRootViewController:roomListViewController];
  
// You can choose to present or push view controller using this code
// Present room list view
[self presentViewController:roomListViewController animated:YES completion:^{
    //completion
}];
  
//  Push room list view
[self.navigationController pushViewController:roomListNavigationController animated:YES]; 
  
//Or you can add to your window root view controller
self.window.rootViewController = roomListNavigationController;
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Note:** You can get TapTalk.io current view controller or navigation controller to integrate to your current view controller by using [getCurrentTapTalkActiveViewController](/powertalk-chat-sdk-documentation/powertalk-ios/general#obtain-current-navigation-controller-in-tapui) method.
{% endhint %}

### Room List View Controller Lifecycle

If you need to do something in `TapUIRoomListViewController` view lifecycle, you can implement our `TapUIRoomListViewControllerLifecycleDelegate` in [Event Delegate - Room List Lifecycle Delegate](/powertalk-chat-sdk-documentation/powertalk-ios/event-delegate#tapuiroomlistviewcontrollerlifecycledelegate) section.<br>


# Room List - TapCore

If you are using core implementation type, you can manage the application's chat room list with the following methods:

{% hint style="warning" %}
**Note:** Please add **`#import <TapTalk/TapCoreRoomListManager.h>`** before using these methods.
{% endhint %}

| **TapTalk Room List Method**                                                                                                     | **Description**                                                                                    |
| -------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| [Get Updated Room List](/powertalk-chat-sdk-documentation/powertalk-ios/room-list/room-list-tapcore#get-updated-room-list)       | Call this method to fetch the latest room list data from the server and update to the local cache. |
| [Get Room List From Cache](/powertalk-chat-sdk-documentation/powertalk-ios/room-list/room-list-tapcore#get-room-list-from-cache) | Call this method to retrieve list of room data obtained from the local cache.                      |
| [Fetch New Message](#fetch-new-message)                                                                                          | Call this method to fetch new/updated messages that have not yet been received by the device       |
| [Search Local Room List](#search-local-room-list)                                                                                | Call this method to search room lists from the device's local storage with a keyword               |
| [​Mark Chat Room as Unread](#mark-chat-room-as-unread)                                                                           | ​Adds the chat room ID to the marked as unread chat room list​                                     |
| [​Remove Unread Mark from Chat Room​](#remove-unread-mark-from-chat-room)                                                        | Removes chat room ID from the marked as unread chat room list​                                     |
| [Get Marked as Unread Chat Room List](#get-marked-as-unread-chat-room-list)                                                      | ​Retrieve the list of chat room IDs that has been marked as unread                                 |
| [Mute/Unmute Chat Room](#mute-unmute-chat-room)                                                                                  | Mute selected chat rooms until a specified time                                                    |
| [Get Muted Chat Rooms](#get-muted-chat-rooms)                                                                                    | Retrieve the list of muted chat room IDs and their respective mute expiry time                     |
| [Pin/Unpin Chat Room](#pin-unpin-chat-room)                                                                                      | Add or remove the chat room ID to pinned chat room list                                            |
| [Get Pinned Chat Rooms](#get-pinned-chat-rooms)                                                                                  | Retrieve list of pinned chat room IDs from the server                                              |

### Get Updated Room List

Call this method to fetch the latest room list data from the server and update to the local cache.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapCoreRoomListManager.h>
  
[[TAPCoreRoomListManager sharedManager] getUpdatedRoomListWithSuccess:^(NSArray<TAPRoomListModel *> * _Nonnull roomListArray) {
    // Successfully fetched updated room list data
}
failure:^(NSError * _Nonnull error) {
    // Failed to get updated room list data
}];
```

{% endtab %}
{% endtabs %}

### Get Room List From Cache

Call this method to retrieve list of room data obtained from the local cache.this method to fetch the latest room list data from the server and update to the local cache.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapCoreRoomListManager.h>
  
[[TAPCoreRoomListManager sharedManager] getRoomListFromCacheWithSuccess:^(NSArray<TAPRoomListModel *> * _Nonnull roomListResultArray) {
    // Successfully fetched room list data
}
failure:^(NSError * _Nonnull error) {
    // Failed to get room list data
}];
```

{% endtab %}
{% endtabs %}

### Fetch New Message

Call this method to fetch new/updated messages that have not yet been received by the device. Can be used to retrieve pending messages when the device goes back online after an offline state.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapCoreRoomListManager.h>
  
[[TAPCoreRoomListManager sharedManager] fetchNewMessagesWithSuccess:^(NSArray<TAPMessageModel *> * _Nonnull messageArray) {
    // Returns list of messages received by the user while the device is offline
}
failure:^(NSError * _Nonnull error) {
    // Failed to get messages
}];
```

{% endtab %}
{% endtabs %}

### Search Local Room List

Call this method to search room lists from the device's local storage with a keyword. Provided keyword will be used to filter **room name** in the search result.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapCoreRoomListManager.h>
  
[[TAPCoreRoomListManager sharedManager] searchLocalRoomListWithKeyword:KEYWORD
success:^(NSArray<TAPRoomListModel *> * _Nonnull roomListResultArray) {
    // Returns filtered room lists obtained from cache
}
failure:^(NSError * _Nonnull error) {
    // Failed to get room list data
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`KEYWORD`**: (String) search keyword to filter room name
{% endhint %}

### Mark Chat Room as Unread

Call this method to add the selected chat room ID to the marked as unread chat room list.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapCoreRoomListManager.h>

// Mark single chat room as unread
[[TAPCoreRoomListManager sharedManager] markChatRoomAsUnreadWithRoomID:ROOM_ID 
success:^{
    // Successfully marked chat room as unread
} 
failure:^(NSError * _Nonnull error) {
        
}];


// Mark multiple chat rooms as unread
[[TAPCoreRoomListManager sharedManager] markChatRoomsAsUnreadWithRoomID:ROOM_IDS 
success:^{
    // Successfully marked chat rooms as unread
} 
failure:^(NSError * _Nonnull error) {
        
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`ROOM_ID`**: (String) ID of the target room\
**`ROOM_IDS`**: (Array\<String>) array containing IDs of target rooms
{% endhint %}

### Remove Unread Mark from Chat Room

Call this method to remove the selected chat room ID from the marked as unread chat room list.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapCoreRoomListManager.h>

// Remove unread mark from single chat room
[[TAPCoreRoomListManager sharedManager] removeUnreadMarkFromChatRoom:ROOM_ID 
success:^{
    // Successfully removed unread mark from chat room
} 
failure:^(NSError * _Nonnull error) {
        
}];


// Remove unread mark from multiple chat rooms
[[TAPCoreRoomListManager sharedManager] removeUnreadMarkFromChatRooms:ROOM_IDS 
success:^{
    // Successfully removed unread mark from chat rooms
} 
failure:^(NSError * _Nonnull error) {
        
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`ROOM_ID`**: (NSString) ID of the target room\
**`ROOM_IDS`**: (NSArray\<NsSString>) array containing IDs of target rooms
{% endhint %}

### Get Marked as Unread Chat Room List

Call this method to retrieve the list of chat room IDs that has been marked as unread.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapCoreRoomListManager.h>

[[TAPCoreRoomListManager sharedManager] getMarkedAsUnreadChatRoomListWithSuccess:^(NSArray * _Nonnull unreadRoomIDs) {
    // Returns list of roomID that has been marked as unread
} 
failure:^(NSError * _Nonnull error) {
    
}];
```

{% endtab %}
{% endtabs %}

### Mute/Unmute Chat Room

Call these methods to mute the selected chat rooms until a specified time. Active user will not receive notifications from muted chat rooms.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapCoreRoomListManager.h>

// Mute a single chat room
[[TAPCoreRoomListManager sharedManager] muteChatRoomWithRoomID:ROOM_ID 
                                                     expiredAt:EXPIRED_AT
success:^{
    // Successfully muted chat room
} 
failure:^(NSError * _Nonnull error) {
        
}];

// Mute multiple chat rooms
[[TAPCoreRoomListManager sharedManager] muteChatRoomsWithRoomIDs:ROOM_IDS
                                                       expiredAt:EXPIRED_AT
success:^{
    // Successfully muted chat rooms
} 
failure:^(NSError * _Nonnull error) {
        
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`ROOM_ID`**: (NSString) ID of the target room\
**`ROOM_IDS`**: (NSArray\<NsSString>) array containing IDs of target rooms\
**`EXPIRED_AT`**: (NSNumber) chat room will stay muted until this time, fill with 0 to mute the room forever or until the room is unmuted
{% endhint %}

To return chat rooms to its normal state and continue retrieving notifications, use `unmuteChatRoomWithRoomID:` method.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapCoreRoomListManager.h>

// Unmute a single chat room
[[TAPCoreRoomListManager sharedManager] unmuteChatRoomWithRoomID:ROOM_ID 
success:^(NSArray *roomIDs) {
    // Successfully unmuted chat room
} 
failure:^(NSError * _Nonnull error) {
        
}];

// Unmute multiple chat rooms
[[TAPCoreRoomListManager sharedManager] unmuteChatRoomsWithRoomIDs:ROOM_IDS
success:^(NSArray *roomIDs) {
    // Successfully unmuted chat rooms
} 
failure:^(NSError * _Nonnull error) {
        
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`ROOM_ID`**: (NSString) ID of the target room\
**`ROOM_IDS`**: (NSArray\<NsSString>) array containing IDs of target rooms
{% endhint %}

### Get Muted Chat Rooms

Retrieve the list of muted chat room IDs and their respective mute expiry time.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapCoreRoomListManager.h>

[[TAPCoreRoomListManager sharedManager] getMutedChatRoomListWithSuccess:^(NSMutableArray<TAPMutedRoomModel *> *mutedRoomListArray) {
    // Returns list of TAPMutedRoomModel which contains 
    // roomID and expiry time of the muted chat rooms
} 
failure:^(NSError * _Nonnull error) {
    
}];
```

{% endtab %}
{% endtabs %}

### Pin/Unpin Chat Room

You may call `pinChatRoomWithRoomID:` to add or remove the chat room ID to pinned chat room list. Chat rooms pinned by the user are generally shown on top of the chat room list. You can later retrieve the list of pinned chat room IDs with `getPinnedChatRoomIDs`.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapCoreRoomListManager.h>

// Pin a single chat room
[[TAPCoreRoomListManager sharedManager] pinChatRoomWithRoomID:ROOM_ID 
success:^(NSArray *roomIDs) {
    // Successfully pinned chat room
} 
failure:^(NSError * _Nonnull error) {
        
}];

// Pin multiple chat rooms
[[TAPCoreRoomListManager sharedManager] pinChatRoomsWithRoomIDs:ROOM_IDS
success:^(NSArray *roomIDs) {
    // Successfully pinned chat rooms
} 
failure:^(NSError * _Nonnull error) {
        
}];
```

{% endtab %}
{% endtabs %}

Use `unpinChatRoomWithRoomID:` to remove existing pinned chat room ID from the pinned chat room list.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapCoreRoomListManager.h>

// Unpin a single chat room
[[TAPCoreRoomListManager sharedManager] unpinChatRoomWithRoomID:ROOM_ID 
success:^(NSArray *roomIDs) {
    // Successfully unpinned chat room
} 
failure:^(NSError * _Nonnull error) {
        
}];

// Pin multiple chat rooms
[[TAPCoreRoomListManager sharedManager] unpinChatRoomsWithRoomIDs:ROOM_IDS
success:^(NSArray *roomIDs) {
    // Successfully unpinned chat rooms
} 
failure:^(NSError * _Nonnull error) {
        
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`ROOM_ID`**: (NSString) ID of the target room\
**`ROOM_IDS`**: (NSArray\<NsSString>) array containing IDs of target rooms
{% endhint %}

### Get Pinned Chat Rooms

You can retrieve the list of the active user's pinned chat room IDs from the server with `getPinnedChatRoomIDs`.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapCoreRoomListManager.h>

[[TAPCoreRoomListManager sharedManager] getPinnedChatRoomIDsWithSuccess:^(NSArray *pinnedRoomIDs) {
    // Returns list of roomID of the active user's pinned chat rooms
} 
failure:^(NSError * _Nonnull error) {
    
}];
```

{% endtab %}
{% endtabs %}


# Chat Room and Messages

You can implement manage chat room and messages with [TapUI](/powertalk-chat-sdk-documentation/powertalk-ios/group-chat/group-chat-tapui) or [TapCore](/powertalk-chat-sdk-documentation/powertalk-ios/group-chat/group-chat-tapcore).


# Chat Room and Messages - TapUI

You can use these methods when implementing your app with TapUI to open a chat room when UI implementation type is used.

| **TapTalk UI Chat Room Method**                                                                                                                                                                    | **Description**                                                                                                                         |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| [Create Personal Chat Room with User Model](#create-chat-room-with-user-model)                                                                                                                     | Creates room with user model. This method will return `TapUIChatViewController` on success.                                             |
| [Create Personal Chat Room with TapTalk.io User ID](#create-chat-room-with-taptalk.io-user-id)                                                                                                     | Creates room with TapTalk.io user ID. This method will return `TapUIChatViewController` on success.                                     |
| [Create Personal Chat Room with Client User ID](#create-chat-room-with-client-user-id)                                                                                                             | Creates room with client user ID. This method will return `TapUIChatViewController` on success.                                         |
| [Create Room with Room Model](/powertalk-chat-sdk-documentation/powertalk-ios/group-chat/group-chat-tapui#create-room-with-room-model)                                                             | Creates room with room model. This method will return `TapUIChatViewController` on success.                                             |
| [Create Room with Room Model & Scroll to Selected Message](/powertalk-chat-sdk-documentation/powertalk-ios/group-chat/group-chat-tapui#create-room-with-room-model-and-scroll-to-selected-message) | Creates room with room model. This method will return `TapUIChatViewController` on success and scroll the view to the selected message. |
| [Create Saved Messages Chat Room](#create-saved-messages-chat-room)                                                                                                                                | Creates the active user's Saved Messages chat room. This method will return `TapUIChatViewController` on success.                       |

{% hint style="info" %}
**Note:** You can get TapTalk.io current view controller or navigation controller to integrate to your current view controller by using [getCurrentTapTalkActiveViewController](/powertalk-chat-sdk-documentation/powertalk-ios/general#obtain-current-navigation-controller-in-tapui) method.
{% endhint %}

### Create Personal Chat Room with User Model

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapUI.h>

[TapUI sharedInstance] createRoomWithOtherUser:OTHER_USER success:^[(TapUIChatViewController * _Nonnull chatViewController) {
   // You can choose to present or push view controller
   
   // Present room list view
   [self presentViewController:chatViewController animated:YES completion:^{
        // Completion
   }];

   // Push room list view
   [self.navigationController pushViewController:chatViewController animated:YES];
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`OTHER_USER`**: (TAPUserModel) recipient user model that will be shown
{% endhint %}

### Create Personal Chat Room with TapTalk.io User ID

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapUI.h>

[[TapUI sharedInstance] createRoomWithUserID:USER_ID
                               prefilledText:PREFILLED_TEXT
                            customQuoteTitle:CUSTOM_QUOTE_TITLE
                          customQuoteContent:CUSTOM_QUOTE_CONTENT
                   customQuoteImageURLString:CUSTOM_QUOTE_IMAGE_URL_STRING
                                    userInfo:USER_INFO
success:^(TapUIChatViewController * _Nonnull chatViewController) {
    // Successfully created chat room
    // You can choose to present or push view controller
    
    // Present room list view
    [self presentViewController:chatViewController animated:YES completion:^{
        // Completion    
    }];

    // Push room list view
    [self.navigationController pushViewController:chatViewController animated:YES];
}
failure:^(NSError * _Nonnull error) {
    // Failed open room
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`USER_ID`**: (String) TapTalk.io user ID\
**`PREFILLED_TEXT`**: (String) prefilled text of message\
**`CUSTOM_QUOTE_TITLE`**: (String) title of custom quote data\
**`CUSTOM_QUOTE_CONTENT`**: (String) content / subtitle of custom quote data\
**`CUSTOM_QUOTE_IMAGE_URL_STRING`**: (String) image url string of custom quote image\
**`USER_INFO`**: (String) client-specified data or details of the custom quote
{% endhint %}

### Create Personal Chat Room with Client User ID

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapUI.h>

[[TapUI sharedInstance] createRoomWithXCUserID:XC_USER_ID
                                 prefilledText:PREFILLED_TEXT
                              customQuoteTitle:CUSTOM_QUOTE_TITLE
                            customQuoteContent:CUSTOM_QUOTE_CONTENT
                     customQuoteImageURLString:CUSTOM_QUOTE_IMAGE_URL_STRING
                                      userInfo:USER_INFO
success:^(TapUIChatViewController * _Nonnull chatViewController) {
    // Successfully created chat room
    // You can choose to present or push view controller
    
    // Present room list view
    [self presentViewController:chatViewController animated:YES completion:^{
        // Completion
    }];

    // Push room list view
    [self.navigationController pushViewController:chatViewController animated:YES];
  
}
failure:^(NSError * _Nonnull error) {
    // Failed open room
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`XC_USER_ID`**: (String) client user ID\
**`PREFILLED_TEXT`**: (String) prefilled text of message\
**`CUSTOM_QUOTE_TITLE`**: (String) title of custom quote data\
**`CUSTOM_QUOTE_CONTENT`**: (String) content / subtitle of custom quote data\
**`CUSTOM_QUOTE_IMAGE_URL_STRING`**: (String) image url string of custom quote image\
**`USER_INFO`**: (String) client-specified data or details of the custom quote
{% endhint %}

### Create Room with Room Model

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapUI.h>

[[TapUI sharedInstance] createRoomWithRoom:ROOM success:^(TapUIChatViewController * _Nonnull chatViewController) {
   // You can choose to present or push view controller
   
   // Present room list view
   [self presentViewController:chatViewController animated:YES completion:^{
        // Completion
   }];

   // Push room list view
   [self.navigationController pushViewController:chatViewController animated:YES];
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`ROOM`**: (TAPRoomModel) recipient room data model
{% endhint %}

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapUI.h>

[[TapUI sharedInstance] createRoomWithRoom:ROOM customQuoteTitle:CUSTOM_QUOTE_TITLE customQuoteContent:CUSTOM_QUOTE_CONTENT customQuoteImageURLString:CUSTOM_QUOTE_IMAGE_URL_STRING userInfo:USER_INFO success:^(TapUIChatViewController * _Nonnull chatViewController) {
   // You can choose to present or push view controller
   
   // Present room list view
   [self presentViewController:chatViewController animated:YES completion:^{
      // Completion
   }];

   // Push room list view
   [self.navigationController pushViewController:chatViewController animated:YES];
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`ROOM`**: (TAPRoomModel) recipient room data model\
**`CUSTOM_QUOTE_TITLE`**: (String) title of custom quote data\
**`CUSTOM_QUOTE_CONTENT`**: (String) content / subtitle of custom quote data\
**`CUSTOM_QUOTE_IMAGE_URL_STRING`**: (String) image url string of custom quote image\
**`USER_INFO`**: (String) client-specified data or details of the custom quote
{% endhint %}

### Create Room with Room Model & Scroll to Selected Message

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapUI.h>

[[TapUI sharedInstance] createRoomWithRoom:ROOM scrollToMessageWithLocalID:MESSAGE_LOCAL_ID] success:^(TapUIChatViewController * _Nonnull chatViewController) {
   // You can choose to present or push view controller
   // Present room list view
   [self presentViewController:chatViewController animated:YES completion:^{
       // Completion
   }];

   // Push room list view
   [self.navigationController pushViewController:chatViewController animated:YES];
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`ROOM`**: (TAPRoomModel) recipient room data model\
**`MESSAGE_LOCAL_ID`**: (String) scrolls the view to the message with the specified local ID when the chat room is opened
{% endhint %}

### Create Saved Messages Chat Room

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapUI.h>

[[TapUI sharedInstance] createSavedMessagesChatRoom:^(TapUIChatViewController * _Nonnull chatViewController) {
    // Successfully created Saved Messages chat room
  
    // You can choose to present or push view controller
    // Present room list view
    [self presentViewController:chatViewController animated:YES completion:^{
        // Completion    
    }];

    // Push room list view
    [self.navigationController pushViewController:chatViewController animated:YES];
}
failure:^(NSError * _Nonnull error) {
    // Failed to create room
}];
```

{% endtab %}
{% endtabs %}


# Chat Room and Messages - TapCore

If you are using core implementation method, you can use the methods below to manage chat room and messages.

{% hint style="warning" %}
**Note:** Please add **`#import <TapTalk/TAPCoreChatRoomManager.h>`** or \
**`#import <TapTalk/TAPCoreMessageManager.h>`** before using these methods.
{% endhint %}

<table data-header-hidden><thead><tr><th width="347">TapTalk Group Chat Method</th><th>Description</th></tr></thead><tbody><tr><td><strong>TapTalk Group Chat Method</strong></td><td><strong>Description</strong></td></tr><tr><td><a href="/powertalk-chat-sdk-documentation/powertalk-ios/group-chat/group-chat-tapcore#get-active-chat-room">Get Active Chat Room</a></td><td>Returns the room model of the currently active chat room.</td></tr><tr><td><a href="#get-personal-chat-room-with-recipient-user">Get Personal Chat Room with Recipient User</a></td><td>Create new personal chat room with recipient user, or obtain chat room data if it already exists.</td></tr><tr><td><a href="#get-personal-chat-room-with-recipient-user-id">Get Personal Chat Room with Recipient User ID</a></td><td>Create new personal chat room with recipient user ID, or obtain chat room data if it already exists</td></tr><tr><td><a href="#get-local-chat-room-data">Get Local Chat Room Data</a></td><td>Obtain locally saved chat room details with a roomID.</td></tr><tr><td><a href="/powertalk-chat-sdk-documentation/powertalk-ios/group-chat/group-chat-tapcore#create-group-chat-room">Create Group Chat Room</a></td><td>Create a new group chat room with selected group name.</td></tr><tr><td><a href="/powertalk-chat-sdk-documentation/powertalk-ios/group-chat/group-chat-tapcore#create-group-chat-room-1">Create Group Chat Room with Picture</a></td><td>Create a new group chat room with selected group name and group picture.</td></tr><tr><td><a href="/powertalk-chat-sdk-documentation/powertalk-ios/group-chat/group-chat-tapcore#get-group-chat-room">Get Group Chat Room</a></td><td>Get group room data from selected group room ID.</td></tr><tr><td><a href="/powertalk-chat-sdk-documentation/powertalk-ios/group-chat/group-chat-tapcore#update-group-chat-room-details">Update Group Chat Room Details</a></td><td>Update existing group chat room data.</td></tr><tr><td><a href="/powertalk-chat-sdk-documentation/powertalk-ios/group-chat/group-chat-tapcore#update-group-image">Update Group Image</a></td><td>Update group picture with current selected image.</td></tr><tr><td><a href="#delete-group-chat-room">Delete Local Group Chat Room</a></td><td>Delete group chat room from the device's local storage.</td></tr><tr><td><a href="/powertalk-chat-sdk-documentation/powertalk-ios/group-chat/group-chat-tapcore#delete-group-chat-room">Delete Group Chat Room</a></td><td>Delete group chat room and clear all chat data and participants.</td></tr><tr><td><a href="/powertalk-chat-sdk-documentation/powertalk-ios/group-chat/group-chat-tapcore#leave-group-chat">Leave Group Chat</a></td><td>Leave from selected group chat.</td></tr><tr><td><a href="/powertalk-chat-sdk-documentation/powertalk-ios/group-chat/group-chat-tapcore#add-members-to-group-chat">Add Members to Group Chat</a></td><td>Add selected member(s) to current group chat room.</td></tr><tr><td><a href="/powertalk-chat-sdk-documentation/powertalk-ios/group-chat/group-chat-tapcore#remove-members-from-group-chat">Remove Members from Group Chat</a></td><td>Remove selected member(s) from current group chat room.</td></tr><tr><td><a href="/powertalk-chat-sdk-documentation/powertalk-ios/group-chat/group-chat-tapcore#promote-group-admin">Promote Group Admin</a></td><td>Promote selected member(s) as admin(s) to the current group chat room.</td></tr><tr><td><a href="/powertalk-chat-sdk-documentation/powertalk-ios/group-chat/group-chat-tapcore#demote-group-admin">Demote Group Admin</a></td><td>Demote selected admin(s) to member(s) to the current group chat room.</td></tr><tr><td><a href="#get-saved-messages-chat-room">Get Saved Messages Chat Room</a></td><td>Obtain Saved Messages chat room data</td></tr><tr><td><a href="/powertalk-chat-sdk-documentation/powertalk-ios/group-chat/group-chat-tapcore#send-start-typing">Start Typing</a></td><td>Notify that the active user has started typing in the selected room.</td></tr><tr><td><a href="/powertalk-chat-sdk-documentation/powertalk-ios/group-chat/group-chat-tapcore#send-stop-typing">Stop Typing</a></td><td>Notify that the active user has stopped typing in the selected room.</td></tr><tr><td><a href="#send-text-message">Send Text Message</a></td><td>Send a new text message to the selected chat room.</td></tr><tr><td><a href="#send-location-message">Send Location Message</a></td><td>Send a new message with location to the selected chat room.</td></tr><tr><td><a href="#send-image-message">Send Image Message</a></td><td>Send a new image message to the selected chat room.</td></tr><tr><td><a href="#send-video-message">Send Video Message</a></td><td>Send a new video message to the selected chat room.</td></tr><tr><td><a href="#send-file-message">Send File Message</a></td><td>Send a new file message to the selected chat room.</td></tr><tr><td><a href="#send-file-message-1">Send Voice message</a></td><td>Send a new voice message to the selected chat room.</td></tr><tr><td><a href="#send-link-message">Send Link Message</a></td><td>Send a new link message to the selected chat room.</td></tr><tr><td><a href="#forward-a-message">Forward Message</a></td><td>Forward existing messages to the selected chat room.</td></tr><tr><td><a href="#construct-taptalk.io-message-model">Construct Message Model</a></td><td>Construct a customized TapTalk.io message model.</td></tr><tr><td><a href="/powertalk-chat-sdk-documentation/powertalk-ios/group-chat/group-chat-tapcore#send-a-custom-message">Send a Custom Message</a></td><td>Send a new custom message to the room defined in the message model.</td></tr><tr><td><a href="#edit-message">Edit Message</a></td><td>Edit the contents of the selected message</td></tr><tr><td><a href="#delete-message-from-local-cache">Delete Message</a></td><td>Delete the selected message from the server.</td></tr><tr><td><a href="/powertalk-chat-sdk-documentation/powertalk-ios/group-chat/group-chat-tapcore#delete-message-from-local-cache">Delete Message from Local Cache</a></td><td>Delete the selected message from local storage.</td></tr><tr><td><a href="/powertalk-chat-sdk-documentation/powertalk-ios/group-chat/group-chat-tapcore#cancel-message-file-upload">Cancel Message File Upload</a></td><td>Cancel image, video, or file upload on the selected pending message.</td></tr><tr><td><a href="/powertalk-chat-sdk-documentation/powertalk-ios/group-chat/group-chat-tapcore#download-message-file">Download Message File</a></td><td>Start a file download from the selected file, image, or video message.</td></tr><tr><td><a href="/powertalk-chat-sdk-documentation/powertalk-ios/group-chat/group-chat-tapcore#cancel-message-file-download">Cancel Message File Download</a></td><td>Cancel image, video, or file download on the selected message.</td></tr><tr><td><a href="#mark-message-as-delivered">Mark Message as Delivered</a></td><td>Mark message as delivered by the active user.</td></tr><tr><td><a href="/powertalk-chat-sdk-documentation/powertalk-ios/group-chat/group-chat-tapcore#mark-message-as-read">Mark Message as Read</a></td><td>Mark message as read by the active user.</td></tr><tr><td><a href="#mark-all-chat-room-messages-as-read">​Mark All Chat Room Messages as Read​</a></td><td>Mark all unread messages in a chat room as read.</td></tr><tr><td><a href="/powertalk-chat-sdk-documentation/powertalk-ios/group-chat/group-chat-tapcore#get-local-messages-from-chat-room">Get Local Messages from Chat Room</a></td><td>Retrieve messages from chat room that are already stored in the device's local storage.</td></tr><tr><td><a href="/powertalk-chat-sdk-documentation/powertalk-ios/group-chat/group-chat-tapcore#get-older-messages-from-chat-room">Get Older Messages from Chat Room</a></td><td>Retrieve messages that are older than the provided timestamp from the server to the selected chat room.</td></tr><tr><td><a href="/powertalk-chat-sdk-documentation/powertalk-ios/group-chat/group-chat-tapcore#get-newer-messages-from-chat-room">Get Newer Messages from Chat Room</a></td><td>Retrieve newer messages from the server to the selected chat room</td></tr><tr><td><a href="/powertalk-chat-sdk-documentation/powertalk-ios/group-chat/group-chat-tapcore#get-all-messages-from-chat-room">Get All Messages from Chat Room</a></td><td>Retrieve all available messages from the selected chat room.</td></tr><tr><td><a href="#get-unread-messages-from-chat-room">Get Unread Messages from Chat Room</a></td><td>Retrieve unread messages from the device's local storage.</td></tr><tr><td><a href="#get-media-messages-from-chat-room">Get Media Messages from Chat Room</a></td><td>Retrieve media messages from the device's local storage.</td></tr><tr><td><a href="#search-local-message">Search Local Message</a></td><td>Call this method to search messages from the device's local storage with a keyword</td></tr><tr><td><a href="#star-unstar-messages">​Star/Unstar Message</a>​</td><td>Set message as starred or remove star from message for the active user.</td></tr><tr><td><a href="#get-starred-messages">Get Starred Messages</a></td><td>Retrieve list of messages marked as starred in a chat room.</td></tr><tr><td><a href="#pin-unpin-message">Pin/Unpin Message</a></td><td>Set message as pinned or remove pin from message for all room participants.</td></tr><tr><td><a href="#get-pinned-messages">Get Pinned Messages</a></td><td>Retrieve list of pinned messages in a chat room.</td></tr><tr><td><a href="#get-shared-content-messages">Get Shared Content Messages</a></td><td>Retrieve image, video, file, and link messages from a chat room.</td></tr><tr><td><a href="#delete-all-chat-room-messages">Delete All Chat Room Messages</a></td><td>Clear all existing messages in a selected chat room for the active user.</td></tr><tr><td><a href="#create-scheduled-message">Create Scheduled Message</a></td><td>Schedule a message to be delivered at a specified time.</td></tr><tr><td><a href="#get-scheduled-messages">Get Scheduled Messages</a></td><td>Retrieve list of created scheduled messages in a chat room.</td></tr><tr><td><a href="#send-scheduled-message-now">Send Scheduled Message Now</a></td><td>Send a previously created scheduled message immediately to the recipient.</td></tr><tr><td><a href="#edit-scheduled-message-time">Edit Scheduled Message Time</a></td><td>Change the deliver time of a previously created scheduled message.</td></tr><tr><td><a href="#edit-scheduled-message-content">Edit Scheduled Message Content</a></td><td>Update the contents of a scheduled message that has not been delivered.</td></tr><tr><td><a href="#delete-scheduled-message">Delete Scheduled Message</a></td><td>Delete a scheduled message that has not been delivered.</td></tr><tr><td><a href="#get-message-details">Get Message Details</a></td><td>Retrieve info about a message's recipients that has read or received the message.</td></tr><tr><td><a href="#get-message-total-read-count">Get Message Total Read Count</a></td><td>Retrieve a message's total read count from a non-personal room.</td></tr></tbody></table>

### Get Active Chat Room

Returns the room model (TAPRoomModel) of the currently active chat room.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreChatRoomManager.h>

TAPRoomModel *activeRoom = [[TAPCoreChatRoomManager sharedManager] getActiveChatRoom];
```

{% endtab %}
{% endtabs %}

### Get Local Chat Room Data

Obtain locally saved chat room details with a roomID. Returns the saved room model or nil if it does not exist.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreChatRoomManager.h>

TAPRoomModel *room = [[TAPCoreChatRoomManager sharedManager] getLocalChatRoomData:roomID];
```

{% endtab %}
{% endtabs %}

### Create Group Chat Room

Create a new group chat room with selected group name.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreChatRoomManager.h>

[[TAPCoreChatRoomManager sharedManager] createGroupChatRoomWithGroupName:GROUP_NAME listOfParticipantUserIDs:PARTICIPANTS_USERID_ARRAY success:^(TAPRoomModel * _Nonnull room) {
    // Successfully created group chat room
}
failure:^(NSError * _Nonnull error) {
    // Failed to create group chat room
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`GROUP_NAME`**: (String) your group name\
**`PARTICIPANTS_USERID_ARRAY`**: (Array) list of participant userIDs
{% endhint %}

### Get Personal Chat Room with Recipient User

Create new personal chat room with recipient user, or obtain chat room data if it already exists.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreChatRoomManager.h>

[[TAPCoreChatRoomManager sharedManager] getPersonalChatRoomWithRecipientUser:RECIPIENT_USER success:^(TAPRoomModel * _Nonnull room) {
    // Successfully obtained chat room data
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`RECIPIENT_USER`**: (TAPUserModel) recipient user data
{% endhint %}

### Get Personal Chat Room with Recipient User ID

Create new personal chat room with recipient user ID, or obtain chat room data if it already exists.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreChatRoomManager.h>

[[TAPCoreChatRoomManager sharedManager] getPersonalChatRoomWithRecipientUserID:RECIPIENT_USER_ID success:^(TAPRoomModel * _Nonnull room) {
    // Successfully obtained chat room data
}
failure:^(NSError * _Nonnull error) {
    // Failed get chat room data
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`RECIPIENT_USER_ID`**: (String) user ID of recipient
{% endhint %}

### Create Group Chat Room

Create a new group chat room with selected group name and group picture.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreChatRoomManager.h>

[[TAPCoreChatRoomManager sharedManager] createGroupChatRoomWithGroupName:GROUP_NAME profilePicture:PROFILE_PICTURE listOfParticipantUserIDs:PARTICIPANTS_USER_ID_ARRAY success:^(TAPRoomModel * _Nonnull room, BOOL isSuccessUploadGroupPicture) {
    // Successfully created group chat room
}
failure:^(NSError * _Nonnull error) {
    // Failed to create group chat room
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`GROUP_NAME`**: (String) your group name\
**`PARTICIPANTS_USERID_ARRAY`**: (Array) list of participant userIDs\
**`PROFILE_PICTURE`**: (UIImage) group picture image
{% endhint %}

### Get Group Chat Room

Get group room data from selected group room ID.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreChatRoomManager.h>

[[TAPCoreChatRoomManager sharedManager] getGroupChatRoomWithGroupRoomID:GROUP_ROOM_ID success:^(TAPRoomModel * _Nonnull room) {
    // Successfully obtained group chat room
}
failure:^(NSError * _Nonnull error) {
    // Failed to fetch data
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`GROUP_ROOM_ID`**: (String) room ID of group
{% endhint %}

### Update Group Chat Room Details

Create a new Update existing group chat room data.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreChatRoomManager.h>
  
[[TAPCoreChatRoomManager sharedManager] updateGroupChatRoomDetailsWithGroupRoomID:GROUP_ROOM_ID groupName:GROUP_NAME success:^(TAPRoomModel * _Nonnull room) {
    // Successfully updated group chat room    
}
failure:^(NSError * _Nonnull error) {
    // Failed to update group chat room    
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`GROUP_ROOM_ID`**: (String) room ID of group\
**`GROUP_NAME`**: (String) name of group
{% endhint %}

### Update Group Image

Update group picture with current selected image.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreChatRoomManager.h>
  
[[TAPCoreChatRoomManager sharedManager] updateGroupPicture:GROUP_IMAGE roomID:GROUP_ROOM_ID successBlock:^(TAPRoomModel * _Nonnull room) {
    // Successfully updated group profile image
}
progressBlock:^(CGFloat progress, CGFloat total) {
    // Handle upload image progress
}
failureBlock:^(NSError * _Nonnull error) {
    // Failed to update group profile image
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`GROUP_IMAGE`**: (UIImage) image of group profile\
**`GROUP_ROOM_ID`**: (String) room ID of group
{% endhint %}

### Delete Local Group Chat Room

Delete group chat room from the device's local storage and clear all chat data and participants. Locally deleted room data will still be accessible from the server if the user remains a participant in the room.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreChatRoomManager.h>

[[TAPCoreChatRoomManager sharedManager] deleteLocalGroupChatRoom:ROOM_ID success:^{
    // Successfully deleted group chat room locally
}
failure:^(NSError * _Nonnull error) {
    // Failed to delete group chat room
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`ROOM_ID`**: (NSString) group room ID to be deleted
{% endhint %}

### Delete Group Chat Room

Delete group chat room and clear all chat data and participants.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreChatRoomManager.h>

[[TAPCoreChatRoomManager sharedManager] deleteGroupChatRoom:GROUP_ROOM success:^{
    // Successfully deleted group chat room
}
failure:^(NSError * _Nonnull error) {
    // Failed to delete group chat room
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`GROUP_ROOM`**: (TAPRoomModel) group room to be deleted
{% endhint %}

### Leave Group Chat

Leave from selected group chat.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreChatRoomManager.h>
  
[[TAPCoreChatRoomManager sharedManager] leaveGroupChatRoomWithRoomID:GROUP_ROOM_ID success:^{
    // Successfully left group chat room
}
failure:^(NSError * _Nonnull error) {
    // Failed to leave group chat room
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`GROUP_ROOM_ID`**: (String) room ID of group
{% endhint %}

### Add Members to Group Chat

Add selected member(s) to current group chat room.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreChatRoomManager.h>
  
[[TAPCoreChatRoomManager sharedManager] addGroupChatMembersWithUserIDArray:PARTICIPANTS_USER_ID_ARRAY roomID:GROUP_ROOM_ID success:^(TAPRoomModel * _Nonnull room) {
    // Successfully added members to group
}
failure:^(NSError * _Nonnull error) {
    // Failed to add members to group
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`PARTICIPANTS_USER_ID_ARRAY`**: (Array ) list of participant userIDs\
**`GROUP_ROOM_ID`**: (String) room ID of group
{% endhint %}

### Remove Members from Group Chat

Remove selected member(s) from current group chat room.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreChatRoomManager.h>
  
[[TAPCoreChatRoomManager sharedManager] removeGroupChatMembersWithUserIDArray:PARTICIPANTS_USER_ID_ARRAY roomID:GROUP_ROOM_ID success:^(TAPRoomModel * _Nonnull room) {
    // Successfully removed members from group
}
failure:^(NSError * _Nonnull error) {
    // Failed to remove members from group
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`PARTICIPANTS_USER_ID_ARRAY`**: (Array ) list of participant userIDs\
**`GROUP_ROOM_ID`**: (String) room ID of group
{% endhint %}

### Promote Group Admin

Promote selected member(s) as admin(s) to the current group chat room.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreChatRoomManager.h>
  
[[TAPCoreChatRoomManager sharedManager] promoteGroupAdminsWithUserIDArray:USER_ID_ARRAY roomID:GROUP_ROOM_ID success:^(TAPRoomModel * _Nonnull room) {
    // Successfully promoted member to admin
}
failure:^(NSError * _Nonnull error) {
    // Failed to promote member to admin
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`USER_ID_ARRAY`**: (Array ) list of userIDs\
**`GROUP_ROOM_ID`**: (String) room ID of group
{% endhint %}

### Demote Group Admin

Demote selected admin(s) to member(s) to the current group chat room.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreChatRoomManager.h>
  
[[TAPCoreChatRoomManager sharedManager] demoteGroupAdminsWithUserIDArray:USER_ID_ARRAY roomID:GROUP_ROOM_ID success:^(TAPRoomModel * _Nonnull room) {
    // Successfully demoted admin to member
}
failure:^(NSError * _Nonnull error) {
    // Failed to demote admin to member
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`USER_ID_ARRAY`**: (Array ) list of userIDs\
**`GROUP_ROOM_ID`**: (String) room ID of group
{% endhint %}

### Get Saved Messages Chat Room

Obtain Saved Messages chat room data.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreChatRoomManager.h>

[[TAPCoreChatRoomManager sharedManager] getSavedMessagesChatRoom:^(TAPRoomModel * _Nonnull room) {
   // Successfully obtained chat room data
}
failure:^(NSError * _Nonnull error) {
   // Failed to get chat room data
}];
```

{% endtab %}
{% endtabs %}

### Send Start Typing

Notify that the active user has started typing in the selected room.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreChatRoomManager.h>

[[TAPCoreChatRoomManager sharedManager] sendStartTypingEmitWithRoomID:GROUP_ROOM_ID];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`GROUP_ROOM_ID`**: (String) room ID of group
{% endhint %}

### Send Stop Typing

Notify that the active user has stopped typing in the selected room.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreChatRoomManager.h>

[[TAPCoreChatRoomManager sharedManager] sendStopTypingEmitWithRoomID:GROUP_ROOM_ID];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`GROUP_ROOM_ID`**: (String) room ID of group
{% endhint %}

### Send Text Message

To send a text message to a chat room, use the `sendTextMessage:room:start:success:failure:` method from the **TapCoreMessageManager** class.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

// Send text message
[[TAPCoreMessageManager sharedManager] sendTextMessage:MESSAGE_BODY
                                                  room:ROOM
start:^(TAPMessageModel * _Nonnull message) {
    // Message was constructed
}
success:^(TAPMessageModel * _Nonnull message) {
    // Message was sent successfully
}
failure:^(TAPMessageModel * _Nullable message, NSError * _Nonnull error) {
    // Failed to send message
}];
```

{% endtab %}
{% endtabs %}

Use the `sendTextMessage:quotedMessage:room:start:success:failure:` method to send a text message with quote.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

// Send text message with quote
[[TAPCoreMessageManager sharedManager] sendTextMessage:MESSAGE_BODY
                                         quotedMessage:QUOTED_MESSAGE
                                                  room:ROOM
start:^(TAPMessageModel * _Nonnull message) {
    // Message was constructed
}
success:^(TAPMessageModel * _Nonnull message) {
    // Message was sent successfully
}
failure:^(TAPMessageModel * _Nullable message, NSError * _Nonnull error) {
    // Failed to send message
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`MESSAGE_BODY`**: (String) content of the message\
**`ROOM`**: (TAPRoomModel) the destination room where the message will be sent\
**`QUOTED_MESSAGE`**: (TAPMessageModel) quote containing another existing message
{% endhint %}

### Send Location Message

You can send a location embedded in a chat message using `sendLocationMessageWithLatitude:longitude:address:room:start:success:failure:`. This method takes latitude, longitude, and address text as parameters.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

// Send location message
[[TAPCoreMessageManager sharedManager] sendLocationMessageWithLatitude:LATITUDE
                                                             longitude:LONGITUDE
                                                               address:ADDRESS
                                                                  room:ROOM
start:^(TAPMessageModel * _Nonnull message) {
    // Message was constructed  
}
success:^(TAPMessageModel * _Nonnull message) {
    // Message was sent successfully
}
failure:^(TAPMessageModel * _Nullable message, NSError * _Nonnull error) {
    // Failed to send message
}];
```

{% endtab %}
{% endtabs %}

Use the `sendLocationMessageWithLatitude:longitude:quotedMessage:address:room:start:success:failure:` method to send a location message with quote.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

// Send location message with quote
[[TAPCoreMessageManager sharedManager] sendLocationMessageWithLatitude:LATITUDE
                                                             longitude:LONGITUDE
                                                         quotedMessage:QUOTED_MESSAGE
                                                               address:ADDRESS
                                                                  room:ROOM
start:^(TAPMessageModel * _Nonnull message) {
    // Message was constructed  
}
success:^(TAPMessageModel * _Nonnull message) {
    // Message was sent successfully
}
failure:^(TAPMessageModel * _Nullable message, NSError * _Nonnull error) {
    // Failed to send message
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`LATITUDE`**: (Float) latitude of the shared location\
**`LONGITUDE`**: (Float) longitude of the shared location\
**`ADDRESS`**: (String) text data containing the location address\
**`ROOM`**: (TAPRoomModel) the destination room where the message will be sent\
**`QUOTED_MESSAGE`**: (TAPMessageModel) quote containing another existing message
{% endhint %}

### Send Image Message

To send an image to a chat room, you can use `sendImageMessage:` or `sendImageMessageWithAsset:` method by providing either `UIImage`, `PHAsset` , `IMAGE_ASSET_URL`, or  `IMAGE_URL` as parameter.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

// Send image using UIImage
[[TAPCoreMessageManager sharedManager] sendImageMessage:IMAGE
                                                caption:CAPTION
                                                  room:ROOM
start:^(TAPMessageModel * _Nonnull message) {
    // Message was constructed
}
progress:^(TAPMessageModel * _Nullable message, CGFloat progress, CGFloat total) {
    // Image upload is in progress
}
success:^(TAPMessageModel * _Nonnull message) {
    // Message was sent successfully
}
failure:^(TAPMessageModel * _Nullable message, NSError * _Nonnull error) {
    // Failed to send message
}];
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

// Send image using PHAsset
[[TAPCoreMessageManager sharedManager] sendImageMessageWithAsset:IMAGE_ASSET
                                                         caption:CAPTION
                                                            room:ROOM
start:^(TAPMessageModel * _Nonnull message) {
    // Message was constructed
}
progress:^(TAPMessageModel * _Nullable message, CGFloat progress, CGFloat total) {
    // Image upload is in progress
}
success:^(TAPMessageModel * _Nonnull message) {
    // Message was sent successfully
}
failure:^(TAPMessageModel * _Nullable message, NSError * _Nonnull error) {
    // Failed to send message
}];
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

// Send image using image asset URL
[[TAPCoreMessageManager sharedManager] sendImageMessageWithURL:IMAGE_ASSET_URL
                                                       caption:CAPTION
                                                          room:ROOM
start:^(TAPMessageModel * _Nonnull message) {
    // Message was constructed
}
progress:^(TAPMessageModel * _Nullable message, CGFloat progress, CGFloat total) {
    // Image upload is in progress
}
success:^(TAPMessageModel * _Nonnull message) {
    // Message was sent successfully
}
failure:^(TAPMessageModel * _Nullable message, NSError * _Nonnull error) {
    // Failed to send message
}];
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

// Send image using remote image URL
[[TAPCoreMessageManager sharedManager] sendImageMessageWithRemoteUrl:IMAGE_URL
                                                             caption:CAPTION
                                                                room:ROOM
                                                       fetchMetadata:FETCH_METADATA
temporaryMessageCreated:^(TAPMessageModel * _Nonnull message) {
    // Temporary message was created while fetching metadata
    // This callback will be called when FETCH_METADATA is true
}
start:^(TAPMessageModel * _Nonnull message) {
    // Message was constructed
}
success:^(TAPMessageModel * _Nonnull message) {
    // Message was sent successfully
}
failure:^(TAPMessageModel * _Nullable message, NSError * _Nonnull error) {
    // Failed to send message
}];
```

{% endtab %}
{% endtabs %}

Use the `sendImageMessage:` or `sendImageMessageWithAsset:` or `sendImageMessageWithRemoteUrl:` method with extra parameter to send an image message with quote.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

// Send image using UIImage with quote
[[TAPCoreMessageManager sharedManager] sendImageMessage:IMAGE
                                          quotedMessage:QUOTED_MESSAGE
                                                caption:CAPTION
                                                  room:ROOM
start:^(TAPMessageModel * _Nonnull message) {
    // Message was constructed
}
progress:^(TAPMessageModel * _Nullable message, CGFloat progress, CGFloat total) {
    // Image upload is in progress
}
success:^(TAPMessageModel * _Nonnull message) {
    // Message was sent successfully
}
failure:^(TAPMessageModel * _Nullable message, NSError * _Nonnull error) {
    // Failed to send message
}];
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

// Send image using PHAsset with quote
[[TAPCoreMessageManager sharedManager] sendImageMessageWithAsset:IMAGE_ASSET
                                                   quotedMessage:QUOTED_MESSAGE
                                                         caption:CAPTION
                                                            room:ROOM
start:^(TAPMessageModel * _Nonnull message) {
    // Message was constructed
}
progress:^(TAPMessageModel * _Nullable message, CGFloat progress, CGFloat total) {
    // Image upload is in progress
}
success:^(TAPMessageModel * _Nonnull message) {
    // Message was sent successfully
}
failure:^(TAPMessageModel * _Nullable message, NSError * _Nonnull error) {
    // Failed to send message
}];
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

// Send image using image asset URL with quote
[[TAPCoreMessageManager sharedManager] sendImageMessageWithURL:IMAGE_ASSET_URL
                                                 quotedMessage:QUOTED_MESSAGE
                                                       caption:CAPTION
                                                          room:ROOM
start:^(TAPMessageModel * _Nonnull message) {
    // Message was constructed
}
progress:^(TAPMessageModel * _Nullable message, CGFloat progress, CGFloat total) {
    // Image upload is in progress
}
success:^(TAPMessageModel * _Nonnull message) {
    // Message was sent successfully
}
failure:^(TAPMessageModel * _Nullable message, NSError * _Nonnull error) {
    // Failed to send message
}];
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

// Send image using remote image URL with quote
[[TAPCoreMessageManager sharedManager] sendImageMessageWithRemoteUrl:IMAGE_URL
                                                             caption:CAPTION
                                                                room:ROOM
                                                       quotedMessage:QUOTED_MESSAGE
                                                       fetchMetadata:FETCH_METADATA
temporaryMessageCreated:^(TAPMessageModel * _Nonnull message) {
    // Temporary message was created while fetching metadata
    // This callback will be called when FETCH_METADATA is true
}
start:^(TAPMessageModel * _Nonnull message) {
    // Message was constructed
}
success:^(TAPMessageModel * _Nonnull message) {
    // Message was sent successfully
}
failure:^(TAPMessageModel * _Nullable message, NSError * _Nonnull error) {
    // Failed to send message
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`IMAGE`**: (UIImage) selected image with **`UIImage`** type\
**`IMAGE_ASSET`**: (PHAsset) selected image asset data\
**`IMAGE_ASSET_URL`**: (NSURL) local URL of the image asset\
**`IMAGE_URL`**: (String) remote URL of the image\
**`CAPTION`**: (String) caption for the image\
**`ROOM`**: (TAPRoomModel) the destination room where the message will be sent\
**`QUOTED_MESSAGE`**: (TAPMessageModel) quote containing another existing message\
**`FETCH_METADATA`**: (BOOL) inserts metadata from remote URL to the constructed message when true
{% endhint %}

### Send Video Message

To send a video to a chat room, you can use `sendVideoMessageWithAsset:` method by providing the `VIDEO_ASSET`, `VIDEO_ASSET_URL`, or a remote `VIDEO_URL` as parameter.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

// Send video using video asset (PHAsset)
[[TAPCoreMessageManager sharedManager] sendVideoMessageWithAsset:VIDEO_ASSET
                                                         caption:CAPTION
                                                            room:ROOM
start:^(TAPMessageModel * _Nonnull message) {
    // Message was constructed
}
progress:^(TAPMessageModel * _Nullable message, TAPMessageModel * _Nullable message, CGFloat progress, CGFloat total) {
    // Video upload is in progress
}
success:^(TAPMessageModel * _Nonnull message) {
    // Message was sent successfully
}
failure:^(TAPMessageModel * _Nullable message, NSError * _Nonnull error) {
    // Failed to send message
}];
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

// Send video using video asset URL
[[TAPCoreMessageManager sharedManager] sendVideoMessageWithVideoAssetURL:VIDEO_ASSET_URL
                                                                 caption:CAPTION
                                                                    room:ROOM
start:^(TAPMessageModel * _Nonnull message) {
    // Message was constructed
}
progress:^(TAPMessageModel * _Nullable message, TAPMessageModel * _Nullable message, CGFloat progress, CGFloat total) {
    // Video upload is in progress
}
success:^(TAPMessageModel * _Nonnull message) {
    // Message was sent successfully
}
failure:^(TAPMessageModel * _Nullable message, NSError * _Nonnull error) {
    // Failed to send message
}];
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

// Send video using remote video URL
[[TAPCoreMessageManager sharedManager] sendVideoMessageWithRemoteUrl:VIDEO_URL
                                                             caption:CAPTION
                                                                room:ROOM 
                                                       fetchMetaData:FETCH_METADATA
temporaryMessageCreated:^(TAPMessageModel * _Nonnull message) {
    // Temporary message was created while fetching metadata
    // This callback will be called when FETCH_METADATA is true
}
start:^(TAPMessageModel * _Nonnull message) {
    // Message was constructed
}
success:^(TAPMessageModel * _Nonnull message) {
    // Message was sent successfully
}
failure:^(TAPMessageModel * _Nullable message, NSError * _Nonnull error) {
    // Failed to send message
}];
```

{% endtab %}
{% endtabs %}

Use the send video method with extra parameter to send a video message with quote.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

// Send video using video asset (PHAsset) with quote
[[TAPCoreMessageManager sharedManager] sendVideoMessageWithAsset:VIDEO_ASSET
                                                   quotedMessage:QUOTED_MESSAGE
                                                         caption:CAPTION
                                                            room:ROOM
start:^(TAPMessageModel * _Nonnull message) {
    // Message was constructed
}
progress:^(TAPMessageModel * _Nullable message, TAPMessageModel * _Nullable message, CGFloat progress, CGFloat total) {
    // Video upload is in progress
}
success:^(TAPMessageModel * _Nonnull message) {
    // Message was sent successfully
}
failure:^(TAPMessageModel * _Nullable message, NSError * _Nonnull error) {
    // Failed to send message
}];
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

// Send video using video asset URL with quote
[[TAPCoreMessageManager sharedManager] sendVideoMessageWithVideoAssetURL:VIDEO_ASSET_URL
                                                           quotedMessage:QUOTED_MESSAGE
                                                                 caption:CAPTION
                                                                    room:ROOM
start:^(TAPMessageModel * _Nonnull message) {
    // Message was constructed
}
progress:^(TAPMessageModel * _Nullable message, TAPMessageModel * _Nullable message, CGFloat progress, CGFloat total) {
    // Video upload is in progress
}
success:^(TAPMessageModel * _Nonnull message) {
    // Message was sent successfully
}
failure:^(TAPMessageModel * _Nullable message, NSError * _Nonnull error) {
    // Failed to send message
}];
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

// Send video using remote video URL with quote
[[TAPCoreMessageManager sharedManager] sendVideoMessageWithRemoteUrl:VIDEO_URL
                                                             caption:CAPTION
                                                                room:ROOM
                                                       quotedMessage:QUOTED_MESSAGE
                                                       fetchMetaData:FETCH_METADATA
temporaryMessageCreated:^(TAPMessageModel * _Nonnull message) {
    // Temporary message was created while fetching metadata
    // This callback will be called when FETCH_METADATA is true
}
start:^(TAPMessageModel * _Nonnull message) {
    // Message was constructed
}
success:^(TAPMessageModel * _Nonnull message) {
    // Message was sent successfully
}
failure:^(TAPMessageModel * _Nullable message, NSError * _Nonnull error) {
    // Failed to send message
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`VIDEO_ASSET`**: (PHAsset) selected videos asset data\
**`VIDEO_ASSET_URL`**: (NSURL) local URL of the video asset\
**`VIDEO_URL`**: (String) remote URL of the video\
**`CAPTION`**: (String) caption for the video\
**`ROOM`**: (TAPRoomModel) the destination room where the message will be sent\
**`QUOTED_MESSAGE`**: (TAPMessageModel) quote containing another existing message\
**`FETCH_METADATA`**: (BOOL) inserts metadata from remote URL to the constructed message when true
{% endhint %}

### Send File Message

You can also send a file to a chat room using `sendFileMessageWithFileURI:` or `sendFileMessageWithRemoteUrl:`.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

// Send file using file asset URL
[[TAPCoreMessageManager sharedManager] sendFileMessageWithFileURI:FILE_ASSET_URL
                                                             room:ROOM
start:^(TAPMessageModel * _Nonnull message) {
    // Message was constructed
} 
progress:^(TAPMessageModel * _Nullable message, CGFloat progress, CGFloat total) {
    // File upload is in progress
}
success:^(TAPMessageModel * _Nonnull message) {
    // Message was sent successfully
}
failure:^(TAPMessageModel * _Nullable message, NSError * _Nonnull error) {
    // Failed to send message
}];
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

// Send file using remote file URL
[[TAPCoreMessageManager sharedManager] sendFileMessageWithRemoteUrl:FILE_URL
                                                            caption:CAPTION
                                                               room:ROOM
                                                      fetchMetadata:FETCH_METADATA
temporaryMessageCreated:^(TAPMessageModel * _Nonnull message) {
    // Temporary message was created while fetching metadata
    // This callback will be called when FETCH_METADATA is true
}
start:^(TAPMessageModel * _Nonnull message) {
    // Message was constructed
}
success:^(TAPMessageModel * _Nonnull message) {
    // Message was sent successfully
}
failure:^(TAPMessageModel * _Nullable message, NSError * _Nonnull error) {
    // Failed to send message
}];
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

// Send file using remote file URL, file name, and mime type
[[TAPCoreMessageManager sharedManager] sendFileMessageWithRemoteUrl:FILE_URL
                                                            caption:CAPTION
                                                               room:ROOM
                                                           fileName:FILE_NAME
                                                           mimeType:MIME_TYPE
                                                      fetchMetadata:FETCH_METADATA
temporaryMessageCreated:^(TAPMessageModel * _Nonnull message) {
    // Temporary message was created while fetching metadata
    // This callback will be called when FETCH_METADATA is true
}
start:^(TAPMessageModel * _Nonnull message) {
    // Message was constructed
}
success:^(TAPMessageModel * _Nonnull message) {
    // Message was sent successfully
}
failure:^(TAPMessageModel * _Nullable message, NSError * _Nonnull error) {
    // Failed to send message
}];
```

{% endtab %}
{% endtabs %}

Use the send file method with extra parameter to send a file message with quote.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

// Send file using file asset URL with quote
[[TAPCoreMessageManager sharedManager] sendFileMessageWithFileURI:FILE_ASSET_URL
                                                    quotedMessage:QUOTED_MESSAGE
                                                             room:ROOM
start:^(TAPMessageModel * _Nonnull message) {
    // Message was constructed
} 
progress:^(TAPMessageModel * _Nullable message, CGFloat progress, CGFloat total) {
    // File upload is in progress
}
success:^(TAPMessageModel * _Nonnull message) {
    // Message was sent successfully
}
failure:^(TAPMessageModel * _Nullable message, NSError * _Nonnull error) {
    // Failed to send message
}];
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

// Send file using remote file URL with quote
[[TAPCoreMessageManager sharedManager] sendFileMessageWithRemoteUrl:FILE_URL
                                                            caption:CAPTION
                                                               room:ROOM
                                                      quotedMessage:QUOTED_MESSAGE
                                                      fetchMetadata:FETCH_METADATA
temporaryMessageCreated:^(TAPMessageModel * _Nonnull message) {
    // Temporary message was created while fetching metadata
    // This callback will be called when FETCH_METADATA is true
}
start:^(TAPMessageModel * _Nonnull message) {
    // Message was constructed
}
success:^(TAPMessageModel * _Nonnull message) {
    // Message was sent successfully
}
failure:^(TAPMessageModel * _Nullable message, NSError * _Nonnull error) {
    // Failed to send message
}];
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

// Send file using remote file URL, file name, and mime type with quote
[[TAPCoreMessageManager sharedManager] sendFileMessageWithRemoteUrl:FILE_URL
                                                            caption:CAPTION
                                                               room:ROOM
                                                      quotedMessage:QUOTED_MESSAGE
                                                           fileName:FILE_NAME
                                                           mimeType:MIME_TYPE
                                                      fetchMetadata:FETCH_METADATA
temporaryMessageCreated:^(TAPMessageModel * _Nonnull message) {
    // Temporary message was created while fetching metadata
    // This callback will be called when FETCH_METADATA is true
}
start:^(TAPMessageModel * _Nonnull message) {
    // Message was constructed
}
success:^(TAPMessageModel * _Nonnull message) {
    // Message was sent successfully
}
failure:^(TAPMessageModel * _Nullable message, NSError * _Nonnull error) {
    // Failed to send message
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`FILE_ASSET_URL`**: (NSURL) file path of the selected file\
**`FILE_URL`**: (String) remote URL of the video\
**`CAPTION`**: (String) caption for the video\
**`ROOM`**: (TAPRoomModel) the destination room where the message will be sent\
**`QUOTED_MESSAGE`**: (TAPMessageModel) quote containing another existing message\
**`FILE_NAME`**: (String) file name to be included in message data\
**`MIME_TYPE`**: (String) mime type to be included in message data, set to empty to fetch default mime type from the provided URL\
**`FETCH_METADATA`**: (BOOL) inserts metadata from remote URL to the constructed message when true
{% endhint %}

### Send Voice Message

You can also send a voice note to a chat room using the `sendVoiceMessageWithFileURI:` method with a provided `FILE_URI` (`NSURL`).

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

[[TAPCoreMessageManager sharedManager] sendVoiceMessageWithFileURI:AUDIO_ASSET_URL
                                                              room:ROOM
start:^(TAPMessageModel * _Nonnull message) {
    // Message was constructed
}
progress:^(TAPMessageModel * _Nullable message, CGFloat progress, CGFloat total) {
    // File upload is in progress
}
success:^(TAPMessageModel * _Nonnull message) {
    // Message was sent successfully
}
failure:^(TAPMessageModel * _Nullable message, NSError * _Nonnull error) {
    // Failed to send message
}];
```

{% endtab %}
{% endtabs %}

Use the `sendVoiceMessageWithFileURI:` method with extra parameter to send a voice message with quote.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

[[TAPCoreMessageManager sharedManager] sendVoiceMessageWithFileURI:AUDIO_ASSET_URL
                                                     quotedMessage:QUOTED_MESSAGE
                                                              room:ROOM
start:^(TAPMessageModel * _Nonnull message) {
    // Message was constructed
}
progress:^(TAPMessageModel * _Nullable message, CGFloat progress, CGFloat total) {
    // File upload is in progress
}
success:^(TAPMessageModel * _Nonnull message) {
    // Message was sent successfully
}
failure:^(TAPMessageModel * _Nullable message, NSError * _Nonnull error) {
    // Failed to send message
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`AUDIO_ASSET_URL`**: (NSURL) file path of the selected audio\
**`CAPTION`**: (String) caption for the video\
**`ROOM`**: (TAPRoomModel) the destination room where the message will be sent\
**`QUOTED_MESSAGE`**: (TAPMessageModel) quote containing another existing message
{% endhint %}

### Send Link Message

You can send a link message, which is usually composed of a text message with URL on the body, using the `sendLinkMessage:` method.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

// Send link message
[[TAPCoreMessageManager sharedManager] sendLinkMessage:MESSAGE_BODY
                                                  room:ROOM
                                                  urls:URLS
                                                 title:TITLE
                                           description:DESCRIPTION
                                                 image:IMAGE
start:^(TAPMessageModel * _Nonnull message) {
    // Message was constructed
}
success:^(TAPMessageModel * _Nonnull message) {
    // Message was sent successfully
}
failure:^(TAPMessageModel * _Nullable message, NSError * _Nonnull error) {
    //Failed send link message
}];
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

// Send link message with additional metadata parameters
[[TAPCoreMessageManager sharedManager] sendLinkMessage:MESSAGE_BODY
                                                  room:ROOM
                                                  urls:URLS
                                                 title:TITLE
                                           description:DESCRIPTION
                                                 image:IMAGE
                                              siteName:SITE_NAME
                                                  type:TYPE
start:^(TAPMessageModel * _Nonnull message) {
    // Message was constructed
}
success:^(TAPMessageModel * _Nonnull message) {
    // Message was sent successfully
}
failure:^(TAPMessageModel * _Nullable message, NSError * _Nonnull error) {
    // Failed to send message
}];
```

{% endtab %}
{% endtabs %}

Use the `sendLinkMessage:` method with extra parameters to send a link message with quote.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

// Send link message with quote
[[TAPCoreMessageManager sharedManager] sendLinkMessage:MESSAGE_BODY
                                         quotedMessage:QUOTED_MESSAGE
                                                  room:ROOM
                                                  urls:URLS
                                                 title:TITLE
                                           description:DESCRIPTION
                                                 image:IMAGE
start:^(TAPMessageModel * _Nonnull message) {
    // Message was constructed
}
success:^(TAPMessageModel * _Nonnull message) {
    // Message was sent successfully
}
failure:^(TAPMessageModel * _Nullable message, NSError * _Nonnull error) {
    // Failed to send message
}];
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

// Send link message with quote and additional metadata parameters
[[TAPCoreMessageManager sharedManager] sendLinkMessage:MESSAGE_BODY
                                         quotedMessage:QUOTED_MESSAGE
                                                  room:ROOM
                                                  urls:URLS
                                                 title:TITLE
                                           description:DESCRIPTION
                                                 image:IMAGE
                                              siteName:SITE_NAME
                                                  type:TYPE
start:^(TAPMessageModel * _Nonnull message) {
    // Message was constructed
}
success:^(TAPMessageModel * _Nonnull message) {
    // Message was sent successfully
}
failure:^(TAPMessageModel * _Nullable message, NSError * _Nonnull error) {
    // Failed to send message
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`MESSAGE_BODY`**: (String) content of the message\
**`ROOM`**: (TAPRoomModel) the destination room where the message will be sent\
**`QUOTED_MESSAGE`**: (TAPMessageModel) quote containing another existing message\
**`URLS`**: (NSArray\<String>) list of URLs contained in the message\
**`TITLE`**: (String) `og:title` metadata of the specified URL\
**`DESCRIPTION`**: (String) `og:description` metadata of the specified URL\
**`IMAGE`**: (String) `og:image` metadata of the specified URL\
**`SITE_NAME`**: (String) `og:site_name` metadata of the specified URL\
**`TYPE`**: (String) `og:type` metadata of the specified URL
{% endhint %}

### Forward Message

To forward existing messages to chat room, call the `sendForwardedMessage:` method. You may also use `sendForwardedMessageWithMessageArray:` to forward multiple messages at once, or `sendForwardedMessage:toMultipleRooms:` or `sendForwardedMessageWithMessageArray:toMultipleRooms:` to forward messages to multiple rooms at once.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

// Forward a message
[[TAPCoreMessageManager sharedManager] sendForwardedMessage:MESSAGE_TO_FORWARD 
                                                       room:ROOM
start:^(TAPMessageModel * _Nonnull message) {
    // Message was constructed
} 
progress:^(TAPMessageModel * _Nullable message, CGFloat progress, CGFloat total) {

} 
success:^(TAPMessageModel * _Nonnull message) {
    // Message was forwarded successfully
} 
failure:^(TAPMessageModel * _Nullable message, NSError * _Nonnull error) {
    // Failed to forward message
}];
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

// Forward multiple messages at once
[[TAPCoreMessageManager sharedManager] sendForwardedMessageWithMessageArray:MESSAGES_TO_FORWARD
                                                                       room:ROOM 
start:^(TAPMessageModel * _Nonnull message) {
    // Message was constructed
} 
progress:^(TAPMessageModel * _Nullable message, CGFloat progress, CGFloat total) {

} 
success:^(TAPMessageModel * _Nonnull message) {
    // Message was forwarded successfully
} 
failure:^(TAPMessageModel * _Nullable message, NSError * _Nonnull error) {
    // Failed to forward message
}];
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

// Forward a message to multiple chat rooms
[[TAPCoreMessageManager sharedManager] sendForwardedMessage:MESSAGE_TO_FORWARD 
                                            toMultipleRooms:ROOMS
start:^(TAPMessageModel * _Nonnull message) {
    // Message was constructed
} 
progress:^(TAPMessageModel * _Nullable message, CGFloat progress, CGFloat total) {

} 
success:^(TAPMessageModel * _Nonnull message) {
    // Message was forwarded successfully
} 
failure:^(TAPMessageModel * _Nullable message, NSError * _Nonnull error) {
    // Failed to forward message
}];
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

// Forward multiple messages to multiple chat rooms at once
[[TAPCoreMessageManager sharedManager] sendForwardedMessageWithMessageArray:MESSAGES_TO_FORWARD 
                                                            toMultipleRooms:ROOMS
start:^(TAPMessageModel * _Nonnull message) {
    // Message was constructed
} 
progress:^(TAPMessageModel * _Nullable message, CGFloat progress, CGFloat total) {
    // Progress forward message
} 
success:^(TAPMessageModel * _Nonnull message) {
    // Message was forwarded successfully
} 
failure:^(TAPMessageModel * _Nullable message, NSError * _Nonnull error) {
    // Failed to forward message
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`MESSAGE_TO_FORWARD`**: (TAPMessageModel) existing message to be forwarded\
**`MESSAGES_TO_FORWARD`**: (NSArray\<TAPMessageModel>) array of messages to be forwarded\
**`ROOM`**: (TAPRoomModel) the destination room where the message will be forwarded\
**`ROOMS`**: (NSArray\<TAPRoomModel>) list of destination rooms where the message will be forwarded
{% endhint %}

### Construct TapTalk.io Message Model

You can construct your own customized message model to be used in chat as shown below.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

TAPMessageModel *constructedMessage = [[TAPCoreMessageManager sharedManager] constructTapTalkMessageModelWithRoom:ROOM messageBody:MESSAGE_BODY messageType:MESSAGE_TYPE messageData:MESSAGE_DATA];
```

{% endtab %}
{% endtabs %}

To construct a custom message with quote, use the `constructTapTalkMessageModelWithRoom:quotedMessage:` method.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

TAPMessageModel *constructedMessage = [[TAPCoreMessageManager sharedManager] constructTapTalkMessageModelWithRoom:ROOM quotedMessage:QUOTED_MESSAGE messageBody:MESSAGE_BODY messageType:MESSAGE_TYPE messageData:MESSAGE_DATA];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`MESSAGE_BODY`**: (String) content of the message\
**`ROOM`**: (TAPRoomModel) the destination room where the message will be sent\
**`MESSAGE_TYPE`**: (Integer) type of your custom message, check the [Message Type page](/powertalk-chat-sdk-documentation/powertalk-ios/message-type) for more information\
**`MESSAGE_DATA`**: (NSDictionary) custom data for the message (optional)\
**`QUOTED_MESSAGE`**: (TAPMessageModel) quote of the new message model containing another existing message
{% endhint %}

{% hint style="info" %}
**Note**: you are free to put any data that you need for your custom message in the **`MESSAGE_DATA`** parameter, to obtain message data from a **`TAPMessageModel`**, look into the **`data`** property of **`TAPMessageModel`** (message.data).
{% endhint %}

### Send a Custom Message

To send a custom message that you just created above, call the `sendCustomMessageWithMessageModel:` method with the custom message as a parameter.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

[[TAPCoreMessageManager sharedManager] sendCustomMessageWithMessageModel:CUSTOM_MESSAGE start:^(TAPMessageModel * _Nonnull message) {
    // Returns constructed custom message
}
success:^(TAPMessageModel * _Nonnull message) {
    // Successfully sent custom message
}
failure:^(TAPMessageModel * _Nullable message, NSError * _Nonnull error) {
    // Failed to send custom message
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`CUSTOM_MESSAGE`**: (TAPMessageModel) the message to be sent, see the [Construct TapTalk.io Message Model](/powertalk-chat-sdk-documentation/powertalk-ios/group-chat/group-chat-tapcore#construct-taptalk-io-message-model) section to construct a custom message
{% endhint %}

### Edit Message

To update the contents of a message, you may use the `editMessage:` method from **TapCoreMessageManager** class. Editing is currently available for text message and image or video message caption.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

[[TAPCoreMessageManager sharedManager] editMessage:self.currentEditingMessage
                                       updatedText:currentMessage
start:^(TAPMessageModel * _Nonnull message) {
    // Message is being processed
}
success:^(TAPMessageModel * _Nonnull message) {
    // Message was edited successfully
}
failure:^(TAPMessageModel * _Nullable message, NSError *error) {
    // Failed to edit message
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`MESSAGE_MODEL`**: (TAPMessageModel) the message to be updated\
**`UPDATED_TEXT`**: (NSString) new text to replace the body and caption of the message
{% endhint %}

### Delete Message

To delete a message permanently from the server, call `deleteMessage:` from **TapCoreMessageManager** class. When the message is successfully deleted, **TapCoreMessageManagerDelegate** will invoke `tapTalkDidDeleteMessage:` delegate.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>
  
[[TAPCoreMessageManager sharedManager] deleteMessage:MESSAGE_MODEL success:^{
    // Successfully deleted message    
}
failure:^(TAPMessageModel * _Nullable message, NSError * _Nonnull error) {
    // Failed to delete message
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`MESSAGE_MODEL`**: (TAPMessageModel) the message to be deleted
{% endhint %}

### Delete Message from Local Cache

To delete a message from local cache, call `deleteLocalMessageWithLocalID:` from **TapCoreMessageManager** class.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>
  
[[TAPCoreMessageManager sharedManager] deleteLocalMessageWithLocalID:MESSAGE_LOCAL_ID success:^{
    // Successfully deleted message
}
failure:^(TAPMessageModel * _Nullable message, NSError * _Nonnull error) {
    // Failed to delete message    
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`MESSAGE_LOCAL_ID`**: (String) local ID of the message to delete
{% endhint %}

### Cancel Message File Upload

Messages such as **Image**, **Video**, and **File** messages requires a file upload completion before the message is sent. To cancel an ongoing file upload of a message, call the `cancelMessageFileUpload:` method.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>
  
[[TAPCoreMessageManager sharedManager] cancelMessageFileUpload:MESSAGE success:^{
    // Successfully cancelled upload    
}
failure:^(TAPMessageModel * _Nullable message, NSError * _Nonnull error) {
    // Failed to cancel upload
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`MESSAGE`**: (TAPMessageModel) pending message with ongoing file upload
{% endhint %}

### Download Message File

To start a file download from a **File**, **Image**, or **Video** message, you can use these methods below based on what type of message you wish to download.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

// Download file from a message
[[TAPCoreMessageManager sharedManager] downloadMessageFile:MESSAGE
start:^{
    // File download started
}
progress:^(TAPMessageModel * _Nullable message, CGFloat progress, CGFloat total) {
    // File download in progress
}
success:^(NSData * _Nonnull fileData) {
    // Successfully downloaded file
    // Returns NSData
}
failure:^(TAPMessageModel * _Nullable message, NSError * _Nonnull error) {
    // Failed to download file    
}];


// Download image from a message
[[TAPCoreMessageManager sharedManager] downloadMessageImage:MESSAGE
start:^{
    // Image download started
}
progress:^(TAPMessageModel * _Nullable message, CGFloat progress, CGFloat total) {
    // Image download in progress
}
success:^(UIImage * _Nonnull fullImage) {
    // Successfully downloaded image
    // Returns UIImage
}
failure:^(TAPMessageModel * _Nullable message, NSError * _Nonnull error) {
    // Failed to download image    
}];


//Download video from a message
[[TAPCoreMessageManager sharedManager] downloadMessageVideo:MESSAGE start:^{
    // Video download started
}
progress:^(TAPMessageModel * _Nullable message, CGFloat progress, CGFloat total) {
    // Video download in progress    
}
success:^(NSData * _Nonnull fileData) {
    // Successfully downloaded video
    // Returns NSData
}
failure:^(TAPMessageModel * _Nullable message, NSError * _Nonnull error) {
    // Failed to download video    
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`MESSAGE`**: (TAPMessageModel) existing message to download the file from
{% endhint %}

### Cancel Message File Download

You can cancel download message with type such as **Image**, **Video**, and **File** by calling the `cancelMessageFileDownload:` method.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>
  
[[TAPCoreMessageManager sharedManager] cancelMessageFileDownload:MESSAGE success:^{
    // Successfully cancelled file download    
}
failure:^(TAPMessageModel * _Nullable message, NSError * _Nonnull error) {
    // Failed to cancel file download
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`MESSAGE`**: (TAPMessageModel) selected message with ongoing file download
{% endhint %}

### Mark Message as Delivered

To manually mark a message as delivered, call the `markMessageAsDelivered:` method.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

[[TAPCoreMessageManager sharedManager] markMessageAsDelivered:MESSAGE];
```

{% endtab %}
{% endtabs %}

### Mark Message as Read

To manually mark a message as read, call the `markMessageAsRead:` method. You can also mark multiple messages as read at once using `markMessagesAsRead:`.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

// Mark single message as read
[[TAPCoreMessageManager sharedManager] markMessageAsRead:MESSAGE];

// Mark multiple messages as read
[[TAPCoreMessageManager sharedManager] markMessageAsRead:MESSAGE_ARRAY];

// Mark multiple messages as read with completion handler
[[TAPCoreMessageManager sharedManager] markMessageAsRead:MESSAGE_ARRAY 
success:^(NSArray<NSString *> *updatedMessageIDs){
    // updatedMessageIDs contains message IDs that were successfully marked as read
} 
failure:^(NSError *error) {
             
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`MESSAGE`**: (TAPMessageModel) existing message to be marked as read\
**`MESSAGE_ARRAY`**: (NSArray\<TAPMessageModel>) array of message models to be marked as read
{% endhint %}

### Mark All Chat Room Messages as Read

To quickly mark all unread messages in a chat room as read, call `markAllMessageInRoomAsRead:` method.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

// Mark all unread messages in specified chat room as read
[[TAPCoreMessageManager sharedManager] markAllMessagesInRoomAsReadWithRoomID:ROOM_ID];


// Mark all unread messages in specified chat room as read with completion listener
[[TAPCoreMessageManager sharedManager] markAllMessagesInRoomAsReadWithRoomID:ROOM_ID
success:^(NSArray<NSString *> *updatedMessageIDs){
    // updatedMessageIDs contains message IDs that were successfully marked as read
} 
failure:^(NSError *error) {
             
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`ROOM_ID`**: (NSString) room ID of the messages to be marked as read
{% endhint %}

### Get Local Messages from Chat Room

In a chat room, you can retrieve messages that are already stored in the device's local storage by calling `getLocalMessagesWithRoomID:` method.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
// import TapTalk Message Manager
#import <TapTalk/TAPCoreMessageManager.h>

[TAPCoreMessageManager sharedManager] getLocalMessagesWithRoomID:ROOM_ID
success:^(NSArray<TAPMessageModel *> * _Nonnull messageArray) {
    // Successfully obtained messages
}
failure:^(NSError * _Nonnull error) {
    // Failed to get messages
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`ROOM_ID`**: (NSString) the room ID to retrieve the messages for
{% endhint %}

Retrieving local messages is fast and reliable, but may not contain all messages available in the selected chat room. To obtain more messages that are available from the server, you may use `getOlderMessagesBeforeTimestamp:` and `getNewerMessagesAfterTimestamp:` methods.

### Get Older Messages from Chat Room

To retrieve older messages in a chat room from the server, use the `getOlderMessagesBeforeTimestamp:` method.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

[[TAPCoreMessageManager sharedManager] getOlderMessagesBeforeTimestamp:MAX_CREATED_TIMESTAMP
                                                                roomID:ROOM_ID
                                                         numberOfItems:NUMBER_OF_ITEMS
success:^(NSArray<TAPMessageModel *> * _Nonnull messageArray, BOOL hasMoreData) {
    // hasMoreData will return true if more messages that have not been retrieved remain in the chat room
}
failure:^(NSError * _Nonnull error) {
    
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`ROOM_ID`**: (NSString) the room ID to retrieve the messages for\
**`MAX_CREATED_TIMESTAMP`**: (NSNumber) the maximum created time of the messages to retrieve, in milliseconds\
**`NUMBER_OF_ITEMS`**: (NSNumber) maximum limit of the number of messages to retrieve
{% endhint %}

### Get Newer Messages from Chat Room

To retrieve newer messages in a chat room from the server, use the `getNewerMessagesAfterTimestamp:` method.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

[[TAPCoreMessageManager sharedManager] getNewerMessagesAfterTimestamp:MIN_CREATED_TIMESTAMP
                                                 lastUpdatedTimestamp:LAST_UPDATE_TIMESTAMP
                                                               roomID:ROOM_ID
                                                        numberOfItems:NUMBER_OF_ITEMS
success:^(NSArray<TAPMessageModel *> * _Nonnull messageArray) {
  
}
failure:^(NSError * _Nonnull error) {
    
}];
```

{% endtab %}
{% endtabs %}

You can also call `getNewerMessagesWithRoomID:` without providing `MIN_CREATED_TIMESTAMP` and `LAST_UPDATE_TIMESTAMP`, only providing `ROOM_ID` as the parameter. With this method, `MIN_CREATED_TIMESTAMP` will automatically be set to the oldest existing message's created time in the room, and `LAST_UPDATE_TIMESTAMP` will be obtained from local cache.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

[[TAPCoreMessageManager sharedManager] getNewerMessagesWithRoomID:ROOM_ID
success:^(NSArray<TAPMessageModel *> * _Nonnull messageArray) {
  
}
failure:^(NSError * _Nonnull error) {
    
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`ROOM_ID`**: (NSString) the room ID to retrieve the messages for\
**`MIN_CREATED_TIMESTAMP`**: (NSNumber) the minimum created time of the messages to retrieve, in millisecond\
**`LAST_UPDATE_TIMESTAMP`**: (NSNumber) the minimum updated time of the messages to retrieve, in milliseconds\
**`NUMBER_OF_ITEMS`**: (NSNumber) maximum limit of the number of messages to retrieve<br>
{% endhint %}

### Get All Messages from Chat Room

You may also retrieve all available messages from a chat room using the `getAllMessagesWithRoomID:` method.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

[TAPCoreMessageManager sharedManager] getAllMessagesWithRoomID:ROOM_ID
successLocalMessages:^(NSArray<TAPMessageModel *> * _Nonnull messageArray) {
    // Retrieved local messages from room
}
successAllMessages:^(NSArray<TAPMessageModel *> * _Nonnull allMessagesArray, NSArray<TAPMessageModel *> * _Nonnull olderMessagesArray, NSArray<TAPMessageModel *> * _Nonnull newerMessagesArray) {
    // Successfully retrieved all messages from room 
}
failure:^(NSError * _Nonnull error) {
    
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`ROOM_ID`**: (NSString) the room ID to retrieve the messages for
{% endhint %}

`getAllMessagesWithRoomID:` is convenient to obtain all existing chat room messages since the beginning of the room creation, but the process **will take longer** depending on the number of messages contained in the selected room.\
\
This method will trigger two success blocks sequentially during the process of retrieving messages:\
• `successLocalMessages:` will be triggered first once local messages are retrieved, the process will then continue to retrieve more messages from the server.\
• `successAllMessages:` will be triggered after all messages from the server are successfully retrieved, this callback contains three parameters containing **all messages**, **older messages** (that did not exist in local storage), and **newer messages** that have recently been updated, the latter two parameters might be empty depending on the situation.

### Get Unread Messages from Chat Room

You can retrieve unread messages from the device's local storage by calling `getUnreadMessagesFromRoom:` method.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

[TAPCoreMessageManager sharedManager] getUnreadMessagesFromRoom:ROOM_ID
success:^(NSArray<TAPMessageModel *> * _Nonnull unreadMessageArray) {
        
}
failure:^(NSError * _Nonnull error) {
    
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`ROOM_ID`**: (NSString) the room ID to retrieve the messages from
{% endhint %}

### Get Media Messages from Chat Room

You can also retrieve media messages from the device's local storage, which consists of **image**, **video**, and **documents**, by calling `getMediaMessagesFromRoom:` method.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

[TAPCoreMessageManager sharedManager] getMediaMessagesFromRoom:ROOM_ID 
                                                 lastTimestamp:LAST_TIMESTAMP 
                                                  numberOfItem:NUMBER_OF_ITEM 
success:^(NSArray<TAPMessageModel *> * _Nonnull unreadMessageArray) {
        
} 
failure:^(NSError * _Nonnull error) {
    
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`ROOM_ID`**: (NSString) the room ID to retrieve the messages from\
**`LAST_TIMESTAMP`**: (NSNumber)  the maximum created time of the messages to retrieve, in milliseconds\
**`NUMBER_OF_ITEMS`**: (NSNumber) maximum limit of the number of messages to retrieve
{% endhint %}

### Search Local Message

Call this method to search messages from the device's local storage with a keyword. Provided keyword will be used to filter **message body** in the search result.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

[TAPCoreMessageManager sharedManager] searchLocalMessageWithKeyword:KEYWORD
success:^(NSArray<TAPMessageModel *> * _Nonnull messageArray) {
    // Returns filtered messages obtained from local storage    
}
failure:^(NSError * _Nonnull error) {
    
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`KEYWORD`**: (String) search keyword to filter message body
{% endhint %}

### Star/Unstar Messages

You may use these methods to mark a message or multiple messages as starred, or remove messages from the starred list. Only the active user can retrieve his/her own starred messages.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

// Star single message
[[TAPCoreMessageManager sharedManager] starMessageWithMessageID:MESSAGE_ID 
                                                         roomID:ROOM_ID 
success:^(NSArray<NSString *> * _Nonnull starredMessagesIDs) {
    // Returns list of messageID of starred messages
} 
failure:^(NSError * _Nonnull error) {
                            
}];


// Star multiple messages
[[TAPCoreMessageManager sharedManager] starMessagesWithMessageIDs:MESSAGE_IDS 
                                                           roomID:ROOM_ID 
success:^(NSArray<NSString *> * _Nonnull starredMessagesIDs) {
    // Returns list of messageID of starred messages
} 
failure:^(NSError * _Nonnull error) {
                            
}];


// Unstar single message
[[TAPCoreMessageManager sharedManager] unstarMessageWithMessageID:MESSAGE_ID 
                                                           roomID:ROOM_ID 
success:^(NSArray<NSString *> * _Nonnull unstarredMessagesIDs) {
    // Returns list of messageID of unstarred messages
} 
failure:^(NSError * _Nonnull error) {
                            
}];


// Unstar multiple messages
[[TAPCoreMessageManager sharedManager] unstarMessagesWithMessageIDs:MESSAGE_IDS 
                                                             roomID:ROOM_ID 
success:^(NSArray<NSString *> * _Nonnull unstarredMessagesIDs) {
    // Returns list of messageID of unstarred messages
} 
failure:^(NSError * _Nonnull error) {
                            
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`ROOM_ID`**: (NSString) room ID, can be obtained from the message's room model\
**`MESSAGE_ID`**: (NSString) unique server ID from the message\
**`MESSAGE_IDS`**: (NSArray\<NSString>) list containing message IDs to be starred/unstarred
{% endhint %}

### Get Starred Messages

You can use the method below get a list of message IDs marked as starred by the user.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

[[TAPCoreMessageManager sharedManager] getStarredMessageIDsWithRoomID:ROOM_ID 
success:^(NSArray<NSString *> * _Nonnull starredMessagesIDs) {
    // Returns list of messageID of starred messages
} 
failure:^(NSError * _Nonnull error) {
        
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`ROOM_ID`**: (NSString) ID of the target room
{% endhint %}

A method to obtain the full message model list of the starred messages with pagination is also provided.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

[[TAPCoreMessageManager sharedManager] getStarredMessagesWithRoomID:ROOM_ID 
                                                         pageNumber:PAGE_NUMBER
                                                      numberOfItems:NUMBER_OF_ITEMS 
success:^(NSArray<TAPMessageModel *> * _Nonnull starredMessagesArray, BOOL hasMoreData) {
    // hasMoreData will return YES if the room has remaining starred messages that have not been retrieved
} 
failure:^(NSError * _Nonnull error) {
    
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`ROOM_ID`**: (NSString) ID of the target room\
**`PAGE_NUMBER`**: (NSInteger) the number of page to retrieve the items\
**`NUMBER_OF_ITEMS`**: (NSInteger) number of items to be retrieved
{% endhint %}

### Pin/Unpin Message

You may use these methods to pin or unpin a message or multiple messages in a chat room. Every participant in the room can retrieve the chat room's pinned messages.&#x20;

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

// Pin single message
[[TAPCoreMessageManager sharedManager] pinMessageWithMessageID:MESSAGE_ID 
                                                        roomID:ROOM_ID 
success:^(NSArray<NSString *> * _Nonnull pinnedMessagesIDs) {
    // Returns list of messageID of pinned messages
} 
failure:^(NSError * _Nonnull error) {
                            
}];


// Pin multiple messages
[[TAPCoreMessageManager sharedManager] pinMessagesWithMessageIDs:MESSAGE_IDS 
                                                          roomID:ROOM_ID 
success:^(NSArray<NSString *> * _Nonnull pinnedMessagesIDs) {
    // Returns list of messageID of pinned messages
} 
failure:^(NSError * _Nonnull error) {
                            
}];


// Unpin single message
[[TAPCoreMessageManager sharedManager] unpinMessageWithMessageID:MESSAGE_ID 
                                                          roomID:ROOM_ID 
success:^(NSArray<NSString *> * _Nonnull unpinnedMessagesIDs) {
    // Returns list of messageID of unpinned messages
} 
failure:^(NSError * _Nonnull error) {
                            
}];


// Unpin multiple messages
[[TAPCoreMessageManager sharedManager] unpinMessagesWithMessageIDs:MESSAGE_IDS 
                                                            roomID:ROOM_ID 
success:^(NSArray<NSString *> * _Nonnull unpinnedMessagesIDs) {
    // Returns list of messageID of unpinned messages
} 
failure:^(NSError * _Nonnull error) {
                            
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`ROOM_ID`**: (NSString) room ID, can be obtained from the message's room model\
**`MESSAGE_ID`**: (NSString) unique server ID from the message\
**`MESSAGE_IDS`**: (NSArray\<NSString>) list containing message IDs to be pinned/unpinned
{% endhint %}

### Get Pinned Messages

You can use the method below get a list of message IDs of pinned messages in a chat room.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

[[TAPCoreMessageManager sharedManager] getPinnedMessageIDsWithRoomID:ROOM_ID 
success:^(NSArray<NSString *> * _Nonnull pinnedMessagesIDs) {
    // Returns list of messageID of pinned messages
} 
failure:^(NSError * _Nonnull error) {
        
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`ROOM_ID`**: (NSString) ID of the target room
{% endhint %}

A method to obtain the full message model list of the pinned messages with pagination is also provided.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

[[TAPCoreMessageManager sharedManager] getPinnedMessagesWithRoomID:ROOM_ID 
                                                        pageNumber:PAGE_NUMBER
                                                     numberOfItems:NUMBER_OF_ITEMS 
success:^(NSArray<TAPMessageModel *> * _Nonnull pinnedMessagesArray, BOOL hasMoreData) {
    // hasMoreData will return YES if the room has remaining pinned messages that have not been retrieved
} 
failure:^(NSError * _Nonnull error) {
    
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`ROOM_ID`**: (NSString) ID of the target room\
**`PAGE_NUMBER`**: (NSInteger) the number of page to retrieve the items\
**`NUMBER_OF_ITEMS`**: (NSInteger) number of items to be retrieved
{% endhint %}

### Get Shared Content Messages

You can retrieve media-type messages, consisting of image, video, file, and link messages from a chat room by using `getSharedContentMessages` method.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

[[TAPCoreMessageManager sharedManager] getSharedContentMessagesWithRoomID:ROOM_ID 
                                                               maxCreated:MAX_CREATED_TIMESTAMP
                                                               minCreated:MAX_CREATED_TIMESTAMP
success:^(NSArray<TAPMessageModel *> * mediaMessagesArray, NSArray<TAPMessageModel *> * fileMessagesArray, NSArray<TAPMessageModel *> * linkMessagesArray) {
    // mediaMessagesArray contains image and video messages
    // fileMessagesArray contains file/document messages
    // linkMessagesArray contains link messages
} 
failure:^(NSError * _Nonnull error) {
    
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`ROOM_ID`**: (NSString) ID of the target room\
**`MIN_CREATED_TIMESTAMP`**: (long) smallest created time of the messages to retrieve, use 0L to retrieve up to the oldest message in the room\
**`MAX_CREATED_TIMESTAMP`**: (long) largest created time of the messages to retrieve, use current timestamp to retrieve up to the newest message in the room
{% endhint %}

### Delete All Chat Room Messages

Use the **`deleteAllChatRoomMessages:`** method from the **TapCoreChatRoomManager** class to clear all existing messages in a selected chat room for the active user. The selected messages will only be deleted for the active user, and will not affect the other participants in the selected room.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapCoreChatRoomManager.h>

[[TAPCoreChatRoomManager sharedManager] deleteAllChatRoomMessages:ROOM_ID success:^(NSArray * _Nonnull deletedRoomIDs) {
    // Successfully deleted all messages in the chat room
}
failure:^(NSError * _Nonnull error) {
        
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`ROOM_ID`**: (NSString) ID of the target room
{% endhint %}

### Create Scheduled Message

You can schedule a constructed message model to be delivered at a specified time to a chat room.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

// Construct a TapTalk message model to be scheduled
TAPMessageModel *constructedMessage = [[TAPCoreMessageManager sharedManager] constructTapTalkMessageModelWithRoom:ROOM 
                                                                                                      messageBody:MESSAGE_BODY 
                                                                                                      messageType:MESSAGE_TYPE 
                                                                                                      messageData:MESSAGE_DATA];

// Schedule the constructed message
[[TAPCoreMessageManager sharedManager] createScheduleMessage:constructedMessage
                                                scheduleTime:TIMESTAMP
success:^(TAPMessageModel * _Nonnull message) {
    // Successfully created a scheduled message
}
failure:^(NSError * _Nonnull error) {
    
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`MESSAGE_BODY`**: (String) content of the message\
**`ROOM`**: (TAPRoomModel) the destination room where the message will be sent\
**`MESSAGE_TYPE`**: (Integer) type of your custom message, check the [Message Type page](/powertalk-chat-sdk-documentation/powertalk-ios/message-type) for more information\
**`MESSAGE_DATA`**: (NSDictionary) custom data for the message (optional)\
**`QUOTED_MESSAGE`**: (TAPMessageModel) quote of the new message model containing another existing message\
**`TIMESTAMP`**: (NSNumber) time when the message will be delivered to the destination room (long value)
{% endhint %}

### Get Scheduled Messages

You may then retrieve the list of created scheduled messages that have not yet been delivered in a chat room.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

[[TAPCoreMessageManager sharedManager] getScheduledMessagesWithRoomID:ROOM_ID
success:^(NSArray<TAPScheduledMessageModel *> * _Nonnull scheduleMessageArray) {
    // Successfully retrieved scheduled messages
}
failure:^(NSError * _Nonnull error) {
    
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`ROOM_ID`**: (NSString) ID of the destination chat room
{% endhint %}

### Send Scheduled Message Now

You may also send a previously created scheduled message immediately to the recipient.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

// Send a scheduled message immediately
[[TAPCoreMessageManager sharedManager] sendScheduledMessageNow:SCHEDULED_MESSAGE_ID
                                                        roomID:ROOM_ID
success:^(NSArray<NSNumber *> * _Nonnull sentIDs) {
    // Successfully sent scheduled message
}
failure:^(NSError * _Nonnull error) {
    
}];

// Send multiple scheduled messages immediately
[[TAPCoreMessageManager sharedManager] sendScheduledMessagesNow:SCHEDULED_MESSAGE_IDS
                                                         roomID:ROOM_ID
success:^(NSArray<NSNumber *> * _Nonnull sentIDs) {
    // Successfully sent scheduled messages
}
failure:^(NSError * _Nonnull error) {
    
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`SCHEDULED_MESSAGE_ID`**: (NSNumber) ID of the previously created scheduled message\
**`SCHEDULED_MESSAGE_IDS`**: (NSArray\<NSNumber>) array of scheduled message IDs\
**`ROOM_ID`**: (NSString) ID of the destination chat room
{% endhint %}

### Edit Scheduled Message Time

To change the deliver time of a previously created scheduled message, use the **`editScheduledMessageTime:`** method from **TAPCoreMessageManager**.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

[[TAPCoreMessageManager sharedManager] editScheduledMessageTime:SCHEDULED_MESSAGE_ID 
                                                  scheduledTime:TIMESTAMP
success:^(BOOL isEditTimeSuccess) {
    // Successfully edited scheduled message
}
failure:^(NSError * _Nonnull error) {
    
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`SCHEDULED_MESSAGE_ID`**: (NSNumber) ID of the previously created scheduled message\
**`TIMESTAMP`**: (NSNumber) time when the message will be delivered to the destination room (long value)
{% endhint %}

### Edit Scheduled Message Content

You may also update the contents of a scheduled message that was previously created before it is delivered to the recipient.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

[[TAPCoreMessageManager sharedManager] editScheduledMessageContent:SCHEDULED_MESSAGE_ID
                                                    updatedMessage:MESSAGE
success:^(BOOL isEditContentSuccess) {
    // Successfully edited scheduled message
}
failure:^(NSError * _Nonnull error) {
    
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`SCHEDULED_MESSAGE_ID`**: (NSNumber) ID of the previously created scheduled message\
**`MESSAGE`**: (TAPMessageModel) message model with updated values
{% endhint %}

### Delete Scheduled Message

To cancel sending a scheduled message that has not been delivered, you can delete it using **`deleteScheduledMessage`** method.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

[[TAPCoreMessageManager sharedManager] deleteScheduledMessage:SCHEDULED_MESSAGE_ID
                                                       roomID:ROOM_ID
success:^(NSArray<NSNumber *> * _Nonnull deletedIDs) {
    // Successfully deleted scheduled message
}
failure:^(NSError * _Nonnull error) {
    
}];

[[TAPCoreMessageManager sharedManager] deleteScheduledMessages:SCHEDULED_MESSAGE_IDS
                                                        roomID:ROOM_ID
success:^(NSArray<NSNumber *> * _Nonnull deletedIDs) {
    // Successfully deleted scheduled messages
}
failure:^(NSError * _Nonnull error) {
    
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`SCHEDULED_MESSAGE_ID`**: (NSNumber) ID of the previously created scheduled message\
**`SCHEDULED_MESSAGE_IDS`**: (NSArray\<NSNumber>) array of scheduled message IDs\
**`ROOM_ID`**: (NSString) ID of the destination chat room
{% endhint %}

### Get Message Details

You can retrieve info about a message's recipients that has read or received the message.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

[[TAPCoreMessageManager sharedManager] getMessageDetails:MESSAGE_ID
success:^(TAPMessageModel *message, NSArray<TapMessageRecipientModel *> *deliveredTo, NSArray<TapMessageRecipientModel *> *readBy) {
    // Successfully retrieved message info
    // message: the message model
    // deliveredTo: list of recipients that has received the message
    // readBy: list of recipients that has read the message
}
failure:^(NSError * _Nonnull error) {
    
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`MESSAGE_ID`**: (String) unique server ID from the message
{% endhint %}

### Get Message Total Read Count

You can also retrieve a message's total read count from a non-personal room.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPCoreMessageManager.h>

[[TAPCoreMessageManager sharedManager] getMessageTotalRead:MESSAGE_ID
success:^(NSInteger readCount) {
    // Successfully retrieved message read count
}
failure:^(NSError * _Nonnull error) {
    
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`MESSAGE_ID`**: (String) unique server ID from the message
{% endhint %}


# Contact

If your application is using the core implementation type, you can use these methods to manage your user's contacts.

{% hint style="warning" %}
**Note:** Please add **`#import <TapTalk/TapCoreContactManager.h>`** before using these methods.
{% endhint %}

| **TapTalk Contact Method**                                                                                                                           | **Description**                                                                   |
| ---------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- |
| [Get Contact List](/powertalk-chat-sdk-documentation/powertalk-ios/contact#get-contact-list)                                                         | Get all of the user's contact data from TapTalk.io.                               |
| [Fetch All User Contacts from Server](#fetch-all-user-contacts-from-server)                                                                          | Fetch the user's latest contact data from TapTalk.io server                       |
| [Get Contact Detail Info with TapTalk User ID](/powertalk-chat-sdk-documentation/powertalk-ios/contact#get-contact-detail-info-with-taptalk-user-id) | Get a detailed contact info with selected TapTalk.io user ID.                     |
| [Get Contact Detail Info with Client User ID](/powertalk-chat-sdk-documentation/powertalk-ios/contact#get-contact-detail-info-with-client-user-id)   | Get a detailed contact info with selected Client user ID (xcUserID).              |
| [Add User to Contact with User ID](/powertalk-chat-sdk-documentation/powertalk-ios/contact#add-user-to-contact-with-user-id)                         | Add a user with selected TapTalk.io user ID to the active user's contacts.        |
| [Add User to Contact with Phone Number](/powertalk-chat-sdk-documentation/powertalk-ios/contact#add-user-to-contact-with-phone-number)               | Add a user with selected phone number to the active user's contacts.              |
| [Remove User from Contact](/powertalk-chat-sdk-documentation/powertalk-ios/contact#remove-user-from-contact)                                         | Remove a user with selected TapTalk.io user ID from the active user's contacts.   |
| [Save User Data](/powertalk-chat-sdk-documentation/powertalk-ios/contact#save-user-data)                                                             | Save or update existing user data to local cache.                                 |
| [Search Local Contact](#search-local-contact)                                                                                                        | Search the active user's contacts from the device's local storage with a keyword. |
| [Report User](#report-user)                                                                                                                          | Submit a report for a selected user.                                              |
| [Report Message](#report-message)                                                                                                                    | Submit a report for a selected message.                                           |
| [Block User](#block-user)                                                                                                                            | Block a user from sending or receiving messages.                                  |
| [Unblock User](#unblock-user)                                                                                                                        | Unblock a blocked user.                                                           |
| [Get Blocked User List](#get-blocked-user-list)                                                                                                      | Retrieve a list of blocked users.                                                 |
| [Get Blocked User IDs](#get-blocked-user-ids)                                                                                                        | Retrieve a list of IDs from blocked users.                                        |
| [Get Groups in Common](#get-groups-in-common)                                                                                                        | Retrieve the list of groups in common with another user.                          |

### Get Contact List

Create a new group Get all of the user's contact data from TapTalk.io.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapCoreContactManager.h>

[[TAPCoreContactManager sharedManager] getAllUserContactsWithSuccess:^(NSArray<TAPUserModel *> * _Nonnull userArray) {
    // Successfully fetched contact list data
}
failure:^(NSError * _Nonnull error) {
    // Failed to get contact list data
}];
```

{% endtab %}
{% endtabs %}

### Fetch All User Contacts from Server

Calling `fetchAllUserContactsFromServer` will fetch the user's latest contact data from TapTalk.io server and syncs it to the device's local storage.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapCoreContactManager.h>

[[TAPCoreContactManager sharedManager] fetchAllUserContactsFromServerWithSuccess:^(NSArray<TAPUserModel *> * _Nonnull userArray) {
    // Successfully fetched contact list data
}
failure:^(NSError * _Nonnull error) {
    // Failed to get contact list data
}];
```

{% endtab %}
{% endtabs %}

### Get Contact Detail Info with TapTalk User ID

Get a detailed contact info with selected TapTalk.io user ID.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapCoreContactManager.h>

[[TAPCoreContactManager sharedManager] getUserDataWithUserID:USER_ID
success:^(TAPUserModel * _Nonnull user) {
    // Successfully obtained contact details
}
failure:^(NSError * _Nonnull error) {
    // Failed to get contact details
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`USER_ID`**: (String) Taptalk.io User ID of the selected user
{% endhint %}

### Get Contact Detail Info with Client User ID

Get a detailed contact info with selected Client user ID (xcUserID).

{% tabs %}
{% tab title="Objective-C" %}

```csharp
//import TapTalk Contact Manager
#import <TapTalk/TapCoreContactManager.h>

[[TAPCoreContactManager sharedManager] getUserDataWithXCUserID:XC_USER_ID
success:^(TAPUserModel * _Nonnull user) {
    // Successfully obtained contact details
}
failure:^(NSError * _Nonnull error) {
    // Failed to get contact details
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`XC_USER_ID`**: (String) Client User ID of the selected user
{% endhint %}

### Add User to Contacts with User ID

Add a user with selected TapTalk.io user ID to the active user's contacts.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapCoreContactManager.h>

[[TAPCoreContactManager sharedManager] addToTapTalkContactsWithUserID:USER_ID
success:^{
    // Successfully added contact
}
failure:^(NSError * _Nonnull error) {
    // Failed to add contact
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`USER_ID`**: (String) Taptalk.io User ID of the contact to be added
{% endhint %}

### Add User to Contacts with Phone Number

Add a user with selected phone number to the active user's contacts.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapCoreContactManager.h>

[[TAPCoreContactManager sharedManager] addToTapTalkContactsWithPhoneNumber:PHONE_NUMBER
success:^{
    // Successfully added contact
}
failure:^(NSError * _Nonnull error) {
    // Failed to add contact
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`PHONE_NUMBER`**: (String) phone number of the contact to be added
{% endhint %}

### Remove User from Contacts

Remove a user with selected TapTalk.io user ID from the active user's contacts.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapCoreContactManager.h>

[[TAPCoreContactManager sharedManager] removeFromTapTalkContactsWithUserID:USER_ID
success:^(NSString * _Nonnull successMessage) {
    // Successfully removed contact
}
failure:^(NSError * _Nonnull error) {
    // Failed to remove contact
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`USER_ID`**: (String) Taptalk.io User ID of the contact to remove.
{% endhint %}

### Save User Data

Save or update existing user data to local cache.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapCoreContactManager.h>

[[TAPCoreContactManager sharedManager] saveUserData:USER];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`USER`**: (TAPUserModel) the user data model to be saved
{% endhint %}

### Search Local Contact

Call this method to search the active user's contacts from the device's local storage with a keyword. Provided keyword will be used to filter the contacts' **full name** in the search result.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapCoreContactManager.h>

[[TAPCoreContactManager sharedManager] searchLocalContactsByName:KEYWORD
success:^(NSArray<TAPUserModel *> * _Nonnull userArray) {
    // Returns filtered contacts
}
failure:^(NSError * _Nonnull error) {
    // Failed to get contact list data
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`KEYWORD`**: (String) search keyword to filter full name
{% endhint %}

### Report User

You may call this method to submit a report for a selected user. Submitted reports can then be viewed through the dashboard.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapCoreContactManager.h>

[[TAPCoreContactManager sharedManager] reportUser:USER_ID 
                                         category:CATEGORY
                                  isOtherCategory:IS_OTHER_CATEGORY
                                           reason:REASON
success:^(BOOL isSuccess) {
    // Successfully reported user
}
failure:^(NSError * _Nonnull error) {

}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`USER_ID`**: (String) ID of the user to report\
**`CATEGORY`**: (String) Category of the violation. max length is 100 characters\
**`IS_OTHER_CATEGORY`**: (Boolean) If the category is other than the predefined categories\
**`REASON`**: (String) reason why the user is reported
{% endhint %}

### Report Message

You may call this method to submit a report for a selected message. Submitted reports can then be viewed through the dashboard.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapCoreContactManager.h>

[[TAPCoreContactManager sharedManager] reportMessage:MESSAGE_ID 
                                              roomID:ROOM_ID
                                            category:CATEGORY
                                     isOtherCategory:IS_OTHER_CATEGORY
                                              reason:REASON
success:^(BOOL isSuccess) {
    // Successfully reported message
}
failure:^(NSError * _Nonnull error) {

}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`MESSAGE_ID`**: (String) unique server ID of the message to report\
**`ROOM_ID`**: (String) ID of the room where the message belongs to\
**`CATEGORY`**: (String) Category of the violation. max length is 100 characters\
**`IS_OTHER_CATEGORY`**: (Boolean) If the category is other than the predefined categories\
**`REASON`**: (String) reason why the message is reported
{% endhint %}

### Block User

You may block a user to stop conversation flow with the blocked user. Blocked users will not be able to send and receive message, or retrieve profile info from the active user.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapCoreContactManager.h>

[[TAPCoreContactManager sharedManager] blockUserWithUserID:USER_ID 
success:^(TAPUserModel *blockedUser) {
    // Successfully blocked user
}
failure:^(NSError * _Nonnull error) {

}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`USER_ID`**: (String) ID of the user to block
{% endhint %}

### Unblock User

You may unblock a blocked user to let them send and receive message from the active user.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapCoreContactManager.h>

[[TAPCoreContactManager sharedManager] unblockUserWithUserID:USER_ID 
success:^(BOOL isSuccess) {
    // Successfully unblocked user
}
failure:^(NSError * _Nonnull error) {

}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`USER_ID`**: (String) ID of the user to unblock
{% endhint %}

### Get Blocked User List

You may call this method to retrieve a list of blocked users.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapCoreContactManager.h>

[[TAPCoreContactManager sharedManager] getBlockedUserList:^(NSArray<TAPUserModel *> *blockedUserList) {
    // Successfully retrieved blocked users
}
failure:^(NSError * _Nonnull error) {

}];
```

{% endtab %}
{% endtabs %}

### Get Blocked User IDs

You may call this method to retrieve a list of IDs from blocked users.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapCoreContactManager.h>

[[TAPCoreContactManager sharedManager] getBlockedUserIDs:^(NSArray<NSString *> *blockedUserIDs) {
    // Successfully retrieved blocked user IDs
}
failure:^(NSError * _Nonnull error) {

}];
```

{% endtab %}
{% endtabs %}

### Get Groups in Common

You may use **`getGroupsInCommon`** method to retrieve the list of groups in common with another user.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapCoreContactManager.h>

[[TAPCoreContactManager sharedManager] getGroupsInCommon:USER_ID 
success:^(NSArray<TAPRoomModel *> *groupRooms) {
    // Successfully retrieved rooms
}
failure:^(NSError * _Nonnull error) {

}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`USER_ID`**: (String) ID of the other user
{% endhint %}


# Message Type

TapTalk.io use a predefined type for each chat message bubble as shown below:

<table data-header-hidden><thead><tr><th width="332.3333333333333">TapTalk Chat Message Type Name</th><th width="86">Type</th><th>Description</th></tr></thead><tbody><tr><td><strong>TapTalk Chat Message Type Name</strong></td><td><strong>Type</strong></td><td><strong>Description</strong></td></tr><tr><td>TAPChatMessageTypeMessage</td><td>1001</td><td>Used for text message bubble.</td></tr><tr><td>TAPChatMessageTypeImage</td><td>1002</td><td>Used for image message bubble.</td></tr><tr><td>TAPChatMessageTypeVideo</td><td>1003</td><td>Used for video message bubble.</td></tr><tr><td>TAPChatMessageTypeFile</td><td>1004</td><td>Used for file message bubble.</td></tr><tr><td>TAPChatMessageTypeLocation</td><td>1005</td><td>Used for location message bubble.</td></tr><tr><td>TAPChatMessageTypeContact*</td><td>1006</td><td>Used for contact message bubble *(coming soon).</td></tr><tr><td>TAPChatMessageTypeSticker*</td><td>1007</td><td>Used for contact message bubble *(coming soon).</td></tr><tr><td>TAPChatMessageTypeLink</td><td>1010</td><td>Used for message bubble that contains URL.</td></tr><tr><td>TAPChatMessageTypeSystemMessage</td><td>9001</td><td>Used for system message bubble</td></tr><tr><td>TAPChatMessageTypeUnreadMessageIdentifier</td><td>9002</td><td>Used to mark the start of unread messages in chat room</td></tr></tbody></table>

{% hint style="info" %}
**TapTalk.io Chat Message Type**

1xxx for Standard Message Bubble\
9xxx for System Message Bubble\
3xxx for User Customized Message Bubble

If you wish to create custom message bubble, please set your customized chat message bubble type with **3** as prefix (e.g. 3001).
{% endhint %}

{% hint style="info" %}
You can add your own customized chat message bubble by following the instructions in [Customized Chat Message Bubble Page](/powertalk-chat-sdk-documentation/powertalk-ios/customized-chat-message-bubble)
{% endhint %}


# Customize UI Appearance

If you are using the default interface from TapTalk.io UI implementation type, you can customize the appearance of the chat UI. To do this, you can add the methods below to your `AppDelegate` class.

{% hint style="info" %}
**Note:** Don't forget to add **`#import <TapTalk/TAPStyleManager.h>`**
{% endhint %}

## Default Color Theme

### Customize default color theme

To customize the chat UI's color theme, you can define your own color by accessing `TAPStyleManager` using the following method.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPStyleManager.h>

// You can use this method
[[TAPStyleManager sharedManager] setDefaultColor:COLOR forType:TYPE];

// Example: set your default primary color
[[TAPStyleManager sharedManager] setDefaultColor:[UIColor blueColor] forType:TAPDefaultColorPrimary];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`COLOR`**: (UIColor) Your preferred color\
**`TYPE`**: (Enum TAPDefaultColor) type of default color
{% endhint %}

{% hint style="warning" %}
**Note:** you can override the default color values partially, but it is recommended to change all of them accordingly to make sure the color theme within the chat UI matches
{% endhint %}

### Obtain default color theme

You can get customized chat UI's color theme by accessing `TAPStyleManager` using the following method.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPStyleManager.h>

// Obtain default primary color
UIColor *color = [[TAPStyleManager sharedManager] getDefaultColorForType:TAPDefaultColorPrimary];
```

{% endtab %}
{% endtabs %}

| **TAPDefaultColorType**          | **Description**                                                                                                                  |
| -------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| TAPDefaultColorPrimary           | Your default primary brand color, will be used in various style, icons and shapes in the TapTalk.io SDK.                         |
| TAPDefaultColorPrimaryExtraLight | Your default primary brand color with extra light accent, will be used in various style, icons and shapes in the TapTalk.io SDK. |
| TAPDefaultColorPrimaryLight      | Your default primary brand color with light accent, will be used in various style, icons and shapes in the TapTalk.io SDK.       |
| TAPDefaultColorPrimaryDark       | Your default primary brand color with dark accent, will be used in various style, icons and shapes in the TapTalk.io SDK.        |

### Customize general colors

The following are the values used as general component colors, you can set the colors by calling the same method as above in `TAPStyleManager`.

| **TAPDefaultColorType**        | **Description**                                                |
| ------------------------------ | -------------------------------------------------------------- |
| TAPDefaultColorSuccess         | Identifies successful actions.                                 |
| TAPDefaultColorError           | Identifies errors or destructive actions.                      |
| TAPDefaultColorTextLight       | Light text color on dark background.                           |
| TAPDefaultColorTextMedium      | Medium text color generally used on subtitles or placeholders. |
| TAPDefaultColorTextDark        | Dark text color on light background.                           |
| TAPDefaultColorIconPrimary     | Primary colored icons used on light background.                |
| TAPDefaultColorIconWhite       | White icons used on colored background.                        |
| TAPDefaultColorIconGray        | Default color for gray icons.                                  |
| TAPDefaultColorIconSuccess     | Default icon color for successful actions.                     |
| TAPDefaultColorIconDestructive | Default icon color for errors or destructive actions.          |

## Components Colors

### Customize component colors

The following are the values used as component colors, you can set the colors by calling this method in `TAPStyleManager`.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPStyleManager.h>

// You can use this method
[[TAPStyleManager sharedManager] setComponentColor:COLOR forType:TYPE];

// Example: set your navigation bar background
[[TAPStyleManager sharedManager] setComponentColor:[UIColor grayColor] forType:TAPComponentColorDefaultNavigationBarBackground];

// Example: set your text field cursor color
[[TAPStyleManager sharedManager] setComponentColor:[UIColor redColor] forType:TAPComponentColorTextFieldCursor];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`COLOR`**: (UIColor) Your preferred color\
**`TYPE`**: (Enum TAPComponentColor) type of component color
{% endhint %}

### Obtain component colors

You can get component color by accessing `TAPStyleManager` with the following method.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPStyleManager.h>

// Obtain componentcolor
UIColor *color = [[TAPStyleManager sharedManager] getComponentColorForType:COMPONENT_COLOR_TYPE];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`COMPONENT_COLOR_TYPE`**: (Enum TAPComponentColor) type of component color
{% endhint %}

### Component Color Type

#### **Default Components**

| **TAPComponentColorType**                       | **Description**                                           |
| ----------------------------------------------- | --------------------------------------------------------- |
| TAPComponentColorDefaultNavigationBarBackground | Set the color for all navigation bar backgroun&#x64;**.** |
| TAPComponentColorDefaultBackground              | Set the color for all view background.                    |

#### **Chat Bubble**

| **TAPComponentColorType**                         | **Description**                                                               |
| ------------------------------------------------- | ----------------------------------------------------------------------------- |
| TAPComponentColorDefaultRightBubbleBackground     | Set the background color for all chat bubbles sent by use&#x72;**.**          |
| TAPComponentColorDefaultRightBubbleDarkBackground | Set the darker background color for all chat bubbles sent by use&#x72;**.**   |
| TAPComponentColorDefaultLeftBubbleBackground      | Set the background color for all chat bubbles sent by other&#x73;**.**        |
| TAPComponentColorDefaultLeftBubbleDarkBackground  | Set the darker background color for all chat bubbles sent by other&#x73;**.** |

#### Text Field

| **TAPComponentColorType**                | **Description**                                         |
| ---------------------------------------- | ------------------------------------------------------- |
| TAPComponentColorTextFieldCursor         | Set the color for textfield's cursor.                   |
| TAPComponentColorTextFieldBorderActive   | Set the color for textfield's border in active state.   |
| TAPComponentColorTextFieldBorderInactive | Set the color for textfield's border in inactive state. |
| TAPComponentColorTextFieldBorderError    | Set the color for textfield's border in error state.    |

#### Button

| **TAPComponentColorType**                              | **Description**                                                                                                                                                                                                                                                                                 |
| ------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| TAPComponentColorButtonActiveBackgroundGradientLight   | Set the color for gradient background of the button (light) in active state, Currently TapTalk.io use 2 gradient color for button's background color in active state, if you wish to set one-tone color for the background, fill both gradient light and gradient dark with the same color.     |
| TAPComponentColorButtonActiveBackgroundGradientDark    | Set the color for gradient background of the button (dark) in active state, Currently TapTalk.io use 2 gradient color for button's background color in active state, if you wish to set one-tone color for the background, fill both gradient light and gradient dark with the same color.      |
| TAPComponentColorButtonActiveBorder                    | Set the color for button's border in active state.                                                                                                                                                                                                                                              |
| TAPComponentColorButtonInactiveBackgroundGradientLight | Set the color for gradient background of the button (light) in inactive state, Currently TapTalk.io use 2 gradient color for button's background color in inactive state, if you wish to set one-tone color for the background, fill both gradient light and gradient dark with the same color. |
| TAPComponentColorButtonInactiveBackgroundGradientDark  | Set the color for gradient background of the button (dark) in inactive state, Currently TapTalk.io use 2 gradient color for button's background color in inactive state, if you wish to set one-tone color for the background, fill both gradient light and gradient dark with the same color.  |
| TAPComponentColorButtonInactiveBorder                  | Set the color for button's border in inactive state.                                                                                                                                                                                                                                            |
| TAPComponentColorButtonDestructiveBackground           | Set the color for background of destructive button.                                                                                                                                                                                                                                             |
| TAPComponentColorButtonIcon                            | Set the color for icon in button.                                                                                                                                                                                                                                                               |
| TAPComponentColorButtonIconPrimary                     | Set the color for icon in primary button.                                                                                                                                                                                                                                                       |
| TAPComponentColorButtonIconDestructive                 | Set the color for icon in destructive button.                                                                                                                                                                                                                                                   |

#### Switch

| **TAPComponentColorType**                | **Description**                                          |
| ---------------------------------------- | -------------------------------------------------------- |
| TAPComponentColorSwitchActiveBackground  | Set the color for switch's background in active state.   |
| TAPComponentColorSwitchInactiveBackgroud | Set the color for switch's background in inactive state. |

**Popup Dialog**

| **TAPComponentColorType**                                  | **Description**                                               |
| ---------------------------------------------------------- | ------------------------------------------------------------- |
| TAPComponentColorPopupDialogPrimaryButtonSuccessBackground | Set the color for right button's background in success state. |
| TAPComponentColorPopupDialogPrimaryButtonErrorBackground   | Set the color for right button's background in error state.   |
| TAPComponentColorPopupDialogSecondaryButtonBackground      | Set the color for left button's background.                   |

**Unread Badge**

| **TAPComponentColorType**                      | **Description**                                                      |
| ---------------------------------------------- | -------------------------------------------------------------------- |
| TAPComponentColorUnreadBadgeBackground         | Set the color for circular unread badge's background.                |
| TAPComponentColorUnreadBadgeInactiveBackground | Set the color for circular unread badge's inactive state background. |

**Table View**&#x20;

| **TAPComponentColorType**              | **Description**                                                                                   |
| -------------------------------------- | ------------------------------------------------------------------------------------------------- |
| TAPComponentColorTableViewSectionIndex | Set the color for table view's section index (alphabetical list in the right side of table view). |

**Search Bar**&#x20;

| **TAPComponentColorType**                | **Description**                                          |
| ---------------------------------------- | -------------------------------------------------------- |
| TAPComponentColorSearchBarBorderActive   | Set the color for search bar's border in inactive state. |
| TAPComponentColorSearchBarBorderInactive | Set the color for search bar's border in inactive state. |

**Media Preview**&#x20;

| **TAPComponentColorType**                            | **Description**                                                     |
| ---------------------------------------------------- | ------------------------------------------------------------------- |
| TAPComponentColorSelectedMediaPreviewThumbnailBorder | Set the color for border in selected media preview thumbnail.       |
| TAPComponentColorMediaPreviewWarningBackgroundColor  | Set the color for background of warning info view in media preview. |

**Search**&#x20;

| **TAPComponentColorType**                            | **Description**                                                          |
| ---------------------------------------------------- | ------------------------------------------------------------------------ |
| TAPComponentColorSearchConnectionLostBackgroundColor | Set the color for background of search connection lost information view. |

**Chat Room Page**&#x20;

| **TAPComponentColorType**                             | **Description**                                                                            |
| ----------------------------------------------------- | ------------------------------------------------------------------------------------------ |
| TAPComponentColorChatRoomBackground                   | Set the color for chat room background view.                                               |
| TAPComponentColorChatComposerBackground               | Set the color for chat composer (text field for chat) background view.                     |
| TAPComponentColorQuoteLayoutDecorationBackground      | Set the color for quote decoration background in chat room quote view.                     |
| TAPComponentColorRightBubbleQuoteDecorationBackground | Set the color for quote decoration in right message bubble.                                |
| TAPComponentColorLeftBubbleQuoteDecorationBackground  | Set the color for quote decoration in left message bubble.                                 |
| TAPComponentColorLeftBubbleBackground                 | Set the color for left side chat bubble view.                                              |
| TAPComponentColorRightBubbleBackground                | Set the color for right side chat bubble view.                                             |
| TAPComponentColorLeftBubbleQuoteBackground            | Set the color for left side quote view in chat bubble.                                     |
| TAPComponentColorRightBubbleQuoteBackground           | Set the color for right side quote view in chat bubble.                                    |
| TAPComponentColorLeftFileButtonBackground             | Set the color for left side button's background in file chat bubble.                       |
| TAPComponentColorRightFileButtonBackground            | Set the color for right side button's background in file chat bubble.                      |
| TAPComponentColorIconQuotedFileBackgroundRight        | Set the background color for quoted file icon in right message bubble.                     |
| TAPComponentColorIconQuotedFileBackgroundLeft         | Set the background color for quoted file icon in left message bubble.                      |
| TAPComponentColorSystemMessageBackground              | Set the color for background of system message bubble.                                     |
| TAPComponentColorSystemMessageBackgroundShadow        | Set the color for shadow of system message bubble.                                         |
| TAPComponentColorFileProgressBackgroundPrimary        | Set the color for progress bar when uploading or downloading in right file bubble message. |
| TAPComponentColorFileProgressBackgroundWhite          | Set the color for progress bar when uploading or downloading in left file bubble message.  |
| TAPComponentColorDeletedChatRoomInfoBackground        | Set the color for deleted chat room information background view.                           |
| TAPComponentColorUnreadIdentifierBackground           | Set the color for unread identifier background view.                                       |

## Icon Colors

### Customize icon colors

The following are the values used as icon colors, you can set the colors by calling this method in `TAPStyleManager`.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPStyleManager.h>

// You can use the same method to set component color and icon color
[[TAPStyleManager sharedManager] setComponentColor:COLOR forType:COMPONENT_COLOR_TYPE];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`COLOR`**: (UIColor) Your preferred color\
**`COMPONENT_COLOR_TYPE`**: (Enum TAPComponentColor) type of component color
{% endhint %}

### Obtain icon colors

You can get icon color by accessing `TAPStyleManager` with the following method.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPStyleManager.h>

// Use the same method to get component color and icon color
UIColor *color = [[TAPStyleManager sharedManager] getComponentColorForType:COMPONENT_COLOR_TYPE];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Parameters**\
**`COMPONENT_COLOR_TYPE`**: (Enum TAPComponentColor) type of icon color
{% endhint %}

### Icon Color Type

#### **Default Icons**

| TAPComponentColorType                              | Description                                                          |
| -------------------------------------------------- | -------------------------------------------------------------------- |
| TAPComponentColorIconLoadingProgressPrimary        | Set the color for icon loading progress with brand primary color     |
| TAPComponentColorIconLoadingProgressWhite          | Set the color for icon loading progress with default white color     |
| TAPComponentColorIconChevronRightPrimary           | Set the color for icon chevron right with brand primary color        |
| TAPComponentColorIconChevronRightGray              | Set the color for icon chevron right with default gray color         |
| TAPComponentColorIconChecklist                     | Set the color for icon checklist                                     |
| TAPComponentColorIconCircleSelectionActive         | Set the color for icon selection in active state                     |
| TAPComponentColorIconCircleSelectionInactive       | Set the color for icon selection in inactive state                   |
| TAPComponentColorIconLoadingPopupSuccess           | Set the color for icon loading popup in success state                |
| TAPComponentColorIconSearchConnectionLost          | Set the color for icon lost search connection                        |
| TAPComponentColorIconChatRoomMessageSending        | Set the color for icon sending message bubble in chat room           |
| TAPComponentColorIconChatRoomMessageFailed         | Set the color for icon failed message bubble in chat room            |
| TAPComponentColorIconChatRoomMessageSent           | Set the color for icon sent message bubble in chat room              |
| TAPComponentColorIconChatRoomMessageSentImage      | Set the color for icon sent image/video message with no caption      |
| TAPComponentColorIconChatRoomMessageDelivered      | Set the color for icon delivered message bubble in chat room         |
| TAPComponentColorIconChatRoomMessageDeliveredImage | Set the color for icon delivered image/video message with no caption |
| TAPComponentColorIconChatRoomMessageRead           | Set the color for icon read message bubble in chat room              |
| TAPComponentColorIconChatRoomMessageDeletedLeft    | Set the color for icon deleted right message bubble in chat room     |
| TAPComponentColorIconChatRoomMessageDeletedRight   | Set the color for icon deleted left message bubble in chat room      |
| TAPComponentColorIconRemoveItem                    | Set the color for icon remove item                                   |
| TAPComponentColorIconRemoveItemBackground          | Set the color for icon remove item background                        |

#### **Navigation Bar Icons**

| TAPComponentColorType                                | Description                                                    |
| ---------------------------------------------------- | -------------------------------------------------------------- |
| TAPComponentColorIconNavigationBarBackButton         | Set the color for icon back in navigation bar                  |
| TAPComponentColorIconTransparentBackgroundBackButton | Set the color for icon back button with transparent background |
| TAPComponentColorIconNavigationBarCloseButton        | Set the color for icon close in navigation bar                 |
| TAPComponentColorIconClearTextButton                 | Set the color for clear text button icon                       |
| TAPComponentColorIconSearchBarMagnifier              | Set the color for magnifier icon in search bar                 |

#### **Action Sheet Icons**

| TAPComponentColorType                        | Description                                                 |
| -------------------------------------------- | ----------------------------------------------------------- |
| TAPComponentColorIconActionSheetDocument     | Set the color for document icon in action sheet option      |
| TAPComponentColorIconActionSheetCamera       | Set the color for camera icon in action sheet option        |
| TAPComponentColorIconActionSheetGallery      | Set the color for gallery icon in action sheet option       |
| TAPComponentColorIconActionSheetLocation     | Set the color for location icon in action sheet option      |
| TAPComponentColorIconActionSheetComposeEmail | Set the color for compose email icon in action sheet option |
| TAPComponentColorIconActionSheetCopy         | Set the color for copy icon in action sheet option          |
| TAPComponentColorIconActionSheetOpen         | Set the color for open icon in action sheet option          |
| TAPComponentColorIconActionSheetSMS          | Set the color for SMS icon in action sheet option           |
| TAPComponentColorIconActionSheetSendMessage  | Set the color for Send Message icon in action sheet option  |
| TAPComponentColorIconActionSheetViewProfile  | Set the color for View Profile icon in action sheet option  |
| TAPComponentColorIconActionSheetCall         | Set the color for call icon in action sheet option          |
| TAPComponentColorIconActionSheetReply        | Set the color for reply icon in action sheet option         |
| TAPComponentColorIconActionSheetForward      | Set the color for forward icon in action sheet option       |
| TAPComponentColorIconActionSheetTrash        | Set the color for trash icon in action sheet option         |

#### **Room List Page Icons**

| TapComponentColorType                         | Description                                             |
| --------------------------------------------- | ------------------------------------------------------- |
| TAPComponentColorIconRoomListMuted            | Set the color for muted icon in room list page          |
| TAPComponentColorIconStartNewChatButton       | Set the color for start new chat icon in room list page |
| TAPComponentColorIconRoomListSettingUp        | Set the color for setting up icon in room list page     |
| TAPComponentColorIconRoomListSetUpSuccess     | Set the color for success setup icon in room list page  |
| TAPComponentColorIconRoomListSetUpFailure     | Set the color for fail to setup icon in room list page  |
| TAPComponentColorIconRoomListRetrySetUpButton | Set the color for retry setup icon in room list page    |
| TAPComponentColorIconRoomListMessageSending   | Set the color for room list message sending icon        |
| TAPComponentColorIconRoomListMessageFailed    | Set the color for room list message failed icon         |
| TAPComponentColorIconRoomListMessageSent      | Set the color for room list message sent icon           |
| TAPComponentColorIconRoomListMessageDelivered | Set the color for room list message delivered icon      |
| TAPComponentColorIconRoomListMessageRead      | Set the color for room list message read icon           |
| TAPComponentColorIconRoomListMessageDeleted   | Set the color for room list message deleted icon        |

#### **New Chat Page Icons**

| TapComponentColorType               | Description                                                 |
| ----------------------------------- | ----------------------------------------------------------- |
| TAPComponentColorIconMenuNewContact | Set the color for new contact option icon in new chat page  |
| TAPComponentColorIconMenuScanQRCode | Set the color for scan QR code option icon in new chat page |
| TAPComponentColorIconMenuNewGroup   | Set the color for new group option icon in new chat page    |

**Chat / Group Profile Page Icons**

| TapComponentColorType                                    | Description                                                             |
| -------------------------------------------------------- | ----------------------------------------------------------------------- |
| TAPComponentColorIconChatProfileMenuNotificationActive   | Set the color for active state notification icon in profile page menu   |
| TAPComponentColorIconChatProfileMenuNotificationInactive | Set the color for inactive state notification icon in profile page menu |
| TAPComponentColorIconChatProfileMenuConversationColor    | Set the color for conversation color icon in profile page menu          |
| TAPComponentColorIconChatProfileMenuBlockUser            | Set the color for block user icon in profile page menu                  |
| TAPComponentColorIconChatProfileMenuSearchChat           | Set the color for search chat icon in profile page menu                 |
| TAPComponentColorIconChatProfileMenuClearChat            | Set the color for clear chat icon in profile page menu                  |
| TAPComponentColorIconGroupProfileMenuViewMembers         | Set the color for view members icon in profile page of group chat       |
| TAPComponentColorIconGroupMemberProfileMenuAddToContacts | Set the color for add to contact icon in profile page of group chat     |
| TAPComponentColorIconGroupMemberProfileMenuSendMessage   | Set the color for send message icon in profile page of group chat       |
| TAPComponentColorIconGroupMemberProfileMenuPromoteAdmin  | Set the color for promote admin icon in profile page of group chat      |
| TAPComponentColorIconGroupMemberProfileMenuDemoteAdmin   | Set the color for demote admin icon in profile page of group chat       |
| TAPComponentColorIconGroupMemberProfileMenuRemoveMember  | Set the color for remove member icon in profile page of group chat      |

**Media / Image Detail Preview Icons**

| TapComponentColorType                                       | Description                                                            |
| ----------------------------------------------------------- | ---------------------------------------------------------------------- |
| TAPComponentColorIconMediaPreviewAdd                        | Set the color for add icon in media preview                            |
| TAPComponentColorIconMediaPreviewWarning                    | Set the color for warning icon in media preview                        |
| TAPComponentColorIconMediaPreviewThumbnailWarning           | Set the color for warning icon in media preview thumbnail              |
| TAPComponentColorIconMediaPreviewThumbnailWarningBackground | Set the color for warning icon's background in media preview thumbnail |
| TAPComponentColorIconSaveImage                              | Set the color for save image icon in media preview                     |
| TAPComponentColorIconMediaListVideo                         | Set the color for video icon in media list                             |

**Location Picker Icons**

| TapComponentColorType                                     | Description                                                                             |
| --------------------------------------------------------- | --------------------------------------------------------------------------------------- |
| TAPComponentColorIconLocationPickerMarker                 | Set the color for location picker marker icon in pick location page                     |
| TAPComponentColorIconLocationPickerRecenter               | Set the color for location picker recenter icon in pick location page                   |
| TAPComponentColorIconLocationPickerRecenterBackground     | Set the color for location picker recenter icon's background in pick location page      |
| TAPComponentColorIconLocationPickerSendLocation           | Set the color for location picker send location icon in pick location page              |
| TAPComponentColorIconLocationPickerSendLocationBackground | Set the color for location picker send location icon's background in pick location page |
| TAPComponentColorIconLocationPickerAddressActive          | Set the color for location picker address icon in active state                          |
| TAPComponentColorIconLocationPickerAddressInactive        | Set the color for location picker address icon in inactive state                        |

**Scan Result Icons**

| TapComponentColorType                          | Description                                     |
| ---------------------------------------------- | ----------------------------------------------- |
| TAPComponentColorIconCloseScanResult           | Set the color for scan result icon              |
| TAPComponentColorIconCloseScanResultBackground | Set the color for scan result icon's background |
| TAPComponentColorIconCloseScanResultBackground | Set the color for scan result icon's background |

**Chat Room Page Icons**

| TapComponentColorType                                   | Description                                                                   |
| ------------------------------------------------------- | ----------------------------------------------------------------------------- |
| TAPComponentColorIconUserStatusActive                   | Set the color for active state user status icon in chat room page             |
| TAPComponentColorIconLocationBubbleMarker               | Set the color for location bubble marker icon in chat room page               |
| TAPComponentColorIconQuotedFileBackground               | Set the color for quoted file icon's background in chat room page             |
| TAPComponentColorIconDeletedChatRoom                    | Set the color for deleted chat room icon in chat room page                    |
| TAPComponentColorIconChatRoomScrollToBottomBackground   | Set the color for scroll to bottom icon's background in chat room page        |
| TAPComponentColorIconChatRoomScrollToBottom             | Set the color for scroll to bottom icon in chat room page                     |
| TAPComponentColorIconChatRoomUnreadButton               | Set the color for unread button icon in chat room page                        |
| TAPComponentColorIconChatRoomFloatingUnreadButton       | Set the color for floating unread button icon in chat room page               |
| TAPComponentColorIconChatComposerBurgerMenuBackground   | Set the color for burger menu icon of chat composer in chat room page         |
| TAPComponentColorIconChatComposerShowKeyboardBackground | Set the color for show keyboard menu icon of chat composer in chat room page  |
| TAPComponentColorIconChatComposerAttach                 | Set the color for attach icon of chat composer in chat room page              |
| TAPComponentColorIconFilePrimary                        | Set the color for file icon in right message bubble                           |
| TAPComponentColorIconFileWhite                          | Set the color for file icon in left message bubble                            |
| TAPComponentColorIconFileUploadDownloadPrimary          | Set the color for upload or download file icon in right message bubble        |
| TAPComponentColorIconFileUploadDownloadWhite            | Set the color for upload or download file icon in left message bubble         |
| TAPComponentColorIconCancelUploadDownloadPrimary        | Set the color for cancel upload or download file icon in right message bubble |
| TAPComponentColorIconCancelUploadDownloadWhite          | Set the color for cancel upload or download file icon in left message bubble  |
| TAPComponentColorIconFileRetryUploadDownloadPrimary     | Set the color for retry upload or download file icon in right message bubble  |
| TAPComponentColorIconFileRetryUploadDownloadWhite       | Set the color for retry upload or download file icon in left message bubble   |
| TAPComponentColorIconFilePlayMedia                      | Set the color for play media icon in chat room page                           |

### Font Style

{% hint style="danger" %}
If you are using a custom font on your application, don't forget to add key **'Fonts Provided by application'** in your **info.plist file**. Otherwise, font won't be loaded
{% endhint %}

![Add custom font in info.plist](https://files.readme.io/6be4107-Screen_Shot_2020-03-10_at_12.25.12.png)

### Customize default font style

To use your application's font resource in the chat UI, set the following values in `TapStyleManager` method with the following example:

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPStyleManager.h>

// You can use this method to set default font
[[TAPStyleManager sharedManager] setDefaultFont:FONT forType:TYPE];

// Example: set your default regular font
[[TAPStyleManager sharedManager] setDefaultFont:[UIFont boldSystemFontOfSize:16.0f] forType:TAPDefaultFontRegular];
```

{% endtab %}
{% endtabs %}

### Obtain default font style

To use your application's font resource in the chat UI, you can obtain `UIFont` by using this method.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPStyleManager.h>

// Obtain regular font
UIFont *obtainedFont = [[TAPStyleManager sharedManager] getDefaultFontForType:TAPDefaultFontRegular];
```

{% endtab %}
{% endtabs %}

| TAPDefaultFontType    | Description                                         |
| --------------------- | --------------------------------------------------- |
| TAPDefaultFontRegular | Your defined default font family with regular style |
| TAPDefaultFontMedium  | Your defined default font family with medium style  |
| TAPDefaultFontBold    | Your defined default font family with bold style    |
| TAPDefaultFontItalic  | Your defined default font family with italic style  |

### Customize component font style & color

You can also override the component's font style and color to customize specific text styles to your liking, or you you may also override their respective color value if you wish to change only the color of the text.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TAPStyleManager.h>

// You can use this method to set the font for a specific component
[[TAPStyleManager sharedManager] setComponentFont:FONT forType:TAP_COMPONENT_FONT_TYPE];

// And use this method to set the color for the specific component
[[TAPStyleManager sharedManager] setTextColor:COLOR forType:TAP_TEXT_COLOR_TYPE];

// Example: if you wish to set the style for your title label, you can use the following methods:
// Set the font (consists of font name and size)
[[TAPStyleManager sharedManager] setComponentFont:FONT forType:TAPComponentFontTitleLabel];
// Set the color
[[TAPStyleManager sharedManager] setTextColor:FONT forType:TAPTextColorTitleLabel];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Note**\
You can choose to specified one of the following methods. If you wish to change just the font, just use **`setComponentFont`** method, and if you wish to change just the text color, you can use **`setTextColor`** method.
{% endhint %}


# Customize Chat Features

If you are using the default interface from TapTalk.io UI implementation type, you can choose to enable or disable the available chat features that we provided by using the **TapUI** class.

### Enable / Disable Message Read Status

You can choose to enable or disable read status of messages in room list and chat room. When disabled, read messages will show as delivered instead. Read status is enabled by default.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapUI.h>

[[TapUI sharedInstance] setHideReadStatus:ENABLED];
```

{% endtab %}
{% endtabs %}

### Enable / Disable Add Contact Feature

You can also choose to enable or disable the user from adding another user as TapTalk contact.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapUI.h>

[[TapUI sharedInstance] setAddContactEnabled:ENABLED];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Note:** Disabling add contact feature will also hide the following:

• Add to Contacts button in chat room

• Add to Contacts button in user profile

• New Contact button in start new chat page

• Scan QR Code button in start new chat page
{% endhint %}

### Customize Room List Features

The following features in TapTalk default room list can be customized:

• Close Room List Button

• Search Chat

• My Account

• Start New Chat

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapUI.h>

[[TapUI sharedInstance] setCloseRoomListButtonVisible:VISIBLE];

[[TapUI sharedInstance] setSearchBarInRoomListVisible:VISIBLE];

[[TapUI sharedInstance] setMyAccountButtonInRoomListVisible:VISIBLE];

[[TapUI sharedInstance] setNewChatButtonInRoomListVisible:VISIBLE];
```

{% endtab %}
{% endtabs %}

### Customize Chat Room Features

The following features in TapTalk default chat room can be customized:

• User / Group Profile Button

• Add to Contacts

• Mention Username

• Send Voice Note

• Link Preview in Message Bubble

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapUI.h>

[[TapUI sharedInstance] setProfileButtonInChatRoomVisible:VISIBLE];

[[TapUI sharedInstance] setAddToContactsButtonInChatRoomVisible:VISIBLE];

[[TapUI sharedInstance] setMentionUsernameEnabled:ENABLED];

[[TapUI sharedInstance] setSendVoiceNoteMenuEnabled:ENABLED];

[[TapUI sharedInstance] setLinkPreviewInMessageEnabled:ENABLED];
```

{% endtab %}
{% endtabs %}

### Customize Chat Room Attachments

You can choose to enable or disable message attachments in chat room as follows:

• Documents

• Camera

• Gallery

• Location (requires Google Places API Key)

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapUI.h>

[[TapUI sharedInstance] setDocumentAttachmentEnabled:ENABLED];

[[TapUI sharedInstance] setCameraAttachmentEnabled:ENABLED];

[[TapUI sharedInstance] setGalleryAttachmentEnabled:ENABLED];

[[TapUI sharedInstance] setLocationAttachmentEnabled:ENABLED];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Note:** Location attachment will be disabled by default when Google Places API Key is not set from **TapTalk** class.
{% endhint %}

### Customize Chat Bubble Long Press Action

You can choose to enable or disable long press action menus in chat room as follows:

• Reply Message

• Forward Message

• Edit Message

• Delete Message

• Delete Others' Message by Admin

• Message Info

• Save Media to Gallery

• Save Document

• Open Link

• Compose Email

• Dial Number

• Send SMS

• View Profile

• Send Message

• Report Message (disabled by default)

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapUI.h>

[[TapUI sharedInstance] setReplyMessageMenuEnabled:ENABLED];

[[TapUI sharedInstance] setForwardMessageMenuEnabled:ENABLED];

[[TapUI sharedInstance] setEditMessageMenuEnabled:ENABLED];

[[TapUI sharedInstance] setDeleteMessageMenuEnabled:ENABLED];

[[TapUI sharedInstance] setAllowDeleteOthersMessageForAdminEnabled:ENABLED];

[[TapUI sharedInstance] setMessageInfoMenuEnabled:ENABLED];

[[TapUI sharedInstance] setSaveMediaToGalleryMenuEnabled:ENABLED];

[[TapUI sharedInstance] setSaveDocumentMenuEnabled:ENABLED];

[[TapUI sharedInstance] setOpenLinkMenuEnabled:ENABLED];

[[TapUI sharedInstance] setComposeEmailMenuEnabled:ENABLED];

[[TapUI sharedInstance] setDialNumberMenuEnabled:ENABLED];

[[TapUI sharedInstance] setSendSMSMenuEnabled:ENABLED];

[[TapUI sharedInstance] setViewProfileMenuEnabled:ENABLED];

[[TapUI sharedInstance] setSendMessageMenuEnabled:ENABLED];

[[TapUI sharedInstance] setReportMessageMenuEnabled:ENABLED];
```

{% endtab %}
{% endtabs %}

### Customize Start New Chat Features

If `setNewChatButtonInRoomListVisible` is enabled (default), you can also customize the availability of its contents:

• Add New Contact (add contact by search)

• Scan QR Code (add contact by scanning QR code)

• Create new group

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapUI.h>

[[TapUI sharedInstance] setNewContactMenuButtonVisible:VISIBLE];

[[TapUI sharedInstance] setScanQRMenuButtonVisible:VISIBLE];

[[TapUI sharedInstance] setNewGroupMenuButtonVisible:VISIBLE];
```

{% endtab %}
{% endtabs %}

### Customize My Account Page

You can choose to show or hide the logout and delete account button in TapTalk My Account page.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapUI.h>

[[TapUI sharedInstance] setLogoutButtonVisible:VISIBLE];

[[TapUI sharedInstance] setDeleteAccountButtonVisible:VISIBLE];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
Delete account button is hidden and does nothing if pressed by default, its action needs to be handled manually using [**TapUIMyAccountDelegate**](/powertalk-chat-sdk-documentation/powertalk-ios/event-delegate#tapuimyaccountdelegate).
{% endhint %}

### Customize User Profile Page

You can choose to show or hide the add to contacts & report/block button in TapTalk Chat Profile page.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapUI.h>

[[TapUI sharedInstance] setAddToContactsButtonInChatProfileVisible:VISIBLE];

[[TapUI sharedInstance] setReportButtonInChatProfileVisible:VISIBLE];

[[TapUI sharedInstance] setReportButtonInUserProfileVisible:VISIBLE];

[[TapUI sharedInstance] setReportButtonInGroupProfileVisible:VISIBLE];

[[TapUI sharedInstance] setBlockUserMenuEnabled:ENABLED];

[[TapUI sharedInstance] setGroupInCommonMenuEnabled:ENABLED];

[[TapUI sharedInstance] setSharedMediaMenuEnabled:ENABLED];

[[TapUI sharedInstance] setSharedMediaMediasTabVisible:VISIBLE];

[[TapUI sharedInstance] setSharedMediaLinksTabVisible:VISIBLE];

[[TapUI sharedInstance] setSharedMediaDocumentsTabVisible:VISIBLE];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
The report button is hidden by default, and the report button in group profile currently does nothing by default when pressed, its action needs to be handled manually using [**TapUIChatProfileDelegate**](/powertalk-chat-sdk-documentation/powertalk-ios/event-delegate#tapuichatprofiledelegate).
{% endhint %}

### Customize Star Message Menu

To enable or disable star message menu in chat room and chat profile page, you may call `setStarMessageMenuEnabled:` method from **TapUI** class. This feature is enabled by default.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapUI.h>

[[TapUI sharedInstance] setStarMessageMenuEnabled:ENABLED];
```

{% endtab %}
{% endtabs %}

### Customize Room List Item Swipe Menu&#x20;

User is able to swipe an item in the room list page to quickly complete some actions. To enable/disable this feature, you may call the following methods below.

{% tabs %}
{% tab title="Objective-C" %}

<pre class="language-csharp"><code class="lang-csharp"><strong>#import &#x3C;TapTalk/TapUI.h>
</strong><strong>
</strong><strong>// Enable/disable mark as read swipe menu action
</strong>[[TapUI sharedInstance] setMarkAsReadRoomListSwipeMenuEnabled:ENABLED];

// Enable/disable mark as unread swipe menu action
[[TapUI sharedInstance] setMarkAsUnreadRoomListSwipeMenuEnabled:ENABLED];

// Enable/disable pin and unpin swipe menu action
[[TapUI sharedInstance] setPinRoomListSwipeMenuEnabled:ENABLED];

// Enable/disable mute and unmute swipe menu action
[[TapUI sharedInstance] setMuteRoomListSwipeMenuEnabled:ENABLED];

// Enable/disable delete chat swipe menu action
[[TapUI sharedInstance] setDeleteRoomListSwipeMenuEnabled:ENABLED];
</code></pre>

{% endtab %}
{% endtabs %}

### Customize Saved Messages Feature

To enable or disable Saved Messages feature, call the `setSavedMessagesMenuEnabled:` from **TapUI**. This feature is enabled by default. Disabling this feature when the user has previously used it will not remove the user's existing messages that has been sent to the Saved Messages chat room.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapUI.h>

[[TapUI sharedInstance] setSavedMessagesMenuEnabled:ENABLED];
```

{% endtab %}
{% endtabs %}

### Customize Pin Message Menu

To enable or disable pin message menu in chat room, you may call `setPinMessageMenuEnabled:` method from **TapUI** class. This feature is enabled by default.

{% tabs %}
{% tab title="Objective-C" %}

```csharp
#import <TapTalk/TapUI.h>

[[TapUI sharedInstance] setPinMessageMenuEnabled:ENABLED];
```

{% endtab %}
{% endtabs %}




---

[Next Page](/llms-full.txt/1)

