Documentation
¶
Index ¶
- Constants
- Variables
- func EncodeUDPAudioPacket(dst []byte, p UDPAudioPacket) (int, error)
- func HashSessionToken(token string) uint32
- type AckSettings
- type ActiveClient
- type AdminLogEntry
- type AdminLoginRequest
- type AdminLogsResponse
- type AdminUserView
- type AudioModeInfo
- type BootstrapResponse
- type BroadcastGroup
- type ButtonImageRenderConfig
- type ButtonImageRenderer
- type ButtonState
- type ChatAckInbound
- type ChatAckUpdate
- type ChatHistory
- func (h *ChatHistory) AppendForRoom(roomID string, e RoutedEvent)
- func (h *ChatHistory) AppendForUser(userID string, e RoutedEvent)
- func (h *ChatHistory) Clear()
- func (h *ChatHistory) HistoryForRooms(roomIDs []string) []RoutedEvent
- func (h *ChatHistory) HistoryForUserAndRooms(userID string, roomIDs []string) []RoutedEvent
- type CompanionAdminSummaryResponse
- type CompanionBridgeState
- type CompanionCommand
- type CompanionCommandResult
- type CompanionDiscoveryResponse
- type CompanionProfileResponse
- type CompanionPublishedProfileSummary
- type CompanionRoleUser
- type CompanionRoomDiscovery
- type Config
- type ConfigurationDocument
- type ConfigurationImportRequest
- type ConfigurationImportResponse
- type ConfigurationMetadata
- type ConfigurationUserAssignment
- type ConfigurationUserStreamDeckSettings
- type Hub
- func (h *Hub) ActiveTalkRoomForToken(token string) (string, bool)
- func (h *Hub) ActiveUserByUsername(username string) (User, bool)
- func (h *Hub) Add(c *client)
- func (h *Hub) BroadcastChatHistoryCleared()
- func (h *Hub) BroadcastConfigUpdate(data PublicBootstrapResponse)
- func (h *Hub) ClearChatHistory()
- func (h *Hub) GetActiveClients(ctx context.Context) []ActiveClient
- func (h *Hub) HasActiveSessionsForRole(roleID string) bool
- func (h *Hub) IsNativeTransport(token string) bool
- func (h *Hub) LatestRoleSession(roleID string) (Session, bool)
- func (h *Hub) LatestTokenForUsername(username string) (string, bool)
- func (h *Hub) ListenRoomsForToken(token string) []string
- func (h *Hub) PresenceForUsername(username string) (PresenceState, bool)
- func (h *Hub) RealtimeStats() HubRealtimeStats
- func (h *Hub) Remove(token string)
- func (h *Hub) RemoveWithReason(token string, reason string)
- func (h *Hub) ReplyTargetForUsername(username string) (string, string, bool)
- func (h *Hub) RoomListenerCounts() map[string]int
- func (h *Hub) RouteChatAck(senderToken string, in ChatAckInbound)
- func (h *Hub) RouteEvent(senderToken string, eventType string, e RoutedEvent)
- func (h *Hub) SendChatHistorySnapshot(token string) int
- func (h *Hub) SendChatToRole(roleID string, e RoutedEvent)
- func (h *Hub) SendChatToRoom(roomID string, e RoutedEvent)
- func (h *Hub) SendChatToUser(userID string, e RoutedEvent)
- func (h *Hub) SendPresenceSnapshot(token string)
- func (h *Hub) SendRoomChatHistory(token string, roomIDs []string) int
- func (h *Hub) SendToToken(token string, msg WSOutbound) bool
- func (h *Hub) SessionCountForUsername(username string) int
- func (h *Hub) SetBroadcastActive(token, groupID string, enabled bool)
- func (h *Hub) SetChatHook(fn func(eventType string, e RoutedEvent))
- func (h *Hub) SetMediaManager(m *MediaManager)
- func (h *Hub) SetRoomMatrix(token string, listenRooms []string, talkRooms []string)
- func (h *Hub) SetUDPAudioRelay(r *UDPAudioRelay)
- func (h *Hub) SetVoiceState(token, state string)
- func (h *Hub) SignalStateForUsername(username string) (string, string, bool)
- func (h *Hub) SignalStateWithMetadataForUsername(username string) (string, string, string, string, string, bool)
- func (h *Hub) SignalStateWithScopeForUsername(username string) (string, string, string, bool)
- func (h *Hub) SubscribePresence() (chan []PresenceState, func())
- func (h *Hub) TokensForRole(roleID string) []string
- type HubRealtimeStats
- type ImageStreamClient
- type ImageStreamCoordinator
- func (c *ImageStreamCoordinator) BroadcastImageUpdate(state ButtonState, bank, buttonIndex int)
- func (c *ImageStreamCoordinator) BroadcastImageUpdateForTarget(roleID, username string, state ButtonState, bank, buttonIndex int)
- func (c *ImageStreamCoordinator) RegisterClient(client *ImageStreamClient)
- func (c *ImageStreamCoordinator) ResetTargetCache(roleID, username string)
- func (c *ImageStreamCoordinator) UnregisterClient(client *ImageStreamClient)
- type ImageStreamMessage
- type LoginConflictResponse
- type LoginRequest
- type LoginResponse
- type LoginTakeoverRequest
- type MediaBridge
- type MediaManager
- func (m *MediaManager) BridgeNativeOpusToWebRTC(sourceToken string, opus []byte)
- func (m *MediaManager) EnsureNativeSource(sourceToken string, userID string) error
- func (m *MediaManager) EnsureNegotiation(token string)
- func (m *MediaManager) EnsurePeer(token string, user User) error
- func (m *MediaManager) HandleAnswer(token string, sdp string) error
- func (m *MediaManager) HandleICECandidate(token string, c WebRTCIceCandidate) error
- func (m *MediaManager) NoteVoiceStateTrigger()
- func (m *MediaManager) RealtimeStats() MediaRealtimeStats
- func (m *MediaManager) RemovePeer(token string)
- func (m *MediaManager) RoutingForSource(sourceToken string) map[string]bool
- func (m *MediaManager) SetBroadcastGroupActive(sourceToken, groupID string, enabled bool)
- func (m *MediaManager) SetDirectTargetActive(sourceToken, targetUserID string, enabled bool)
- func (m *MediaManager) SetIdleRoomFallbackSuppressed(sourceToken string, suppressed bool)
- func (m *MediaManager) SetUDPAudioRelay(relay *UDPAudioRelay)
- func (m *MediaManager) SyncRouting()
- func (m *MediaManager) SyncRoutingSource(sourceToken string)
- type MediaRealtimeStats
- type NativeAudioEndpoint
- type PolicyCacheStats
- type PresenceState
- type PublicBootstrapResponse
- type RealtimeStatsResponse
- type Role
- type Room
- type RoomMatrixEvent
- type RoomPermissionEntry
- type RoutedEvent
- type RoutingStatusEvent
- type Server
- func (s *Server) HandleDebugButtonImage(w http.ResponseWriter, r *http.Request)
- func (s *Server) HandleDebugButtonImagePreview(w http.ResponseWriter, r *http.Request)
- func (s *Server) HandleImageStreamWebSocket(w http.ResponseWriter, r *http.Request)
- func (s *Server) ListenAndServe() error
- func (s *Server) Shutdown(ctx context.Context) error
- type Session
- type SessionManager
- func (m *SessionManager) CancelScheduledDisconnectLogout(token string) bool
- func (m *SessionManager) Create(user User) Session
- func (m *SessionManager) Delete(token string)
- func (m *SessionManager) DeleteByRole(roleID string) []Session
- func (m *SessionManager) DeleteByUsername(username string) []Session
- func (m *SessionManager) Get(token string) (Session, bool)
- func (m *SessionManager) LatestForRole(roleID string) (Session, bool)
- func (m *SessionManager) ScheduleDisconnectLogout(token string, delay time.Duration) bool
- type SessionRevokedEvent
- type StatusResponse
- type Store
- func (s *Store) BindTelegramAllowlistEntryNumericID(ctx context.Context, telegramUsername, numericID string) error
- func (s *Store) BroadcastGroupAllowsRole(ctx context.Context, groupID, roleID string) (bool, error)
- func (s *Store) BroadcastGroupRoomIDs(ctx context.Context, groupID string) ([]string, error)
- func (s *Store) BulkUpdateRoomPermissions(ctx context.Context, entries []RoomPermissionEntry) error
- func (s *Store) Close() error
- func (s *Store) CreateBroadcastGroup(ctx context.Context, id, name string, roomIDs, allowedRoleIDs []string) error
- func (s *Store) CreateRole(ctx context.Context, id, name, defaultRoomID, defaultVoiceMode string, ...) error
- func (s *Store) CreateRoom(ctx context.Context, id, name string, ...) error
- func (s *Store) CreateTelegramAllowlistEntry(ctx context.Context, id, telegramUsername, kesherUsername string) error
- func (s *Store) CreateTelegramMapping(ctx context.Context, id, chatID, label, roomID string) error
- func (s *Store) CreateTelegramUserMapping(ctx context.Context, id, telegramUserID, username, privateChatID string) error
- func (s *Store) DeleteBroadcastGroup(ctx context.Context, id string) error
- func (s *Store) DeleteRole(ctx context.Context, id string) error
- func (s *Store) DeleteRoleStreamDeckSettings(ctx context.Context, roleID string) error
- func (s *Store) DeleteRoom(ctx context.Context, id string) error
- func (s *Store) DeleteTelegramAllowlistEntry(ctx context.Context, id string) error
- func (s *Store) DeleteTelegramMapping(ctx context.Context, id string) error
- func (s *Store) DeleteUser(ctx context.Context, id string) error
- func (s *Store) DeleteUserStreamDeckSettings(ctx context.Context, userID string) error
- func (s *Store) FindTelegramAllowlistEntryByNumericID(ctx context.Context, numericID string) (TelegramAllowlistEntry, error)
- func (s *Store) FindTelegramAllowlistEntryByUsername(ctx context.Context, telegramUsername string) (TelegramAllowlistEntry, error)
- func (s *Store) FindTelegramMappingByChatID(ctx context.Context, chatID string) (TelegramMapping, error)
- func (s *Store) FindTelegramUserMappingByTelegramID(ctx context.Context, telegramUserID string) (TelegramUserMapping, error)
- func (s *Store) FindTelegramUserMappingByUsername(ctx context.Context, username string) (TelegramUserMapping, error)
- func (s *Store) FindUserByID(ctx context.Context, id string) (User, error)
- func (s *Store) FindUserByUsername(ctx context.Context, username string) (User, error)
- func (s *Store) ForcedListenRoomIDs(ctx context.Context, roleID string) ([]string, error)
- func (s *Store) GetAdminPIN(ctx context.Context) (string, error)
- func (s *Store) GetAllCompanionRolePages(ctx context.Context) (map[string]int, error)
- func (s *Store) GetBirthdayUsersToday(ctx context.Context) ([]string, error)
- func (s *Store) GetCompanionProfileByRole(ctx context.Context, roleID string) (CompanionProfileResponse, error)
- func (s *Store) GetCompanionRolePage(ctx context.Context, roleID string) (int, error)
- func (s *Store) GetRoleStreamDeckSettings(ctx context.Context, roleID string) (StreamDeckSettings, error)
- func (s *Store) GetSubscribedTelegramUsersForRoom(ctx context.Context, roomID string) ([]string, error)
- func (s *Store) GetTelegramUserRoomSubscriptions(ctx context.Context, telegramUserID string) ([]string, error)
- func (s *Store) GetUserStreamDeckSettings(ctx context.Context, userID string) (StreamDeckSettings, error)
- func (s *Store) IsTelegramUserSubscribedToRoom(ctx context.Context, telegramUserID, roomID string) (bool, error)
- func (s *Store) ListBroadcastGroups(ctx context.Context) ([]BroadcastGroup, error)
- func (s *Store) ListRoleStreamDeckSettings(ctx context.Context) (map[string]StreamDeckSettings, error)
- func (s *Store) ListRoles(ctx context.Context) ([]Role, error)
- func (s *Store) ListRooms(ctx context.Context) ([]Room, error)
- func (s *Store) ListTelegramAllowlistEntries(ctx context.Context) ([]TelegramAllowlistEntry, error)
- func (s *Store) ListTelegramMappings(ctx context.Context) ([]TelegramMapping, error)
- func (s *Store) ListUserStreamDeckSettingsByUsername(ctx context.Context) ([]ConfigurationUserStreamDeckSettings, error)
- func (s *Store) ListUsers(ctx context.Context) ([]User, error)
- func (s *Store) PolicyCacheStats() PolicyCacheStats
- func (s *Store) PublishCompanionProfile(ctx context.Context, roleID string, publishedByUserID string, ...) (CompanionProfileResponse, error)
- func (s *Store) ReplaceConfiguration(ctx context.Context, state configurationState, updateUsers bool, ...) error
- func (s *Store) ResolveSinglePublishedCompanionRole(ctx context.Context) (string, error)
- func (s *Store) RoleExists(ctx context.Context, roleID string) (bool, error)
- func (s *Store) RoomAllowsReceiverRole(ctx context.Context, roomID, roleID string) (bool, error)
- func (s *Store) RoomAllowsSenderRole(ctx context.Context, roomID, roleID string) (bool, error)
- func (s *Store) SaveCompanionRolePage(ctx context.Context, roleID string, pageNumber int) error
- func (s *Store) SetAdminPIN(ctx context.Context, pin string) error
- func (s *Store) SetBirthdayUsersToday(ctx context.Context, usernames []string) error
- func (s *Store) SetBroadcastGroupPriorityLevel(ctx context.Context, id string, priorityLevel int) error
- func (s *Store) SetRoomPriorityLevel(ctx context.Context, id string, priorityLevel int) error
- func (s *Store) ToggleTelegramUserRoomSubscription(ctx context.Context, telegramUserID, roomID string) (bool, error)
- func (s *Store) UpdateBroadcastGroup(ctx context.Context, id, name string, roomIDs, allowedRoleIDs []string) error
- func (s *Store) UpdateRole(ctx context.Context, id, name, defaultRoomID, defaultVoiceMode string, ...) error
- func (s *Store) UpdateRoom(ctx context.Context, id, name string, ...) error
- func (s *Store) UpdateTelegramMapping(ctx context.Context, id, chatID, label, roomID string) error
- func (s *Store) UpdateTelegramUserMapping(ctx context.Context, id, username string) error
- func (s *Store) UpsertRoleStreamDeckSettings(ctx context.Context, roleID string, settings StreamDeckSettings) (StreamDeckSettings, error)
- func (s *Store) UpsertUser(ctx context.Context, username, roleID string) (User, error)
- func (s *Store) UpsertUserStreamDeckSettings(ctx context.Context, userID string, settings StreamDeckSettings) (StreamDeckSettings, error)
- type StreamDeckActionType
- type StreamDeckButtonAction
- type StreamDeckButtonConfig
- type StreamDeckPageConfig
- type StreamDeckPageType
- type StreamDeckSettings
- type TelegramAllowlistEntry
- type TelegramBot
- type TelegramCallbackQuery
- type TelegramChat
- type TelegramInlineKeyboardButton
- type TelegramInlineKeyboardMarkup
- type TelegramInlineQuery
- type TelegramInlineQueryResultArticle
- type TelegramInputMessageContent
- type TelegramMapping
- type TelegramMessage
- type TelegramStatusResponse
- type TelegramUpdate
- type TelegramUser
- type TelegramUserMapping
- type UDPAudioPacket
- type UDPAudioRelay
- func (r *UDPAudioRelay) Close()
- func (r *UDPAudioRelay) IsNativeRegistered(token string) bool
- func (r *UDPAudioRelay) LocalAddr() net.Addr
- func (r *UDPAudioRelay) PeerByToken(token string) *udpPeer
- func (r *UDPAudioRelay) RemovePeer(token string)
- func (r *UDPAudioRelay) SendOpusToToken(destToken string, opus []byte)
- func (r *UDPAudioRelay) SetMediaBridge(b MediaBridge)
- func (r *UDPAudioRelay) Start(addr string) error
- func (r *UDPAudioRelay) Stats() UDPAudioStats
- type UDPAudioStats
- type User
- type VersionInfo
- type WSInbound
- type WSOutbound
- type WebRTCAnswer
- type WebRTCIceCandidate
- type WebRTCOffer
Constants ¶
const ( StreamDeckGridColumns = 5 StreamDeckGridRows = 3 StreamDeckButtonCount = StreamDeckGridColumns * StreamDeckGridRows )
const ( MinPriorityLevel = 0 MaxPriorityLevel = 3 DefaultPriority = 1 )
Variables ¶
var ( ErrInvalidInput = errors.New("invalid input") ErrConflict = errors.New("conflict") ErrNotFound = errors.New("not found") )
var ( // Version is the application version, set via -ldflags "-X github.com/KesherCom/kesher/backend/internal/app.Version=..." Version string // BuildTimestamp is the build timestamp in RFC3339 format, set via -ldflags BuildTimestamp string )
Version and BuildTimestamp are set during build via ldflags. For local development builds, they default to "dev" and current time.
Functions ¶
func EncodeUDPAudioPacket ¶
func EncodeUDPAudioPacket(dst []byte, p UDPAudioPacket) (int, error)
EncodeUDPAudioPacket serialises a packet into dst. dst must be large enough (header + len(payload)). Returns the total encoded length.
func HashSessionToken ¶
HashSessionToken derives the short token identifier used in audio/heartbeat packets so the relay does not have to ship the full token on every frame.
Types ¶
type AckSettings ¶
type AckSettings struct {
Enabled bool `json:"enabled"`
}
type ActiveClient ¶
type AdminLogEntry ¶
type AdminLogEntry struct {
TimestampUnixMs int64 `json:"timestampUnixMs"`
Level string `json:"level"`
Category string `json:"category"`
Message string `json:"message"`
Method string `json:"method,omitempty"`
Path string `json:"path,omitempty"`
Status int `json:"status,omitempty"`
DurationMs int64 `json:"durationMs,omitempty"`
Username string `json:"username,omitempty"`
RoleID string `json:"roleId,omitempty"`
RemoteAddr string `json:"remoteAddr,omitempty"`
Error string `json:"error,omitempty"`
}
type AdminLoginRequest ¶
type AdminLoginRequest struct {
PIN string `json:"pin"`
}
type AdminLogsResponse ¶
type AdminLogsResponse struct {
Entries []AdminLogEntry `json:"entries"`
Total int `json:"total"`
TimestampUnixMs int64 `json:"timestampUnixMs"`
}
type AdminUserView ¶
type AudioModeInfo ¶
type AudioModeInfo struct {
Mode string `json:"mode"`
}
AudioModeInfo tells the client which transport the server expects. "native" instructs Tauri clients to skip WebRTC and use the native UDP pipeline; "webrtc" is the fallback (browser, or native when relay is unavailable).
type BootstrapResponse ¶
type BootstrapResponse struct {
Self User `json:"self"`
Roles []Role `json:"roles"`
Rooms []Room `json:"rooms"`
BroadcastGroups []BroadcastGroup `json:"broadcastGroups"`
Users []User `json:"users"`
AckEnabled bool `json:"ackEnabled"`
AppVersion VersionInfo `json:"appVersion"`
}
type BroadcastGroup ¶
type ButtonImageRenderConfig ¶
ButtonImageRenderConfig holds rendering configuration
type ButtonImageRenderer ¶
type ButtonImageRenderer struct {
// contains filtered or unexported fields
}
ButtonImageRenderer renders button state to image buffers
func NewButtonImageRenderer ¶
func NewButtonImageRenderer(config *ButtonImageRenderConfig) (*ButtonImageRenderer, error)
NewButtonImageRenderer creates a new renderer with default config
func (*ButtonImageRenderer) RenderButtonImage ¶
func (r *ButtonImageRenderer) RenderButtonImage(state ButtonState) ([]byte, error)
RenderButtonImage renders a button state as a PNG using the same card palette and typography rules as web/src/lib/streamDeckHardwareFeedback.ts.
type ButtonState ¶
type ButtonState struct {
Channel string
State string // "IDLE", "TALK", "LISTEN", "BROADCAST"
Label string
Subtitle string
EffectValue int
ActionType string
Color string
TalkCount int
IsListening bool
IsPTTSelected bool
IsActive bool
}
ButtonState represents the state of a button for rendering
type ChatAckInbound ¶
type ChatAckUpdate ¶
type ChatHistory ¶
type ChatHistory struct {
// contains filtered or unexported fields
}
func NewChatHistory ¶
func NewChatHistory(limit int) *ChatHistory
func (*ChatHistory) AppendForRoom ¶
func (h *ChatHistory) AppendForRoom(roomID string, e RoutedEvent)
func (*ChatHistory) AppendForUser ¶
func (h *ChatHistory) AppendForUser(userID string, e RoutedEvent)
func (*ChatHistory) Clear ¶
func (h *ChatHistory) Clear()
func (*ChatHistory) HistoryForRooms ¶
func (h *ChatHistory) HistoryForRooms(roomIDs []string) []RoutedEvent
func (*ChatHistory) HistoryForUserAndRooms ¶
func (h *ChatHistory) HistoryForUserAndRooms(userID string, roomIDs []string) []RoutedEvent
type CompanionAdminSummaryResponse ¶
type CompanionAdminSummaryResponse struct {
PublishedProfiles []CompanionPublishedProfileSummary `json:"publishedProfiles"`
}
type CompanionBridgeState ¶
type CompanionBridgeState struct {
Username string `json:"username"`
Bound bool `json:"bound"`
Presence *PresenceState `json:"presence,omitempty"`
SessionCount int `json:"sessionCount,omitempty"`
MultiSessionWarning bool `json:"multiSessionWarning,omitempty"`
ReplyDirectUserID string `json:"replyDirectUserId,omitempty"`
ReplyDirectUsername string `json:"replyDirectUsername,omitempty"`
SignalActive bool `json:"signalActive"`
SignalFrom string `json:"signalFrom,omitempty"`
SignalMessage string `json:"signalMessage,omitempty"`
ImageEffectMapJSON string `json:"imageEffectMapJson,omitempty"`
CurrentPageNumber int `json:"currentPageNumber,omitempty"`
ProfileVersion int `json:"profileVersion,omitempty"`
ProfileStatus string `json:"profileStatus,omitempty"`
ProfileUpdatedAt int64 `json:"profileUpdatedAt,omitempty"`
}
type CompanionCommand ¶
type CompanionCommand struct {
CommandID string `json:"commandId,omitempty"`
Command string `json:"command"`
Mode string `json:"mode,omitempty"`
Scope string `json:"scope,omitempty"`
TargetID string `json:"targetId,omitempty"`
State string `json:"state,omitempty"`
Signal string `json:"signal,omitempty"`
ButtonIndex int `json:"buttonIndex,omitempty"`
VolumeDelta int `json:"volumeDelta,omitempty"`
ListenRoomIDs []string `json:"listenRoomIds"`
TalkRoomIDs []string `json:"talkRoomIds"`
Brightness int `json:"brightness,omitempty"`
PageNumber int `json:"pageNumber,omitempty"`
}
type CompanionCommandResult ¶
type CompanionCommandResult struct {
CommandID string `json:"commandId,omitempty"`
Command string `json:"command,omitempty"`
OK bool `json:"ok"`
Status string `json:"status,omitempty"`
Error string `json:"error,omitempty"`
Source string `json:"source,omitempty"`
Timestamp int64 `json:"timestamp,omitempty"`
}
type CompanionDiscoveryResponse ¶
type CompanionDiscoveryResponse struct {
Username string `json:"username"`
RoleID string `json:"roleId"`
Rooms []CompanionRoomDiscovery `json:"rooms"`
Users []User `json:"users"`
ActiveRoleUsers []CompanionRoleUser `json:"activeRoleUsers,omitempty"`
BroadcastGroups []BroadcastGroup `json:"broadcastGroups"`
CurrentPageNumber int `json:"currentPageNumber,omitempty"`
ProfileVersion int `json:"profileVersion,omitempty"`
ProfileStatus string `json:"profileStatus,omitempty"`
ProfileUpdatedAt int64 `json:"profileUpdatedAt,omitempty"`
}
type CompanionProfileResponse ¶
type CompanionProfileResponse struct {
RoleID string `json:"roleId"`
Username string `json:"username"`
PageNumber int `json:"pageNumber,omitempty"`
CurrentPageNumber int `json:"currentPageNumber,omitempty"`
Rooms []CompanionRoomDiscovery `json:"rooms"`
Users []User `json:"users"`
ActiveRoleUsers []CompanionRoleUser `json:"activeRoleUsers,omitempty"`
BroadcastGroups []BroadcastGroup `json:"broadcastGroups"`
StreamDeck StreamDeckSettings `json:"streamDeckSettings"`
ProfileVersion int `json:"profileVersion"`
ProfileStatus string `json:"profileStatus"`
ProfileUpdatedAt int64 `json:"profileUpdatedAt,omitempty"`
}
type CompanionRoleUser ¶
type CompanionRoomDiscovery ¶
type Config ¶
type Config struct {
Addr string
StaticDir string
DBPath string
AllowCORS bool
AdminPIN string
AdminPINFromEnv bool
SessionTTL time.Duration
DisconnectLogoutDelay time.Duration
TrustedLANHTTP bool
TLSMode string
TLSCertFile string
TLSKeyFile string
ProductionMode bool
ProductionHTTPSAddr string
ProductionHTTPRedirectAddr string
CertMagicDomains []string
CertMagicEmail string
CertMagicCA string
CertMagicStoragePath string
CertMagicChallenge string
CertMagicDNSProvider string
CertMagicPropagationDelay time.Duration
CertMagicPropagationTimeout time.Duration
CertMagicResolvers []string
TelegramBotToken string
TelegramWebhookSecret string
TelegramMode string // "polling" (default) or "webhook"
CompanionAllowedUsernames []string
CompanionImageEffectMapFile string
CompanionDynamicPaging bool
// Native low-latency UDP audio relay (performance mode). Empty UDPAudioAddr
// disables the relay; native clients then fall back to the WebRTC pipeline.
UDPAudioAddr string
UDPAudioAdvertiseIP string
}
func LoadConfig ¶
type ConfigurationDocument ¶
type ConfigurationDocument struct {
Meta ConfigurationMetadata `json:"meta"`
Roles []Role `json:"roles,omitempty"`
Users []ConfigurationUserAssignment `json:"users,omitempty"`
Rooms []Room `json:"rooms,omitempty"`
BroadcastGroups []BroadcastGroup `json:"broadcastGroups,omitempty"`
TelegramAllowlist []TelegramAllowlistEntry `json:"telegramAllowlist,omitempty"`
AckSettings *AckSettings `json:"ackSettings,omitempty"`
StreamDeck []ConfigurationUserStreamDeckSettings `json:"streamDeckSettings,omitempty"`
}
type ConfigurationImportRequest ¶
type ConfigurationImportRequest struct {
Document ConfigurationDocument `json:"document"`
Sections []string `json:"sections,omitempty"`
}
type ConfigurationImportResponse ¶
type ConfigurationImportResponse struct {
ImportedSections []string `json:"importedSections"`
}
type ConfigurationMetadata ¶
type ConfigurationMetadata struct {
Format string `json:"format"`
SchemaVersion int `json:"schemaVersion"`
ExportedAt string `json:"exportedAt"`
SourceVersion VersionInfo `json:"sourceVersion"`
Sections []string `json:"sections"`
}
type ConfigurationUserStreamDeckSettings ¶
type ConfigurationUserStreamDeckSettings struct {
Username string `json:"username"`
Settings StreamDeckSettings `json:"settings"`
}
type Hub ¶
type Hub struct {
// contains filtered or unexported fields
}
func (*Hub) ActiveTalkRoomForToken ¶
func (*Hub) BroadcastChatHistoryCleared ¶
func (h *Hub) BroadcastChatHistoryCleared()
func (*Hub) BroadcastConfigUpdate ¶
func (h *Hub) BroadcastConfigUpdate(data PublicBootstrapResponse)
func (*Hub) ClearChatHistory ¶
func (h *Hub) ClearChatHistory()
func (*Hub) GetActiveClients ¶
func (h *Hub) GetActiveClients(ctx context.Context) []ActiveClient
GetActiveClients returns a list of currently connected clients with their basic info. The list is sorted by username for consistent ordering.
func (*Hub) HasActiveSessionsForRole ¶
func (*Hub) IsNativeTransport ¶
IsNativeTransport reports whether the session uses the native UDP transport (performance mode). Browser clients always return false.
func (*Hub) LatestTokenForUsername ¶
func (*Hub) ListenRoomsForToken ¶
func (*Hub) PresenceForUsername ¶
func (h *Hub) PresenceForUsername(username string) (PresenceState, bool)
func (*Hub) RealtimeStats ¶
func (h *Hub) RealtimeStats() HubRealtimeStats
func (*Hub) RemoveWithReason ¶
func (*Hub) ReplyTargetForUsername ¶
func (*Hub) RoomListenerCounts ¶
func (*Hub) RouteChatAck ¶
func (h *Hub) RouteChatAck(senderToken string, in ChatAckInbound)
func (*Hub) RouteEvent ¶
func (h *Hub) RouteEvent(senderToken string, eventType string, e RoutedEvent)
func (*Hub) SendChatHistorySnapshot ¶
func (*Hub) SendChatToRole ¶
func (h *Hub) SendChatToRole(roleID string, e RoutedEvent)
SendChatToRole sends a chat message to all active sessions of a role. Used by external systems (like Telegram) for role-targeted messages.
func (*Hub) SendChatToRoom ¶
func (h *Hub) SendChatToRoom(roomID string, e RoutedEvent)
func (*Hub) SendChatToUser ¶
func (h *Hub) SendChatToUser(userID string, e RoutedEvent)
SendChatToUser sends a chat message to all sessions of a specific user. Used by external systems (like Telegram) to deliver messages to Kesher users.
func (*Hub) SendPresenceSnapshot ¶
SendPresenceSnapshot sends the current presence state to a specific client.
func (*Hub) SendRoomChatHistory ¶
func (*Hub) SendToToken ¶
func (h *Hub) SendToToken(token string, msg WSOutbound) bool
func (*Hub) SessionCountForUsername ¶
func (*Hub) SetBroadcastActive ¶
func (*Hub) SetChatHook ¶
func (h *Hub) SetChatHook(fn func(eventType string, e RoutedEvent))
func (*Hub) SetMediaManager ¶
func (h *Hub) SetMediaManager(m *MediaManager)
func (*Hub) SetRoomMatrix ¶
func (*Hub) SetUDPAudioRelay ¶
func (h *Hub) SetUDPAudioRelay(r *UDPAudioRelay)
SetUDPAudioRelay registers the native-audio relay so that disconnected sessions are also unbound from the relay's peer registry.
func (*Hub) SetVoiceState ¶
func (*Hub) SignalStateForUsername ¶
func (*Hub) SignalStateWithMetadataForUsername ¶
func (*Hub) SignalStateWithScopeForUsername ¶
func (*Hub) SubscribePresence ¶
func (h *Hub) SubscribePresence() (chan []PresenceState, func())
func (*Hub) TokensForRole ¶
type HubRealtimeStats ¶
type HubRealtimeStats struct {
ConnectedClients int `json:"connectedClients"`
NormalQueueDepthTotal int `json:"normalQueueDepthTotal"`
NormalQueueDepthMax int `json:"normalQueueDepthMax"`
PriorityQueueDepthTotal int `json:"priorityQueueDepthTotal"`
PriorityQueueDepthMax int `json:"priorityQueueDepthMax"`
DroppedCriticalMessages uint64 `json:"droppedCriticalMessages"`
DroppedNormalMessages uint64 `json:"droppedNormalMessages"`
DroppedMessagesByType map[string]uint64 `json:"droppedMessagesByType"`
PresenceBroadcasts uint64 `json:"presenceBroadcasts"`
PresenceBroadcastsMerged uint64 `json:"presenceBroadcastsMerged"`
}
type ImageStreamClient ¶
type ImageStreamClient struct {
RoleID string
Username string
// contains filtered or unexported fields
}
ImageStreamClient represents a connected image stream client
type ImageStreamCoordinator ¶
type ImageStreamCoordinator struct {
// contains filtered or unexported fields
}
ImageStreamCoordinator manages image stream connections and broadcasting
func NewImageStreamCoordinator ¶
func NewImageStreamCoordinator(logger *slog.Logger) (*ImageStreamCoordinator, error)
NewImageStreamCoordinator creates a new image stream coordinator
func (*ImageStreamCoordinator) BroadcastImageUpdate ¶
func (c *ImageStreamCoordinator) BroadcastImageUpdate(state ButtonState, bank, buttonIndex int)
BroadcastImageUpdate sends an image update to all connected clients.
func (*ImageStreamCoordinator) BroadcastImageUpdateForTarget ¶
func (c *ImageStreamCoordinator) BroadcastImageUpdateForTarget(roleID, username string, state ButtonState, bank, buttonIndex int)
BroadcastImageUpdateForTarget sends an image update only to clients bound to the same role. If username is provided and the client also declared one, both usernames must match.
func (*ImageStreamCoordinator) RegisterClient ¶
func (c *ImageStreamCoordinator) RegisterClient(client *ImageStreamClient)
RegisterClient registers a new image stream client
func (*ImageStreamCoordinator) ResetTargetCache ¶
func (c *ImageStreamCoordinator) ResetTargetCache(roleID, username string)
ResetTargetCache clears dedup signatures for matching clients so subsequent image emissions are always re-sent even if signatures are unchanged.
func (*ImageStreamCoordinator) UnregisterClient ¶
func (c *ImageStreamCoordinator) UnregisterClient(client *ImageStreamClient)
UnregisterClient unregisters a client
type ImageStreamMessage ¶
type ImageStreamMessage struct {
Type string `json:"type"` // "update_button_image"
Bank int `json:"bank"`
ButtonIndex int `json:"buttonIndex"`
ImageBuffer string `json:"imageBuffer"` // Base64-encoded PNG
EffectValue int `json:"effectValue,omitempty"`
Label string `json:"label,omitempty"`
Channel string `json:"channel,omitempty"`
State string `json:"state,omitempty"` // "IDLE", "TALK", "LISTEN", "BROADCAST"
ActionType string `json:"actionType,omitempty"`
Color string `json:"color,omitempty"`
IsListening bool `json:"isListening,omitempty"`
IsPTTSelected bool `json:"isPttSelected,omitempty"`
}
ImageStreamMessage represents an image update message sent via WebSocket
type LoginConflictResponse ¶
type LoginRequest ¶
type LoginResponse ¶
type LoginTakeoverRequest ¶
type MediaBridge ¶
type MediaBridge interface {
// RoutingForSource returns the per-destination gate map for the given
// source token. Implementations may return a nil map if the source is
// unknown.
RoutingForSource(sourceToken string) map[string]bool
// BridgeNativeOpusToWebRTC pushes a native-origin Opus frame into the
// WebRTC fan-out for the given source token. The implementation is
// responsible for repacking into RTP and respecting routing gates.
BridgeNativeOpusToWebRTC(sourceToken string, opus []byte)
}
MediaBridge is the slim contract MediaManager (or any future SFU) implements so the relay can hand off native source frames to WebRTC destinations and query the routing snapshot.
type MediaManager ¶
type MediaManager struct {
// contains filtered or unexported fields
}
func NewMediaManager ¶
func NewMediaManager(hub *Hub, logger *slog.Logger) *MediaManager
func (*MediaManager) BridgeNativeOpusToWebRTC ¶
func (m *MediaManager) BridgeNativeOpusToWebRTC(sourceToken string, opus []byte)
BridgeNativeOpusToWebRTC writes a single Opus frame originating from a native UDP source to all WebRTC peers that the routing snapshot says should hear this source.
func (*MediaManager) EnsureNativeSource ¶
func (m *MediaManager) EnsureNativeSource(sourceToken string, userID string) error
EnsureNativeSource is called when a native (UDP) source first delivers a frame for a given session token. It creates a shared StaticSample track and attaches it to all currently-connected WebRTC peers that the routing snapshot says should hear this source.
func (*MediaManager) EnsureNegotiation ¶
func (m *MediaManager) EnsureNegotiation(token string)
func (*MediaManager) EnsurePeer ¶
func (m *MediaManager) EnsurePeer(token string, user User) error
func (*MediaManager) HandleAnswer ¶
func (m *MediaManager) HandleAnswer(token string, sdp string) error
func (*MediaManager) HandleICECandidate ¶
func (m *MediaManager) HandleICECandidate(token string, c WebRTCIceCandidate) error
func (*MediaManager) NoteVoiceStateTrigger ¶
func (m *MediaManager) NoteVoiceStateTrigger()
func (*MediaManager) RealtimeStats ¶
func (m *MediaManager) RealtimeStats() MediaRealtimeStats
func (*MediaManager) RemovePeer ¶
func (m *MediaManager) RemovePeer(token string)
func (*MediaManager) RoutingForSource ¶
func (m *MediaManager) RoutingForSource(sourceToken string) map[string]bool
RoutingForSource is the MediaBridge implementation used by UDPAudioRelay to learn which native destinations should receive a given native source's audio frames.
func (*MediaManager) SetBroadcastGroupActive ¶
func (m *MediaManager) SetBroadcastGroupActive(sourceToken, groupID string, enabled bool)
func (*MediaManager) SetDirectTargetActive ¶
func (m *MediaManager) SetDirectTargetActive(sourceToken, targetUserID string, enabled bool)
func (*MediaManager) SetIdleRoomFallbackSuppressed ¶
func (m *MediaManager) SetIdleRoomFallbackSuppressed(sourceToken string, suppressed bool)
func (*MediaManager) SetUDPAudioRelay ¶
func (m *MediaManager) SetUDPAudioRelay(relay *UDPAudioRelay)
SetUDPAudioRelay wires the relay into MediaManager and registers the bidirectional bridge so the relay can push native frames to WebRTC dests.
func (*MediaManager) SyncRouting ¶
func (m *MediaManager) SyncRouting()
func (*MediaManager) SyncRoutingSource ¶
func (m *MediaManager) SyncRoutingSource(sourceToken string)
type MediaRealtimeStats ¶
type MediaRealtimeStats struct {
Peers int `json:"peers"`
Sources int `json:"sources"`
SyncRequests uint64 `json:"syncRequests"`
SyncRuns uint64 `json:"syncRuns"`
SyncRequestsCoalesced uint64 `json:"syncRequestsCoalesced"`
SyncDirtySourcesAvg uint64 `json:"syncDirtySourcesAvg"`
SyncDirtySourcesMax uint64 `json:"syncDirtySourcesMax"`
SyncRunAvgMs uint64 `json:"syncRunAvgMs"`
SyncRunMaxMs uint64 `json:"syncRunMaxMs"`
SyncLockWaitAvgMs uint64 `json:"syncLockWaitAvgMs"`
SyncLockWaitMaxMs uint64 `json:"syncLockWaitMaxMs"`
SyncLockHoldAvgMs uint64 `json:"syncLockHoldAvgMs"`
SyncLockHoldMaxMs uint64 `json:"syncLockHoldMaxMs"`
VoiceStateToSyncAvgMs uint64 `json:"voiceStateToSyncAvgMs"`
VoiceStateToSyncMaxMs uint64 `json:"voiceStateToSyncMaxMs"`
Renegotiations uint64 `json:"renegotiations"`
RenegotiationAvgMs uint64 `json:"renegotiationAvgMs"`
RenegotiationMaxMs uint64 `json:"renegotiationMaxMs"`
}
type NativeAudioEndpoint ¶
type NativeAudioEndpoint struct {
Host string `json:"host"`
Port int `json:"port"`
Token string `json:"token"`
TokenHash uint32 `json:"tokenHash"`
FrameDuration int `json:"frameDurationMs"`
SampleRate int `json:"sampleRate"`
Channels int `json:"channels"`
}
NativeAudioEndpoint is sent over the WebSocket to native (Tauri) clients that requested the performance transport. It contains the UDP relay address the client should send Opus frames to, plus the session token (echoed back for the REGISTER packet). Browser clients never receive this message.
type PolicyCacheStats ¶
type PolicyCacheStats struct {
RoomPolicyHits uint64 `json:"roomPolicyHits"`
RoomPolicyMisses uint64 `json:"roomPolicyMisses"`
BroadcastAllowedHits uint64 `json:"broadcastAllowedHits"`
BroadcastAllowedMisses uint64 `json:"broadcastAllowedMisses"`
BroadcastRoomHits uint64 `json:"broadcastRoomHits"`
BroadcastRoomMisses uint64 `json:"broadcastRoomMisses"`
ForcedListenHits uint64 `json:"forcedListenHits"`
ForcedListenMisses uint64 `json:"forcedListenMisses"`
}
type PresenceState ¶
type PresenceState struct {
UserID string `json:"userId"`
Username string `json:"username"`
RoleID string `json:"roleId"`
ListenRooms []string `json:"listenRooms"`
TalkRooms []string `json:"talkRooms"`
VoiceMode string `json:"voiceMode"`
MicEnabled bool `json:"micEnabled"`
BroadcastActive bool `json:"broadcastActive"`
}
type PublicBootstrapResponse ¶
type PublicBootstrapResponse struct {
Roles []Role `json:"roles"`
Rooms []Room `json:"rooms"`
BroadcastGroups []BroadcastGroup `json:"broadcastGroups"`
AckEnabled bool `json:"ackEnabled"`
AppVersion VersionInfo `json:"appVersion"`
}
type RealtimeStatsResponse ¶
type RealtimeStatsResponse struct {
Hub HubRealtimeStats `json:"hub"`
Media MediaRealtimeStats `json:"media"`
StorePolicyCache PolicyCacheStats `json:"storePolicyCache"`
TimestampUnixMs int64 `json:"timestampUnixMs"`
}
type RoomMatrixEvent ¶
type RoomPermissionEntry ¶
type RoomPermissionEntry struct {
RoomID string `json:"roomId"`
SenderRoleIDs []string `json:"senderRoleIds"`
ReceiverRoleIDs []string `json:"receiverRoleIds"`
ForcedListenRoleIDs []string `json:"forcedListenRoleIds"`
}
RoomPermissionEntry describes the sender/receiver/forced-listen role mapping for one room.
type RoutedEvent ¶
type RoutedEvent struct {
Scope string `json:"scope"`
TargetType string `json:"targetType,omitempty"`
TargetID string `json:"targetId"`
Body string `json:"body"`
Source string `json:"source,omitempty"`
Signal string `json:"signal,omitempty"`
MessageID string `json:"messageId,omitempty"`
AckRequired bool `json:"ackRequired,omitempty"`
Acked bool `json:"acked,omitempty"`
AckedBy *User `json:"ackedBy,omitempty"`
AckedAt int64 `json:"ackedAt,omitempty"`
FromUser User `json:"fromUser"`
Timestamp int64 `json:"timestamp"`
}
type RoutingStatusEvent ¶
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
func (*Server) HandleDebugButtonImage ¶
func (s *Server) HandleDebugButtonImage(w http.ResponseWriter, r *http.Request)
HandleDebugButtonImage renders a single button image as PNG for browser-based inspection.
func (*Server) HandleDebugButtonImagePreview ¶
func (s *Server) HandleDebugButtonImagePreview(w http.ResponseWriter, r *http.Request)
HandleDebugButtonImagePreview serves a tiny HTML page to inspect generated images.
func (*Server) HandleImageStreamWebSocket ¶
func (s *Server) HandleImageStreamWebSocket(w http.ResponseWriter, r *http.Request)
HandleImageStreamWebSocket handles WebSocket connections for image streaming
func (*Server) ListenAndServe ¶
type SessionManager ¶
type SessionManager struct {
// contains filtered or unexported fields
}
func NewSessionManager ¶
func NewSessionManager(ttl time.Duration) *SessionManager
func (*SessionManager) CancelScheduledDisconnectLogout ¶
func (m *SessionManager) CancelScheduledDisconnectLogout(token string) bool
func (*SessionManager) Create ¶
func (m *SessionManager) Create(user User) Session
func (*SessionManager) Delete ¶
func (m *SessionManager) Delete(token string)
func (*SessionManager) DeleteByRole ¶
func (m *SessionManager) DeleteByRole(roleID string) []Session
func (*SessionManager) DeleteByUsername ¶
func (m *SessionManager) DeleteByUsername(username string) []Session
func (*SessionManager) LatestForRole ¶
func (m *SessionManager) LatestForRole(roleID string) (Session, bool)
func (*SessionManager) ScheduleDisconnectLogout ¶
func (m *SessionManager) ScheduleDisconnectLogout(token string, delay time.Duration) bool
type SessionRevokedEvent ¶
type StatusResponse ¶
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
func (*Store) BindTelegramAllowlistEntryNumericID ¶
func (s *Store) BindTelegramAllowlistEntryNumericID(ctx context.Context, telegramUsername, numericID string) error
BindTelegramAllowlistEntryNumericID binds the telegram_numeric_id for a user (TOFU - Trust On First Use).
func (*Store) BroadcastGroupAllowsRole ¶
func (*Store) BroadcastGroupRoomIDs ¶
func (*Store) BulkUpdateRoomPermissions ¶
func (s *Store) BulkUpdateRoomPermissions(ctx context.Context, entries []RoomPermissionEntry) error
BulkUpdateRoomPermissions updates sender/receiver role mappings for multiple rooms in a single transaction. It only touches role mappings — room names are left unchanged.
func (*Store) CreateBroadcastGroup ¶
func (*Store) CreateRole ¶
func (*Store) CreateRoom ¶
func (*Store) CreateTelegramAllowlistEntry ¶
func (s *Store) CreateTelegramAllowlistEntry(ctx context.Context, id, telegramUsername, kesherUsername string) error
CreateTelegramAllowlistEntry adds a new Telegram user to the allowlist. The telegramNumericID is initially empty and will be bound on first login (TOFU).
func (*Store) CreateTelegramMapping ¶
func (*Store) CreateTelegramUserMapping ¶
func (*Store) DeleteBroadcastGroup ¶
func (*Store) DeleteRoleStreamDeckSettings ¶
func (*Store) DeleteTelegramAllowlistEntry ¶
DeleteTelegramAllowlistEntry removes a user from the allowlist.
func (*Store) DeleteTelegramMapping ¶
func (*Store) DeleteUserStreamDeckSettings ¶
func (*Store) FindTelegramAllowlistEntryByNumericID ¶
func (s *Store) FindTelegramAllowlistEntryByNumericID(ctx context.Context, numericID string) (TelegramAllowlistEntry, error)
FindTelegramAllowlistEntryByNumericID finds an allowlist entry by numeric Telegram ID.
func (*Store) FindTelegramAllowlistEntryByUsername ¶
func (s *Store) FindTelegramAllowlistEntryByUsername(ctx context.Context, telegramUsername string) (TelegramAllowlistEntry, error)
FindTelegramAllowlistEntryByUsername finds an allowlist entry by Telegram username (case-insensitive).
func (*Store) FindTelegramMappingByChatID ¶
func (*Store) FindTelegramUserMappingByTelegramID ¶
func (*Store) FindTelegramUserMappingByUsername ¶
func (*Store) FindUserByID ¶
func (*Store) FindUserByUsername ¶
func (*Store) ForcedListenRoomIDs ¶
ForcedListenRoomIDs returns the list of room IDs that the given role must listen to.
func (*Store) GetAllCompanionRolePages ¶
func (*Store) GetBirthdayUsersToday ¶
func (*Store) GetCompanionProfileByRole ¶
func (*Store) GetCompanionRolePage ¶
func (*Store) GetRoleStreamDeckSettings ¶
func (*Store) GetSubscribedTelegramUsersForRoom ¶
func (s *Store) GetSubscribedTelegramUsersForRoom(ctx context.Context, roomID string) ([]string, error)
GetSubscribedTelegramUsersForRoom returns all telegram user IDs subscribed to a specific room.
func (*Store) GetTelegramUserRoomSubscriptions ¶
func (s *Store) GetTelegramUserRoomSubscriptions(ctx context.Context, telegramUserID string) ([]string, error)
GetTelegramUserRoomSubscriptions returns all room IDs that a telegram user is subscribed to.
func (*Store) GetUserStreamDeckSettings ¶
func (*Store) IsTelegramUserSubscribedToRoom ¶
func (s *Store) IsTelegramUserSubscribedToRoom(ctx context.Context, telegramUserID, roomID string) (bool, error)
IsTelegramUserSubscribedToRoom checks if a telegram user is subscribed to a specific room.
func (*Store) ListBroadcastGroups ¶
func (s *Store) ListBroadcastGroups(ctx context.Context) ([]BroadcastGroup, error)
func (*Store) ListRoleStreamDeckSettings ¶
func (*Store) ListTelegramAllowlistEntries ¶
func (s *Store) ListTelegramAllowlistEntries(ctx context.Context) ([]TelegramAllowlistEntry, error)
ListTelegramAllowlistEntries returns all allowlist entries with computed status.
func (*Store) ListTelegramMappings ¶
func (s *Store) ListTelegramMappings(ctx context.Context) ([]TelegramMapping, error)
func (*Store) ListUserStreamDeckSettingsByUsername ¶
func (s *Store) ListUserStreamDeckSettingsByUsername(ctx context.Context) ([]ConfigurationUserStreamDeckSettings, error)
func (*Store) PolicyCacheStats ¶
func (s *Store) PolicyCacheStats() PolicyCacheStats
func (*Store) PublishCompanionProfile ¶
func (s *Store) PublishCompanionProfile(ctx context.Context, roleID string, publishedByUserID string, profile CompanionProfileResponse) (CompanionProfileResponse, error)
func (*Store) ReplaceConfiguration ¶
func (*Store) ResolveSinglePublishedCompanionRole ¶
func (*Store) RoleExists ¶
func (*Store) RoomAllowsReceiverRole ¶
func (*Store) RoomAllowsSenderRole ¶
func (*Store) SaveCompanionRolePage ¶
func (*Store) SetBirthdayUsersToday ¶
func (*Store) SetBroadcastGroupPriorityLevel ¶
func (*Store) SetRoomPriorityLevel ¶
func (*Store) ToggleTelegramUserRoomSubscription ¶
func (s *Store) ToggleTelegramUserRoomSubscription(ctx context.Context, telegramUserID, roomID string) (bool, error)
ToggleTelegramUserRoomSubscription toggles the subscription status (subscribe if not subscribed, unsubscribe if subscribed). Returns the new subscription status (true if subscribed, false if unsubscribed).
func (*Store) UpdateBroadcastGroup ¶
func (*Store) UpdateRole ¶
func (*Store) UpdateRoom ¶
func (*Store) UpdateTelegramMapping ¶
func (*Store) UpdateTelegramUserMapping ¶
func (*Store) UpsertRoleStreamDeckSettings ¶
func (s *Store) UpsertRoleStreamDeckSettings(ctx context.Context, roleID string, settings StreamDeckSettings) (StreamDeckSettings, error)
func (*Store) UpsertUser ¶
func (*Store) UpsertUserStreamDeckSettings ¶
func (s *Store) UpsertUserStreamDeckSettings(ctx context.Context, userID string, settings StreamDeckSettings) (StreamDeckSettings, error)
type StreamDeckActionType ¶
type StreamDeckActionType string
const ( StreamDeckActionTypeNone StreamDeckActionType = "none" StreamDeckActionTypePTTRoom StreamDeckActionType = "ptt_room" StreamDeckActionTypeSelectTalkRoom StreamDeckActionType = "select_talk_room" StreamDeckActionTypeSelectListen StreamDeckActionType = "select_listen_room" StreamDeckActionTypePTTSelected StreamDeckActionType = "ptt_selected" StreamDeckActionTypeListenRoom StreamDeckActionType = "listen_room" StreamDeckActionTypeCallRoom StreamDeckActionType = "call_room" StreamDeckActionTypeDirectUser StreamDeckActionType = "direct_user" StreamDeckActionTypeDirectRole StreamDeckActionType = "direct_role" StreamDeckActionTypeReplyToCaller StreamDeckActionType = "reply_to_caller" StreamDeckActionTypeIncomingCall StreamDeckActionType = "incoming_call_indicator" StreamDeckActionTypeBroadcastPTT StreamDeckActionType = "broadcast_ptt" StreamDeckActionTypeMuteToggle StreamDeckActionType = "mute_toggle" StreamDeckActionTypeVolumeDelta StreamDeckActionType = "volume_delta" StreamDeckActionTypePageUp StreamDeckActionType = "page_up" StreamDeckActionTypePageDown StreamDeckActionType = "page_down" StreamDeckActionTypePageJump StreamDeckActionType = "page_jump" StreamDeckActionTypePageHome StreamDeckActionType = "page_home" StreamDeckActionTypePageBack StreamDeckActionType = "page_back" )
type StreamDeckButtonAction ¶
type StreamDeckButtonAction struct {
Type StreamDeckActionType `json:"type"`
RoomID string `json:"roomId,omitempty"`
UserID string `json:"userId,omitempty"`
RoleID string `json:"roleId,omitempty"`
BroadcastGroupID string `json:"broadcastGroupId,omitempty"`
VolumeDelta int `json:"volumeDelta,omitempty"`
TargetPage int `json:"targetPage,omitempty"`
}
type StreamDeckButtonConfig ¶
type StreamDeckButtonConfig struct {
Index int `json:"index"`
Label string `json:"label,omitempty"`
Color string `json:"color,omitempty"`
Action *StreamDeckButtonAction `json:"action,omitempty"`
}
type StreamDeckPageConfig ¶
type StreamDeckPageConfig struct {
Page int `json:"page"`
Title string `json:"title,omitempty"`
PageType StreamDeckPageType `json:"pageType,omitempty"`
ParentPage *int `json:"parentPage,omitempty"`
Buttons []StreamDeckButtonConfig `json:"buttons"`
}
type StreamDeckPageType ¶
type StreamDeckPageType string
const ( StreamDeckPageTypeManual StreamDeckPageType = "manual" StreamDeckPageTypeAllRoles StreamDeckPageType = "all_roles" StreamDeckPageTypeAllPartyLines StreamDeckPageType = "all_party_lines" )
type StreamDeckSettings ¶
type StreamDeckSettings struct {
Version int `json:"version"`
GridColumns int `json:"gridColumns"`
GridRows int `json:"gridRows"`
SelectedPage int `json:"selectedPage"`
Pages []StreamDeckPageConfig `json:"pages"`
}
func DefaultStreamDeckSettings ¶
func DefaultStreamDeckSettings() StreamDeckSettings
type TelegramAllowlistEntry ¶
type TelegramAllowlistEntry struct {
ID string `json:"id"`
TelegramUsername string `json:"telegramUsername"`
TelegramNumericID string `json:"telegramNumericId,omitempty"`
KesherUsername string `json:"kesherUsername"`
CreatedAt int64 `json:"createdAt"`
Status string `json:"status"`
IsBound bool `json:"isBound"`
}
type TelegramBot ¶
type TelegramBot struct {
// contains filtered or unexported fields
}
TelegramBot handles receiving and sending Telegram messages.
func NewTelegramBot ¶
func (*TelegramBot) DeleteWebhook ¶
func (t *TelegramBot) DeleteWebhook() error
DeleteWebhook removes any previously set webhook so polling works cleanly.
func (*TelegramBot) HandleWebhook ¶
func (t *TelegramBot) HandleWebhook(w http.ResponseWriter, r *http.Request)
HandleWebhook processes incoming Telegram webhook updates.
func (*TelegramBot) Mode ¶
func (t *TelegramBot) Mode() string
Mode returns the configured mode ("polling" or "webhook").
func (*TelegramBot) StartPolling ¶
func (t *TelegramBot) StartPolling()
StartPolling begins long-polling the Telegram getUpdates API. This is suitable for servers behind NAT/firewall without a public IP.
func (*TelegramBot) StopPolling ¶
func (t *TelegramBot) StopPolling()
StopPolling gracefully stops the long-polling goroutine.
type TelegramCallbackQuery ¶
type TelegramCallbackQuery struct {
ID string `json:"id"`
From *TelegramUser `json:"from"`
Message *TelegramMessage `json:"message,omitempty"`
Data string `json:"data"`
}
type TelegramChat ¶
type TelegramInlineKeyboardMarkup ¶
type TelegramInlineKeyboardMarkup struct {
InlineKeyboard [][]TelegramInlineKeyboardButton `json:"inline_keyboard"`
}
type TelegramInlineQuery ¶
type TelegramInlineQuery struct {
ID string `json:"id"`
From *TelegramUser `json:"from"`
Query string `json:"query"`
Offset string `json:"offset"`
}
type TelegramInlineQueryResultArticle ¶
type TelegramInlineQueryResultArticle struct {
Type string `json:"type"`
ID string `json:"id"`
Title string `json:"title"`
InputMessageContent TelegramInputMessageContent `json:"input_message_content"`
Description string `json:"description,omitempty"`
}
type TelegramInputMessageContent ¶
type TelegramInputMessageContent struct {
MessageText string `json:"message_text"`
}
type TelegramMapping ¶
type TelegramMessage ¶
type TelegramMessage struct {
MessageID int64 `json:"message_id"`
From *TelegramUser `json:"from,omitempty"`
Chat TelegramChat `json:"chat"`
Text string `json:"text,omitempty"`
}
type TelegramStatusResponse ¶
type TelegramStatusResponse struct {
BotConfigured bool `json:"botConfigured"`
Mode string `json:"mode"` // "polling" or "webhook"
Mappings []TelegramMapping `json:"mappings"`
}
type TelegramUpdate ¶
type TelegramUpdate struct {
UpdateID int64 `json:"update_id"`
Message *TelegramMessage `json:"message,omitempty"`
CallbackQuery *TelegramCallbackQuery `json:"callback_query,omitempty"`
InlineQuery *TelegramInlineQuery `json:"inline_query,omitempty"`
}
type TelegramUser ¶
type TelegramUserMapping ¶
type UDPAudioPacket ¶
type UDPAudioPacket struct {
Flags byte
Sequence uint16
Timestamp uint32
TokenHash uint32
Payload []byte
}
UDPAudioPacket is the parsed view of a single relay datagram.
func DecodeUDPAudioPacket ¶
func DecodeUDPAudioPacket(buf []byte) (UDPAudioPacket, error)
DecodeUDPAudioPacket parses a datagram. The returned Payload aliases the caller's buffer; callers that retain it after the buffer is reused must copy.
type UDPAudioRelay ¶
type UDPAudioRelay struct {
// contains filtered or unexported fields
}
UDPAudioRelay is the central UDP listener and per-peer registry.
func NewUDPAudioRelay ¶
func NewUDPAudioRelay(hub *Hub, logger *slog.Logger) *UDPAudioRelay
NewUDPAudioRelay creates the relay but does not start listening. Call Start to bind and begin the receive loop.
func (*UDPAudioRelay) Close ¶
func (r *UDPAudioRelay) Close()
Close stops the relay and tears down peers.
func (*UDPAudioRelay) IsNativeRegistered ¶
func (r *UDPAudioRelay) IsNativeRegistered(token string) bool
IsNativeRegistered returns true if the given token currently has an authenticated UDP peer with a fresh heartbeat.
func (*UDPAudioRelay) LocalAddr ¶
func (r *UDPAudioRelay) LocalAddr() net.Addr
LocalAddr exposes the bound listen address (mainly for tests and for the Endpoint info that the hub sends to native clients).
func (*UDPAudioRelay) PeerByToken ¶
func (r *UDPAudioRelay) PeerByToken(token string) *udpPeer
PeerByToken returns the bound peer for a session token, or nil.
func (*UDPAudioRelay) RemovePeer ¶
func (r *UDPAudioRelay) RemovePeer(token string)
RemovePeer removes a session's binding from the relay. Called from the hub when a session disconnects.
func (*UDPAudioRelay) SendOpusToToken ¶
func (r *UDPAudioRelay) SendOpusToToken(destToken string, opus []byte)
SendOpusToToken delivers a single Opus frame to a specific native destination. Used by the WebRTC bridge to fan out browser-origin audio to native listeners.
func (*UDPAudioRelay) SetMediaBridge ¶
func (r *UDPAudioRelay) SetMediaBridge(b MediaBridge)
SetMediaBridge wires the WebRTC bridge after construction (avoids a circular dependency with MediaManager).
func (*UDPAudioRelay) Start ¶
func (r *UDPAudioRelay) Start(addr string) error
Start binds to addr and launches the receive loop in a goroutine. addr must be in net.ListenPacket form (e.g. ":8081" or "0.0.0.0:8081").
func (*UDPAudioRelay) Stats ¶
func (r *UDPAudioRelay) Stats() UDPAudioStats
Stats returns aggregated counters for monitoring.
type UDPAudioStats ¶
type UDPAudioStats struct {
Peers int `json:"peers"`
RxFrames uint64 `json:"rxFrames"`
TxFrames uint64 `json:"txFrames"`
}
PeerStats is a snapshot used in /api/realtime-stats.
type VersionInfo ¶
type VersionInfo struct {
Version string `json:"version"`
BuildTimestamp string `json:"buildTimestamp"`
}
VersionInfo represents the version and build information.
func GetVersionInfo ¶
func GetVersionInfo() VersionInfo
GetVersionInfo returns the current version and build timestamp.
type WSOutbound ¶
type WebRTCAnswer ¶
type WebRTCAnswer struct {
SDP string `json:"sdp"`
}
type WebRTCIceCandidate ¶
type WebRTCOffer ¶
type WebRTCOffer struct {
SDP string `json:"sdp"`
}