// the Bot API asks for, or 0.
func telegramRetryable(err error) (bool, time.Duration) {
var network *TelegramNetworkError
+
if errors.As(err, &network) {
return true, 0
}
var answer *TelegramError
+
if errors.As(err, &answer) {
return answer.Status == http.StatusTooManyRequests || answer.Status >= 500, answer.RetryAfter
}
// tell this, so it is not a refusal.
func telegramRejected(err error) bool {
var answer *TelegramError
+
return errors.As(err, &answer) && answer.Refused && (answer.Status == http.StatusBadRequest || answer.Status == http.StatusNotFound)
}
// messages are asked for.
func (b *TelegramAPI) GetUpdates(ctx context.Context, offset int64) ([]TelegramUpdate, error) {
var updates []TelegramUpdate
+
err := b.call(ctx, telegramPollTimeout, "getUpdates", map[string]any{
"offset": offset,
"timeout": telegramPollSeconds,
}
request.Header.Set("Content-Type", "application/json")
+
response, err := b.http.Do(request)
if err != nil {
return b.networkError("no answer", err, timeout)
data, err := io.ReadAll(io.LimitReader(response.Body, telegramAnswerBytes))
err = errors.Join(err, response.Body.Close())
if err != nil {
- return b.networkError("the answer broke off", err, timeout)
+ return b.networkError("answer cut off", err, timeout)
}
var answer TelegramAnswer
+
err = json.Unmarshal(data, &answer)
if err != nil && response.StatusCode != http.StatusOK {
return &TelegramError{
}
if err != nil {
- return b.networkError("the answer is not valid JSON", err, timeout)
+ return b.networkError("invalid JSON", err, timeout)
}
if !answer.OK {
err = json.Unmarshal(answer.Result, result)
if err != nil {
- return b.networkError("the result is not valid", err, timeout)
+ return b.networkError("invalid result", err, timeout)
}
return nil
// cause is kept.
func (b *TelegramAPI) redact(err error) string {
var urlError *url.Error
+
if errors.As(err, &urlError) {
err = urlError.Err
}
}
// TelegramError is an answer of the Bot API that tells of a failure. Its text
-// gives the HTTP status and the description, such as "Telegram answered 502 Bad
-// Gateway". RetryAfter is the wait that the Bot API asks for after HTTP 429.
-// Refused tells that the answer is a Bot API answer with ok false, not a page
-// of a proxy or of a server error.
+// gives the HTTP status and the description, such as "502 Bad Gateway".
+// RetryAfter is the wait that the Bot API asks for after HTTP 429. Refused
+// tells that the answer is a Bot API answer with ok false, not a page of a
+// proxy or of a server error.
type TelegramError struct {
Status int
Description string
}
func (e *TelegramError) Error() string {
- return fmt.Sprintf("Telegram answered %d %s", e.Status, e.Description)
+ return fmt.Sprintf("%d %s", e.Status, e.Description)
}
// TelegramUpdate is one update of getUpdates. Message is nil for the kinds of