Files
bunny-bot/internal/moon/greet.go
eleksir 0c34b6e781 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
2026-10-20 12:20:16 +03:00

99 lines
3.6 KiB
Go

package moon
import (
"bunny-bot/internal/mylog"
"math/rand/v2"
"strings"
"github.com/NicoNex/echotron/v3"
)
// greetings are the templates used to greet a newly joined member. The single
// verb is replaced with the newcomer's computed display name. The fourth one is
// intentionally kept verbatim despite looking like a typo.
var greetings = []string{
"Дарована, %s. Представьтес, пожалуйста, и расскажите, что вас сюда привело.",
"Добро пожаловать в наше скромное коммунити, %s. Представьтес, пожалуйста, и расскажите, что вас сюда привело.",
"Доброе утро, день или вечер, %s. Представьтес, пожалуйста, и расскажите, что вас сюда привело.",
"Наше вам с кисточкой тут, на канальчике, %s. Представьтес, пожалуйста, и расскажите, что вас сюда привело.",
}
// displayName builds the name substituted into a greeting for the given user.
// Preference order: "FirstName LastName", then LastName alone, then FirstName
// alone, then the username.
func displayName(u *echotron.User) string {
if u == nil {
return ""
}
name := strings.TrimSpace(strings.Join([]string{u.FirstName, u.LastName}, " "))
if name != "" {
return name
}
return u.Username
}
// sendGreeting sends a randomly chosen greeting for the given newcomer into the chat.
//
// It returns the id of the greeting it sent and whether it was actually
// delivered. Both matter: a newcomer who never received the question must not be
// judged on their silence, and a newcomer who is banned later must have the
// question taken back down.
//
// The mention makes the greeting a clickable link to the newcomer, and the
// message is sent in HTML mode because that is the only mode in which an
// arbitrary display name can be embedded safely — see greetMention.
func sendGreeting(chatid int64, u *echotron.User) (int, bool) {
// Everything below dereferences u, including the error paths that name the
// user, so an entity with no id is refused here rather than crashing later.
if !usableUser(u) {
return 0, false
}
// math/rand is sufficient here: we pick one of four static templates, not a
// secret or a security-relevant value.
greeting := greetings[rand.IntN(len(greetings))] //nolint: gosec // G404
text := strings.Replace(greeting, "%s", greetingAddressee(u), 1)
res, err := Tg.SendMessage(text, chatid, &echotron.MessageOptions{
ParseMode: echotron.HTML,
})
if err != nil {
mylog.Errorf("GREETING NOT DELIVERED to user %d in chat %d: %s", u.ID, chatid, err)
return 0, false
}
mylog.Debugf("Greeted user %d in chat %d", u.ID, chatid)
// A response carrying no message still means the greeting was delivered; we
// simply have no id to retract later.
return sentMessageID(res), true
}
// greetingAddressee is the name the template's %s is replaced with: a mention of
// the newcomer when they can be mentioned, and their plain display name when they
// cannot, so an unmentionable user is still greeted rather than skipped.
func greetingAddressee(u *echotron.User) string {
if mention := greetMention(u); mention != "" {
return mention
}
return displayName(u)
}
// sentMessageID pulls the id out of a send response, tolerating a response that
// carries no message at all.
func sentMessageID(res echotron.APIResponseMessage) int {
if res.Result == nil {
return 0
}
return res.Result.ID
}
/* vim: set ft=go noet ai ts=4 sw=4 sts=4: */