Admin SDK
For trusted server-to-server communication. Requires your secret API key.
Installation
Install the Paanj Admin SDK for your server-side environment.
npm install @paanj/admin @paanj/chat-admin
go get github.com/paanj-cloud/paanj-go
Initialization & Connection
Initialize the client with your secret API key. This is a one-time setup for your server.
import { PaanjAdmin } from '@paanj/admin';
import { AdminChat } from '@paanj/chat-admin';
const admin = new PaanjAdmin('YOUR_SECRET_API_KEY');
await admin.connect();
const chat = new AdminChat(admin);
(async () => {
try {
// Listen to events
chat.messages.onCreate((msg) => console.log('New message:', msg));
console.log('Successfully connected to Paanj!');
} catch (error) {
console.error('Failed to connect:', error);
}
})();
package main
import (
"log"
adminpkg "github.com/paanj-cloud/paanj-go/admin"
)
func main() {
admin := adminpkg.NewAdmin("YOUR_SECRET_API_KEY", adminpkg.AdminOptions{
ApiUrl: "https://api.paanj.com",
WsUrl: "wss://ws.paanj.com",
})
if err := admin.Connect(); err != nil {
log.Fatalf("Failed to connect: %v", err)
}
defer admin.Disconnect()
log.Println("Successfully connected to Paanj!")
}
Create a Participant
Provision a new participant (user) in your system.
(async () => {
const newUser = await chat.users.create({
email: 'john@example.com',
name: 'John Doe',
userData: { avatar: 'https://example.com/avatar.png' }
});
console.log('Participant created:', newUser.userId);
})();
package main
import (
"log"
adminpkg "github.com/paanj-cloud/paanj-go/admin"
chatadmin "github.com/paanj-cloud/paanj-go/chat/admin"
)
func createParticipant() {
admin := adminpkg.NewAdmin("YOUR_SECRET_API_KEY", adminpkg.AdminOptions{
ApiUrl: "https://api.paanj.com",
WsUrl: "wss://ws.paanj.com",
})
chat := chatadmin.NewAdminChat(admin)
user, err := chat.Users.Create(map[string]interface{}{
"email": "john@example.com",
"name": "John Doe",
"userData": map[string]interface{}{
"avatar": "https://example.com/avatar.png",
},
})
if err != nil {
log.Fatalf("create participant failed: %v", err)
}
log.Printf("Participant created: %v", user["userId"])
}
Update a Participant
Update an existing participant's data.
(async () => {
await chat.users.update('user-123', {
email: 'newemail@example.com',
userData: {
name: 'Johnathan Doe',
avatar: 'https://example.com/new-avatar.png',
status: 'online'
}
});
console.log('Participant updated successfully.');
})();
package main
import (
"log"
adminpkg "github.com/paanj-cloud/paanj-go/admin"
chatadmin "github.com/paanj-cloud/paanj-go/chat/admin"
)
func updateParticipant() {
admin := adminpkg.NewAdmin("YOUR_SECRET_API_KEY", adminpkg.AdminOptions{
ApiUrl: "https://api.paanj.com",
WsUrl: "wss://ws.paanj.com",
})
chat := chatadmin.NewAdminChat(admin)
_, err := chat.Users.Update("user-123", map[string]interface{}{
"email": "newemail@example.com",
"userData": map[string]interface{}{
"name": "Johnathan Doe",
"avatar": "https://example.com/new-avatar.png",
"status": "online",
},
})
if err != nil {
log.Fatalf("update participant failed: %v", err)
}
log.Println("Participant updated successfully")
}
Delete a Participant
Permanently delete a participant from your system. This action cannot be undone.
(async () => {
await chat.users.delete('user-123');
console.log('Participant deleted successfully.');
})();
package main
import (
"log"
adminpkg "github.com/paanj-cloud/paanj-go/admin"
chatadmin "github.com/paanj-cloud/paanj-go/chat/admin"
)
func deleteParticipant() {
admin := adminpkg.NewAdmin("YOUR_SECRET_API_KEY", adminpkg.AdminOptions{
ApiUrl: "https://api.paanj.com",
WsUrl: "wss://ws.paanj.com",
})
chat := chatadmin.NewAdminChat(admin)
if _, err := chat.Users.Delete("user-123"); err != nil {
log.Fatalf("delete participant failed: %v", err)
}
log.Println("Participant deleted successfully")
}
Create a Conversation
Create a new conversation for your participants.
(async () => {
const groupChat = await chat.conversations.create({
name: 'Project Phoenix',
members: [
{ userId: 'user-123', role: 'admin' },
{ userId: 'user-456', role: 'member' }
],
metadata: { department: 'engineering' }
});
console.log('Group chat created:', groupChat.id);
})();
package main
import (
"log"
adminpkg "github.com/paanj-cloud/paanj-go/admin"
chatadmin "github.com/paanj-cloud/paanj-go/chat/admin"
)
func createConversation() {
admin := adminpkg.NewAdmin("YOUR_SECRET_API_KEY", adminpkg.AdminOptions{
ApiUrl: "https://api.paanj.com",
WsUrl: "wss://ws.paanj.com",
})
chat := chatadmin.NewAdminChat(admin)
conversation, err := chat.Conversations.Create(map[string]interface{}{
"name": "Project Phoenix",
"members": []map[string]interface{}{
{"userId": "123", "role": "admin"},
{"userId": "456", "role": "member"},
},
"metadata": map[string]interface{}{"department": "engineering"},
})
if err != nil {
log.Fatalf("create conversation failed: %v", err)
}
log.Printf("Group chat created: %v", conversation["id"])
}
Update a Conversation
Manage participants and their permissions within a conversation.
Add Participants
const conv = chat.conversation('group-abc');
await conv.addParticipant('user-789', 'member'); // Role is optional, defaults to 'member'
package main
import (
"log"
adminpkg "github.com/paanj-cloud/paanj-go/admin"
chatadmin "github.com/paanj-cloud/paanj-go/chat/admin"
)
func addParticipant() {
admin := adminpkg.NewAdmin("YOUR_SECRET_API_KEY", adminpkg.AdminOptions{
ApiUrl: "https://api.paanj.com",
WsUrl: "wss://ws.paanj.com",
})
chat := chatadmin.NewAdminChat(admin)
if _, err := chat.Conversation("group-abc").AddParticipant("user-789", "member"); err != nil {
log.Fatalf("add participant failed: %v", err)
}
log.Println("Participant added successfully")
}
Remove Participants
const conv = chat.conversation('group-abc');
await conv.removeParticipant('user-456');
package main
import (
"log"
adminpkg "github.com/paanj-cloud/paanj-go/admin"
chatadmin "github.com/paanj-cloud/paanj-go/chat/admin"
)
func removeParticipant() {
admin := adminpkg.NewAdmin("YOUR_SECRET_API_KEY", adminpkg.AdminOptions{
ApiUrl: "https://api.paanj.com",
WsUrl: "wss://ws.paanj.com",
})
chat := chatadmin.NewAdminChat(admin)
if _, err := chat.Conversation("group-abc").RemoveParticipant("user-456"); err != nil {
log.Fatalf("remove participant failed: %v", err)
}
log.Println("Participant removed successfully")
}
Delete a Conversation
Permanently delete a conversation and all its associated messages. This action cannot be undone.
await chat.conversations.delete('group-abc');
package main
import (
"log"
adminpkg "github.com/paanj-cloud/paanj-go/admin"
chatadmin "github.com/paanj-cloud/paanj-go/chat/admin"
)
func deleteConversation() {
admin := adminpkg.NewAdmin("YOUR_SECRET_API_KEY", adminpkg.AdminOptions{
ApiUrl: "https://api.paanj.com",
WsUrl: "wss://ws.paanj.com",
})
chat := chatadmin.NewAdminChat(admin)
if _, err := chat.Conversations.Delete("group-abc"); err != nil {
log.Fatalf("delete conversation failed: %v", err)
}
log.Println("Conversation deleted successfully")
}
Manage Blocks
As an admin, you can unilaterally block or unblock communication between any two participants.
Block User
// Block 'user-456' on behalf of 'user-123'
await chat.users('user-123').block('user-456');
package main
import (
"log"
adminpkg "github.com/paanj-cloud/paanj-go/admin"
chatadmin "github.com/paanj-cloud/paanj-go/chat/admin"
)
func blockUser() {
admin := adminpkg.NewAdmin("YOUR_SECRET_API_KEY", adminpkg.AdminOptions{
ApiUrl: "https://api.paanj.com",
WsUrl: "wss://ws.paanj.com",
})
chat := chatadmin.NewAdminChat(admin)
if _, err := chat.Users.Block("user-123", "user-456"); err != nil {
log.Fatalf("block failed: %v", err)
}
log.Println("Block applied successfully")
}
Unblock User
// Allow 'user-456' to contact 'user-123' again
await chat.users('user-123').unblock('user-456');
package main
import (
"log"
adminpkg "github.com/paanj-cloud/paanj-go/admin"
chatadmin "github.com/paanj-cloud/paanj-go/chat/admin"
)
func unblockUser() {
admin := adminpkg.NewAdmin("YOUR_SECRET_API_KEY", adminpkg.AdminOptions{
ApiUrl: "https://api.paanj.com",
WsUrl: "wss://ws.paanj.com",
})
chat := chatadmin.NewAdminChat(admin)
if _, err := chat.Users.Unblock("user-123", "user-456"); err != nil {
log.Fatalf("unblock failed: %v", err)
}
log.Println("Unblock applied successfully")
}
Listen for Admin Events
Listen for system-level events to build audit trails, monitoring, or automated workflows.
chat.users.onCreate((user) => {
console.log('A new participant was created:', user);
});
chat.conversations.onCreate((conversation) => {
console.log('A new conversation was created:', conversation);
});
package main
import (
"log"
adminpkg "github.com/paanj-cloud/paanj-go/admin"
chatadmin "github.com/paanj-cloud/paanj-go/chat/admin"
)
func main() {
admin := adminpkg.NewAdmin("YOUR_SECRET_API_KEY", adminpkg.AdminOptions{
ApiUrl: "https://api.paanj.com",
WsUrl: "wss://ws.paanj.com",
})
if err := admin.Connect(); err != nil {
log.Fatalf("connect failed: %v", err)
}
defer admin.Disconnect()
chat := chatadmin.NewAdminChat(admin)
chat.Users.OnCreate(func(data interface{}) {
log.Printf("A new participant was created: %+v", data)
})
chat.Conversations.OnCreate(func(data interface{}) {
log.Printf("A new conversation was created: %+v", data)
})
chat.Messages.OnCreate(func(data interface{}) {
log.Printf("A new message was created: %+v", data)
})
}
Subscribe to a Conversation
Subscribe to all messages sent to a specific conversation. Listen for real-time message events.
(async () => {
const conversation = chat.conversation('group-abc');
conversation.onMessage((message) => {
console.log('New message:', message);
});
})();
package main
import (
"log"
adminpkg "github.com/paanj-cloud/paanj-go/admin"
chatadmin "github.com/paanj-cloud/paanj-go/chat/admin"
)
func main() {
admin := adminpkg.NewAdmin("YOUR_SECRET_API_KEY", adminpkg.AdminOptions{
ApiUrl: "https://api.paanj.com",
WsUrl: "wss://ws.paanj.com",
})
if err := admin.Connect(); err != nil {
log.Fatalf("connect failed: %v", err)
}
defer admin.Disconnect()
chat := chatadmin.NewAdminChat(admin)
conversation := chat.Conversation("group-abc")
conversation.OnMessage(func(message interface{}) {
log.Printf("New message: %+v", message)
})
}
Send a Message
Send a message to a specific conversation from the admin.
(async () => {
const conversation = chat.conversation('group-abc');
await conversation.send('Hello, world!');
console.log('Message sent successfully.');
})();
Note: The SDK currently only supports sending string content. If you want to send JSON, please stringify it first.
package main
import (
"log"
adminpkg "github.com/paanj-cloud/paanj-go/admin"
chatadmin "github.com/paanj-cloud/paanj-go/chat/admin"
)
func main() {
admin := adminpkg.NewAdmin("YOUR_SECRET_API_KEY", adminpkg.AdminOptions{
ApiUrl: "https://api.paanj.com",
WsUrl: "wss://ws.paanj.com",
})
chat := chatadmin.NewAdminChat(admin)
if _, err := chat.Conversation("group-abc").Send(
"Hello, world!",
map[string]interface{}{"source": "admin-docs"},
); err != nil {
log.Fatalf("send failed: %v", err)
}
}
Client SDK
For client-side applications. Requires a public API key.
Installation
Install the Paanj Client SDK to build your front-end application.
npm install @paanj/client @paanj/chat-client
go get github.com/paanj-cloud/paanj-go
flutter pub add paanj_client paanj_chat_client
Initialization
Initialize the client with your public API key.
import { PaanjClient } from '@paanj/client';
import { ChatClient } from '@paanj/chat-client';
const client = new PaanjClient({
apiKey: 'YOUR_PUBLIC_API_KEY'
});
const chat = new ChatClient(client);
package main
import (
"log"
chatclient "github.com/paanj-cloud/paanj-go/chat/client"
"github.com/paanj-cloud/paanj-go/client"
)
func main() {
c := client.NewClient(client.ClientOptions{ApiKey: "YOUR_PUBLIC_API_KEY"})
chat := chatclient.NewChatClient(c)
_ = chat
log.Println("Initialized Paanj Go client and chat client")
}
import 'package:paanj_client/paanj_client.dart';
import 'package:paanj_chat_client/paanj_chat_client.dart';
final client = PaanjClient(
'YOUR_PUBLIC_API_KEY',
options: ClientOptions(
apiKey: 'YOUR_PUBLIC_API_KEY',
apiUrl: 'https://api.paanj.com',
wsUrl: 'wss://ws.paanj.com',
persistSession: true,
),
);
final chat = ChatClient(client);
Authentication
Create an anonymous user to start interacting. This will return a session with an access token.
// Create an anonymous user with private data
// Private data is not stored but sent to webhooks
const session = await client.authenticateAnonymous({
name: 'John Doe',
metadata: { email: 'john@example.com' }
}, {
internalId: 'u_789'
});
console.log('User ID:', session.userId);
console.log('Access Token:', session.accessToken);
// Authenticate anonymous user (example)
package main
import (
"log"
"github.com/paanj-cloud/paanj-go/client"
)
func main() {
c := client.NewClient(client.ClientOptions{ApiKey: "YOUR_PUBLIC_API_KEY"})
auth, err := c.AuthenticateAnonymous(map[string]interface{}{"name": "Go User"}, nil)
if err != nil {
log.Fatalf("auth failed: %v", err)
}
log.Printf("Authenticated user: %s", auth.UserId)
}
final session = await client.authenticateAnonymous(
{
'name': 'Flutter User',
'metadata': {'email': 'john@example.com'},
},
);
await client.connect();
print('User ID: ${session.userId}');
print('Access Token: ${session.accessToken}');
Create a Conversation
Create a new conversation. You can add other users by their ID.
// Create a conversation
const conversation = await chat.conversations.create({
name: 'Team Project',
participants: [
{ userId: 'user_456', role: 'member' } // Add another user
// You (creator) are automatically added as admin
],
metadata: { isPrivate: false }
});
// You are automatically subscribed to this conversation
console.log('Conversation created:', conversation.id);
package main
import (
"log"
chatclient "github.com/paanj-cloud/paanj-go/chat/client"
"github.com/paanj-cloud/paanj-go/client"
)
func main() {
c := client.NewClient(client.ClientOptions{ApiKey: "YOUR_PUBLIC_API_KEY"})
chat := chatclient.NewChatClient(c)
if _, err := c.AuthenticateAnonymous(map[string]interface{}{"name": "Go User"}, nil); err != nil {
log.Fatalf("auth failed: %v", err)
}
conversation, err := chat.Conversations.Create(map[string]interface{}{
"name": "Team Project",
"participants": []map[string]interface{}{
{"userId": "456", "role": "member"},
},
"metadata": map[string]interface{}{"isPrivate": false},
})
if err != nil {
log.Fatalf("create conversation failed: %v", err)
}
log.Printf("Conversation created: %v", conversation["id"])
}
final conversation = await chat.createConversation(
CreateConversationData(
name: 'Team Project',
participants: [
ConversationMember(userId: 'user_456', role: 'member'),
],
metadata: {'isPrivate': false},
),
);
print('Conversation created: ${conversation.id}');
List Conversations
Retrieve a list of conversations you are a member of.
// List conversations with fluent API
const conversations = await chat.conversations.list()
.limit(10)
.offset(0);
console.log('Conversations:', conversations);
// List conversations (Go)
result, err := chat.Conversations.List(map[string]interface{}{
"limit": 10,
"offset": 0,
})
if err != nil {
log.Fatalf("list conversations failed: %v", err)
}
log.Printf("Conversations response: %+v", result)
if conversations, ok := result["conversations"]; ok {
log.Printf("Conversations: %+v", conversations)
}
final conversations = await chat.listConversations(
filters: ConversationFilters(limit: 10, page: 1),
);
print('Conversations: $conversations');
Real-time Messaging
Connect to the WebSocket server to send and receive messages in real-time.
// Connect to WebSocket
await client.connect();
// Listen for messages globally
chat.conversations.onMessage((msg) => {
console.log('New message:', msg.content);
console.log('From User:', msg.senderId);
});
// Send a message
const ctx = chat.conversations(conversation.id);
await ctx.send('Hello, world!');
// Connect, listen and send (Go)
package main
import (
"log"
chatclient "github.com/paanj-cloud/paanj-go/chat/client"
"github.com/paanj-cloud/paanj-go/client"
)
func main() {
c := client.NewClient(client.ClientOptions{ApiKey: "test-api-key"})
chat := chatclient.NewChatClient(c)
conversationID := "YOUR_CONVERSATION_ID"
chat.Conversations.OnMessage(func(data interface{}) {
log.Printf("New message: %v", data)
})
if _, err := c.AuthenticateAnonymous(map[string]interface{}{"name": "Go User"}, nil); err != nil {
log.Fatalf("auth failed: %v", err)
}
if err := c.Connect(); err != nil {
log.Fatalf("connect failed: %v", err)
}
conv := chat.Conversation(conversationID)
conv.OnMessage(func(data interface{}) {
log.Printf("Conversation message: %v", data)
})
if _, err := conv.Send("Hello from Go SDK!"); err != nil {
log.Printf("send failed: %v", err)
}
}
await client.connect();
chat.onMessage((dynamic msg) {
print('New message: ${msg.content}');
print('From User: ${msg.senderId}');
});
final ctx = chat.conversation(conversation.id);
final stopConversationMessages = ctx.onMessage((Message msg) {
print('Conversation message: ${msg.content}');
});
await ctx.send('Hello, world!');
stopConversationMessages();
List Messages
Retrieve message history with a fluent API.
// List messages with fluent API
const messages = await chat.conversations(conversation.id)
.messages()
.list()
.limit(20)
.page(1);
console.log('History:', messages);
// List messages (Go)
conversationID := "YOUR_CONVERSATION_ID"
messages, err := chat.Conversation(conversationID).Messages().List(map[string]interface{}{
"limit": 20,
"offset": 0,
})
if err != nil {
log.Fatalf("list messages failed: %v", err)
}
log.Printf("History: %+v", messages)
final messages = await chat
.conversation(conversation.id)
.messages()
.list(filters: MessageFilters(limit: 20, page: 1));
print('History: $messages');
Manage Conversations
Manage conversation membership and settings.
const cnv = chat.conversations(conversation.id);
// Leave a conversation
await cnv.leave();
// List participants
const participants = await cnv.participants().list();
console.log('Participants:', participants);
// Add a participant (if you have permission)
await cnv.participants().add('user_789', 'member');
// Get conversation details
const details = await cnv.get();
console.log('Details:', details);
// Listen for updates
cnv.onUpdate((update) => {
console.log('Conversation updated:', update);
});
// Manage conversations (Go)
conversationID := "YOUR_CONVERSATION_ID"
cnv := chat.Conversation(conversationID)
participants, err := cnv.Participants().List()
if err != nil {
log.Fatalf("list participants failed: %v", err)
}
log.Printf("Participants: %+v", participants)
if _, err := cnv.Participants().Add("789", "member"); err != nil {
log.Printf("add participant failed: %v", err)
}
details, err := cnv.Get()
if err != nil {
log.Printf("get conversation failed: %v", err)
} else {
log.Printf("Details: %+v", details)
}
cnv.OnUpdate(func(data interface{}) {
log.Printf("Conversation updated: %+v", data)
})
if err := cnv.Leave(); err != nil {
log.Printf("leave conversation failed: %v", err)
}
final cnv = chat.conversation(conversation.id);
final participants = await cnv.participants().list();
print('Participants: $participants');
await cnv.participants().add('user_789', role: 'member');
final details = await cnv.get();
print('Details: $details');
final stopUpdates = cnv.onUpdate((dynamic update) {
print('Conversation updated: $update');
});
await cnv.leave();
stopUpdates();
cnv.dispose();
Block and Unblock Users
Users can block other users to prevent unwanted communication.
// Block a user
await chat.users('user_456').block();
// Get blocked users
const blockedUsers = await chat.users.getBlocked();
console.log('Blocked users:', blockedUsers);
// Unblock a user
await chat.users('user_456').unblock();
// Block and unblock users (Go)
if _, err := chat.User("456").Block(); err != nil {
log.Fatalf("block failed: %v", err)
}
blocked, err := chat.Users.GetBlocked()
if err != nil {
log.Fatalf("get blocked users failed: %v", err)
}
log.Printf("Blocked users: %+v", blocked["blockedUserIds"])
if _, err := chat.User("456").Unblock(); err != nil {
log.Fatalf("unblock failed: %v", err)
}
chat.Users.OnTokenRefresh(func(data interface{}) {
log.Printf("token updated: %+v", data)
})
await chat.user('user_456').block();
final blockedUsers = await chat.getBlockedUsers();
print('Blocked users: $blockedUsers');
await chat.user('user_456').unblock();
final stopGlobalTokenRefresh = chat.onTokenRefresh((dynamic data) {
print('Token updated: $data');
});
final stopUserTokenRefresh = chat.user('user_456').onTokenRefresh((dynamic data) {
print('User token updated: $data');
});
stopGlobalTokenRefresh();
stopUserTokenRefresh();