Skip to content

Чтение ввода

Каждый обработчик получает *goroku.Message. Эти хелперы покрывают почти весь разбор аргументов.

Args

Всё после слова команды, с обрезанными пробелами по краям:

go
// .say привет всем
msg.Args() // "привет всем"

// .say
msg.Args() // ""

Внутренние пробелы сохраняются — .say a b даёт "a b" — так что это безопасно для текста, который вы собираетесь отдать дословно.

ArgsList и Arg

Разбиение по пробелам:

go
// .ban 42 спам тут
msg.ArgsList() // []string{"42", "спам", "тут"}
msg.Arg(0)     // "42"
msg.Arg(1)     // "спам"
msg.Arg(9)     // "" — без паники

Arg не выходит за границы. Проверять длину заранее не нужно:

go
func (m *Mod) BanCmd(msg *goroku.Message) error {
	id := msg.Arg(0)
	if id == "" {
		return msg.Answer(m.T("no_id", "❌ <b>Кого?</b>"))
	}
	reason := msg.Arg(1) // "" если не указана — и это нормально
	return m.ban(id, reason)
}

ArgsOrReply

Паттерн, который нужен большинству команд: взять напечатанные аргументы, а если их нет — текст сообщения, на которое ответили.

go
func (m *HTML) HTMLCmd(msg *goroku.Message) error {
	code := msg.ArgsOrReply()
	if code == "" {
		return msg.Answer(m.T("no_args", "❌ <b>Пришлите текст или ответьте на сообщение</b>"))
	}
	return msg.Answer(code)
}

Теперь работают оба варианта:

.html <b>привет</b>       → отрисует напечатанную разметку
.html  (в ответ)          → отрисует сообщение, на которое ответили

Пустой результат означает, что нет ни того ни другого — считайте это «делать нечего».

Сообщение, на которое ответили

Для всего, кроме текста, получите его целиком:

go
reply, err := msg.GetReplyMessage()
if err != nil || reply == nil {
	return msg.Answer(m.T("reply_needed", "❌ <b>Ответьте на сообщение</b>"))
}

if reply.Media != nil {
	// обработать вложение
}

Чтобы требовать ответ, лучше объявить это декларативно — диспетчер отфильтрует до запуска обработчика:

go
"mycmd": { OnlyReply: true },

Поля Message

ПолеТипСмысл
IDint64ID сообщения
ChatIDint64Где отправлено
SenderIDint64Кто отправил
TextstringТекст с применённым форматированием
RawTextstringТекст как напечатан
OutboolОтправлено вами
IsPrivate, IsGroup, IsChannelboolТип чата
Mediatg.MessageMediaClassВложение, nil если нет
ReplyToMsgIDint640, если это не ответ
IsForwardedboolПереслано откуда-то

Отмена

msg.Context() отменяется при завершении бота. Передавайте его во всё долгое:

go
req, err := http.NewRequestWithContext(msg.Context(), http.MethodGet, url, nil)
if err != nil {
	return err
}
resp, err := http.DefaultClient.Do(req)

Обработчики, которые его игнорируют, работать не перестанут — завершение просто их дождётся.

Released under the GNU AGPL v3 License.