(new): support Bot API 10.3
Golang lint / lint (push) Failing after 1m37s

(fix): finalize v2 contracts
(tests): cover v2 migration
(doc): prepare release guidance
This commit is contained in:
2026-09-08 23:21:38 +03:00
parent 24040fe164
commit d78526242b
88 changed files with 2321 additions and 918 deletions
+20 -20
View File
@@ -11,7 +11,7 @@ import (
"strings"
"time"
"git.scuroneko.dev/scuroneko/laniakea/utils"
"git.scuroneko.dev/scuroneko/laniakea/v2/utils"
"git.scuroneko.dev/scuroneko/sneklog/v2"
)
@@ -125,19 +125,19 @@ func NewUploaderRequestWithChatID[R, P any](method string, params P, chatID int6
return UploaderRequest[R, P]{method: method, files: files, params: params, chatID: chatID}
}
func (r UploaderRequest[R, P]) doRequest(ctx context.Context, up *Uploader) (R, error) {
func (u *Uploader) doRequest[R, P any](ctx context.Context, r UploaderRequest[R, P]) (R, error) {
var zero R
methodPrefix := ""
if up.api.useTestServer {
if u.api.useTestServer {
methodPrefix = "/test"
}
url := fmt.Sprintf("%s/bot%s%s/%s", up.api.apiURL, up.api.token, methodPrefix, r.method)
url := fmt.Sprintf("%s/bot%s%s/%s", u.api.apiURL, u.api.token, methodPrefix, r.method)
retries := 0
for {
if up.api.Limiter != nil {
if err := up.api.Limiter.Check(ctx, up.api.dropOverflowLimit, r.chatID); err != nil {
if u.api.Limiter != nil {
if err := u.api.Limiter.Check(ctx, u.api.dropOverflowLimit, r.chatID); err != nil {
return zero, err
}
}
@@ -152,11 +152,11 @@ func (r UploaderRequest[R, P]) doRequest(ctx context.Context, up *Uploader) (R,
req.Header.Set("Accept", "application/json")
req.Header.Set("User-Agent", fmt.Sprintf("Laniakea/%s", utils.VersionString))
up.logger.Debugln("UPLOADER REQ", url)
resp, err := up.api.client.Do(req)
u.logger.Debugln("UPLOADER REQ", url)
resp, err := u.api.client.Do(req)
_ = requestBody.Close()
if err != nil {
return zero, fmt.Errorf("HTTP upload request failed: %w", redactHTTPError(err, up.api.token))
return zero, fmt.Errorf("HTTP upload request failed: %w", redactHTTPError(err, u.api.token))
}
body, err := readBody(resp.Body)
@@ -164,7 +164,7 @@ func (r UploaderRequest[R, P]) doRequest(ctx context.Context, up *Uploader) (R,
if err != nil {
return zero, err
}
up.logger.Debugln("UPLOADER RES", responseLogSummary(r.method, len(body)))
u.logger.Debugln("UPLOADER RES", responseLogSummary(r.method, len(body)))
response, err := parseBody[R](body)
if err != nil {
@@ -179,15 +179,15 @@ func (r UploaderRequest[R, P]) doRequest(ctx context.Context, up *Uploader) (R,
}
if response.ErrorCode == 429 && response.Parameters != nil && response.Parameters.RetryAfter != nil {
after := *response.Parameters.RetryAfter
up.logger.Warnf("Rate limited, retry after %d seconds (chat: %d)", after, r.chatID)
if up.api.Limiter != nil {
u.logger.Warnf("Rate limited, retry after %d seconds (chat: %d)", after, r.chatID)
if u.api.Limiter != nil {
if r.chatID != 0 {
up.api.Limiter.SetChatLock(r.chatID, after)
u.api.Limiter.SetChatLock(r.chatID, after)
} else {
up.api.Limiter.SetGlobalLock(after)
u.api.Limiter.SetGlobalLock(after)
}
}
if retries >= up.api.maxRetries {
if retries >= u.api.maxRetries {
return zero, fmt.Errorf("%w after %d retries: %w", ErrRetryLimit, retries, responseErr)
}
retries++
@@ -207,11 +207,11 @@ func (r UploaderRequest[R, P]) doRequest(ctx context.Context, up *Uploader) (R,
// DoWithContext executes the upload request asynchronously via the worker pool.
// Returns the result or error. Respects context cancellation.
func (r UploaderRequest[R, P]) DoWithContext(ctx context.Context, up *Uploader) (R, error) {
func (u *Uploader) DoWithContext[R, P any](ctx context.Context, r UploaderRequest[R, P]) (R, error) {
var zero R
result, err := up.api.pool.submit(ctx, func(ctx context.Context) (any, error) {
return r.doRequest(ctx, up)
result, err := u.api.pool.submit(ctx, func(ctx context.Context) (any, error) {
return u.doRequest(ctx, r)
})
if err != nil {
return zero, err
@@ -233,8 +233,8 @@ func (r UploaderRequest[R, P]) DoWithContext(ctx context.Context, up *Uploader)
// Do executes the upload request synchronously with a background context.
// Use only for simple, non-critical uploads.
func (r UploaderRequest[R, P]) Do(up *Uploader) (R, error) {
return r.DoWithContext(context.Background(), up)
func (u *Uploader) Do[R, P any](r UploaderRequest[R, P]) (R, error) {
return u.DoWithContext(context.Background(), r)
}
func prepareMultipartStream[P any](files []UploaderFile, params P) (io.ReadCloser, string) {