Initial release of go-telegram

A fully-generated, strongly-typed Go client for the Telegram Bot API.

* 176 methods + 301 types generated from Bot API v10.0
* 1408 auto-generated tests (8 scenarios per method)
* Typed unions throughout — no 'any' in the public surface
* Pluggable HTTP transport and JSON codec (default goccy/go-json)
* Built-in retry middleware honouring Telegram's retry_after
* Generic dispatcher with filters and conversation handlers
* Self-verifying codegen pipeline (regen → audit → emit → run tests)
* 14 example bots covering common patterns
This commit is contained in:
2026-05-09 13:09:27 +01:00
commit ac7cae8fa7
164 changed files with 100239 additions and 0 deletions
+43
View File
@@ -0,0 +1,43 @@
// Package callback provides Filter helpers for *api.CallbackQuery payloads.
package callback
import (
"regexp"
"strings"
"github.com/lukaszraczylo/go-telegram/api"
"github.com/lukaszraczylo/go-telegram/dispatch"
)
// Data returns a Filter that matches callback queries whose Data matches
// pattern (regex). Panics at registration time on an invalid pattern.
func Data(pattern string) dispatch.Filter[*api.CallbackQuery] {
re := regexp.MustCompile(pattern)
return func(q *api.CallbackQuery) bool {
return q != nil && re.MatchString(q.Data)
}
}
// DataEquals returns a Filter that matches callback queries whose Data equals
// s exactly.
func DataEquals(s string) dispatch.Filter[*api.CallbackQuery] {
return func(q *api.CallbackQuery) bool {
return q != nil && q.Data == s
}
}
// DataPrefix returns a Filter that matches callback queries whose Data starts
// with prefix.
func DataPrefix(prefix string) dispatch.Filter[*api.CallbackQuery] {
return func(q *api.CallbackQuery) bool {
return q != nil && strings.HasPrefix(q.Data, prefix)
}
}
// FromUser returns a Filter that matches callback queries whose From.ID equals
// userID.
func FromUser(userID int64) dispatch.Filter[*api.CallbackQuery] {
return func(q *api.CallbackQuery) bool {
return q != nil && q.From.ID == userID
}
}
@@ -0,0 +1,56 @@
package callback_test
import (
"testing"
"github.com/lukaszraczylo/go-telegram/api"
cbfilter "github.com/lukaszraczylo/go-telegram/dispatch/filters/callback"
"github.com/stretchr/testify/require"
)
func cq(data string, userID int64) *api.CallbackQuery {
return &api.CallbackQuery{
ID: "q",
From: api.User{ID: userID},
Data: data,
}
}
func TestData(t *testing.T) {
f := cbfilter.Data(`^like:\d+$`)
require.True(t, f(cq("like:42", 1)))
require.False(t, f(cq("dislike:42", 1)))
require.False(t, f(nil))
}
func TestData_PanicsOnBadPattern(t *testing.T) {
require.Panics(t, func() { cbfilter.Data(`[bad`) })
}
func TestDataEquals(t *testing.T) {
f := cbfilter.DataEquals("yes")
require.True(t, f(cq("yes", 1)))
require.False(t, f(cq("yes please", 1)))
require.False(t, f(nil))
}
func TestDataPrefix(t *testing.T) {
f := cbfilter.DataPrefix("vote:")
require.True(t, f(cq("vote:up", 1)))
require.False(t, f(cq("novote:up", 1)))
require.False(t, f(nil))
}
func TestFromUser(t *testing.T) {
f := cbfilter.FromUser(7)
require.True(t, f(cq("data", 7)))
require.False(t, f(cq("data", 8)))
require.False(t, f(nil))
}
func TestComposedCallbackFilters(t *testing.T) {
f := cbfilter.DataPrefix("vote:").And(cbfilter.FromUser(7))
require.True(t, f(cq("vote:up", 7)))
require.False(t, f(cq("vote:up", 8)))
require.False(t, f(cq("other", 7)))
}