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
+35
View File
@@ -0,0 +1,35 @@
// Package inline provides Filter helpers for *api.InlineQuery payloads.
package inline
import (
"regexp"
"strings"
"github.com/lukaszraczylo/go-telegram/api"
"github.com/lukaszraczylo/go-telegram/dispatch"
)
// Query returns a Filter that matches inline queries whose Query field matches
// pattern (regex). Panics at registration time on an invalid pattern.
func Query(pattern string) dispatch.Filter[*api.InlineQuery] {
re := regexp.MustCompile(pattern)
return func(q *api.InlineQuery) bool {
return q != nil && re.MatchString(q.Query)
}
}
// QueryEquals returns a Filter that matches inline queries whose Query equals
// s exactly.
func QueryEquals(s string) dispatch.Filter[*api.InlineQuery] {
return func(q *api.InlineQuery) bool {
return q != nil && q.Query == s
}
}
// QueryPrefix returns a Filter that matches inline queries whose Query starts
// with prefix.
func QueryPrefix(prefix string) dispatch.Filter[*api.InlineQuery] {
return func(q *api.InlineQuery) bool {
return q != nil && strings.HasPrefix(q.Query, prefix)
}
}
+45
View File
@@ -0,0 +1,45 @@
package inline_test
import (
"testing"
"github.com/lukaszraczylo/go-telegram/api"
ilfilter "github.com/lukaszraczylo/go-telegram/dispatch/filters/inline"
"github.com/stretchr/testify/require"
)
func iq(query string) *api.InlineQuery {
return &api.InlineQuery{ID: "i", From: api.User{ID: 1}, Query: query}
}
func TestQuery(t *testing.T) {
f := ilfilter.Query(`^find`)
require.True(t, f(iq("find me")))
require.False(t, f(iq("search me")))
require.False(t, f(nil))
}
func TestQuery_PanicsOnBadPattern(t *testing.T) {
require.Panics(t, func() { ilfilter.Query(`[bad`) })
}
func TestQueryEquals(t *testing.T) {
f := ilfilter.QueryEquals("exact")
require.True(t, f(iq("exact")))
require.False(t, f(iq("exact match")))
require.False(t, f(nil))
}
func TestQueryPrefix(t *testing.T) {
f := ilfilter.QueryPrefix("@user")
require.True(t, f(iq("@username")))
require.False(t, f(iq("no prefix")))
require.False(t, f(nil))
}
func TestComposedInlineFilters(t *testing.T) {
f := ilfilter.QueryPrefix("find").Or(ilfilter.QueryEquals("help"))
require.True(t, f(iq("find me")))
require.True(t, f(iq("help")))
require.False(t, f(iq("other")))
}