2023-09-20 03:20:44 +08:00
|
|
|
package tgc
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/cenkalti/backoff/v4"
|
2024-02-12 04:52:41 +08:00
|
|
|
"github.com/divyam234/teldrive/internal/config"
|
2023-12-03 03:47:23 +08:00
|
|
|
"github.com/divyam234/teldrive/internal/kv"
|
2024-06-04 16:46:03 +08:00
|
|
|
"github.com/divyam234/teldrive/internal/logging"
|
2024-06-03 01:41:18 +08:00
|
|
|
"github.com/divyam234/teldrive/internal/recovery"
|
|
|
|
"github.com/divyam234/teldrive/internal/retry"
|
2024-05-15 19:54:44 +08:00
|
|
|
"github.com/divyam234/teldrive/internal/utils"
|
2023-09-20 03:20:44 +08:00
|
|
|
"github.com/gotd/contrib/middleware/floodwait"
|
|
|
|
"github.com/gotd/contrib/middleware/ratelimit"
|
|
|
|
"github.com/gotd/td/session"
|
|
|
|
"github.com/gotd/td/telegram"
|
2024-05-15 19:54:44 +08:00
|
|
|
"github.com/gotd/td/telegram/dcs"
|
|
|
|
"github.com/pkg/errors"
|
2024-06-04 16:46:03 +08:00
|
|
|
"go.uber.org/zap"
|
2024-05-15 19:54:44 +08:00
|
|
|
"golang.org/x/net/proxy"
|
2023-09-20 03:20:44 +08:00
|
|
|
"golang.org/x/time/rate"
|
|
|
|
)
|
|
|
|
|
2024-05-15 19:54:44 +08:00
|
|
|
func New(ctx context.Context, config *config.TGConfig, handler telegram.UpdateHandler, storage session.Storage, middlewares ...telegram.Middleware) (*telegram.Client, error) {
|
|
|
|
|
|
|
|
var dialer dcs.DialFunc = proxy.Direct.DialContext
|
|
|
|
if config.Proxy != "" {
|
|
|
|
d, err := utils.Proxy.GetDial(config.Proxy)
|
|
|
|
if err != nil {
|
|
|
|
return nil, errors.Wrap(err, "get dialer")
|
|
|
|
}
|
|
|
|
dialer = d.DialContext
|
|
|
|
}
|
2023-09-20 03:20:44 +08:00
|
|
|
|
2024-06-04 16:46:03 +08:00
|
|
|
var logger *zap.Logger
|
|
|
|
if config.EnableLogging {
|
|
|
|
logger = logging.FromContext(ctx).Desugar().Named("td")
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2023-09-20 03:20:44 +08:00
|
|
|
opts := telegram.Options{
|
2024-05-15 19:54:44 +08:00
|
|
|
Resolver: dcs.Plain(dcs.PlainOptions{
|
|
|
|
Dial: dialer,
|
|
|
|
}),
|
2024-05-28 03:43:43 +08:00
|
|
|
ReconnectionBackoff: func() backoff.BackOff {
|
2024-06-03 01:41:18 +08:00
|
|
|
return newBackoff(config.ReconnectTimeout)
|
2024-05-28 03:43:43 +08:00
|
|
|
},
|
2024-02-12 04:52:41 +08:00
|
|
|
Device: telegram.DeviceConfig{
|
|
|
|
DeviceModel: config.DeviceModel,
|
|
|
|
SystemVersion: config.SystemVersion,
|
|
|
|
AppVersion: config.AppVersion,
|
|
|
|
SystemLangCode: config.SystemLangCode,
|
|
|
|
LangPack: config.LangPack,
|
|
|
|
LangCode: config.LangCode,
|
|
|
|
},
|
2023-09-20 03:20:44 +08:00
|
|
|
SessionStorage: storage,
|
2024-06-22 20:29:59 +08:00
|
|
|
RetryInterval: 2 * time.Second,
|
|
|
|
MaxRetries: 10,
|
2023-09-20 03:20:44 +08:00
|
|
|
DialTimeout: 10 * time.Second,
|
|
|
|
Middlewares: middlewares,
|
|
|
|
UpdateHandler: handler,
|
2024-06-04 16:46:03 +08:00
|
|
|
Logger: logger,
|
2023-09-20 03:20:44 +08:00
|
|
|
}
|
|
|
|
|
2024-05-15 19:54:44 +08:00
|
|
|
return telegram.NewClient(config.AppId, config.AppHash, opts), nil
|
2023-09-20 03:20:44 +08:00
|
|
|
}
|
|
|
|
|
2024-05-15 19:54:44 +08:00
|
|
|
func NoAuthClient(ctx context.Context, config *config.TGConfig, handler telegram.UpdateHandler, storage session.Storage) (*telegram.Client, error) {
|
2024-06-03 01:41:18 +08:00
|
|
|
middlewares := []telegram.Middleware{
|
|
|
|
floodwait.NewSimpleWaiter(),
|
|
|
|
}
|
2023-09-20 03:20:44 +08:00
|
|
|
middlewares = append(middlewares, ratelimit.New(rate.Every(time.Millisecond*100), 5))
|
2024-02-12 04:52:41 +08:00
|
|
|
return New(ctx, config, handler, storage, middlewares...)
|
2023-09-20 03:20:44 +08:00
|
|
|
}
|
|
|
|
|
2024-06-06 02:49:30 +08:00
|
|
|
func AuthClient(ctx context.Context, config *config.TGConfig, sessionStr string, middlewares ...telegram.Middleware) (*telegram.Client, error) {
|
2023-09-20 03:20:44 +08:00
|
|
|
data, err := session.TelethonSession(sessionStr)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
var (
|
|
|
|
storage = new(session.StorageMemory)
|
|
|
|
loader = session.Loader{Storage: storage}
|
|
|
|
)
|
|
|
|
|
|
|
|
if err := loader.Save(context.TODO(), data); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2024-05-15 19:54:44 +08:00
|
|
|
return New(ctx, config, nil, storage, middlewares...)
|
2023-09-20 03:20:44 +08:00
|
|
|
}
|
|
|
|
|
2024-06-06 02:49:30 +08:00
|
|
|
func BotClient(ctx context.Context, KV kv.KV, config *config.TGConfig, token string, middlewares ...telegram.Middleware) (*telegram.Client, error) {
|
2024-06-03 01:41:18 +08:00
|
|
|
|
2024-02-12 04:52:41 +08:00
|
|
|
storage := kv.NewSession(KV, kv.Key("botsession", token))
|
2023-11-25 12:31:29 +08:00
|
|
|
|
2024-06-06 02:49:30 +08:00
|
|
|
return New(ctx, config, nil, storage, middlewares...)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
func Middlewares(config *config.TGConfig, retries int) []telegram.Middleware {
|
2024-06-03 01:41:18 +08:00
|
|
|
middlewares := []telegram.Middleware{
|
|
|
|
floodwait.NewSimpleWaiter(),
|
2024-06-06 02:49:30 +08:00
|
|
|
recovery.New(context.Background(), newBackoff(config.ReconnectTimeout)),
|
2024-06-03 01:41:18 +08:00
|
|
|
retry.New(retries),
|
2023-11-25 12:31:29 +08:00
|
|
|
}
|
2024-05-28 03:43:43 +08:00
|
|
|
if config.RateLimit {
|
2024-06-06 02:49:30 +08:00
|
|
|
middlewares = append(middlewares, ratelimit.New(rate.Every(time.Millisecond*time.Duration(config.Rate)), config.RateBurst))
|
2024-05-28 03:43:43 +08:00
|
|
|
}
|
2024-06-06 02:49:30 +08:00
|
|
|
return middlewares
|
2024-06-03 01:41:18 +08:00
|
|
|
|
2024-05-28 03:43:43 +08:00
|
|
|
}
|
|
|
|
|
2024-06-03 01:41:18 +08:00
|
|
|
func newBackoff(timeout time.Duration) backoff.BackOff {
|
2024-05-28 03:43:43 +08:00
|
|
|
b := backoff.NewExponentialBackOff()
|
2023-11-25 12:31:29 +08:00
|
|
|
b.Multiplier = 1.1
|
2024-05-28 03:43:43 +08:00
|
|
|
b.MaxElapsedTime = timeout
|
|
|
|
b.MaxInterval = 10 * time.Second
|
2023-11-25 12:31:29 +08:00
|
|
|
return b
|
2023-09-20 03:20:44 +08:00
|
|
|
}
|