Global code ovehaul - remove CAS and other, add 15 minute greet check

- Remove CAS, as it no longer works for us
- Remove other checks
- Implement 15 minute greet timeout check
- Fix chat logos
- Ditch thirdparty logger, use stdlib log facility wrapper for logging
This commit is contained in:
eleksir
2026-10-20 12:20:16 +03:00
parent 2f467af6cf
commit 0c34b6e781
1597 changed files with 6440 additions and 648118 deletions

View File

@@ -1,40 +1,82 @@
package moon
import (
"os"
"time"
"github.com/NicoNex/echotron/v3"
"github.com/akyoto/cache"
)
// MyConfig describes bot config file format.
type MyConfig struct {
Name string `json:"name,omitempty"`
Token string `json:"token,omitempty"`
LogLevel string `json:"loglevel,omitempty"`
LogFile string `json:"logfile,omitempty"`
LogChats bool `json:"logchats,omitempty"`
CSign string `json:"csign,omitempty"`
DataDir string `json:"datadir,omitempty"`
// ChatLogs is the directory for per-chat, per-day chat event logs. Empty
// disables chat logging. If set, the directory must already exist: a path
// that does not is a typo, and silently logging nowhere is the worst
// possible response to one.
ChatLogs string `json:"chat_logs,omitempty"`
}
// CasFalse describes response from api.cas.chat when user is not blacklisted.
type CasFalse struct {
Ok bool `json:"ok"`
Description string `json:"description"`
// tgClient is the subset of the Telegram API that bunny-bot actually calls.
// It exists so tests can substitute a fake; echotron.API satisfies it.
type tgClient interface {
SendMessage(text string, chatID int64, opts *echotron.MessageOptions) (echotron.APIResponseMessage, error)
BanChatMember(chatID int64, userID int64, opts *echotron.BanOptions) (echotron.APIResponseBool, error)
DeleteMessage(chatID int64, messageID int) (echotron.APIResponseBase, error)
}
// CasFalse describes response from api.cas.chat when user is blacklisted.
type CasTrue struct {
Ok bool `json:"ok"`
Result struct {
Reasons []int `json:"reasons"`
Offenses int `json:"offenses"`
TimeAdded time.Time `json:"time_added"`
} `json:"result"`
// chatUser identifies a user's membership of one specific chat. The same user is
// a different identity in every chat: being silent in one says nothing about
// another, and answering in one must not rescue them in another.
type chatUser struct {
chatID int64
userID int64
}
type Chatlog struct {
LogFilePath string
File *os.File
// banOutcome is what a squash attempt actually did. The three cases are distinct
// on purpose: a duplicate ban is a success, not a failure, and reporting it as
// one makes a working ban look broken in the logs.
type banOutcome int
// eventCache is a typed wrapper over akyoto/cache.Cache that stores values of
// type T keyed by a Unix timestamp in microseconds. It hides the underlying
// sync.Map so callers never deal with interface{} keys/values or per-access type
// conversions.
type eventCache[T any] struct {
cache *cache.Cache
}
// joinRef is one stale join, kept together with everything the verdict and the
// retraction need so neither has to look anything up.
type joinRef struct {
micros int64
// chat and user come from the join event itself, so a ban can be logged with
// the newcomer's real name and the chat's real title instead of a cache
// lookup that may have expired or never been populated.
chat echotron.Chat
user *echotron.User
// greetingID is the question we asked them, deleted once they are banned for
// never answering it. Zero means we never managed to ask.
greetingID int
}
// pendingGreeting is one recorded join: the message that announced it, and the
// id of the greeting we sent in reply.
//
// The greeting id lives here rather than in a second cache, so that recording,
// forgetting and retracting are all one lookup on one key. A zero greeting id
// means "no greeting was ever delivered for this join" — never a failure.
type pendingGreeting struct {
join *echotron.Message
greetingID int
}
// retractOutcome is what a retraction pass actually achieved. The three cases are
// distinct because "nothing to delete" and "tried and failed" call for different
// log lines, and only the second is worth an operator's attention.
type retractOutcome int
/* vim: set ft=go noet ai ts=4 sw=4 sts=4: */