Documentation
¶
Index ¶
- Constants
- type AuthzReason
- type Chat
- type Client
- func (c *Client) AckUpdate(ctx context.Context, updateID int) error
- func (c *Client) GetUpdate(ctx context.Context, updateID int) (*Update, error)
- func (c *Client) GetUpdates(ctx context.Context, limit int) ([]Update, error)
- func (c *Client) SendMessage(ctx context.Context, chatID int64, text string) error
- func (c *Client) SetHTTPDoer(doer apiclient.HTTPDoer)
- type Config
- type Instance
- type Message
- type MessageDetail
- type MessageSummary
- type Update
- type User
Constants ¶
const ( ChatTypePrivate = "private" ChatTypeGroup = "group" ChatTypeSupergroup = "supergroup" ChatTypeChannel = "channel" )
Chat type constants as returned by the Telegram Bot API in the Chat.Type field. See https://core.telegram.org/bots/api#chat.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AuthzReason ¶
type AuthzReason string
AuthzReason describes why a message was accepted or rejected by IsAllowed. Rejections use a stable string form suitable for structured logging and metrics, so operators can distinguish probing attempts (NotInAllowlist) from misconfigured group-chat dispatch (GroupChatDenied).
const ( // AuthzAllowed means the user and chat pass all access checks. AuthzAllowed AuthzReason = "allowed" // AuthzNotInAllowlist means the user is not in AllowedUsers, or there // is no allowlist configured at all (default-deny). AuthzNotInAllowlist AuthzReason = "not_in_allowlist" // AuthzGroupChatDenied means the user is allowlisted but the message // came from a group, supergroup, or channel that is not in AllowedChats. // Group dispatch is default-deny and must be opted in per chat. AuthzGroupChatDenied AuthzReason = "group_chat_denied" // AuthzUnknownChatType means the chat type is not one of the four // documented values. Future-proofing: deny unknown chat types. AuthzUnknownChatType AuthzReason = "unknown_chat_type" )
func IsAllowed ¶
func IsAllowed(user *User, chat Chat, allowedUsers, allowedChats []int64) (bool, AuthzReason)
IsAllowed decides whether a (user, chat) pair is allowed to dispatch.
The rule, in order:
- Empty allowedUsers → deny. (Default-deny, the invariant established by [SC-71] commit 3e6acdb.)
- User not in allowedUsers → deny with reason NotInAllowlist.
- Private chat (1:1 with the bot) → allow. The chat ID equals the user ID in a private chat, so AllowedChats need not list it.
- Group / supergroup / channel chat → deny unless chat.ID is in allowedChats. Group dispatch is a distinct trust surface from private DMs and must be opted in per chat.
- Any other chat type → deny with reason UnknownChatType.
A nil user is always denied (malformed update).
type Chat ¶
type Chat struct {
ID int64 `json:"id"`
Type string `json:"type"`
Title string `json:"title,omitempty"`
}
Chat represents a Telegram chat.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is a Telegram Bot API client.
func (*Client) AckUpdate ¶
AckUpdate acknowledges all updates up to and including updateID by calling getUpdates with offset = updateID + 1. This permanently removes those updates from the pending queue.
func (*Client) GetUpdate ¶
GetUpdate fetches all pending updates and returns the one matching updateID. Returns an error if the update is not found among pending updates.
func (*Client) GetUpdates ¶
GetUpdates fetches pending updates from the Telegram Bot API. It does not pass an offset, so this is a read-only peek at pending messages.
func (*Client) SendMessage ¶
SendMessage sends a text message to the given chat via the Telegram Bot API.
func (*Client) SetHTTPDoer ¶
SetHTTPDoer replaces the HTTP client used for API requests.
type Config ¶
type Config struct {
Name string `mapstructure:"name"`
Token string `mapstructure:"token"`
Description string `mapstructure:"description"`
AllowedUsers []int64 `mapstructure:"allowed_users"`
// AllowedChats is the set of group/supergroup/channel chat IDs allowed
// to dispatch messages. Private chats (1:1 between user and bot) do not
// need an entry here — being in AllowedUsers is sufficient. For group
// dispatch this must be set explicitly, per-chat, as an opt-in.
AllowedChats []int64 `mapstructure:"allowed_chats"`
NotifyChatID int64 `mapstructure:"notify_chat_id"` // Chat ID for proactive notifications (destructive ops, etc.)
}
Config holds the configuration for a single Telegram bot instance.
func LoadConfigs ¶
LoadConfigs reads a .humanconfig YAML file from dir and returns the list of configured Telegram instances. Returns nil and no error if the file does not exist.
type Instance ¶
type Instance struct {
Name string
Description string
Client *Client
AllowedUsers []int64
AllowedChats []int64 // see Config.AllowedChats
NotifyChatID int64 // Chat ID for proactive notifications
}
Instance represents a configured Telegram bot ready for use.
func LoadInstances ¶
LoadInstances reads config, applies env overrides, creates clients, and returns ready-to-use Telegram instances.
func LoadInstancesWithResolver ¶
func LoadInstancesWithResolver(dir string, resolver config.SecretResolveFunc) ([]Instance, error)
LoadInstancesWithResolver is like LoadInstances but uses a vault secret resolver for 1pw:// references.
func (*Instance) ConfigWarnings ¶
ConfigWarnings returns human-readable warnings about this instance's configuration relative to the auth rule enforced by IsAllowed. An empty slice means the configuration is healthy. Warnings surface silent misconfigurations like "Telegram is enabled but the allowlist is empty, so every message will be rejected" — the runtime behavior is still safe (default-deny), but operators deserve to know.
type Message ¶
type Message struct {
MessageID int `json:"message_id"`
From *User `json:"from,omitempty"`
Chat Chat `json:"chat"`
Date int64 `json:"date"`
Text string `json:"text"`
}
Message represents a Telegram message.
type MessageDetail ¶
type MessageDetail struct {
UpdateID int `json:"update_id"`
MessageID int `json:"message_id"`
From string `json:"from"`
FromID int64 `json:"from_id"`
Username string `json:"username"`
ChatID int64 `json:"chat_id"`
ChatType string `json:"chat_type"`
Date string `json:"date"`
Text string `json:"text"`
}
MessageDetail is the CLI output type for the get command.
type MessageSummary ¶
type MessageSummary struct {
UpdateID int `json:"update_id"`
MessageID int `json:"message_id"`
From string `json:"from"`
Date string `json:"date"`
Text string `json:"text"`
}
MessageSummary is the CLI output type for the list command.