chadango

package module
v0.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 23, 2023 License: MIT Imports: 25 Imported by: 0

README

Chadango

Chadango is a Go library for interacting with Chatango, a platform for creating and managing chat rooms. It provides functionalities to work with Chatango APIs, handle WebSocket connections, and perform various operations related to chat rooms and user profiles.

Table of Contents

Introduction

Welcome to Chadango!

Chadango is a powerful and flexible chatbot framework inspired by the combination of Chatango and Dango. Just like the delightful combination of flavors in Dango, Chadango aims to bring together the best of both worlds, offering a robust chatbot solution with a touch of whimsy.

Features

These are some of the features, but not limited to:

  1. Each event is handled by its own goroutine.
  2. Lightweight.
  3. Some features are wrapped into solicited style (e.g., getting user list, online statuses, etc.).
  4. Extensible.

Installation

To run the example file, please follow the steps below:

Prerequisites

Go 1.20 or higher should be installed on your system. You can download it from the official Go website: https://golang.org/dl/

Download the Example File

Download the example file minimal.go from the examples folder of this repository: minimal.go

Install Required Packages

Navigate to the directory where you downloaded the example file and run the following command to install the required packages:

go mod init minimal
go get -u github.com/n0h4rt/chadango
go mod tidy
Run the Example

Once the required packages are installed, execute the example file using the go run command:

go run minimal.go

This will execute the example code and display the output in the console. Make sure you are in the correct directory where the minimal.go file is located. Feel free to modify the example file according to your needs and explore the functionality provided by the packages you installed. That's it! You have successfully installed the necessary packages and executed the example file.

Usage

This is a simple usage.

package main

import (
	"context"
	"fmt"

	dango "github.com/n0h4rt/chadango"
)

func main() {
	config := &dango.Config{
		Username: "username", // Change this
		Password: "password", // Change this
		Prefix:   ".",
		EnableBG: true,
		EnablePM: true,
		Groups:   []string{"groupchat1", "groupchat2"}, // Change this
	}

	app := dango.New(config)

	echoHandler := dango.NewCommandHandler(OnEcho, nil, "echo", "say")

	app.AddHandler(echoHandler)

	app.Initialize()

	ctx := context.Background()
	app.Start(ctx)

	// The `app.Park()` call is blocking, use CTRL + C to stop the application.
	// Use this if it is the top layer application.
	app.Park()
}

// OnEcho prints the command to the console and sends the argument as a reply.
func OnEcho(event *dango.Event, context *dango.Context) {
	var msg *dango.Message
	var err error

	if event.WithArgument {
		msg, err = event.Message.Reply(event.Argument)
	} else {
		msg, err = event.Message.Reply(`How to use ".echo Hello World!"`)
	}

	if err != nil {
		fmt.Printf("OnEcho: an error occurred when sending a reply (%s)\n", err)
	}
	if msg != nil {
		fmt.Printf("OnEcho: replied with: %s\n", msg.Text)
	}
}

Dependencies

The Chadango library has the following dependencies:

Contributing

Contributions are welcome! If you find any issues or have suggestions for improvements, please open an issue or submit a pull request on the Chadango GitHub repository.

License

Chadango is licensed under the MIT License.

Contact

You can find me in khususme, available from 21:00 to 23:00 UTC-7. Feel free to reach out if you have any questions, suggestions, or just want to chat about Chadango!

Documentation

Index

Constants

View Source
const (
	WEBSOCKET_ORIGIN    = "http://st.chatango.com"
	PM_SERVER           = "ws://c1.chatango.com:8080/"
	EVENT_BUFFER_SIZE   = 30
	PING_INTERVAL       = 90 * time.Second
	DEFAULT_COLOR       = "000"
	DEFAULT_TEXT_FONT   = "1"
	DEFAULT_TEXT_SIZE   = 11
	MAX_MESSAGE_HISTORY = 100
	SYNC_SEND_TIMEOUT   = 5 * time.Second
	BASE_BACKOFF_DUR    = 1 * time.Second
	MAX_BACKOFF_DUR     = 30 * time.Second
	MAX_RETRIES         = 10
	MSG_LENGTH_DEFAULT  = 2900
	MSG_LENGTH_SHORT    = 850
	API_TIMEOUT         = 10 * time.Second
)
View Source
const (
	FlagPremium int64
	FlagBackground
	FlagMedia
	FlagCensored
	FlagModIcon
	FlagStaffIcon
	FlagRedChannel // js: #ed1c24

	FlagBlueChannel // js: #25aae1

	FlagModChannel
)
View Source
const (
	// CombineFilterAnd combines filter using logical AND.
	CombineFilterAnd int = iota
	// CombineFilterAnd combines filter using logical OR.
	CombineFilterOr
	// CombineFilterAnd combines filter using logical XOR.
	CombineFilterXor
)

Variables

View Source
var (
	ErrNotAGroup        = errors.New("not a group")
	ErrNotConnected     = errors.New("not connected")
	ErrAlreadyConnected = errors.New("already connected")
	ErrConnectionClosed = errors.New("connection closed")
	ErrRetryEnds        = errors.New("retry ends")
	ErrCLimited         = errors.New("climited")

	ErrLoginFailed = errors.New("failed to login")
	ErrNoArgument  = errors.New("no argument")
	ErrTimeout     = errors.New("timeout")

	ErrRateLimited          = errors.New("rate limited")
	ErrMessageLength        = errors.New("message length exceeded")
	ErrFloodWarning         = errors.New("flood warning")
	ErrFloodBanned          = errors.New("flood banned")
	ErrNonSenseWarning      = errors.New("nonsense warning")
	ErrSpamWarning          = errors.New("spam warning")
	ErrShortWarning         = errors.New("short warning")
	ErrRestricted           = errors.New("restricted")
	ErrMustLogin            = errors.New("must login")
	ErrProxyBanned          = errors.New("proxy banned")
	ErrVerificationRequired = errors.New("verification required")
	ErrOfflineLimit         = errors.New("offline message limit")

	ErrBadAlias = errors.New("bad alias")
	ErrBadLogin = errors.New("bad login")

	ErrRequestFailed = errors.New("request failed")
)
View Source
var (
	AnonSeedRe         = regexp.MustCompile(`<n\d{4}/>`)
	NameColorRe        = regexp.MustCompile(`<n([\da-fA-F]{1,6})\/>`)
	FontStyleRe        = regexp.MustCompile(`<f x([\da-fA-F]+)?="([\d\w]+)?">`)
	NameFontTag        = regexp.MustCompile(`<[nf]\s[^>]*>`)
	PrivateFontStyleRe = regexp.MustCompile(`<g x(\d+)?s([\da-fA-F]+)?="([\d\w]+)?">`)

	// Go does not support negative lookahead `<(?!br\s*\/?>).*?>`.
	// This alternative will match either the `<br>` and `<br/>` tags (captured in group 1)
	// or any other HTML tags (captured in group 2).
	// Then the `ReplaceAllString(text, "$1")` method will then keep the content matched by group 1
	// and remove the content matched by group 2.
	HtmlTagRe = regexp.MustCompile(`(<br\s*\/?>)|(<[^>]+>)`)
)
View Source
var GroupPermissions = map[string]int64{
	"DELETED":                1,
	"EDIT_MODS":              2,
	"EDIT_MOD_VISIBILITY":    4,
	"EDIT_BW":                8,
	"EDIT_RESTRICTIONS":      16,
	"EDIT_GROUP":             32,
	"SEE_COUNTER":            64,
	"SEE_MOD_CHANNEL":        128,
	"SEE_MOD_ACTIONS":        256,
	"EDIT_NLP":               512,
	"EDIT_GP_ANNC":           1024,
	"EDIT_ADMINS":            2048,
	"EDIT_SUPERMODS":         4096,
	"NO_SENDING_LIMITATIONS": 8192,
	"SEE_IPS":                16384,
	"CLOSE_GROUP":            32768,
	"CAN_BROADCAST":          65536,
	"MOD_ICON_VISIBLE":       131072,
	"IS_STAFF":               262144,
	"STAFF_ICON_VISIBLE":     524288,
	"UNBAN_ALL":              1048576,
}
View Source
var GroupStatuses = map[string]int64{
	"MISSING_1":                1,
	"NO_ANONS":                 4,
	"MISSING_2":                8,
	"NO_COUNTER":               16,
	"DISALLOW_IMAGES":          32,
	"DISALLOW_LINKS":           64,
	"DISALLOW_VIDEOS":          128,
	"MISSING_3":                256,
	"MISSING_4":                512,
	"BANWORD_ONLY_TO_AUTHOR":   1024,
	"FLOOD_CONTROLLED":         2048,
	"ENABLE_CHANNELS":          8192,
	"BASIC_NONSENSE_DETECTION": 16384,
	"BLOCK_REPETITIOUS_MSGS":   32768,
	"BROADCAST_MODE":           65536,
	"CLOSED_NO_MODS":           131072,
	"GROUP_CLOSED":             262144,
	"DISPLAY_BADGES":           524288,
	"MODS_CHOOSE_BADGES":       1048576,
	"ADV_NONSENSE_DETECTION":   2097152,
	"BAN_PROXIES_AND_VPN":      4194304,
	"MISSING_5":                8388608,
	"MISSING_6":                268435456,
	"MISSING_7":                536870912,
}
View Source
var ModactionTmpl = map[string]string{
	"mod_actions_title":           "Moderator Actions Log",
	"mod_actions_title_sm":        "Moderator Log",
	"action_desc_amod":            "*name**ip* made *target* a moderator",
	"action_desc_aadm":            "*name**ip* made *target* an administrator",
	"action_desc_rmod":            "*name**ip* removed *target* as a moderator",
	"action_desc_radm":            "*name**ip* removed *target* as an administrator",
	"action_desc_emod":            "*name**ip*",
	"added_perm":                  "gave *target* permission to: *added*",
	"and":                         "and",
	"removed_perm":                "removed *target*'s permission to: *removed*",
	"action_desc_chrl":            "*name**ip* changed rate limit to *rl*",
	"action_desc_anon":            "*name**ip* *didallow* anons in the group",
	"action_desc_prxy":            "*name**ip* *didallow* messaging from proxies and VPNs in the group",
	"action_desc_brdc":            "*name**ip* *didenable* broadcast mode",
	"action_desc_cinm":            "*name**ip* *didenable* closed without moderators mode",
	"action_desc_acls":            "Group auto-closed since no moderators were online",
	"action_desc_aopn":            "Group re-opened upon moderator login",
	"action_desc_chan":            "*name**ip* *didenable* channels in the group",
	"action_desc_cntr":            "*name**ip* *didenable* the counter in the group",
	"action_desc_chbw":            "*name**ip* changed banned words",
	"action_desc_enlp":            "*name**ip* changed auto-moderation to",
	"action_desc_annc":            "*name**ip* *didenable* auto-announcement",
	"action_desc_egrp":            "*name**ip* edited group",
	"action_desc_shwi":            "*name**ip* forced moderators to show a badge",
	"action_desc_hidi":            "*name**ip* hid all moderator badges",
	"action_desc_chsi":            "*name**ip* let moderators choose their own badge visibility",
	"action_desc_ubna":            "*name**ip* removed all bans",
	"enable_annc":                 "every *n* seconds: *msg*",
	"perm_edit_mods":              "add, remove and edit mods",
	"perm_edit_mod_visibility":    "edit mod visibility",
	"perm_edit_bw":                "edit banned content",
	"perm_edit_restrictions":      "edit chat restrictions",
	"perm_edit_group":             "edit group",
	"perm_see_counter":            "see counter",
	"perm_see_mod_channel":        "see mod channel",
	"perm_see_mod_actions":        "see mod actions log",
	"perm_can_broadcast":          "send messages in broadcast mode",
	"perm_edit_nlp":               "edit auto-moderation",
	"perm_edit_gp_annc":           "edit group announcement",
	"perm_no_sending_limitations": "bypass message sending limitations",
	"perm_see_ips":                "see IPs",
	"perm_is_staff":               "display staff badge",
	"perm_close_group":            "close group input",
	"perm_unban_all":              "unban all",
	"flood_cont":                  "flood controlled",
	"slow_mode":                   "slow mode restricted to *time* *secs*",
	"second":                      "second",
	"seconds":                     "seconds",
	"disallowed":                  "disallowed",
	"allowed":                     "allowed",
	"enabled":                     "enabled",
	"disabled":                    "disabled",
	"nlp_single_msg":              "nonsense messages (basic)",
	"nlp_msg_queue":               "repetitious messages",
	"nlp_ngram":                   "nonsense messages (advanced)",
	"allow":                       "allow",
	"block":                       "block",
}

Functions

func BoolZeroOrOne added in v0.0.2

func BoolZeroOrOne(b bool) string

BoolZeroOrOne returns either "0" or "1"

func ComputeFlagChanges

func ComputeFlagChanges(oldFlags, newFlags int64) (addedFlags, removedFlags int64)

ComputeFlagChanges computes the flag changes between the oldFlags and newFlags values.

func Contains

func Contains[T comparable](arr []T, item T) bool

Contains is a generic function that checks whether the specified item is present in the given array.

func CreateAnonSeed

func CreateAnonSeed(name string, sid int) (seed int)

CreateAnonSeed creates an anonymous seed using the provided name and sid.

func FileExists

func FileExists(filename string) bool

FileExists checks whether the specified file exists.

func GetAnonName

func GetAnonName(seed, sid int) (name string)

GetAnonName generates an anonymous name using the provided seed and sid.

func GetServer

func GetServer(name string) string

GetServer retrieves the server URL for the specified name. This function takes a string as input and returns a URL string for a server based on the input string. The returned URL is used for establishing a WebSocket connection. The function uses a weighted round-robin algorithm to select a server based on the input string. The input string is first converted to base36 integer by replacing "_" and "-" characters with "q". The first and second halves of the modified string are used to calculate a modulus ratio. The modulus ratio is then used to select a server based on its weight. The function returns a default URL if no server is selected.

func IsDigit

func IsDigit(strnum string) bool

IsDigit checks whether the provided string represents a digit.

func Max

func Max[T Number](a T, b ...T) (c T)

Max is a generic function that returns the maximum value among the provided numbers.

func Min

func Min[T Number](a T, b ...T) (c T)

Min is a generic function that returns the minimum value among the provided numbers.

func ParseTime

func ParseTime(strtime string) (t time.Time, err error)

ParseTime parses the provided string representation of time into a time.Time value.

func Remove

func Remove[T comparable](arr []T, item T) []T

Remove is a generic function that removes the specified item from the given array.

func SaveConfig

func SaveConfig(filename string, config *Config) error

SaveConfig saves the configuration to the specified file.

func SplitTextIntoChunks

func SplitTextIntoChunks(text string, chunkSize int) (chunks []string)

SplitTextIntoChunks splits the provided text into chunks of the specified size.

Types

type API

type API struct {
	Username string
	Password string
	// contains filtered or unexported fields
}

API is a struct representing a compilation of various Chatango APIs.

func (*API) CheckUsername added in v0.0.2

func (api *API) CheckUsername(username string) (ok bool, notOkReasons []string, err error)

CheckUsername checks whether the specified username is available for purchase. It returns `ok=true` if the username is purchasable. If not, the reasons for it not being available will be provided in the `notOkReasons` slice.

func (*API) GetBackground added in v0.0.2

func (api *API) GetBackground(username string) (background MessageBackground, err error)

GetBackground retrieves the message background of the specified username.

func (*API) GetCookie

func (api *API) GetCookie(cookiename string) (cookie string, ok bool)

GetCookie retrieves cookie value.

func (*API) GetFullProfile

func (api *API) GetFullProfile(username string) (profile FullProfile, err error)

GetFullProfile retrieves the full profile of the specified username.

func (*API) GetGroupList

func (api *API) GetGroupList() (groups GroupsList, err error)

GetGroupList retrieves the user's chat group list.

func (*API) GetMiniProfile

func (api *API) GetMiniProfile(username string) (profile MiniProfile, err error)

GetMiniProfile retrieves the mini profile of the specified username.

func (*API) GetStyle added in v0.0.2

func (api *API) GetStyle(username string) (style MessageStyle, err error)

GetStyle retrieves the message style of the specified username.

func (*API) GetToken

func (api *API) GetToken(gcmID string) (token string, err error)

GetToken retrieves the token for the specified GCM ID.

func (*API) Initialize

func (api *API) Initialize() (err error)

Initialize initializes the Chatango API client and retrieves cookies from the specified username and password. It authenticates the client by obtaining and storing the necessary cookies. The retrieved cookies will be stored in the API's cookies field for external access through `api.GetCookie`.

func (*API) IsGroup

func (api *API) IsGroup(groupname string) (answer bool, err error)

IsGroup checks whether the specified name is a group.

func (*API) RegisterGCM

func (api *API) RegisterGCM(gcmID, token string) (err error)

RegisterGCM registers the specified GCM ID with the provided token.

func (*API) SearchPeople

func (api *API) SearchPeople(query PeopleQuery) (usernames [][2]string, err error)

SearchPeople searches for people based on the provided query. It returns a list of usernames and online status data.

func (*API) SetBackground added in v0.0.2

func (api *API) SetBackground(background MessageBackground) (err error)

SetBackground updates the message background of the current user. Normally, the `background` parameter is obtained/modified from `api.GetBackground()`.

func (*API) SetStyle added in v0.0.2

func (api *API) SetStyle(style MessageStyle) (err error)

SetStyle updates the message style of the current user. Normally, the `style` parameter is obtained/modified from `api.GetStyle()`.

func (*API) UnregisterGCM

func (api *API) UnregisterGCM(gcmID string) (err error)

UnregisterGCM unregisters the specified GCM ID.

type Application

type Application struct {
	Config      *Config                 // Config holds the configuration for the application.
	Persistence *Persistence            // Persistence manages data persistence for the application.
	API         *API                    // API provides access to various Chatango APIs used by the application.
	Private     Private                 // Private represents the private chat functionality of the application.
	Groups      SyncMap[string, *Group] // Groups stores the groups the application is connected to.
	// contains filtered or unexported fields
}

Application represents the main application.

func New

func New(config *Config) *Application

New creates a new instance of the `*Application` with the provided configuration.

func (*Application) AddHandler

func (app *Application) AddHandler(handler Handler) *Application

AddHandler adds a new handler to the application. It returns the `*Application` to allow for nesting.

func (*Application) ConnectPM

func (app *Application) ConnectPM() error

ConnectPM connects to private messages.

func (*Application) DisconnectPM

func (app *Application) DisconnectPM()

DisconnectPM disconnects from private messages.

func (*Application) Dispatch

func (app *Application) Dispatch(event *Event)

Dispatch dispatches an event to the appropriate handler.

func (*Application) Initialize

func (app *Application) Initialize()

Initialize initializes the application.

func (*Application) JoinGroup

func (app *Application) JoinGroup(groupName string) error

JoinGroup joins a group in the application.

func (*Application) LeaveGroup

func (app *Application) LeaveGroup(groupName string) error

LeaveGroup leaves a group in the application.

func (*Application) Park

func (app *Application) Park()

Park waits for the application to stop or receive an interrupt signal.

func (*Application) RemoveHandler

func (app *Application) RemoveHandler(handler Handler)

RemoveHandler removes a handler from the application.

func (*Application) Start

func (app *Application) Start(ctx context.Context)

Start starts the application.

func (*Application) Stop

func (app *Application) Stop()

Stop stops the application.

type Backoff

type Backoff struct {
	Duration    time.Duration // Duration represents the current backoff duration.
	MaxDuration time.Duration // MaxDuration is the maximum allowed backoff duration.
	// contains filtered or unexported fields
}

Backoff represents a backoff mechanism with configurable duration and maximum duration.

func (*Backoff) Cancel

func (b *Backoff) Cancel()

Cancel cancels the ongoing backoff sleep.

func (*Backoff) Sleep

func (b *Backoff) Sleep(ctx context.Context) bool

Sleep is a mock of time.Sleep(), that is also responsive to the cancel signal. It adds some jitter to the context and waits until the context is done. Returns true if the sleep was cancelled before the deadline, false otherwise.

type BanWord

type BanWord struct {
	WholeWords string `json:"wholeWords"` // Whole words to be banned.
	Words      string `json:"words"`      // Words to be banned.
}

BanWord represents a banned word.

func (*BanWord) GetPartial

func (bw *BanWord) GetPartial() []string

GetPartial returns the partial banned words as a slice of strings.

func (*BanWord) GetWhole

func (bw *BanWord) GetWhole() []string

GetWhole returns the whole banned words as a slice of strings.

func (*BanWord) SetPartial

func (bw *BanWord) SetPartial(partial []string)

SetPartial sets the partial banned words.

func (*BanWord) SetWhole

func (bw *BanWord) SetWhole(exact []string)

SetWhole sets the whole banned words.

type BirthDate

type BirthDate time.Time

BirthDate represents a birth date of a user.

func (*BirthDate) UnmarshalXML

func (c *BirthDate) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error

UnmarshalXML unmarshals the XML data into the BirthDate value.

type Blocked

type Blocked struct {
	IP           string    // IP address of the blocked user.
	ModerationID string    // Moderation ID of the block.
	Target       string    // Target username.
	Blocker      string    // Username of the blocker.
	Time         time.Time // Time of blocking.
}

Blocked represents a banned user in a group.

type Callback

type Callback func(*Event, *Context)

Callback is a function type that represents a callback function for handling events.

type ChatFilter

type ChatFilter struct {
	Chats []string // Chats is a list of chat names to filter events based on chat information.
}

ChatFilter represents a filter for chats.

func (*ChatFilter) Add

func (f *ChatFilter) Add(chatName string)

Add adds a chat to the filter's list of chats.

func (*ChatFilter) And

func (f *ChatFilter) And(filter Filter) Filter

And returns a new CombineFilter that combines the current filter with the provided filter using logical AND.

func (*ChatFilter) Check

func (f *ChatFilter) Check(event *Event) bool

Check checks if the event's group is in the filter's list of chats.

func (*ChatFilter) Not

func (f *ChatFilter) Not() Filter

Not returns a new NotFilter negating the current filter.

func (*ChatFilter) Or

func (f *ChatFilter) Or(filter Filter) Filter

Or returns a new CombineFilter that combines the current filter with the provided filter using logical OR.

func (*ChatFilter) Remove

func (f *ChatFilter) Remove(chatName string)

Remove removes a chat from the filter's list of chats.

func (*ChatFilter) Xor

func (f *ChatFilter) Xor(filter Filter) Filter

Xor returns a new CombineFilter that combines the current filter with the provided filter using logical XOR.

type CombineFilter

type CombineFilter struct {
	Left  Filter // Left represents the first filter to be combined using logical AND.
	Right Filter // Right represents the second filter to be combined using logical AND.
	Mode  int    // Mode specifies the combination mode: 0 for AND, 1 for OR, and 2 for XOR.
}

CombineFilter is a struct that represents the logical AND of two filters.

func (*CombineFilter) And

func (f *CombineFilter) And(filter Filter) Filter

And returns a new CombineFilter that combines the current filter with the provided filter using logical AND.

func (*CombineFilter) Check

func (f *CombineFilter) Check(event *Event) bool

Check returns true if both the left and right filters return true.

func (*CombineFilter) Not

func (f *CombineFilter) Not() Filter

Not returns a new NotFilter negating the current filter.

func (*CombineFilter) Or

func (f *CombineFilter) Or(filter Filter) Filter

Or returns a new CombineFilter that combines the current filter with the provided filter using logical OR.

func (*CombineFilter) Xor

func (f *CombineFilter) Xor(filter Filter) Filter

Xor returns a new CombineFilter that combines the current filter with the provided filter using logical XOR.

type CommandHandler

type CommandHandler struct {
	Callback Callback // Callback is the function that will be invoked when a command event is triggered.
	Filter   Filter   // Filter is the filter that will be applied to the events before invoking the callback.
	Commands []string // Commands is a list of command names that this handler will respond to.
	// contains filtered or unexported fields
}

CommandHandler is a struct that implements the Handler interface for handling command in message events.

func (*CommandHandler) Check

func (ch *CommandHandler) Check(event *Event) bool

Check checks if the event is a command event that matches the prefix and command.

func (*CommandHandler) Invoke

func (ch *CommandHandler) Invoke(event *Event, context *Context)

Invoke executes the callback function for the command event.

type Config

type Config struct {
	Username  string   `json:"username"`  // Username of the configuration.
	Password  string   `json:"password"`  // Password of the configuration.
	AnonName  string   `json:"anonname"`  // Anonymous name of the configuration.
	Groups    []string `json:"groups"`    // List of groups in the configuration.
	NameColor string   `json:"namecolor"` // Name color in the configuration.
	TextColor string   `json:"textcolor"` // Text color in the configuration.
	TextFont  string   `json:"textfont"`  // Text font in the configuration.
	TextSize  int      `json:"textsize"`  // Text size in the configuration.
	SessionID string   `json:"sessionid"` // Session ID in the configuration.
	EnableBG  bool     `json:"enablebg"`  // Enable background in the configuration.
	EnablePM  bool     `json:"enablepm"`  // Enable private messages in the configuration.
	Debug     bool     `json:"debug"`     // Debug mode in the configuration.
	Prefix    string   `json:"prefix"`    // Prefix for commands in the configuration.
}

Config represents a configuration object.

func LoadConfig

func LoadConfig(filename string) (*Config, error)

LoadConfig loads the configuration from the specified file.

type Context

type Context struct {
	App      *Application          // App is a pointer to the Application that manages this context.
	ChatData *SyncMap[string, any] // ChatData is a synchronized map to store data specific to the chat.
	BotData  *SyncMap[string, any] // BotData is a synchronized map to store data specific to the bot.
}

Context represents the context for event callback.

type Event

type Event struct {
	Type             EventType    // The type of the event.
	IsPrivate        bool         // Indicates if the event is related to a private chat.
	Private          *Private     // The private chat associated with the event.
	Group            *Group       // The group associated with the event.
	User             *User        // The user associated with the event.
	Message          *Message     // The message associated with the event.
	Command          string       // The command associated with the event.
	WithArgument     bool         // Indicates if the command has an argument.
	Argument         string       // The argument associated with the command.
	Arguments        []string     // The arguments associated with the command.
	Participant      *Participant // The participant associated with the event.
	FlagAdded        int64        // The flags added in the event.
	FlagRemoved      int64        // The flags removed in the event.
	Blocked          *Blocked     // The blocked user associated with the event.
	Unblocked        *Unblocked   // The unblocked user associated with the event.
	GroupInfo        *GroupInfo   // The group information associated with the event.
	ModGrantedAccess int64        // The granted moderator access level associated with the event.
	ModRevokedAccess int64        // The revoked moderator access level associated with the event.
	Error            any          // The error associated with the event.
}

Event represents an event that can occur in the application.

type EventType

type EventType int64

EventType represents the type of an event.

const (
	// Event triggered when the application starts.
	OnStart EventType = 1 << iota
	// Event triggered when the application stops.
	OnStop
	// Event triggered when an error occurs.
	OnError

	// Event triggered when the bot joins a group.
	OnGroupJoined
	// Event triggered when the bot leaves a group.
	OnGroupLeft
	// Event triggered when the bot reconnects to a group.
	OnGroupReconnected
	// Event triggered when a user joins a group.
	OnJoin
	// Event triggered when a user logs in.
	OnLogin
	// Event triggered when a user logs out.
	OnLogout
	// Event triggered when a user leaves a group.
	OnLeave
	// Event triggered when the participant count in a group changes.
	OnParticipantCountChange
	// Event triggered when a message is received.
	OnMessage
	// Event triggered when a message is deleted.
	OnMessageDelete
	// Event triggered when message history is retrieved.
	OnMessageHistory
	// Event triggered when a message is updated.
	OnMessageUpdate
	// Event triggered when an announcement is received.
	OnAnnouncement
	// Event triggered when the group information is updated.
	OnUpdateGroupInfo
	// Event triggered when flags are updated.
	OnFlagUpdate
	// Event triggered when a moderator is added.
	OnModeratorAdded
	// Event triggered when a moderator is updated.
	OnModeratorUpdated
	// Event triggered when a moderator is removed.
	OnModeratorRemoved
	// Event triggered when all messages are cleared.
	OnClearAll
	// Event triggered when a user is banned.
	OnUserBanned
	// Event triggered when a user is unbanned.
	OnUserUnbanned
	// Event triggered when all users are unbanned.
	OnAllUserUnbanned

	// Event triggered when the bot connects to a private chat.
	OnPrivateConnected
	// Event triggered when the bot disconnects from a private chat.
	OnPrivateDisconnected
	// Event triggered when the bot reconnects to a private chat.
	OnPrivateReconnected
	// Event triggered when the bot is kicked off from a private chat.
	OnPrivateKickedOff
	// Event triggered when a private message is received.
	OnPrivateMessage
	// Event triggered when an offline private message is received.
	OnPrivateOfflineMessage
	// Event triggered when a friend becomes online in a private chat.
	OnPrivateFriendOnline
	// Event triggered when a friend becomes online in a private chat app.
	OnPrivateFriendOnlineApp
	// Event triggered when a friend goes offline in a private chat.
	OnPrivateFriendOffline
	// Event triggered when a friend becomes active in a private chat.
	OnPrivateFriendActive
	// Event triggered when a friend becomes idle in a private chat.
	OnPrivateFriendIdle

	// Event triggered when the user profile is updated.
	OnUpdateUserProfile
)

Event types.

type Filter

type Filter interface {
	Check(*Event) bool // Check evaluates if the given event passes the filter conditions.
	And(Filter) Filter // And returns a new filter that combines the current filter with another using logical AND.
	Or(Filter) Filter  // Or returns a new filter that combines the current filter with another using logical OR.
	Xor(Filter) Filter // Xor returns a new filter that combines the current filter with another using logical XOR.
	Not() Filter       // Not returns a new filter that negates the current filter using logical NOT.
}

Filter is an interface that defines the methods for filtering events.

func NewChatFilter

func NewChatFilter(groupnames ...string) Filter

NewChatFilter returns a new `ChatFilter`.

func NewRegexFilter

func NewRegexFilter(pattern string) Filter

NewRegexFilter returns a new `RegexFilter`.

func NewUserFilter

func NewUserFilter(usernames ...string) Filter

NewUserFilter returns a new `UserFilter`.

type FullProfile

type FullProfile struct {
	XMLName xml.Name     `xml:"mod"`  // Tag name
	Body    QueryEscaped `xml:"body"` // Full profile info
	T       string       `xml:"t"`    // Reserved
}

FullProfile represents a full profile of a user.

type Group

type Group struct {
	App       *Application // Reference to the application.
	Name      string       // The name of the group.
	AnonName  string       // The anonymous user name format.
	NameColor string       // The color for displaying name in the message.
	TextColor string       // The color for displaying text in the message.
	TextFont  string       // The font style for displaying text in the message.
	TextSize  int          // The font size for displaying text in the message.

	WsUrl string // The WebSocket URL for connecting to the group.

	Connected bool // Indicates if the group is currently connected.

	Version    [2]int                 // The version of the group.
	Owner      string                 // The owner of the group.
	SessionID  string                 // The session ID for the group.
	UserID     int                    // The user ID for the group.
	LoggedIn   bool                   // Indicates if the user is logged in to the group.
	LoginName  string                 // The login name of the user.
	LoginTime  time.Time              // The time when the user logged in.
	TimeDiff   time.Duration          // The time difference between the server and client.
	LoginIp    string                 // The IP address of the user.
	Moderators SyncMap[string, int64] // Map of moderators and their access levels.
	Flag       int64                  // The flag value for the group.

	Channel          int64         // The channel flag of the group.
	Restrict         time.Time     // The time when the group is restricted from the flood ban and auto moderation.
	RateLimit        time.Duration // The rate limit duration for sending messages.
	RateLimited      time.Time     // The time when the group is rate-limited.
	MaxMessageLength int           // The maximum allowed length of a message.
	PremiumExpireAt  time.Time     // The time when the premium membership expires.

	Messages       OrderedSyncMap[string, *Message] // Ordered map of messages history in the group.
	TempMessages   SyncMap[string, *Message]        // Map of temporary messages in the group.
	TempMessageIds SyncMap[string, string]          // Map of temporary message IDs in the group.

	Participants     SyncMap[string, *Participant] // Map of participants in the group. Invoke `g.GetParticipantsStart` to initiate the participant feeds.
	ParticipantCount int64                         // The total count of participants in the group.
	UserCount        int                           // The count of registered users in the group.
	AnonCount        int                           // The count of anonymous users in the group.
	// contains filtered or unexported fields
}

Group represents a chat group with various properties and state.

func (*Group) AddModerator

func (g *Group) AddModerator(username string, access int64) (err error)

AddModerator adds a moderator to the group with the specified username and access level.

func (*Group) BanUser

func (g *Group) BanUser(message *Message) (err error)

BanUser bans the user associated with the specified message.

func (*Group) ClearAll

func (g *Group) ClearAll() (err error)

ClearAll clears all messages in the group.

func (*Group) Connect

func (g *Group) Connect(ctx context.Context) (err error)

Connect establishes a connection to the server. It returns an error if the connection cannot be established.

func (*Group) Delete

func (g *Group) Delete(message *Message) (err error)

Delete deletes the specified message from the group.

func (*Group) DeleteAll

func (g *Group) DeleteAll(message *Message) (err error)

DeleteAll deletes all messages in the group.

func (*Group) Disconnect

func (g *Group) Disconnect()

Disconnect gracefully closes the connection to the server.

func (*Group) GetAnnouncement

func (g *Group) GetAnnouncement() (annc string, enabled bool, interval time.Duration, err error)

GetAnnouncement retrieves the announcement settings for the group.

func (*Group) GetBanList

func (g *Group) GetBanList(offset time.Time, ammount int) (banList []Blocked, err error)

GetBanList retrieves a list of blocked users (ban list) for the group. The offset can be set to zero time to retrieve the newest result. The returned order is from newer to older.

func (*Group) GetBanWords

func (g *Group) GetBanWords() (banWord BanWord, err error)

GetBanWords retrieves the banned word settings for the group.

func (*Group) GetContext

func (g *Group) GetContext() context.Context

GetContext returns the context of the private chat.

func (*Group) GetLastUserMessage

func (g *Group) GetLastUserMessage(username string) (msg *Message, ok bool)

GetLastUserMessage retrieves the last message sent by the specified username in the group. This is useful for banning a user by their username.

func (*Group) GetModActions

func (g *Group) GetModActions(dir string, offset int) (modactions []*ModAction, err error)

GetModActions retrieves a list of moderator actions (mod actions) for the group. The `dir` can be either "prev" to go earlier or "next" to go to the latest. The `offset` corresponds to the ID of the earlier-1 or latest+1 `ModAction.ID`.

func (*Group) GetParticipantsStart

func (g *Group) GetParticipantsStart() (p *SyncMap[string, *Participant], err error)

GetParticipantsStart initiates the `participant` event feeds and returns the current participants. The `participant` event will be triggered when there is user activity, such as joining, logging out, logging in, or leaving.

func (*Group) GetParticipantsStop

func (g *Group) GetParticipantsStop() error

GetParticipantsStop stops the participant event feeds. This will leave g.Participants, g.UserCount, g.AnonCount out of date.

func (*Group) GetPremiumInfo

func (g *Group) GetPremiumInfo() (flag int, expire time.Time, err error)

GetPremiumInfo retrieves the premium status and expiration time for the group. This function would activate server validation for the premium status. For example, the message background and media won't activate before this command is sent.

func (*Group) GetRateLimit

func (g *Group) GetRateLimit() (rate, current time.Duration, err error)

GetRateLimit retrieves the rate limit settings for the group.

func (*Group) GetUnbanList

func (g *Group) GetUnbanList(offset time.Time, ammount int) (unbanList []Unblocked, err error)

GetUnbanList retrieves a list of unblocked users (unban list) for the group. The `offset` is taken from the earliest time in the previous result or zero `time.Time`. The `amount` corresponds to the desired number of results.

func (*Group) IsRestricted

func (g *Group) IsRestricted() bool

IsRestricted checks if the group is restricted. The restriction can originate from either a flood ban or a rate limit.

func (*Group) Login

func (g *Group) Login(username, password string) (err error)

Login logs in to the group with the provided username and password. If the password is an empty string, it will log in as the named anon instead.

func (*Group) Logout

func (g *Group) Logout() (err error)

Logout logs out from the group.

func (*Group) ProfileRefresh

func (g *Group) ProfileRefresh() error

ProfileRefresh notifies the server to refresh the profile.

func (*Group) PropagateEvent

func (g *Group) PropagateEvent(frame string)

PropagateEvent propagates the WebSocket frame back to the listener goroutine. It is utilized when the `g.SyncSend` callback receives unwanted frames.

func (*Group) Reconnect

func (g *Group) Reconnect() (err error)

Reconnect attempts to reconnect to the server.

func (*Group) RemoveModerator

func (g *Group) RemoveModerator(username string) (err error)

RemoveModerator removes the specified moderator from the group.

func (*Group) SearchBannedUser

func (g *Group) SearchBannedUser(query string) (banned Blocked, ok bool, err error)

SearchBannedUser searches for a banned user in the group's ban list. The query can be either a user name or an IP address.

func (*Group) Send

func (g *Group) Send(args ...string) error

Send will join the `args` with a ":" separator and then send it to the server asynchronously.

func (*Group) SendMessage

func (g *Group) SendMessage(text string, a ...any) (msg *Message, err error)

SendMessage sends a message to the group with the specified text and optional arguments. It returns a pointer to the sent `*Message` and an error (if any occurred). The text can include formatting placeholders (%s, %d, etc.), and optional arguments can be provided to fill in these placeholders. The function also handles flood warnings, restricted messages, spam warnings, rate limiting, and other Chatango-specific events. If the group is logged in, the message text is styled with the group's name color, text size, text color, and text font. If the group is anonymous, the message text is modified with the anonymous seed based on the group's `AnonName` and `UserID`. The function replaces newlines with the `<br/>` HTML tag to format the message properly.

func (*Group) SendMessageChunked

func (g *Group) SendMessageChunked(text string, chunkSize int) (msgs []*Message, err error)

SendMessage sends the chunked `text` with a size of `chunkSize` and returns the sent `[]*Message`. In the event of an error, the already sent messages will be returned along with the error for the unsent message.

func (*Group) SetAnnouncement

func (g *Group) SetAnnouncement(annc string, enable bool, interval time.Duration) error

SetAnnouncement sets the announcement settings for the group.

func (*Group) SetBackground

func (g *Group) SetBackground(enable bool) (err error)

SetBackground sets the background status of the group. If enable is true, it enables the background feature for the group. If enable is false, it disables the background feature for the group.

func (*Group) SetBanWords

func (g *Group) SetBanWords(banWord BanWord) (err error)

SetBanWords sets the banned word settings for the group.

func (*Group) SetMedia

func (g *Group) SetMedia(enable bool) (err error)

SetMedia sets the media status of the group. If enable is true, it enables the media feature for the group. If enable is false, it disables the media feature for the group.

func (*Group) SetRateLimit

func (g *Group) SetRateLimit(interval time.Duration) (rate time.Duration, err error)

SetRateLimit sets the rate limit interval for the group.

func (*Group) SyncSend

func (g *Group) SyncSend(cb func(string) bool, text ...string) error

SyncSend will send the `args` and wait until receiving the correct reply or until timeout (default to 5 seconds). For more information, refer to the documentation of `g.SyncSendWithTimeout`.

func (*Group) SyncSendWithTimeout

func (g *Group) SyncSendWithTimeout(callback func(string) bool, timeout time.Duration, args ...string) (err error)

SyncSend will send the `args` and wait until receiving the correct reply or until timeout. First, a `g.takeOver` request will be made and it will wait until the listener goroutine catches it. Then, the `args` will be sent to the server. Each time a frame is received, the `callback` function is invoked and passed the frame. The `callback` should return `false` if a correct frame is acquired, and `true` otherwise.

func (*Group) UnbanAll

func (g *Group) UnbanAll() (err error)

UnbanAll unblocks all blocked users.

func (*Group) UnbanUser

func (g *Group) UnbanUser(blocked *Blocked) (err error)

UnbanUser unblocks the specified blocked user.

func (*Group) UpdateGroupFlag

func (g *Group) UpdateGroupFlag(addition, removal int64) (err error)

UpdateGroupFlag updates the group's flag by adding and removing specific flags.

func (*Group) UpdateModerator

func (g *Group) UpdateModerator(username string, access int64) (err error)

UpdateModerator updates the access level of the specified moderator.

type GroupInfo

type GroupInfo struct {
	OwnerMessage string `json:"ownr_msg"`
	Title        string `json:"title"`
}

GroupInfo represents a group info.

func (*GroupInfo) GetMessage

func (gi *GroupInfo) GetMessage() string

GetDescription returns the description of the group.

func (*GroupInfo) GetTitle

func (gi *GroupInfo) GetTitle() string

GetTitle returns the title of the group.

type GroupsList added in v0.0.2

type GroupsList struct {
	RecentGroups   [][2]string `json:"recent_groups"` // List of recently visited groups.
	UnreadMessages int         `json:"n_msg"`         // Number of unread private messages.
	Groups         [][2]string `json:"groups"`        // List of created groups.
}

GroupsList represents the created and recently visited chat groups of the user. It also provides the number of unread private messages.

func (GroupsList) GetGroups added in v0.0.2

func (mg GroupsList) GetGroups() map[string]string

GetGroups returns the map of all chat groups.

func (GroupsList) GetRecentGroups added in v0.0.2

func (mg GroupsList) GetRecentGroups() map[string]string

GetRecentGroups returns the map of recent chat groups.

type Handler

type Handler interface {
	Check(*Event) bool       // Check checks if the event satisfies the conditions specified by the handler.
	Invoke(*Event, *Context) // Invoke handles the event using the specified callback and context.
}

Handler is an interface that defines the methods for handling events.

func NewCommandHandler

func NewCommandHandler(callback Callback, filter Filter, commands ...string) Handler

NewCommandHandler returns a new `CommandHandler`.

func NewMessageHandler

func NewMessageHandler(callback Callback, filter Filter) Handler

NewMessageHandler returns a new `MessageHandler`.

func NewTypeHandler

func NewTypeHandler(callback Callback, filter Filter, eventType EventType) Handler

NewTypeHandler returns a new `TypeHandler`.

type KeyValue

type KeyValue struct {
	Key   string
	Value int64
}

KeyValue represents a key-value pair This is a struct helper for "emod" ModAction parsing.

type Location

type Location struct {
	Country   string  `xml:"c,attr"`    // Country name or US postal code
	G         string  `xml:"g,attr"`    // Reserved
	Latitude  float64 `xml:"lat,attr"`  // Latitude
	Longitude float64 `xml:"lon,attr"`  // Longitude
	Text      string  `xml:",chardata"` // String text of the location
}

Location represents the location information of a user.

type Message

type Message struct {
	Group        *Group    // Group represents the group chat where the message originated (nil if private chat).
	Private      *Private  // Private represents the private chat where the message originated (nil if group chat).
	IsPrivate    bool      // IsPrivate indicates whether the message is from a private chat.
	User         *User     // User represents the user who sent the message.
	Text         string    // Text contains the parsed text of the message.
	RawText      string    // RawText contains the raw text of the message.
	UserID       int       // UserID is the unique identifier of the user who sent the message.
	ID           string    // ID is the unique identifier of the message.
	ModerationID string    // ModerationID is the unique identifier used for moderation actions on the message.
	UserIP       string    // UserIP is the IP address of the user who sent the message.
	Time         time.Time // Time represents the time when the message was sent.
	ReceivedTime time.Time // ReceivedTime represents the time when the message was received.
	Flag         int64     // Flag represents the flag value associated with the message.
	FromSelf     bool      // FromSelf indicates whether the message was sent by the current user.
	FromAnon     bool      // FromAnon indicates whether the message was sent by an anonymous user.
	AnonSeed     int       // AnonSeed represents the seed value used for anonymous user identification.
}

Message represents a message that comes from a group or private chat.

func ParseAnnouncement

func ParseAnnouncement(data string, group *Group) *Message

ParseAnnouncement parses a group announcement data and returns a `*Message` object.

func ParseGroupMessage

func ParseGroupMessage(data string, group *Group) *Message

ParseGroupMessage parses a group message data and returns a `*Message` object.

func ParsePrivateMessage

func ParsePrivateMessage(data string, private *Private) *Message

ParsePrivateMessage parses a private message data and returns a `*Message` object.

func (*Message) BanUser

func (m *Message) BanUser() error

BanUser bans the user who sent the current message from the group. If the message is from a group, it calls the BanUser method on the associated Group to perform the banning action. If the message is private, this method does nothing and returns nil.

func (*Message) Channel

func (m *Message) Channel() (c int64)

Channel returns the channel flag of the message.

func (*Message) Delete

func (m *Message) Delete() error

Delete deletes the message. If the message is from a group, it calls the Delete method on the associated Group to remove the message from the group chat. If the message is private, this method does nothing and returns nil.

func (*Message) DeleteAll

func (m *Message) DeleteAll() error

DeleteAll deletes all messages from the sender of the current message. If the message is from a group, it calls the DeleteAll method on the associated Group to remove all messages from the sender in the group chat. If the message is private, this method does nothing and returns nil.

func (*Message) HasBackground

func (m *Message) HasBackground() bool

HasBackground checks if the message has background flag.

func (*Message) HasMedia

func (m *Message) HasMedia() bool

HasMedia checks if the message has media flag.

func (*Message) HasPremium

func (m *Message) HasPremium() bool

HasPremium checks if the message has premium flag.

func (*Message) IsCensored added in v0.0.2

func (m *Message) IsCensored() bool

IsCensored checks if the message contains censor.

func (*Message) NameColor

func (m *Message) NameColor() string

NameColor returns the name color of the message.

func (*Message) Reply

func (m *Message) Reply(text string, a ...any) (*Message, error)

Reply sends a reply to the message with the specified text. If the message is from a group, it calls the `SendMessage` method on the associated Group to send the reply. If the message is private, it calls the `SendMessage` method on the associated Private to send the reply to the user. The text can include formatting placeholders (%s, %d, etc.), and optional arguments can be provided to fill in these placeholders. The function returns a pointer to the sent `*Message` and an error (if any occurred). If the message is private, the returned `*Message` pointer will be nil, and the error will contain the details of any error that occurred during the sending process.

func (*Message) TextStyle

func (m *Message) TextStyle() (textColor, textFont string, textSize int)

TextStyle returns the text style of the message.

type MessageBackground added in v0.0.2

type MessageBackground struct {
	Align        string `xml:"align,attr"`  // Background image alignment
	Alpha        int    `xml:"bgalp,attr"`  // Background color transparency
	Color        string `xml:"bgc,attr"`    // Background color
	HasRecording int64  `xml:"hasrec,attr"` // Media recording timestamp (ms)
	ImageAlpha   int    `xml:"ialp,attr"`   // Background image transparency
	IsVid        bool   `xml:"isvid,attr"`  // Media is a video?
	Tile         bool   `xml:"tile,attr"`   // Tile image?
	UseImage     bool   `xml:"useimg,attr"` // Use image?
}

MessageBackground represents the background information of a user.

func (*MessageBackground) GetForm added in v0.0.2

func (mb *MessageBackground) GetForm() url.Values

GetForm returns the URL-encoded form values for the `MessageBackground`.

type MessageHandler

type MessageHandler struct {
	Callback Callback // Callback is the function that will be invoked when a message event is triggered.
	Filter   Filter   // Filter is the filter that will be applied to the events before invoking the callback.
}

MessageHandler is a struct that implements the Handler interface for handling message events.

func (*MessageHandler) Check

func (mh *MessageHandler) Check(event *Event) bool

Check checks if the event is a message event.

func (*MessageHandler) Invoke

func (mh *MessageHandler) Invoke(event *Event, context *Context)

Invoke executes the callback function for the message event.

type MessageStyle added in v0.0.2

type MessageStyle struct {
	FontFamily    string `json:"fontFamily"`    // The font family used for the message text.
	FontSize      string `json:"fontSize"`      // The font size used for the message text.
	Bold          bool   `json:"bold"`          // A boolean value indicating whether the message text should be displayed in bold.
	StylesOn      bool   `json:"stylesOn"`      // A boolean value indicating whether the message styles are enabled.
	UseBackground string `json:"usebackground"` // The background color used for the message text.
	Italics       bool   `json:"italics"`       // A boolean value indicating whether the message text should be displayed in italics.
	TextColor     string `json:"textColor"`     // The color used for the message text.
	Underline     bool   `json:"underline"`     // A boolean value indicating whether the message text should be underlined.
	NameColor     string `json:"nameColor"`     // The color used for the username or sender's name in the message.
}

MessageStyle represents the style settings for a message.

func (MessageStyle) GetForm added in v0.0.2

func (mb MessageStyle) GetForm() url.Values

GetForm returns the URL-encoded form values for the `MessageStyle`.

type MiniProfile

type MiniProfile struct {
	XMLName  xml.Name     `xml:"mod"`  // Tag name
	Body     QueryEscaped `xml:"body"` // Mini profile info
	Gender   string       `xml:"s"`    // Gender (M, F)
	Birth    BirthDate    `xml:"b"`    // Date of birth (yyyy-mm-dd)
	Location Location     `xml:"l"`    // Location
	Premium  PremiumDate  `xml:"d"`    // Premium expiration
}

MiniProfile represents a mini profile of a user.

type ModAction

type ModAction struct {
	ID     int       // ID is the unique identifier of the moderation action.
	Type   string    // Type is the type of the moderation action, e.g., "emod", "brdc", "cinm", "chan", "cntr", etc.
	User   string    // User is the name of the moderator who performed the action.
	IP     string    // IP is the IP address of the moderator who performed the action.
	Target string    // Target is the name of the user that the action was performed on.
	Time   time.Time // Time is the timestamp when the action was performed.
	Extra  string    // Extra is any additional information or context related to the moderation action.
}

ModAction represents a moderation action.

func ParseModActions

func ParseModActions(data string) (modActions []*ModAction)

ParseModActions parses a string data and returns a slice of ModAction objects

func (*ModAction) ExtraAsBool

func (ma *ModAction) ExtraAsBool() (ret bool)

ExtraAsBool returns the Extra field as a boolean.

func (*ModAction) ExtraAsInt

func (ma *ModAction) ExtraAsInt() (ret int64)

ExtraAsInt returns the Extra field as an int64.

func (*ModAction) ExtraAsSliceInt

func (ma *ModAction) ExtraAsSliceInt() (ret []int64)

ExtraAsSliceInt returns the Extra field as a slice of int64.

func (*ModAction) ExtraAsSliceInterface

func (ma *ModAction) ExtraAsSliceInterface() (ret []interface{})

ExtraAsSliceInterface returns the Extra field as a slice of interface{}.

func (*ModAction) ExtraBanWord

func (ma *ModAction) ExtraBanWord() (ret BanWord)

ExtraBanWord returns the Extra field as a BanWord.

func (*ModAction) ExtraDescription

func (ma *ModAction) ExtraDescription() (ret GroupInfo)

ExtraDescription returns the Extra field as a GroupInfo.

func (*ModAction) String

func (ma *ModAction) String() (actionDesc string)

String returns a string representation of the ModAction. TODO: use `strings.Builder` instead.

type NotFilter

type NotFilter struct {
	Base Filter // Base represents the filter to be negated using logical NOT.
}

NotFilter is a struct that represents the logical NOT of a filter.

func (*NotFilter) And

func (f *NotFilter) And(filter Filter) Filter

And returns a new CombineFilter that combines the current filter with the provided filter using logical AND.

func (*NotFilter) Check

func (f *NotFilter) Check(event *Event) bool

Check returns the logical negation of the filter's result.

func (*NotFilter) Not

func (f *NotFilter) Not() Filter

Not returns a new NotFilter negating the current filter.

func (*NotFilter) Or

func (f *NotFilter) Or(filter Filter) Filter

Or returns a new CombineFilter that combines the current filter with the provided filter using logical OR.

func (*NotFilter) Xor

func (f *NotFilter) Xor(filter Filter) Filter

Xor returns a new CombineFilter that combines the current filter with the provided filter using logical XOR.

type Number

type Number interface {
	int | int16 | int32 | int64 | float32 | float64
}

Number represents a numeric type.

type OrderedSyncMap

type OrderedSyncMap[K comparable, V any] struct {
	sync.RWMutex
	K []K
	M map[K]V
}

OrderedSyncMap is a synchronized map that maintains the order of keys.

func NewOrderedSyncMap

func NewOrderedSyncMap[K comparable, V any]() OrderedSyncMap[K, V]

NewOrderedSyncMap creates a new instance of OrderedSyncMap.

func (*OrderedSyncMap[K, V]) Clear

func (sm *OrderedSyncMap[K, V]) Clear()

Clear removes all key-value pairs from the OrderedSyncMap.

func (*OrderedSyncMap[K, V]) Del

func (sm *OrderedSyncMap[K, V]) Del(key K)

Del removes the key-value pair with the specified key from the OrderedSyncMap.

func (*OrderedSyncMap[K, V]) Get

func (sm *OrderedSyncMap[K, V]) Get(key K) (val V, ok bool)

Get retrieves the value associated with the specified key from the OrderedSyncMap.

func (*OrderedSyncMap[K, V]) GobDecode

func (sm *OrderedSyncMap[K, V]) GobDecode(data []byte) error

GobDecode decodes the OrderedSyncMap using Gob.

func (*OrderedSyncMap[K, V]) GobEncode

func (sm *OrderedSyncMap[K, V]) GobEncode() ([]byte, error)

GobEncode encodes the OrderedSyncMap using Gob.

func (*OrderedSyncMap[K, V]) Keys

func (sm *OrderedSyncMap[K, V]) Keys() []K

Keys returns a slice of keys in the OrderedSyncMap.

func (*OrderedSyncMap[K, V]) Len

func (sm *OrderedSyncMap[K, V]) Len() int

Len returns the number of key-value pairs in the OrderedSyncMap.

func (*OrderedSyncMap[K, V]) Range

func (sm *OrderedSyncMap[K, V]) Range(fun func(K, V) bool)

Range iterates over each key-value pair in the OrderedSyncMap and calls the specified function. If the function returns false, the iteration stops.

func (*OrderedSyncMap[K, V]) RangeReversed

func (sm *OrderedSyncMap[K, V]) RangeReversed(fun func(K, V) bool)

RangeReversed iterates over each key-value pair in the OrderedSyncMap in reverse order and calls the specified function. If the function returns false, the iteration stops.

func (*OrderedSyncMap[K, V]) Set

func (sm *OrderedSyncMap[K, V]) Set(key K, val V)

Set adds or updates a key-value pair in the OrderedSyncMap.

func (*OrderedSyncMap[K, V]) SetFront

func (sm *OrderedSyncMap[K, V]) SetFront(key K, val V)

SetFront adds or updates a key-value pair at the front of the OrderedSyncMap.

func (*OrderedSyncMap[K, V]) TrimFront

func (sm *OrderedSyncMap[K, V]) TrimFront(length int)

TrimFront trims the front part of the OrderedSyncMap to the specified length. It modifies the OrderedSyncMap in place, removing elements from the beginning of the map until the desired length is reached.

type Participant

type Participant struct {
	ParticipantID string    // Participant ID.
	UserID        int       // User ID.
	User          *User     // User object.
	Time          time.Time // Time of participation.
}

Participant represents a group participant object.

type PeopleQuery

type PeopleQuery struct {
	AgeFrom    int    // Minimum age
	AgeTo      int    // Maximum age
	Gender     string // Gender (B, M, F, N)
	Username   string // Username
	Radius     int    // Radius
	Latitude   string // Latitude
	Longtitude string // Longitude
	Online     bool   // Online status
	Offset     int    // Offset
	Amount     int    // Amount
}

PeopleQuery represents a query for searching people.

func (*PeopleQuery) GetForm

func (pq *PeopleQuery) GetForm() url.Values

GetForm returns the URL-encoded form values for the PeopleQuery.

func (*PeopleQuery) NextOffset

func (pq *PeopleQuery) NextOffset()

NextOffset updates the offset to retrieve the next set of results.

type Persistence

type Persistence struct {
	Filename string                                 // File name for the data.
	Interval time.Duration                          // Interval for auto-saving.
	BotData  SyncMap[string, any]                   // Map to store bot-related data.
	ChatData SyncMap[string, *SyncMap[string, any]] // Map to store chat-related data.
	// contains filtered or unexported fields
}

Persistence is responsible for loading and saving data to a file periodically. If the filename is set to an empty string, it will disable auto-saving. If the interval is set to less than 1 minute, it will be adjusted to 30 minutes.

func (*Persistence) Close

func (p *Persistence) Close() error

Close stops the auto save routine and saves the data to the file.

func (*Persistence) DelChatData

func (p *Persistence) DelChatData(key string)

DelChatData deletes the ChatData for the given key.

func (*Persistence) GetBotData

func (p *Persistence) GetBotData() *SyncMap[string, any]

GetBotData returns a pointer to the BotData.

func (*Persistence) GetChatData

func (p *Persistence) GetChatData(key string) *SyncMap[string, any]

GetChatData returns a pointer to the ChatData for the given key. If the ChatData does not exist, it creates a new one and returns it.

func (*Persistence) Initialize

func (p *Persistence) Initialize() error

Initialize initializes the Persistence struct by loading the data from the file and starting the auto save routine.

func (*Persistence) Load

func (p *Persistence) Load() error

Load loads the data from the file into the Persistence struct.

func (*Persistence) Save

func (p *Persistence) Save() error

Save saves the data from the Persistence struct to the file.

func (*Persistence) StartAutoSave added in v0.0.2

func (p *Persistence) StartAutoSave(ctx context.Context)

type PremiumDate

type PremiumDate time.Time

PremiumDate represents a premium date of a user.

func (*PremiumDate) UnmarshalXML

func (c *PremiumDate) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error

UnmarshalXML unmarshals the XML data into the PremiumDate value.

type Private

type Private struct {
	App       *Application // Reference to the application.
	Name      string       // The name of the group.
	NameColor string       // The color for displaying name in the message.
	TextColor string       // The color for displaying text in the message.
	TextFont  string       // The font style for displaying text in the message.
	TextSize  int          // The font size for displaying text in the message.

	WsUrl string // The WebSocket URL for connecting to the PM server.

	Connected bool // Indicates if the PM server is currently connected.

	LoginName string        // The login name of the user.
	SessionID string        // The session ID for the PM server.
	LoginTime time.Time     // The time when the user logged in.
	TimeDiff  time.Duration // The time difference between the server and client (serverTime - clientTime).

	IsIdle bool // Indicates whether there has been no activity within 1 minute (e.g., sending a message).
	// contains filtered or unexported fields
}

Private represents a private message with various properties and state.

func (*Private) AddFriend

func (p *Private) AddFriend(username string) (status UserStatus, err error)

AddFriend adds a username to the friend list.

func (*Private) Block

func (p *Private) Block(username string) (err error)

Block blocks the user with the specified username.

func (*Private) Connect

func (p *Private) Connect(ctx context.Context) (err error)

Connect establishes a connection to the server. It returns an error if the connection cannot be established.

func (*Private) ConnectUser

func (p *Private) ConnectUser(username string) (status UserStatus, err error)

ConnectUser opens a chat session with the username.

func (*Private) Disconnect

func (p *Private) Disconnect()

Disconnect gracefully closes the connection to the PM server.

func (*Private) DisconnectUser

func (p *Private) DisconnectUser(username string) (err error)

DisconnectUser closes the chat session with the username.

func (*Private) GetBlocked

func (p *Private) GetBlocked() (users []*User, err error)

GetBlocked retrieves the list of blocked users.

func (*Private) GetContext

func (p *Private) GetContext() context.Context

GetContext returns the context of the private chat.

func (*Private) GetFriendList

func (p *Private) GetFriendList() (friendlist []UserStatus, err error)

GetFriendList retrieves the list of friends with their corresponding status.

func (*Private) GetPresence

func (p *Private) GetPresence(usernames []string) (statuslist []UserStatus, err error)

GetPresence retrieves the status of multiple usernames. If the user is offline, the corresponding `UserStatus.Time` is not accurate.

func (*Private) GetSettings

func (p *Private) GetSettings() (setting PrivateSetting, err error)

GetSettings retrieves the current settings.

func (*Private) ProfileRefresh

func (p *Private) ProfileRefresh() error

ProfileRefresh notifies the server to refresh the profile.

func (*Private) PropagateEvent

func (p *Private) PropagateEvent(frame string)

PropagateEvent propagates the WebSocket frame back to the listener goroutine. It is utilized when the `p.SyncSend` callback receives unwanted frames.

func (*Private) Reconnect

func (p *Private) Reconnect() (err error)

Reconnect attempts to reconnect to the PM server.

func (*Private) RemoveFriend

func (p *Private) RemoveFriend(username string) (err error)

RemoveFriend removes the username from the friend list.

func (*Private) Send

func (p *Private) Send(args ...string) error

Send will join the `args` with a ":" separator and then send it to the server asynchronously.

func (*Private) SendMessage

func (p *Private) SendMessage(username, text string, a ...any) (err error)

SendMessage sends a private message to the specified username with the given text and optional arguments. It returns an error if any occurs during the message sending process. The text can include formatting placeholders (%s, %d, etc.), and optional arguments can be provided to fill in these placeholders. The function also handles a flood warning, a flood ban, and the maximum number of unread messages (51) has been reached. The function replaces newlines with the `<br/>` HTML tag to format the message properly.

func (*Private) SetSettings

func (p *Private) SetSettings(setting PrivateSetting) (err error)

SetSettings updates the settings with the provided values.

func (*Private) SyncSend

func (p *Private) SyncSend(cb func(string) bool, text ...string) error

SyncSend will send the `args` and wait until receiving the correct reply or until timeout (default to 5 seconds). For more information, refer to the documentation of `p.SyncSendWithTimeout`.

func (*Private) SyncSendWithTimeout

func (p *Private) SyncSendWithTimeout(callback func(string) bool, timeout time.Duration, args ...string) (err error)

SyncSendWithTimeout will send the `args` and wait until receiving the correct reply or until timeout. First, a `p.takeOver` request will be made and it will wait until the listener goroutine catches it. Then, the `args` will be sent to the server. Each time a frame is received, the `callback` function is invoked and passed the frame. The `callback` should return `false` if a correct frame is acquired, and `true` otherwise.

func (*Private) Track

func (p *Private) Track(username string) (status UserStatus, err error)

Track retrieves the online status of the username.

func (*Private) Unblock

func (p *Private) Unblock(username string) (err error)

Unblock unblocks the user with the specified username.

func (*Private) WentActive

func (p *Private) WentActive()

WentActive notifies the server that the user went active.

func (*Private) WentIdle

func (p *Private) WentIdle()

WentIdle notifies the server that the user went idle.

type PrivateSetting

type PrivateSetting struct {
	DisableIdleTime bool // Disable idle time in private messages.
	AllowAnon       bool // Allow anonymous messages.
	EmailOfflineMsg bool // Email offline messages.
}

PrivateSetting represents the private message settings.

type QueryEscaped

type QueryEscaped string

QueryEscaped represents a query-escaped string.

func (*QueryEscaped) UnmarshalXML

func (c *QueryEscaped) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error

UnmarshalXML unmarshals the XML data into the QueryEscaped value.

type RegexFilter

type RegexFilter struct {
	Pattern *regexp.Regexp // Pattern represents the regular expression pattern used for filtering messages.
}

RegexFilter represents a Message filter based on a regular expression pattern.

func (*RegexFilter) And

func (f *RegexFilter) And(filter Filter) Filter

And returns a new CombineFilter that combines the current filter with the provided filter using logical AND.

func (*RegexFilter) Check

func (f *RegexFilter) Check(event *Event) bool

Check checks if the event matches the regular expression pattern.

func (*RegexFilter) Not

func (f *RegexFilter) Not() Filter

Not returns a new NotFilter negating the current filter.

func (*RegexFilter) Or

func (f *RegexFilter) Or(filter Filter) Filter

Or returns a new CombineFilter that combines the current filter with the provided filter using logical OR.

func (*RegexFilter) Xor

func (f *RegexFilter) Xor(filter Filter) Filter

Xor returns a new CombineFilter that combines the current filter with the provided filter using logical XOR.

type SyncMap

type SyncMap[K comparable, V any] struct {
	sync.RWMutex
	M map[K]V
}

SyncMap is a synchronized map that can be accessed concurrently.

func NewSyncMap

func NewSyncMap[K comparable, V any]() SyncMap[K, V]

NewSyncMap creates a new instance of SyncMap.

func (*SyncMap[K, V]) Clear

func (sm *SyncMap[K, V]) Clear()

Clear removes all key-value pairs from the SyncMap.

func (*SyncMap[K, V]) Del

func (sm *SyncMap[K, V]) Del(key K)

Del removes the key-value pair with the specified key from the SyncMap.

func (*SyncMap[K, V]) Get

func (sm *SyncMap[K, V]) Get(key K) (val V, ok bool)

Get retrieves the value associated with the specified key from the SyncMap.

func (*SyncMap[K, V]) GobDecode

func (sm *SyncMap[K, V]) GobDecode(data []byte) error

GobDecode decodes the SyncMap using Gob decoding.

func (*SyncMap[K, V]) GobEncode

func (sm *SyncMap[K, V]) GobEncode() ([]byte, error)

GobEncode encodes the SyncMap using Gob encoding.

func (*SyncMap[K, V]) Keys

func (sm *SyncMap[K, V]) Keys() (keys []K)

Keys returns a slice of keys in the SyncMap.

func (*SyncMap[K, V]) Len

func (sm *SyncMap[K, V]) Len() int

Len returns the number of key-value pairs in the SyncMap.

func (*SyncMap[K, V]) Range

func (sm *SyncMap[K, V]) Range(fun func(K, V) bool)

Range iterates over each key-value pair in the SyncMap and calls the specified function. If the function returns false, the iteration stops.

func (*SyncMap[K, V]) Set

func (sm *SyncMap[K, V]) Set(key K, val V)

Set adds or updates a key-value pair in the SyncMap.

type Transport

type Transport struct {
	Transport http.RoundTripper // Transport is the underlying RoundTripper.
	Headers   map[string]string // Headers contains custom headers to be added to the requests.
}

Transport is a custom RoundTripper implementation.

func (*Transport) RoundTrip

func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error)

RoundTrip executes a single HTTP request and returns its response. It adds custom headers to the request before performing the request using the underlying Transport.

type TypeHandler

type TypeHandler struct {
	Callback Callback  // Callback is the function that will be invoked when an event of the specified type is triggered.
	Filter   Filter    // Filter is the filter that will be applied to the events before invoking the callback.
	Type     EventType // Type is the type of event that this handler will respond to.
}

TypeHandler is a struct that implements the Handler interface for handling events of a specific type.

func (*TypeHandler) Check

func (th *TypeHandler) Check(event *Event) bool

Check checks if the event is of the specified type.

func (*TypeHandler) Invoke

func (th *TypeHandler) Invoke(event *Event, context *Context)

Invoke executes the callback function for the event of the specified type.

type Unblocked

type Unblocked struct {
	IP           string    // IP address of the unblocked user.
	ModerationID string    // Moderation ID of the unblock.
	Target       string    // Target username.
	Unblocker    string    // Username of the unblocker.
	Time         time.Time // Time of unblocking.
}

Unblocked represents an unblocked user in a group.

type User

type User struct {
	Name   string // Name of the user.
	IsSelf bool   // Indicates if the user is self.
	IsAnon bool   // Indicates if the user is anonymous.
}

User represents a user object.

type UserFilter

type UserFilter struct {
	Users []string // Users is a list of usernames to filter events based on user information.
}

UserFilter represents a filter for users.

func (*UserFilter) Add

func (f *UserFilter) Add(userName string)

Add adds a user to the filter's list of users.

func (*UserFilter) And

func (f *UserFilter) And(filter Filter) Filter

And returns a new CombineFilter that combines the current filter with the provided filter using logical AND.

func (*UserFilter) Check

func (f *UserFilter) Check(event *Event) bool

Check checks if the event's user is in the filter's list of users.

func (*UserFilter) Not

func (f *UserFilter) Not() Filter

Not returns a new NotFilter negating the current filter.

func (*UserFilter) Or

func (f *UserFilter) Or(filter Filter) Filter

Or returns a new CombineFilter that combines the current filter with the provided filter using logical OR.

func (*UserFilter) Remove

func (f *UserFilter) Remove(userName string)

Remove removes a user from the filter's list of users.

func (*UserFilter) Xor

func (f *UserFilter) Xor(filter Filter) Filter

Xor returns a new CombineFilter that combines the current filter with the provided filter using logical XOR.

type UserStatus

type UserStatus struct {
	User *User         // User object.
	Time time.Time     // Time of the status.
	Info string        // Additional information about the status.
	Idle time.Duration // Idle duration of the user.
}

UserStatus represents the online status of a user.

type WebSocket

type WebSocket struct {
	Connected bool        // Connected indicates whether the WebSocket connection is currently active.
	Events    chan string // Events is a channel for receiving WebSocket events and messages.
	OnError   func(error) // OnError is a callback function that will be called in case of an error during WebSocket operation.
	// contains filtered or unexported fields
}

WebSocket represents a WebSocket connection. It implements `golang.org/x/net/websocket` under the hood and wraps it into a channel, allowing it to be select-able along with other channels.

func (*WebSocket) Close

func (w *WebSocket) Close()

Close closes the WebSocket connection.

func (*WebSocket) Connect

func (w *WebSocket) Connect(url string) (err error)

Connect establishes a WebSocket connection to the specified URL.

func (*WebSocket) Recv

func (w *WebSocket) Recv() (msg string, err error)

Recv receives a message from the WebSocket connection.

func (*WebSocket) Send

func (w *WebSocket) Send(msg string) (err error)

Send sends a message over the WebSocket connection.

func (*WebSocket) Sustain

func (w *WebSocket) Sustain(ctx context.Context)

Sustain starts pumping events and keeps the WebSocket connection alive.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL