/
qr.go
83 lines (75 loc) · 1.85 KB
/
qr.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
package main
import (
"context"
"flag"
"os"
"path/filepath"
"github.com/cristalhq/acmd"
"github.com/go-faster/errors"
"github.com/gotd/td/telegram"
"github.com/gotd/td/telegram/auth/qrlogin"
"github.com/gotd/td/tg"
"github.com/mdp/qrterminal/v3"
"go.uber.org/multierr"
"rsc.io/qr"
)
func qrCmd() acmd.Command {
return acmd.Command{
Name: "qr",
Description: "Create session via QR login flow",
ExecFunc: qrExec,
}
}
func qrExec(ctx context.Context, args []string) (rErr error) {
s := flag.NewFlagSet("qr", flag.ContinueOnError)
var (
pngPath string
gotdFlags gotdOptions
printFlags printOptions
)
s.StringVar(&pngPath, "png", "", "Generate path to image of QR")
gotdFlags.install(s)
printFlags.install(s)
if err := s.Parse(args); err != nil {
return err
}
d := tg.NewUpdateDispatcher()
loggedIn := qrlogin.OnLoginToken(d)
data, err := gotdFlags.GetSession(
ctx, telegram.Options{
UpdateHandler: d,
},
func(ctx context.Context, client *telegram.Client) (rErr error) {
show := func(ctx context.Context, token qrlogin.Token) error {
qrterminal.Generate(token.URL(), qrterminal.L, os.Stdout)
return nil
}
if pngPath != "" {
f, err := os.Create(filepath.Clean(pngPath))
if err != nil {
return err
}
defer multierr.AppendInvoke(&rErr, multierr.Close(f))
show = func(ctx context.Context, token qrlogin.Token) error {
encoded, err := qr.Encode(token.URL(), qrterminal.L)
if err != nil {
return errors.Wrap(err, "encode QR")
}
if _, err := f.Write(encoded.PNG()); err != nil {
return errors.Wrap(err, "write png")
}
return nil
}
}
_, err := client.QR().Auth(ctx, loggedIn, show)
if err != nil {
return errors.Wrap(err, "QR login")
}
return nil
},
)
if err != nil {
return err
}
return printSession(ctx, data, printFlags)
}