Module Structure
The OpenChat Bot SDK is organized into several core modules that work together to provide bot functionality:Bot/
Core bot functionality including registration, initialization, and message handling
OC/
OpenChat API integration for interacting with groups, channels, and communities
Governance/
NNS and SNS governance canister integration for proposal tracking
Proposal/
Proposal management and formatting utilities
TallyBot/
Tally tracking and voting statistics bot implementation
ProposalBot/
Automated proposal notification bot implementation
Log/
Logging and debugging utilities
Guards
Access control and authorization
BotService: The Foundation
TheBotService module (located in backend/Bot/BotService.mo) provides the core functionality for all bot implementations:
Key Features
Bot Registration and Initialization
Bot Registration and Initialization
The
initBot() method handles OpenChat bot registration:- Requires 10 XDR (10 trillion cycles) as registration fee
- Registers with the User Index Canister (
4bkt6-4aaaa-aaaaf-aaaiq-cai) - Updates bot status from
#NotInitialized→#Initializing→#Initialized
Group and Community Management
Group and Community Management
BotService provides methods for joining groups and communities:
joinGroup(): Join public or private groups with optional invite codesjoinCommunity(): Join communities on OpenChatjoinChannel(): Join specific channels within a community
Message Operations
Message Operations
Comprehensive message handling capabilities:
sendGroupMessage(): Send messages to groupssendChannelMessage(): Send messages to community channelseditGroupMessage()/editChannelMessage(): Edit existing messagesgetGroupMessagesByIndex(): Retrieve messages by indexgetLatestGroupMessageIndex(): Get the latest message index
Message ID Management
Message ID Management
Built-in message tracking system:Methods:
saveMessageId(): Store message ID with a keygetMessageId(): Retrieve stored message IDdeleteMessageId(): Remove specific message IDdeleteAllMessageIds(): Clear all stored message IDs
Stable Variables Pattern
The SDK uses Motoko’s stable variable pattern to preserve state across canister upgrades:BotModel Structure
The stable keyword ensures that these data structures persist when the canister is upgraded, preventing data loss during updates.
Access Control with Guards
TheGuards module (backend/Guards.mo) provides custodian-based access control:
Usage Pattern
Custodians
List of principals with administrative access to the bot
Notifiers
Separate list for principals authorized to send updates (used in TallyBot)
Guard Functions
isAnonymous(): Check if caller is the anonymous principalisCanisterPrincipal(): Validate that a principal is a canister (ends with-cai)isCustodian(): Verify custodian access
Logging and Metrics
TheLogService module provides structured logging with different severity levels:
Log Levels
Usage
Log Structure
Logs are stored in a circular buffer with a configurable max size (default: 100 entries) to prevent memory overflow.
Architecture Patterns
Service-Oriented Design
Each major feature is encapsulated in its own service class:- BotService: Bot lifecycle and messaging
- OCService: OpenChat API wrapper
- GovernanceService: NNS/SNS governance interaction
- ProposalService: Proposal data management
- LogService: Logging functionality
Separation of Concerns
Dependency Injection
Services receive their dependencies through constructor injection:- Testability: Easy to mock dependencies
- Modularity: Services can be used independently
- Maintainability: Clear dependency relationships
Error Handling
The SDK uses Motoko’sResult type for error handling:
Pattern Usage
Best Practice
Always handle both
#ok and #err cases when working with Result types to ensure robust error handling.