入力の読み取り
すべてのハンドラは *goroku.Message を受け取ります。以下のヘルパーで引数の解析は ほぼ足ります。
Args
コマンド語より後ろすべて、前後の空白を除いたもの。
go
// .say こんにちは みなさん
msg.Args() // "こんにちは みなさん"
// .say
msg.Args() // ""内部の空白は保たれます — .say a b は "a b" になります。そのまま返したい テキストにも安全です。
ArgsList と Arg
空白で分割します。
go
// .ban 42 spam here
msg.ArgsList() // []string{"42", "spam", "here"}
msg.Arg(0) // "42"
msg.Arg(1) // "spam"
msg.Arg(9) // "" — panic しない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 のフィールド
| フィールド | 型 | 意味 |
|---|---|---|
ID | int64 | メッセージ ID |
ChatID | int64 | 送信されたチャット |
SenderID | int64 | 送信者 |
Text | string | 書式適用後のテキスト |
RawText | string | 入力そのままのテキスト |
Out | bool | 自分が送信した |
IsPrivate, IsGroup, IsChannel | bool | チャット種別 |
Media | tg.MessageMediaClass | 添付、無ければ nil |
ReplyToMsgID | int64 | 返信でなければ 0 |
IsForwarded | bool | 転送されたもの |
キャンセル
msg.Context() はボット終了時にキャンセルされます。時間のかかる処理には必ず渡し てください。
go
req, err := http.NewRequestWithContext(msg.Context(), http.MethodGet, url, nil)
if err != nil {
return err
}
resp, err := http.DefaultClient.Do(req)無視するハンドラも動作はします。終了処理がそれを待つだけです。