allgram Chat - Enterprise-Grade Messaging Platform

Build secure, scalable, and feature-rich chat applications with our comprehensive messaging API. From private conversations to public communities, from secure E2EE chats to real-time P2P communication.

allgram Chat provides enterprise-level security, GDPR compliance, and seamless integration with popular platforms. Perfect for businesses, developers, and organizations requiring professional messaging solutions.

Enterprise Security

E2EE, FIPS 140-2, GDPR compliant

Real-time Performance

WebSocket, P2P, instant delivery

Developer Friendly

REST API, SDKs, comprehensive docs

  • Quick Start Guide
  • Node.js
    Server-side implementation with Express.js, WebSocket support, and comprehensive API integration

  • Swift
    iOS native development with UIKit/SwiftUI, real-time messaging, and secure E2EE implementation

  • Kotlin
    Android development with Jetpack Compose, WebSocket integration, and P2P chat capabilities

  • Additional Resources
    Security, performance, API reference, and community support

  • Chat Services
    Explore enterprise features, pricing, and integration options
  • Licensing
    Commercial licenses, compliance, and enterprise agreements
  • Full Documentation
    Complete API reference, tutorials, and best practices

Node.js Integration

Build robust chat applications with Node.js and Express.js. Our comprehensive API provides real-time messaging, WebSocket support, and enterprise-grade security features. Perfect for building scalable backend services and real-time chat applications.

  • Full API Support: Complete REST API with WebSocket integration
  • Enterprise Security: E2EE, RSA-2048, AES-256-GCM encryption
  • Real-time Performance: WebSocket-based instant messaging
  • Scalable Architecture: Built for high-load production environments
Explore Chat Services

// allgram Chat Node.js Integration Example
const express = require('express');
const WebSocket = require('ws');
const crypto = require('crypto');
const axios = require('axios');

class allgramChatClient {
    constructor(apiKey, baseUrl = 'https://api.allgram.best') {
        this.apiKey = apiKey;
        this.baseUrl = baseUrl;
        this.ws = null;
        this.chats = new Map();
    }

    // Initialize WebSocket connection
    async connectWebSocket() {
        try {
            this.ws = new WebSocket(`wss://api.allgram.best/ws/messages/`);

            this.ws.on('open', () => {
                console.log('✅ WebSocket connected');
                // Authenticate with API key
                this.ws.send(JSON.stringify({
                    type: 'auth',
                    api_key: this.apiKey
                }));
            });

            this.ws.on('message', (data) => {
                this.handleWebSocketMessage(JSON.parse(data));
            });

            this.ws.on('error', (error) => {
                console.error('WebSocket error:', error);
                this.reconnect();
            });

        } catch (error) {
            console.error('Failed to connect WebSocket:', error);
        }
    }

    // Create a new chat
    async createChat(name, description, participants, isSecure = false) {
        try {
            const response = await axios.post(`${this.baseUrl}/chats/create`, {
                chat_name: name,
                chat_description: description,
                participants: participants,
                is_secure: isSecure,
                is_public: false,
                is_p2p: false
            }, {
                headers: {
                    'Authorization': `Bearer ${this.apiKey}`,
                    'Content-Type': 'application/json'
                }
            });

            if (response.status === 200) {
                const chat = response.data;
                this.chats.set(chat.chat_id, chat);
                console.log(`✅ Chat created: ${chat.chat_name}`);
                return chat;
            }
        } catch (error) {
            console.error('Failed to create chat:', error.response?.data || error.message);
            throw error;
        }
    }

    // Send encrypted message
    async sendEncryptedMessage(chatId, content, symmetricKey) {
        try {
            // Encrypt content with AES-256-GCM
            const encryptedContent = await this.encryptWithAES(content, symmetricKey);

            const response = await axios.post(`${this.baseUrl}/messages/create`, {
                chat: chatId,
                content: [JSON.stringify({
                    encrypt_data: encryptedContent
                })]
            }, {
                headers: {
                    'Authorization': `Bearer ${this.apiKey}`,
                    'Content-Type': 'application/json'
                }
            });

            if (response.status === 200) {
                console.log('✅ Encrypted message sent');
                return response.data;
            }
        } catch (error) {
            console.error('Failed to send encrypted message:', error.response?.data || error.message);
            throw error;
        }
    }

    // Handle WebSocket messages
    handleWebSocketMessage(message) {
        if (message.content.action) {
            this.handleSystemEvent(message);
        } else if (message.content.text || message.content.media) {
            this.handleNewMessage(message);
        }
    }

    // Handle system events
    handleSystemEvent(message) {
        switch (message.content.action) {
            case 'joined chat':
                console.log(`👥 User joined chat: ${message.author}`);
                break;
            case 'deleted chat':
                console.log(`🗑️ Chat deleted: ${message.chat}`);
                this.chats.delete(message.chat);
                break;
            case 'started call':
                console.log(`📞 Call started in chat: ${message.chat}`);
                break;
        }
    }

    // Handle new messages
    handleNewMessage(message) {
        console.log(`💬 New message from ${message.author}: ${message.content.text}`);
        // Update chat messages cache
        this.updateChatMessages(message.chat, message);
    }

    // AES encryption helper
    async encryptWithAES(data, key) {
        const algorithm = 'aes-256-gcm';
        const iv = crypto.randomBytes(16);
        const cipher = crypto.createCipher(algorithm, key);

        let encrypted = cipher.update(JSON.stringify(data), 'utf8', 'hex');
        encrypted += cipher.final('hex');

        const authTag = cipher.getAuthTag();

        return {
            encrypted,
            iv: iv.toString('hex'),
            authTag: authTag.toString('hex')
        };
    }

    // Reconnection logic
    reconnect() {
        setTimeout(() => {
            console.log('🔄 Attempting to reconnect...');
            this.connectWebSocket();
        }, 5000);
    }

    // Update chat messages cache
    updateChatMessages(chatId, message) {
        if (!this.chats.has(chatId)) return;

        const chat = this.chats.get(chatId);
        if (!chat.messages) chat.messages = [];

        // Check if message already exists
        const existingIndex = chat.messages.findIndex(m => m.message_id === message.message_id);
        if (existingIndex !== -1) {
            chat.messages[existingIndex] = message;
        } else {
            chat.messages.push(message);
        }

        this.chats.set(chatId, chat);
    }
}

// Usage example
const chatClient = new allgramChatClient('your-api-key-here');

// Initialize connection
chatClient.connectWebSocket();

// Create a secure chat
chatClient.createChat('Team Chat', 'Secure team communication', ['user1', 'user2'], true)
    .then(chat => {
        console.log('Chat created successfully:', chat);
    })
    .catch(error => {
        console.error('Failed to create chat:', error);
    });
                                    

Key Features & Benefits

Our Node.js integration provides enterprise-grade chat capabilities with minimal setup. Built on proven technologies like Express.js and WebSocket, it offers exceptional performance and reliability for production applications.

  • WebSocket Integration: Real-time bidirectional communication
  • Security First: End-to-end encryption with industry-standard algorithms
  • Error Handling: Comprehensive error handling and automatic reconnection
  • Scalability: Designed for high-concurrency applications
View Licensing Options

Swift iOS Integration

Build native iOS chat applications with Swift and SwiftUI. Our iOS SDK provides seamless integration with UIKit and SwiftUI, real-time messaging, and secure E2EE implementation. Perfect for creating professional iOS chat applications with modern design patterns.

  • Native iOS Support: Full SwiftUI and UIKit compatibility
  • Real-time Messaging: WebSocket-based instant communication
  • Secure E2EE: Military-grade encryption for sensitive conversations
  • Modern Architecture: MVVM, Combine, and async/await support
Explore Chat Services

// allgram Chat Swift iOS Integration Example
import SwiftUI
import Combine
import CryptoKit

// MARK: - Chat Models
struct Chat: Codable, Identifiable {
    let id: String
    let name: String
    let description: String
    let isSecure: Bool
    let isP2P: Bool
    let participants: [String]
    let creationDate: Date

    enum CodingKeys: String, CodingKey {
        case id = "chat_id"
        case name = "chat_name"
        case description = "chat_description"
        case isSecure = "is_secure"
        case isP2P = "is_p2p"
        case participants
        case creationDate = "creation_datetime"
    }
}

struct Message: Codable, Identifiable {
    let id: String
    let chatId: String
    let author: String
    let content: MessageContent
    let timestamp: Date
    let isEncrypted: Bool

    enum CodingKeys: String, CodingKey {
        case id = "message_id"
        case chatId = "chat"
        case author
        case content
        case timestamp = "creation_datetime"
        case isEncrypted = "is_secure"
    }
}

struct MessageContent: Codable {
    let text: String?
    let media: [String]?
    let poll: String?
    let quote: QuoteData?
}

struct QuoteData: Codable {
    let messageId: String
    let content: String
    let author: String
}

// MARK: - Chat Service
class allgramChatService: ObservableObject {
    @Published var chats: [Chat] = []
    @Published var currentChat: Chat?
    @Published var messages: [Message] = []
    @Published var isConnected = false

    private var webSocket: URLSessionWebSocketTask?
    private var cancellables = Set<AnyCancellable>()
    private let baseURL = "https://api.allgram.best"
    private let apiKey: String

    init(apiKey: String) {
        self.apiKey = apiKey
        setupWebSocket()
    }

    // MARK: - WebSocket Setup
    private func setupWebSocket() {
        guard let url = URL(string: "wss://api.allgram.best/ws/messages/") else { return }

        let session = URLSession(configuration: .default)
        webSocket = session.webSocketTask(with: url)
        webSocket?.resume()

        // Authenticate
        let authMessage = WebSocketMessage(type: "auth", apiKey: apiKey)
        sendWebSocketMessage(authMessage)

        // Start receiving messages
        receiveMessage()
    }

    // MARK: - Chat Management
    func createChat(name: String, description: String, participants: [String], isSecure: Bool = false) async throws -> Chat {
        let url = URL(string: "\(baseURL)/chats/create")!
        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        request.setValue("Bearer \(apiKey)", forHTTPHeaderField: "Authorization")
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")

        let chatData = [
            "chat_name": name,
            "chat_description": description,
            "participants": participants,
            "is_secure": isSecure,
            "is_public": false,
            "is_p2p": false
        ]

        request.httpBody = try JSONSerialization.data(withJSONObject: chatData)

        let (data, response) = try await URLSession.shared.data(for: request)

        guard let httpResponse = response as? HTTPURLResponse,
              httpResponse.statusCode == 200 else {
            throw ChatError.serverError
        }

        let chat = try JSONDecoder().decode(Chat.self, from: data)

        DispatchQueue.main.async {
            self.chats.append(chat)
        }

        return chat
    }

    // MARK: - Message Handling
    func sendMessage(_ text: String, to chatId: String) async throws {
        let url = URL(string: "\(baseURL)/messages/create")!
        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        request.setValue("Bearer \(apiKey)", forHTTPHeaderField: "Authorization")
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")

        let messageData = [
            "chat": chatId,
            "content": [text]
        ]

        request.httpBody = try JSONSerialization.data(withJSONObject: messageData)

        let (_, response) = try await URLSession.shared.data(for: request)

        guard let httpResponse = response as? HTTPURLResponse,
              httpResponse.statusCode == 200 else {
            throw ChatError.serverError
        }

        // Message sent successfully
        print("✅ Message sent to chat: \(chatId)")
    }

    // MARK: - WebSocket Communication
    private func sendWebSocketMessage(_ message: WebSocketMessage) {
        guard let data = try? JSONEncoder().encode(message),
              let jsonString = String(data: data, encoding: .utf8) else { return }

        let wsMessage = URLSessionWebSocketTask.Message.string(jsonString)
        webSocket?.send(wsMessage) { error in
            if let error = error {
                print("❌ Failed to send WebSocket message: \(error)")
            }
        }
    }

    private func receiveMessage() {
        webSocket?.receive { [weak self] result in
            switch result {
            case .success(let message):
                self?.handleWebSocketMessage(message)
                self?.receiveMessage() // Continue receiving
            case .failure(let error):
                print("❌ WebSocket receive error: \(error)")
                DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
                    self?.reconnect()
                }
            }
        }
    }

    private func handleWebSocketMessage(_ message: URLSessionWebSocketTask.Message) {
        switch message {
        case .string(let text):
            guard let data = text.data(using: .utf8),
                  let wsMessage = try? JSONDecoder().decode(WebSocketMessage.self, from: data) else { return }

            DispatchQueue.main.async {
                self.processWebSocketMessage(wsMessage)
            }
        default:
            break
        }
    }

    private func processWebSocketMessage(_ message: WebSocketMessage) {
        if let action = message.action {
            handleSystemEvent(action, message: message)
        } else if message.content?.text != nil || message.content?.media != nil {
            handleNewMessage(message)
        }
    }

    private func handleSystemEvent(_ action: String, message: WebSocketMessage) {
        switch action {
        case "joined chat":
            print("👥 User joined chat: \(message.author ?? "Unknown")")
        case "deleted chat":
            print("🗑️ Chat deleted: \(message.chat ?? "Unknown")")
            if let chatId = message.chat {
                removeChat(withId: chatId)
            }
        case "started call":
            print("📞 Call started in chat: \(message.chat ?? "Unknown")")
        default:
            break
        }
    }

    private func handleNewMessage(_ message: WebSocketMessage) {
        guard let chatId = message.chat,
              let author = message.author,
              let content = message.content else { return }

        let newMessage = Message(
            id: message.messageId ?? UUID().uuidString,
            chatId: chatId,
            author: author,
            content: content,
            timestamp: Date(),
            isEncrypted: false
        )

        DispatchQueue.main.async {
            if self.currentChat?.id == chatId {
                self.messages.append(newMessage)
            }
        }
    }

    // MARK: - Utility Methods
    private func removeChat(withId chatId: String) {
        DispatchQueue.main.async {
            self.chats.removeAll { $0.id == chatId }
            if self.currentChat?.id == chatId {
                self.currentChat = nil
                self.messages = []
            }
        }
    }

    private func reconnect() {
        print("🔄 Attempting to reconnect...")
        setupWebSocket()
    }
}

// MARK: - WebSocket Message Model
struct WebSocketMessage: Codable {
    let type: String?
    let apiKey: String?
    let chat: String?
    let messageId: String?
    let content: MessageContent?
    let author: String?
    let action: String?

    enum CodingKeys: String, CodingKey {
        case type
        case apiKey = "api_key"
        case chat
        case messageId = "message_id"
        case content
        case author
        case action
    }
}

// MARK: - Error Handling
enum ChatError: Error, LocalizedError {
    case serverError
    case networkError
    case authenticationError

    var errorDescription: String? {
        switch self {
        case .serverError:
            return "Server error occurred"
        case .networkError:
            return "Network connection failed"
        case .authenticationError:
            return "Authentication failed"
        }
    }
}

// MARK: - SwiftUI Views
struct ChatListView: View {
    @StateObject private var chatService = allgramChatService(apiKey: "your-api-key")

    var body: some View {
        NavigationView {
            List(chatService.chats) { chat in
                NavigationLink(destination: ChatDetailView(chat: chat, chatService: chatService)) {
                    ChatRowView(chat: chat)
                }
            }
            .navigationTitle("Chats")
            .toolbar {
                ToolbarItem(placement: .navigationBarTrailing) {
                    Button("New Chat") {
                        // Show new chat creation
                    }
                }
            }
        }
    }
}

struct ChatRowView: View {
    let chat: Chat

    var body: some View {
        VStack(alignment: .leading, spacing: 4) {
            HStack {
                Text(chat.name)
                    .font(.headline)
                Spacer()
                if chat.isSecure {
                    Image(systemName: "lock.fill")
                        .foregroundColor(.green)
                }
            }
            Text(chat.description)
                .font(.subheadline)
                .foregroundColor(.secondary)
            Text("\(chat.participants.size) participants")
                .font(.caption)
                .foregroundColor(.secondary)
        }
        .padding(.vertical, 4)
    }
}
                                    

iOS Development Features

Our Swift SDK leverages the latest iOS technologies including SwiftUI, Combine, and async/await. Built with modern iOS development patterns, it provides a seamless developer experience while maintaining high performance and security standards.

  • SwiftUI Integration: Native SwiftUI components and data binding
  • Combine Framework: Reactive programming with publishers and subscribers
  • Async/Await: Modern concurrency for better performance
  • Security: CryptoKit integration for encryption operations
View Licensing Options

Kotlin Android Integration

Build powerful Android chat applications with Kotlin and Jetpack Compose. Our Android SDK provides seamless integration with modern Android development tools, real-time messaging, and P2P chat capabilities. Perfect for creating professional Android chat applications.

  • Jetpack Compose: Modern declarative UI toolkit
  • WebSocket Integration: Real-time bidirectional communication
  • P2P Chat: Direct peer-to-peer messaging capabilities
  • Android Architecture: MVVM, Repository pattern, and Coroutines
Explore Chat Services

// allgram Chat Kotlin Android Integration Example
package com.allgram.chat

import android.util.Log
import androidx.compose.runtime.*
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
import okhttp3.*
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.RequestBody.Companion.toRequestBody
import org.json.JSONObject
import java.security.MessageDigest
import javax.crypto.Cipher
import javax.crypto.spec.GCMParameterSpec
import javax.crypto.spec.SecretKeySpec

// MARK: - Data Models
data class Chat(
    val chatId: String,
    val chatName: String,
    val chatDescription: String,
    val isSecure: Boolean,
    val isP2P: Boolean,
    val participants: List<String>,
    val creationDatetime: Long,
    val isPublic: Boolean = false
)

data class Message(
    val messageId: String,
    val chatId: String,
    val author: String,
    val authorAvatar: String,
    val content: MessageContent,
    val creationDatetime: Long,
    val isEncrypted: Boolean = false,
    val isRead: Boolean = false
)

data class MessageContent(
    val text: String? = null,
    val media: List<String>? = null,
    val poll: String? = null,
    val quote: QuoteData? = null
)

data class QuoteData(
    val messageId: String,
    val content: String,
    val author: String
)

// MARK: - Chat Service
class allgramChatService(
    private val apiKey: String,
    private val baseUrl: String = "https://api.allgram.best"
) {
    private val client = OkHttpClient.Builder()
        .connectTimeout(30, TimeUnit.SECONDS)
        .readTimeout(30, TimeUnit.SECONDS)
        .writeTimeout(30, TimeUnit.SECONDS)
        .build()

    private var webSocket: WebSocket? = null
    private val messageCallbacks = mutableListOf<(Message) -> Unit>()
    private val systemEventCallbacks = mutableListOf<(String, String) -> Unit>()

    // MARK: - WebSocket Management
    fun connectWebSocket() {
        val request = Request.Builder()
            .url("wss://api.allgram.best/ws/messages/")
            .build()

        webSocket = client.newWebSocket(request, object : WebSocketListener() {
            override fun onOpen(webSocket: WebSocket, response: Response) {
                Log.d("allgramChat", "✅ WebSocket connected")
                // Authenticate
                sendWebSocketMessage(JSONObject().apply {
                    put("type", "auth")
                    put("api_key", apiKey)
                }.toString())
            }

            override fun onMessage(webSocket: WebSocket, text: String) {
                try {
                    val json = JSONObject(text)
                    handleWebSocketMessage(json)
                } catch (e: Exception) {
                    Log.e("allgramChat", "Failed to parse WebSocket message", e)
                }
            }

            override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
                Log.e("allgramChat", "WebSocket failure", t)
                // Attempt reconnection
                CoroutineScope(Dispatchers.IO).launch {
                    delay(5000)
                    connectWebSocket()
                }
            }
        })
    }

    // MARK: - Chat Management
    suspend fun createChat(
        name: String,
        description: String,
        participants: List<String>,
        isSecure: Boolean = false,
        isP2P: Boolean = false
    ): Result<Chat> = withContext(Dispatchers.IO) {
        try {
            val requestBody = JSONObject().apply {
                put("chat_name", name)
                put("chat_description", description)
                put("participants", JSONObject().apply {
                    participants.forEachIndexed { index, participant ->
                        put(index.toString(), participant)
                    }
                })
                put("is_secure", isSecure)
                put("is_public", false)
                put("is_p2p", isP2P)
            }.toString()

            val request = Request.Builder()
                .url("$baseUrl/chats/create")
                .post(requestBody.toRequestBody("application/json".toMediaType()))
                .addHeader("Authorization", "Bearer $apiKey")
                .build()

            val response = client.newCall(request).execute()

            if (response.isSuccessful) {
                val responseBody = response.body?.string()
                val chatJson = JSONObject(responseBody ?: "")

                val chat = Chat(
                    chatId = chatJson.getString("chat_id"),
                    chatName = chatJson.getString("chat_name"),
                    chatDescription = chatJson.getString("chat_description"),
                    isSecure = chatJson.optBoolean("is_secure", false),
                    isP2P = chatJson.optBoolean("is_p2p", false),
                    participants = participants,
                    creationDatetime = chatJson.optLong("creation_datetime", System.currentTimeMillis() / 1000)
                )

                Log.d("allgramChat", "✅ Chat created: ${chat.chatName}")
                Result.success(chat)
            } else {
                Log.e("allgramChat", "Failed to create chat: ${response.code}")
                Result.failure(Exception("Server error: ${response.code}"))
            }
        } catch (e: Exception) {
            Log.e("allgramChat", "Exception creating chat", e)
            Result.failure(e)
        }
    }

    // MARK: - Message Handling
    suspend fun sendMessage(
        chatId: String,
        content: String,
        isEncrypted: Boolean = false,
        symmetricKey: ByteArray? = null
    ): Result<Unit> = withContext(Dispatchers.IO) {
        try {
            val messageContent = if (isEncrypted && symmetricKey != null) {
                val encryptedContent = encryptWithAES(content, symmetricKey)
                JSONObject().apply {
                    put("encrypt_data", encryptedContent)
                }.toString()
            } else {
                content
            }

            val requestBody = JSONObject().apply {
                put("chat", chatId)
                put("content", JSONObject().apply {
                    put("0", messageContent)
                })
            }.toString()

            val request = Request.Builder()
                .url("$baseUrl/messages/create")
                .post(requestBody.toRequestBody("application/json".toMediaType()))
                .addHeader("Authorization", "Bearer $apiKey")
                .build()

            val response = client.newCall(request).execute()

            if (response.isSuccessful) {
                Log.d("allgramChat", "✅ Message sent to chat: $chatId")
                Result.success(Unit)
            } else {
                Log.e("allgramChat", "Failed to send message: ${response.code}")
                Result.failure(Exception("Server error: ${response.code}"))
            }
        } catch (e: Exception) {
            Log.e("allgramChat", "Exception sending message", e)
            Result.failure(e)
        }
    }

    // MARK: - WebSocket Communication
    private fun sendWebSocketMessage(message: String) {
        webSocket?.send(message) ?: run {
            Log.w("allgramChat", "WebSocket not connected")
        }
    }

    private fun handleWebSocketMessage(json: JSONObject) {
        when {
            json.has("action") -> {
                val action = json.getString("action")
                val chatId = json.optString("chat", "")
                handleSystemEvent(action, chatId)
            }
            json.has("content") -> {
                val message = parseMessageFromJson(json)
                message?.let { handleNewMessage(it) }
            }
        }
    }

    private fun handleSystemEvent(action: String, chatId: String) {
        Log.d("allgramChat", "System event: $action in chat: $chatId")
        systemEventCallbacks.forEach { callback ->
            callback(action, chatId)
        }
    }

    private fun handleNewMessage(message: Message) {
        Log.d("allgramChat", "New message from ${message.author}: ${message.content.text}")
        messageCallbacks.forEach { callback ->
            callback(message)
        }
    }

    private fun parseMessageFromJson(json: JSONObject): Message? {
        return try {
            val content = json.optJSONObject("content")
            Message(
                messageId = json.optString("message_id", ""),
                chatId = json.optString("chat", ""),
                author = json.optString("author", ""),
                authorAvatar = json.optString("author_avatar", ""),
                content = MessageContent(
                    text = content?.optString("text"),
                    media = content?.optJSONArray("media")?.let { mediaArray ->
                        List(mediaArray.length()) { i -> mediaArray.getString(i) }
                    },
                    poll = content?.optString("poll"),
                    quote = content?.optJSONObject("quote")?.let { quoteJson ->
                        QuoteData(
                            messageId = quoteJson.optString("message_id", ""),
                            content = quoteJson.optString("content", ""),
                            author = quoteJson.optString("author", "")
                        )
                    }
                ),
                creationDatetime = json.optLong("creation_datetime", System.currentTimeMillis() / 1000),
                isEncrypted = json.optBoolean("is_secure", false)
            )
        } catch (e: Exception) {
            Log.e("allgramChat", "Failed to parse message", e)
            null
        }
    }

    // MARK: - Encryption
    private fun encryptWithAES(data: String, key: ByteArray): String {
        val cipher = Cipher.getInstance("AES/GCM/NoPadding")
        val secretKey = SecretKeySpec(key, "AES")
        val iv = ByteArray(12).apply {
            java.security.SecureRandom().nextBytes(this)
        }
        val gcmSpec = GCMParameterSpec(128, iv)

        cipher.init(Cipher.ENCRYPT_MODE, secretKey, gcmSpec)
        val encrypted = cipher.doFinal(data.toByteArray())

        return android.util.Base64.encodeToString(
            iv + encrypted,
            android.util.Base64.NO_WRAP
        )
    }

    // MARK: - Callbacks
    fun addMessageCallback(callback: (Message) -> Unit) {
        messageCallbacks.add(callback)
    }

    fun addSystemEventCallback(callback: (String, String) -> Unit) {
        systemEventCallbacks.add(callback)
    }

    fun removeMessageCallback(callback: (Message) -> Unit) {
        messageCallbacks.remove(callback)
    }

    fun removeSystemEventCallback(callback: (String, String) -> Unit) {
        systemEventCallbacks.remove(callback)
    }

    // MARK: - Cleanup
    fun disconnect() {
        webSocket?.close(1000, "Disconnecting")
        webSocket = null
    }
}

// MARK: - ViewModel
class ChatViewModel(
    private val chatService: allgramChatService
) : ViewModel() {

    private val _chats = MutableStateFlow<List<Chat>>(emptyList())
    val chats: StateFlow<List<Chat>> = _chats.asStateFlow()

    private val _currentChat = MutableStateFlow<Chat?>(null)
    val currentChat: StateFlow<Chat?> = _currentChat.asStateFlow()

    private val _messages = MutableStateFlow<List<Message>>(emptyList())
    val messages: StateFlow<List<Message>> = _messages.asStateFlow()

    private val _isLoading = MutableStateFlow(false)
    val isLoading: StateFlow<Boolean> = _isLoading.asStateFlow()

    init {
        setupChatService()
    }

    private fun setupChatService() {
        chatService.addMessageCallback { message ->
            if (message.chatId == _currentChat.value?.chatId) {
                _messages.value = _messages.value + message
            }
        }

        chatService.addSystemEventCallback { action, chatId ->
            when (action) {
                "deleted chat" -> {
                    _chats.value = _chats.value.filter { it.chatId != chatId }
                    if (_currentChat.value?.chatId == chatId) {
                        _currentChat.value = null
                        _messages.value = emptyList()
                    }
                }
                "joined chat" -> {
                    // Refresh chat participants
                }
            }
        }
    }

    fun createChat(name: String, description: String, participants: List<String>, isSecure: Boolean = false) {
        viewModelScope.launch {
            _isLoading.value = true
            try {
                val result = chatService.createChat(name, description, participants, isSecure)
                result.onSuccess { chat ->
                    _chats.value = _chats.value + chat
                }.onFailure { error ->
                    Log.e("ChatViewModel", "Failed to create chat", error)
                }
            } finally {
                _isLoading.value = false
            }
        }
    }

    fun sendMessage(content: String) {
        val currentChat = _currentChat.value ?: return

        viewModelScope.launch {
            val result = chatService.sendMessage(currentChat.chatId, content)
            result.onFailure { error ->
                Log.e("ChatViewModel", "Failed to send message", error)
            }
        }
    }

    fun selectChat(chat: Chat) {
        _currentChat.value = chat
        // Load chat messages
        loadChatMessages(chat.chatId)
    }

    private fun loadChatMessages(chatId: String) {
        // Implementation for loading chat messages
        // This would typically involve API calls to fetch message history
    }

    override fun onCleared() {
        super.onCleared()
        chatService.disconnect()
    }
}

// MARK: - Compose UI
@Composable
fun ChatListScreen(
    viewModel: ChatViewModel = viewModel { ChatViewModel(allgramChatService("your-api-key")) }
) {
    val chats by viewModel.chats.collectAsState()
    val isLoading by viewModel.isLoading.collectAsState()

    LazyColumn {
        items(chats) { chat ->
            ChatItem(
                chat = chat,
                onClick = { viewModel.selectChat(chat) }
            )
        }
    }

    if (isLoading) {
        CircularProgressIndicator()
    }
}

@Composable
fun ChatItem(
    chat: Chat,
    onClick: () -> Unit
) {
    Card(
        modifier = Modifier
            .fillMaxWidth()
            .padding(8.dp)
            .clickable { onClick() },
        elevation = CardDefaults.cardElevation(defaultElevation = 4.dp)
    ) {
        Column(
            modifier = Modifier.padding(16.dp)
        ) {
            Row(
                modifier = Modifier.fillMaxWidth(),
                horizontalArrangement = Arrangement.SpaceBetween,
                verticalAlignment = Alignment.CenterVertically
            ) {
                Text(
                    text = chat.chatName,
                    style = MaterialTheme.typography.h6
                )
                if (chat.isSecure) {
                    Icon(
                        imageVector = Icons.Default.Lock,
                        contentDescription = "Secure Chat",
                        tint = Color.Green
                    )
                }
            }

            Text(
                text = chat.chatDescription,
                style = MaterialTheme.typography.body2,
                color = MaterialTheme.colors.onSurface.copy(alpha = 0.6f)
            )

            Text(
                text = "${chat.participants.size} participants",
                style = MaterialTheme.typography.caption,
                color = MaterialTheme.colors.onSurface.copy(alpha = 0.6f)
            )
        }
    }
}
                                    

Android Development Features

Our Kotlin SDK leverages the latest Android technologies including Jetpack Compose, Coroutines, and modern Android architecture patterns. Built with performance and developer experience in mind, it provides a robust foundation for building scalable chat applications.

  • Jetpack Compose: Modern declarative UI with Material Design 3
  • Coroutines: Asynchronous programming with structured concurrency
  • MVVM Architecture: Clean architecture with Repository pattern
  • Security: Built-in encryption and secure communication
View Licensing Options

Additional Resources & Next Steps

Ready to take your chat integration to the next level? Explore our comprehensive resources and advanced features to build enterprise-grade chat applications with allgram.

Security & Compliance

Learn about our enterprise security features, GDPR compliance, and FIPS 140-2 certification.

Learn More →

Performance Optimization

Discover advanced techniques for optimizing chat performance and scalability.

Learn More →

API Reference

Complete API documentation with examples, error codes, and best practices.

View Docs →

Community Support

Join our developer community for support, updates, and collaboration.

Join Community →