allgram Calendar - Enterprise-Grade Event Management Platform

Build secure, scalable calendar applications with our comprehensive event management API. From personal meetings to public events, from secure E2EE scheduling to real-time P2P communication.

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

Enterprise Security

E2EE, FIPS 140-2, GDPR compliant

Real-time Performance

WebSocket, P2P, instant updates

Developer Friendly

REST API, SDKs, comprehensive docs

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

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

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

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

  • Calendar 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 calendar applications with Node.js and Express.js. Our comprehensive API provides real-time event management, WebSocket support, and enterprise-grade security features. Perfect for building scalable backend services and real-time calendar 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 updates
  • Scalable Architecture: Built for high-load production environments
Explore Calendar Services

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

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

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

            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 event
    async createEvent(name, description, startTime, endTime, participants, isPublic = false) {
        try {
            const response = await axios.post(`${this.baseUrl}/events/v1/event/create/`, {
                event_name: name,
                event_description: description,
                event_start_datetime: Math.floor(startTime.getTime() / 1000),
                event_end_datetime: Math.floor(endTime.getTime() / 1000),
                is_public: isPublic,
                is_urgent: false,
                is_whole_day: false,
                is_joinable: true,
                participants_limit: 50,
                users_to_add: participants
            }, {
                headers: {
                    'Authorization': `Bearer ${this.apiKey}`,
                    'Content-Type': 'application/json'
                }
            });

            if (response.status === 200) {
                const event = response.data;
                this.events.set(event.event_id, event);
                console.log(`✅ Event created: ${event.event_name}`);
                return event;
            }
        } catch (error) {
            console.error('Failed to create event:', error.response?.data || error.message);
            throw error;
        }
    }

    // Get calendar data for a specific date range
    async getCalendarData(startDate, endDate, timezone = 'UTC') {
        try {
            const response = await axios.get(`${this.baseUrl}/events/v1/my/private/calendar/`, {
                headers: {
                    'Authorization': `Bearer ${this.apiKey}`,
                    'Content-Type': 'application/json'
                },
                params: {
                    timezone: timezone,
                    week_start: 1 // Monday
                }
            });

            if (response.status === 200) {
                console.log('✅ Calendar data retrieved');
                return response.data;
            }
        } catch (error) {
            console.error('Failed to get calendar data:', error.response?.data || error.message);
            throw error;
        }
    }

    // Handle WebSocket messages
    handleWebSocketMessage(message) {
        if (message.content && message.content.action) {
            this.handleSystemEvent(message);
        } else if (message.event_id) {
            this.handleEventUpdate(message);
        }
    }

    // Handle system events
    handleSystemEvent(message) {
        switch (message.content.action) {
            case 'event_created':
                console.log(`📅 New event created: ${message.event_name}`);
                break;
            case 'event_updated':
                console.log(`📝 Event updated: ${message.event_name}`);
                break;
            case 'event_deleted':
                console.log(`🗑️ Event deleted: ${message.event_id}`);
                this.events.delete(message.event_id);
                break;
            case 'participant_joined':
                console.log(`👥 Participant joined event: ${message.event_name}`);
                break;
        }
    }

    // Handle event updates
    handleEventUpdate(message) {
        console.log(`📅 Event update: ${message.event_name}`);
        // Update local event cache
        this.updateEventCache(message);
    }

    // Update event cache
    updateEventCache(event) {
        if (this.events.has(event.event_id)) {
            this.events.set(event.event_id, { ...this.events.get(event.event_id), ...event });
        } else {
            this.events.set(event.event_id, event);
        }
    }

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

// Usage example
const calendarClient = new allgramCalendarClient('your-api-key-here');

// Initialize connection
calendarClient.connectWebSocket();

// Create a new event
const startTime = new Date('2025-02-15T10:00:00Z');
const endTime = new Date('2025-02-15T11:00:00Z');

calendarClient.createEvent('Team Meeting', 'Weekly team sync', startTime, endTime, ['user1', 'user2'], false)
    .then(event => {
        console.log('Event created successfully:', event);
    })
    .catch(error => {
        console.error('Failed to create event:', error);
    });

// Get calendar data
calendarClient.getCalendarData(new Date(), new Date(Date.now() + 7 * 24 * 60 * 60 * 1000))
    .then(calendarData => {
        console.log('Calendar data:', calendarData);
    })
    .catch(error => {
        console.error('Failed to get calendar data:', error);
    });
                                    

Key Features & Benefits

Our Node.js integration provides enterprise-grade calendar 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 calendar applications with Swift and SwiftUI. Our iOS SDK provides seamless integration with UIKit and SwiftUI, real-time calendar updates, and secure E2EE implementation. Perfect for creating professional iOS calendar applications with modern design patterns.

  • Native iOS Support: Full SwiftUI and UIKit compatibility
  • Real-time Updates: WebSocket-based instant calendar synchronization
  • Secure E2EE: Military-grade encryption for sensitive events
  • Modern Architecture: MVVM, Combine, and async/await support
Explore Calendar Services

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

// MARK: - Calendar Models
struct CalendarEvent: Codable, Identifiable {
    let id: String
    let name: String
    let description: String
    let startTime: Date
    let endTime: Date
    let location: String?
    let isPublic: Bool
    let isUrgent: Bool
    let participants: [String]
    let creationDate: Date

    enum CodingKeys: String, CodingKey {
        case id = "event_id"
        case name = "event_name"
        case description = "event_description"
        case startTime = "event_start_datetime"
        case endTime = "event_end_datetime"
        case location = "event_location"
        case isPublic = "is_public"
        case isUrgent = "is_urgent"
        case participants
        case creationDate = "creation_datetime"
    }
}

struct CalendarDay: Codable {
    let date: String
    let events: [CalendarEvent]
    let isToday: Bool
    let isSelected: Bool
}

// MARK: - Calendar Service
class allgramCalendarService: ObservableObject {
    @Published var events: [CalendarEvent] = []
    @Published var selectedDate: Date = Date()
    @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/events/") 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: - Event Management
    func createEvent(name: String, description: String, startTime: Date, endTime: Date, participants: [String], isPublic: Bool = false) async throws -> CalendarEvent {
        let url = URL(string: "\(baseURL)/events/v1/event/create/")!
        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        request.setValue("Bearer \(apiKey)", forHTTPHeaderField: "Authorization")
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")

        let eventData = [
            "event_name": name,
            "event_description": description,
            "event_start_datetime": Int(startTime.timeIntervalSince1970),
            "event_end_datetime": Int(endTime.timeIntervalSince1970),
            "is_public": isPublic,
            "is_urgent": false,
            "is_whole_day": false,
            "is_joinable": true,
            "participants_limit": 50,
            "users_to_add": participants
        ]

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

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

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

        let event = try JSONDecoder().decode(CalendarEvent.self, from: data)

        DispatchQueue.main.async {
            self.events.append(event)
        }

        return event
    }

    // MARK: - Calendar Data
    func getCalendarData(timezone: String = "UTC", weekStart: Int = 1) async throws -> [CalendarDay] {
        let url = URL(string: "\(baseURL)/events/v1/my/private/calendar/")!
        var request = URLRequest(url: url)
        request.httpMethod = "GET"
        request.setValue("Bearer \(apiKey)", forHTTPHeaderField: "Authorization")

        let queryItems = [
            URLQueryItem(name: "timezone", value: timezone),
            URLQueryItem(name: "week_start", value: String(weekStart))
        ]
        request.url?.append(queryItems: queryItems)

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

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

        let calendarData = try JSONDecoder().decode([CalendarDay].self, from: data)
        return calendarData
    }

    // 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.eventId != nil {
            handleEventUpdate(message)
        }
    }

    private func handleSystemEvent(_ action: String, message: WebSocketMessage) {
        switch action {
        case "event_created":
            print("📅 New event created: \(message.eventName ?? "Unknown")")
        case "event_updated":
            print("📝 Event updated: \(message.eventName ?? "Unknown")")
        case "event_deleted":
            print("🗑️ Event deleted: \(message.eventId ?? "Unknown")")
            if let eventId = message.eventId {
                removeEvent(withId: eventId)
            }
        case "participant_joined":
            print("👥 Participant joined event: \(message.eventName ?? "Unknown")")
        default:
            break
        }
    }

    private func handleEventUpdate(_ message: WebSocketMessage) {
        guard let eventId = message.eventId else { return }
        print("📅 Event update: \(message.eventName ?? "Unknown")")
        // Update local event cache
        updateEventCache(message)
    }

    // MARK: - Utility Methods
    private func removeEvent(withId eventId: String) {
        DispatchQueue.main.async {
            self.events.removeAll { $0.id == eventId }
        }
    }

    private func updateEventCache(_ message: WebSocketMessage) {
        // Implementation for updating event cache
    }

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

// MARK: - WebSocket Message Model
struct WebSocketMessage: Codable {
    let type: String?
    let apiKey: String?
    let eventId: String?
    let eventName: String?
    let action: String?

    enum CodingKeys: String, CodingKey {
        case type
        case apiKey = "api_key"
        case eventId = "event_id"
        case eventName = "event_name"
        case action
    }
}

// MARK: - Error Handling
enum CalendarError: 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 CalendarView: View {
    @StateObject private var calendarService = allgramCalendarService(apiKey: "your-api-key")

    var body: some View {
        NavigationView {
            VStack {
                // Calendar grid implementation
                Text("Calendar View")
                    .font(.title)

                List(calendarService.events) { event in
                    EventRowView(event: event)
                }
            }
            .navigationTitle("Calendar")
            .toolbar {
                ToolbarItem(placement: .navigationBarTrailing) {
                    Button("New Event") {
                        // Show new event creation
                    }
                }
            }
        }
    }
}

struct EventRowView: View {
    let event: CalendarEvent

    var body: some View {
        VStack(alignment: .leading, spacing: 4) {
            HStack {
                Text(event.name)
                    .font(.headline)
                Spacer()
                if event.isUrgent {
                    Image(systemName: "exclamationmark.triangle.fill")
                        .foregroundColor(.red)
                }
            }
            Text(event.description)
                .font(.subheadline)
                .foregroundColor(.secondary)
            Text("\(event.startTime, style: .time) - \(event.endTime, style: .time)")
                .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 calendar applications with Kotlin and Jetpack Compose. Our Android SDK provides seamless integration with modern Android development tools, real-time calendar updates, and P2P calendar capabilities. Perfect for creating professional Android calendar applications.

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

// allgram Calendar Kotlin Android Integration Example
package com.allgram.calendar

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 CalendarEvent(
    val eventId: String,
    val eventName: String,
    val eventDescription: String,
    val startTime: Long,
    val endTime: Long,
    val location: String?,
    val isPublic: Boolean,
    val isUrgent: Boolean,
    val participants: List<String>,
    val creationDatetime: Long
)

data class CalendarDay(
    val date: String,
    val events: List<CalendarEvent>,
    val isToday: Boolean,
    val isSelected: Boolean
)

// MARK: - Calendar Service
class allgramCalendarService(
    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 eventCallbacks = mutableListOf<(CalendarEvent) -> Unit>()
    private val systemEventCallbacks = mutableListOf<(String, String) -> Unit>()

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

        webSocket = client.newWebSocket(request, object : WebSocketListener() {
            override fun onOpen(webSocket: WebSocket, response: Response) {
                Log.d("allgramCalendar", "✅ 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("allgramCalendar", "Failed to parse WebSocket message", e)
                }
            }

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

    // MARK: - Event Management
    suspend fun createEvent(
        name: String,
        description: String,
        startTime: Long,
        endTime: Long,
        participants: List<String>,
        isPublic: Boolean = false
    ): Result<CalendarEvent> = withContext(Dispatchers.IO) {
        try {
            val requestBody = JSONObject().apply {
                put("event_name", name)
                put("event_description", description)
                put("event_start_datetime", startTime)
                put("event_end_datetime", endTime)
                put("is_public", isPublic)
                put("is_urgent", false)
                put("is_whole_day", false)
                put("is_joinable", true)
                put("participants_limit", 50)
                put("users_to_add", JSONObject().apply {
                    participants.forEachIndexed { index, participant ->
                        put(index.toString(), participant)
                    }
                })
            }.toString()

            val request = Request.Builder()
                .url("$baseUrl/events/v1/event/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 eventJson = JSONObject(responseBody ?: "")

                val event = CalendarEvent(
                    eventId = eventJson.getString("event_id"),
                    eventName = eventJson.getString("event_name"),
                    eventDescription = eventJson.optString("event_description", ""),
                    startTime = eventJson.optLong("event_start_datetime", 0),
                    endTime = eventJson.optLong("event_end_datetime", 0),
                    location = eventJson.optString("event_location", null),
                    isPublic = eventJson.optBoolean("is_public", false),
                    isUrgent = eventJson.optBoolean("is_urgent", false),
                    participants = participants,
                    creationDatetime = eventJson.optLong("creation_datetime", System.currentTimeMillis() / 1000)
                )

                Log.d("allgramCalendar", "✅ Event created: ${event.eventName}")
                Result.success(event)
            } else {
                Log.e("allgramCalendar", "Failed to create event: ${response.code}")
                Result.failure(Exception("Server error: ${response.code}"))
            }
        } catch (e: Exception) {
            Log.e("allgramCalendar", "Exception creating event", e)
            Result.failure(e)
        }
    }

    // MARK: - Calendar Data
    suspend fun getCalendarData(timezone: String = "UTC", weekStart: Int = 1): Result<List<CalendarDay>> = withContext(Dispatchers.IO) {
        try {
            val request = Request.Builder()
                .url("$baseUrl/events/v1/my/private/calendar/?timezone=$timezone&week_start=$weekStart")
                .addHeader("Authorization", "Bearer $apiKey")
                .build()

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

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

                // Parse calendar data
                val calendarData = parseCalendarData(calendarJson)
                Log.d("allgramCalendar", "✅ Calendar data retrieved")
                Result.success(calendarData)
            } else {
                Log.e("allgramCalendar", "Failed to get calendar data: ${response.code}")
                Result.failure(Exception("Server error: ${response.code}"))
            }
        } catch (e: Exception) {
            Log.e("allgramCalendar", "Exception getting calendar data", e)
            Result.failure(e)
        }
    }

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

    private fun handleWebSocketMessage(json: JSONObject) {
        when {
            json.has("action") -> {
                val action = json.getString("action")
                val eventId = json.optString("event_id", "")
                handleSystemEvent(action, eventId)
            }
            json.has("event_id") -> {
                val event = parseEventFromJson(json)
                event?.let { handleEventUpdate(it) }
            }
        }
    }

    private fun handleSystemEvent(action: String, eventId: String) {
        Log.d("allgramCalendar", "System event: $action for event: $eventId")
        systemEventCallbacks.forEach { callback ->
            callback(action, eventId)
        }
    }

    private fun handleEventUpdate(event: CalendarEvent) {
        Log.d("allgramCalendar", "Event update: ${event.eventName}")
        eventCallbacks.forEach { callback ->
            callback(event)
        }
    }

    private fun parseEventFromJson(json: JSONObject): CalendarEvent? {
        return try {
            CalendarEvent(
                eventId = json.optString("event_id", ""),
                eventName = json.optString("event_name", ""),
                eventDescription = json.optString("event_description", ""),
                startTime = json.optLong("event_start_datetime", 0),
                endTime = json.optLong("event_end_datetime", 0),
                location = json.optString("event_location", null),
                isPublic = json.optBoolean("is_public", false),
                isUrgent = json.optBoolean("is_urgent", false),
                participants = emptyList(), // Parse from participants array
                creationDatetime = json.optLong("creation_datetime", System.currentTimeMillis() / 1000)
            )
        } catch (e: Exception) {
            Log.e("allgramCalendar", "Failed to parse event", e)
            null
        }
    }

    private fun parseCalendarData(json: JSONObject): List<CalendarDay> {
        // Implementation for parsing calendar data
        return emptyList()
    }

    // MARK: - Callbacks
    fun addEventCallback(callback: (CalendarEvent) -> Unit) {
        eventCallbacks.add(callback)
    }

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

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

// MARK: - ViewModel
class CalendarViewModel(
    private val calendarService: allgramCalendarService
) : ViewModel() {

    private val _events = MutableStateFlow<List<CalendarEvent>>(emptyList())
    val events: StateFlow<List<CalendarEvent>> = _events.asStateFlow()

    private val _selectedDate = MutableStateFlow<CalendarDay?>(null)
    val selectedDate: StateFlow<CalendarDay?> = _selectedDate.asStateFlow()

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

    init {
        setupCalendarService()
    }

    private fun setupCalendarService() {
        calendarService.addEventCallback { event ->
            _events.value = _events.value + event
        }

        calendarService.addSystemEventCallback { action, eventId ->
            when (action) {
                "event_deleted" -> {
                    _events.value = _events.value.filter { it.eventId != eventId }
                }
                "event_updated" -> {
                    // Handle event update
                }
            }
        }
    }

    fun createEvent(name: String, description: String, startTime: Long, endTime: Long, participants: List<String>) {
        viewModelScope.launch {
            _isLoading.value = true
            try {
                val result = calendarService.createEvent(name, description, startTime, endTime, participants)
                result.onSuccess { event ->
                    _events.value = _events.value + event
                }.onFailure { error ->
                    Log.e("CalendarViewModel", "Failed to create event", error)
                }
            } finally {
                _isLoading.value = false
            }
        }
    }

    fun loadCalendarData(timezone: String = "UTC") {
        viewModelScope.launch {
            _isLoading.value = true
            try {
                val result = calendarService.getCalendarData(timezone)
                result.onSuccess { calendarData ->
                    // Process calendar data
                }.onFailure { error ->
                    Log.e("CalendarViewModel", "Failed to load calendar data", error)
                }
            } finally {
                _isLoading.value = false
            }
        }
    }

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

// MARK: - Compose UI
@Composable
fun CalendarScreen(
    viewModel: CalendarViewModel = viewModel { CalendarViewModel(allgramCalendarService("your-api-key")) }
) {
    val events by viewModel.events.collectAsState()
    val isLoading by viewModel.isLoading.collectAsState()

    LazyColumn {
        items(events) { event ->
            EventItem(
                event = event,
                onClick = { /* Handle event click */ }
            )
        }
    }

    if (isLoading) {
        CircularProgressIndicator()
    }
}

@Composable
fun EventItem(
    event: CalendarEvent,
    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 = event.eventName,
                    style = MaterialTheme.typography.h6
                )
                if (event.isUrgent) {
                    Icon(
                        imageVector = Icons.Default.Warning,
                        contentDescription = "Urgent Event",
                        tint = Color.Red
                    )
                }
            }

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

            Text(
                text = "${event.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 calendar 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 calendar integration to the next level? Explore our comprehensive resources and advanced features to build enterprise-grade calendar 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 calendar 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 →