Compare commits

..
1 Commits
14 changed files with 38 additions and 169 deletions
+25 -25
View File
@@ -25,12 +25,12 @@ jobs:
vet:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-go@v6
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: '1.25.x'
check-latest: true
- uses: actions/cache@v5
- uses: actions/cache@v4
with:
path: |
~/go/pkg/mod
@@ -41,12 +41,12 @@ jobs:
staticcheck:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-go@v6
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: '1.25.x'
check-latest: true
- uses: actions/cache@v5
- uses: actions/cache@v4
with:
path: |
~/go/pkg/mod
@@ -58,12 +58,12 @@ jobs:
govulncheck:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-go@v6
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: '1.25.x'
check-latest: true
- uses: actions/cache@v5
- uses: actions/cache@v4
with:
path: |
~/go/pkg/mod
@@ -75,12 +75,12 @@ jobs:
gosec:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-go@v6
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: '1.25.x'
check-latest: true
- uses: actions/cache@v5
- uses: actions/cache@v4
with:
path: |
~/go/pkg/mod
@@ -98,12 +98,12 @@ jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-go@v6
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: '1.25.x'
check-latest: true
- uses: actions/cache@v5
- uses: actions/cache@v4
with:
path: |
~/go/pkg/mod
@@ -112,7 +112,7 @@ jobs:
- run: go test -race -coverprofile=coverage.out ./...
- name: Build all examples
run: go build ./examples/...
- uses: actions/upload-artifact@v7
- uses: actions/upload-artifact@v4
with:
name: coverage
path: coverage.out
@@ -120,12 +120,12 @@ jobs:
codegen-clean:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-go@v6
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: '1.25.x'
check-latest: true
- uses: actions/cache@v5
- uses: actions/cache@v4
with:
path: |
~/go/pkg/mod
@@ -139,14 +139,14 @@ jobs:
audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v4
with:
fetch-depth: 0 # need history for drift comparison
- uses: actions/setup-go@v6
- uses: actions/setup-go@v5
with:
go-version: '1.25.x'
check-latest: true
- uses: actions/cache@v5
- uses: actions/cache@v4
with:
path: |
~/go/pkg/mod
@@ -196,11 +196,11 @@ jobs:
github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-go@v6
- uses: actions/setup-go@v5
with:
go-version: '1.25.x'
check-latest: true
@@ -258,7 +258,7 @@ jobs:
- name: Run GoReleaser
if: github.event_name != 'workflow_dispatch' || inputs.dry-run-release == false
uses: goreleaser/goreleaser-action@v7
uses: goreleaser/goreleaser-action@v6
with:
distribution: goreleaser
version: '~> v2'
+1 -1
View File
@@ -24,7 +24,7 @@ jobs:
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v4
- uses: actions/configure-pages@v5
- uses: actions/upload-pages-artifact@v3
with:
+3 -3
View File
@@ -13,12 +13,12 @@ jobs:
regen:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v4
with:
fetch-depth: 0 # full history so audit -drift can compare against main
- name: Set up Go
uses: actions/setup-go@v6
uses: actions/setup-go@v5
with:
go-version: '1.25.x'
check-latest: true
@@ -89,7 +89,7 @@ jobs:
- name: Open PR
if: steps.diff.outputs.no_changes != 'true'
uses: peter-evans/create-pull-request@v8
uses: peter-evans/create-pull-request@v7
with:
token: ${{ secrets.GITHUB_TOKEN }}
commit-message: |
+1 -4
View File
@@ -35,10 +35,7 @@ lint: vet
integration:
$(GO) test -tags=integration -v ./test/integration/...
# Resolve via testdata/html/latest.html symlink so the pinned-fixture target
# auto-tracks whatever snapshot regen.yml last committed. Override with
# SCRAPE_INPUT=path/to/snapshot.html for ad-hoc replays.
SCRAPE_INPUT ?= testdata/html/$(shell readlink testdata/html/latest.html)
SCRAPE_INPUT ?= testdata/html/snapshot_2026-05-08.html
SCRAPE_OUTPUT ?= internal/spec/api.json
snapshot:
-14
View File
@@ -371,20 +371,6 @@ bot := client.New("token", client.WithHTTPClient(fakeDoer{
The library's own generated test suite (`api/methods_gen_test.go`) covers 176 methods × 8 scenarios each: Success, APIError, NetworkError, ParseError, ContextCanceled, MissingRequiredFields, Forbidden, ServerError.
## Telemetry
On the **first call to `client.New`** in a process, this library sends a
single anonymous adoption ping — project name, version, timestamp; no
identifiers, no message contents, no API call metadata. Fire-and-forget
with a 2-second timeout; cannot block `New` or panic.
Local source: [`client/telemetry.go`](client/telemetry.go). Upstream
implementation, exact wire format, and full opt-out documentation:
**[oss-telemetry — Disabling telemetry](https://github.com/lukaszraczylo/oss-telemetry#disabling-telemetry)**.
Quick opt-out: set any of `DO_NOT_TRACK=1`, `OSS_TELEMETRY_DISABLED=1`,
or `GO_TELEGRAM_DISABLE_TELEMETRY=1`.
## Contributing
See [CONTRIBUTING.md](CONTRIBUTING.md).
-1
View File
@@ -45,7 +45,6 @@ func (b *Bot) Logger() Logger { return b.logger }
// NewDefaultHTTPDoer); the default codec wraps encoding/json; the default
// logger discards records.
func New(token string, opts ...Option) *Bot {
fireTelemetryOnce()
b := &Bot{
token: token,
base: defaultBaseURL,
-33
View File
@@ -1,33 +0,0 @@
package client
import (
"sync"
telemetry "github.com/lukaszraczylo/oss-telemetry"
)
// telemetryOnce guards the single anonymous "library used" ping that is sent
// on the first call to New. Long-running bots typically construct one Bot;
// short-lived programs or test suites may construct many, but the Once gate
// keeps the fire-and-forget call from amplifying into per-construction pings.
var telemetryOnce sync.Once
// fireTelemetryOnce dispatches a fire-and-forget anonymous adoption ping.
//
// The call is failproof by contract of oss-telemetry: it never blocks New,
// never panics, never returns errors, and silently no-ops if disabled or
// if the network is unavailable.
//
// Opt-out is honored via any of these environment variables (case-insensitive
// truthy values "1", "true", "yes", "on"):
//
// - DO_NOT_TRACK
// - OSS_TELEMETRY_DISABLED
// - GO_TELEGRAM_DISABLE_TELEMETRY
//
// See README §Telemetry for the full disclosure.
func fireTelemetryOnce() {
telemetryOnce.Do(func() {
telemetry.SendForModule("go-telegram", "github.com/lukaszraczylo/go-telegram", Version)
})
}
-54
View File
@@ -1,54 +0,0 @@
package client
import (
"os"
"sync"
"testing"
telemetry "github.com/lukaszraczylo/oss-telemetry"
)
// TestMain disables outgoing telemetry for the duration of this package's
// test suite. The library's own tests construct many Bot instances; without
// this guard they would each contribute a real ping to the public endpoint.
// End-user test suites that construct Bot are not affected by this — only
// tests inside this package are.
func TestMain(m *testing.M) {
telemetry.Disable()
os.Exit(m.Run())
}
// TestFireTelemetryOnce_OnlyFiresOnce verifies the sync.Once gate. Even if
// New is called repeatedly, the underlying telemetry.Send is invoked at most
// once per process. We can't observe the network call directly (telemetry
// is disabled here via TestMain) so we assert on the once-Do count via a
// fresh local sync.Once paralleling the production one.
func TestFireTelemetryOnce_OnlyFiresOnce(t *testing.T) {
// Reset the package-level Once so this test starts from a clean state.
telemetryOnce = sync.Once{}
t.Cleanup(func() { telemetryOnce = sync.Once{} })
calls := 0
probe := func() { telemetryOnce.Do(func() { calls++ }) }
for i := 0; i < 50; i++ {
probe()
}
if calls != 1 {
t.Fatalf("expected exactly 1 Once execution, got %d", calls)
}
}
// TestNew_DoesNotPanicUnderRepeatedConstruction is a smoke test that
// telemetry wiring does not affect New's existing contract. New must never
// panic, regardless of telemetry state.
func TestNew_DoesNotPanicUnderRepeatedConstruction(t *testing.T) {
defer func() {
if r := recover(); r != nil {
t.Fatalf("New panicked: %v", r)
}
}()
for i := 0; i < 20; i++ {
_ = New("test-token-" + string(rune('A'+i)))
}
}
-11
View File
@@ -1,11 +0,0 @@
package client
// Version is a fallback version string used only when Go's build info is
// unavailable (replace directives, detached `go run`) or has been overridden
// via linker flags. The authoritative version forwarded to telemetry is
// resolved at runtime by [telemetry.SendForModule] from the build info of
// whatever binary linked this library, so this constant does NOT need to be
// bumped on every release. Exposed as a var (not const) for ldflag override:
//
// go build -ldflags="-X github.com/lukaszraczylo/go-telegram/client.Version=1.2.3"
var Version = "0.0.0-fallback"
-10
View File
@@ -87,16 +87,6 @@ var (
)
```
<a name="Version"></a>Version is a fallback version string used only when Go's build info is unavailable \(replace directives, detached \`go run\`\) or has been overridden via linker flags. The authoritative version forwarded to telemetry is resolved at runtime by \[telemetry.SendForModule\] from the build info of whatever binary linked this library, so this constant does NOT need to be bumped on every release. Exposed as a var \(not const\) for ldflag override:
```
go build -ldflags="-X github.com/lukaszraczylo/go-telegram/client.Version=1.2.3"
```
```go
var Version = "0.0.0-fallback"
```
<a name="Call"></a>
## func [Call](<https://github.com/lukaszraczylo/go-telegram/blob/main/client/call.go#L68>)
+2 -3
View File
@@ -4,10 +4,8 @@ go 1.25.0
require (
github.com/goccy/go-json v0.10.6
github.com/lukaszraczylo/oss-telemetry v0.2.1
github.com/stretchr/testify v1.9.0
github.com/valyala/fasthttp v1.71.0
golang.org/x/net v0.55.0
golang.org/x/net v0.54.0
)
require (
@@ -17,5 +15,6 @@ require (
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/stretchr/objx v0.5.2 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasthttp v1.71.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
+2 -6
View File
@@ -6,8 +6,6 @@ github.com/goccy/go-json v0.10.6 h1:p8HrPJzOakx/mn/bQtjgNjdTcN+/S6FcG2CTtQOrHVU=
github.com/goccy/go-json v0.10.6/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
github.com/klauspost/compress v1.18.6 h1:2jupLlAwFm95+YDR+NwD2MEfFO9d4z4Prjl1XXDjuao=
github.com/klauspost/compress v1.18.6/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ=
github.com/lukaszraczylo/oss-telemetry v0.2.1 h1:6ULyfzXplpdmIY/i01OPM1jeod9+L1RAhI0jtbVnJI0=
github.com/lukaszraczylo/oss-telemetry v0.2.1/go.mod h1:+Cn78qZo8rc3T9eZt0v3oICYRdd75wORtSidc8lNjDQ=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
@@ -18,10 +16,8 @@ github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6Kllzaw
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasthttp v1.71.0 h1:tepR7H+Guh9VUqxxcPggYi8R3lGUu2Rsdh+z7/FCY3k=
github.com/valyala/fasthttp v1.71.0/go.mod h1:z1sDUvOShhXq/C9mwH/fSm1Vb71tUJwmQdgkBrBNwnA=
github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8=
golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww=
golang.org/x/net v0.54.0 h1:2zJIZAxAHV/OHCDTCOHAYehQzLfSXuf/5SoL/Dv6w/w=
golang.org/x/net v0.54.0/go.mod h1:Sj4oj8jK6XmHpBZU/zWHw3BV3abl4Kvi+Ut7cQcY+cQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+1 -1
View File
@@ -1 +1 @@
snapshot_2026-05-20.html
snapshot_2026-05-18.html
@@ -99,7 +99,7 @@ To learn how to create…">
</ul>
<p><strong>General</strong></p>
<ul>
<li>Allowed <a href="https://core.telegram.org/bots/features#secretary-bots">Secretary Bots</a> to manage accounts of users without a Telegram Premium subscription.</li>
<li>Allowed Business Bots to manage user accounts without a Telegram Premium subscription.</li>
<li>Added the ability to send messages to other bots via username if both bots enabled bot-to-bot communication.</li>
<li>Added the ability to reply to other bots from a business bot if the business bot enabled bot-to-bot communication.</li>
<li>Allowed bots to pass an empty text in the method <a href="#sendmessagedraft">sendMessageDraft</a>.</li>
@@ -19854,7 +19854,7 @@ pre-formatted fixed-width code block written in the Python programming language
<h5><a href="//telegram.org/press">Press</a></h5>
</div>
<div class="footer_column">
<h5><a href="//telegram.org/moderation">Safety</a></h5>
<h5><a href="//telegram.org/moderation">Moderation</a></h5>
</div>
</div>
</div>
@@ -19869,4 +19869,4 @@ removePreloadInit();
</script>
</body>
</html>
<!-- page generated in 48.09ms -->
<!-- page generated in 39.15ms -->