Developer Integration Guide
Integrate real-time support chatting widgets and voice channels into any application—whether it is a simple static website, a modern web app (React/Next.js/Vue), or a native mobile app (Android/iOS).
Prerequisites
Before integrating, make sure you have generated a Public API Key (begins with dosti_pub_...) by subscribing to a plan on our landing page.
1. Simple HTML / PHP Integration
For standard websites built with HTML, WordPress, PHP, or Shopify, simply paste this script tag at the bottom of your HTML body (before the closing </body> tag):
<script src="https://api.dosti.space/widget.js" data-key="YOUR_PUBLIC_API_KEY"> </script>
2. React / Next.js Integration
In a React or Next.js application, load the widget dynamically inside a layout or page hook:
import { useEffect } from 'react';
export default function ChatWidget() {
useEffect(() => {
const script = document.createElement('script');
script.src = "https://api.dosti.space/widget.js";
script.setAttribute('data-key', 'YOUR_PUBLIC_API_KEY');
script.async = true;
document.body.appendChild(script);
return () => {
document.body.removeChild(script);
};
}, []);
return null;
}
3. Native Android Integration (Kotlin / Java)
Because the Dosti backend runs a standard Socket.IO server, native mobile apps can connect using Socket.IO clients directly. This bypasses the need for web embeds, allowing you to design a custom native chat interface.
Step A: Import Socket.IO Dependency
Add the dependency to your app/build.gradle file:
dependencies {
implementation ('io.socket:socket.io-client:2.0.1') {
exclude group: 'org.json', module: 'json'
}
}
Step B: Establish Connection in Kotlin
Connect to the backend and pass your Public API Key and session variables in the query string:
import io.socket.client.IO
import io.socket.client.Socket
import org.json.JSONObject
// Initialize connection options
val options = IO.Options().apply {
query = "apiKey=YOUR_PUBLIC_API_KEY&role=visitor&visitorId=android_user_789&visitorName=JohnDoe"
}
// Connect to socket backend
val socket = IO.socket("https://api.dosti.space", options)
socket.on(Socket.EVENT_CONNECT) {
println("Connected to Dosti Support Room!")
}
// Send a chat message
val payload = JSONObject().apply {
put("type", "saas")
put("message", "Hello from Android Native App!")
}
socket.emit("send_message", payload)
// Listen for replies from support agent
socket.on("receive_message") { args ->
val data = args[0] as JSONObject
val message = data.getString("message")
val senderName = data.getString("visitorName") // "Support"
println("Received reply from $senderName: $message")
}
4. Native iOS Integration (Swift)
For native iOS development, install the Swift Socket.IO Client via Swift Package Manager and establish connection:
import SocketIO
let manager = SocketManager(socketURL: URL(string: "https://api.dosti.space")!, config: [
.log(true),
.compress,
.connectParams(["apiKey": "YOUR_PUBLIC_API_KEY", "role": "visitor", "visitorId": "ios_user_555", "visitorName": "iOS User"])
])
let socket = manager.defaultSocket
socket.on(clientEvent: .connect) { data, ack in
print("iOS App Connected to Dosti support!")
// Send a message
socket.emit("send_message", ["type": "saas", "message": "Hello from Swift!"])
}
// Listen for incoming messages
socket.on("receive_message") { data, ack in
if let dict = data[0] as? [String: Any],
let message = dict["message"] as? String {
print("Received support message: \(message)")
}
}
socket.connect()
5. Real-Time Events Protocol
If you are building custom clients on other platforms (e.g. Flutter, React Native, Unity), use these event names to handle the chat session:
Outgoing Events (App to Server)
- send_message: Emits a message. Payload format:
{"type": "saas", "message": "text"} - typing: Notifies the agent you are typing. Payload:
{"type": "saas"} - stop_typing: Notifies the agent you stopped typing. Payload:
{"type": "saas"}
Incoming Events (Server to App)
- receive_message: Fired when agent replies. Payload structure:
{"visitorId": "vis_...", "visitorName": "Support", "message": "text"} - partner_typing: Fired when agent is typing. Payload structure:
{"deviceId": "agent"} - partner_stopped_typing: Fired when agent stops typing. Payload structure:
{"deviceId": "agent"} - agent_joined: Fired when support agent connects to this session room.
6. Stateless HTTP REST API Pipeline
If you prefer a stateless HTTP request-response model over persistent WebSockets, Dosti provides simple REST endpoints. This is highly suitable for backend servers, IoT devices, or mobile environments where you want to design a custom chat experience and manually poll/send messages.
Endpoint 1: Send Message
Send a message from a visitor to the support team. This will immediately display the visitor in the Agent Console and alert the agents.
HTTP Method: POST
URL: https://business.dosti.space/api/chat/send
POST https://business.dosti.space/api/chat/send
Content-Type: application/json
{
"apiKey": "YOUR_PUBLIC_API_KEY",
"visitorId": "android_user_789",
"visitorName": "John Doe",
"message": "Hello from my custom chat interface!"
}
Endpoint 2: Poll Messages (GET or POST)
Retrieve chat messages for a visitor. You can optionally pass lastTimestamp (milliseconds Unix epoch) to fetch only new messages since the last poll.
HTTP Method: GET
URL: https://business.dosti.space/api/chat/poll?apiKey=YOUR_PUBLIC_API_KEY&visitorId=android_user_789&lastTimestamp=1781625600000
Or make a POST request:
POST https://business.dosti.space/api/chat/poll
Content-Type: application/json
{
"apiKey": "YOUR_PUBLIC_API_KEY",
"visitorId": "android_user_789",
"lastTimestamp": 1781625600000
}
Response Format
{
"success": true,
"messages": [
{
"id": "msg_a1b2c3d4",
"sender": "visitor",
"senderName": "You",
"message": "Hello from my custom chat interface!",
"timestamp": 1781625601000
},
{
"id": "msg_e5f6g7h8",
"sender": "agent",
"senderName": "Support",
"message": "Hi John! How can I help you today?",
"timestamp": 1781625615000
}
]
}
Integration Example (PHP)
<?php
// 1. Send Message
$url = "https://business.dosti.space/api/chat/send";
$data = array(
"apiKey" => "YOUR_PUBLIC_API_KEY",
"visitorId" => "php_user_123",
"visitorName" => "PHP Client",
"message" => "Hello from PHP!"
);
$options = array(
'http' => array(
'header' => "Content-Type: application/json\r\n",
'method' => 'POST',
'content' => json_encode($data)
)
);
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
$response = json_decode($result, true);
// 2. Poll messages (only new messages since 10 seconds ago)
$last_ts = (time() - 10) * 1000;
$poll_url = "https://business.dosti.space/api/chat/poll?apiKey=YOUR_PUBLIC_API_KEY&visitorId=php_user_123&lastTimestamp=" . $last_ts;
$poll_result = file_get_contents($poll_url);
$poll_response = json_decode($poll_result, true);
foreach ($poll_response['messages'] as $msg) {
echo $msg['senderName'] . ": " . $msg['message'] . "\n";
}
?>
Integration Example (Android Kotlin - HTTP REST)
Bypass WebSockets and use standard HTTP requests to send and poll messages. Here is a simple implementation using OkHttp:
import okhttp3.*
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.RequestBody.Companion.toRequestBody
import org.json.JSONObject
import java.io.IOException
class DostiChatClient(val apiKey: String, val visitorId: String, val visitorName: String) {
private val client = OkHttpClient()
private val JSON = "application/json; charset=utf-8".toMediaType()
// Send a message
fun sendMessage(messageText: String) {
val payload = JSONObject().apply {
put("apiKey", apiKey)
put("visitorId", visitorId)
put("visitorName", visitorName)
put("message", messageText)
}
val request = Request.Builder()
.url("https://business.dosti.space/api/chat/send")
.post(payload.toString().toRequestBody(JSON))
.build()
client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) { e.printStackTrace() }
override fun onResponse(call: Call, response: Response) {
println("Message sent successfully: \${response.body?.string()}")
}
})
}
// Poll for new messages since lastTimestamp
fun pollMessages(lastTimestamp: Long, callback: (List<JSONObject>) -> Unit) {
val url = "https://business.dosti.space/api/chat/poll?apiKey=\$apiKey&visitorId=\$visitorId&lastTimestamp=\$lastTimestamp"
val request = Request.Builder().url(url).build()
client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) { e.printStackTrace() }
override fun onResponse(call: Call, response: Response) {
val responseData = response.body?.string() ?: return
val json = JSONObject(responseData)
if (json.getBoolean("success")) {
val messagesArray = json.getJSONArray("messages")
val list = mutableListOf<JSONObject>()
for (i in 0 until messagesArray.length()) {
list.add(messagesArray.getJSONObject(i))
}
callback(list)
}
}
})
}
}