-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtgcalls.go
137 lines (123 loc) · 2.28 KB
/
tgcalls.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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
package tgcalls
import (
"context"
"errors"
"io"
"os/exec"
"github.com/gotd/td/tg"
"github.com/gotgcalls/tgcalls/connection"
)
const (
Ok = 0
NotMuted = 1
AlreadyMuted = 1
NotPaused = 1
NotStreaming = 1
NotInCall = 2
Err = 3
)
var (
DefaultName = "npx"
DefaultArgs = []string{"gotgcalls-server"}
)
var (
ErrNotRunning = errors.New("tgcalls not running")
ErrUnexpectedType = errors.New("got an unexpected type")
ErrNoCall = errors.New("no active call in the provided chat")
ErrNoAccessHash = errors.New("no access hash for the provided chat")
)
type TGCalls struct {
ctx context.Context
chat *tg.InputChannel
api *tg.Client
opts *TGCallsOpts
cmd *exec.Cmd
conn *connection.Connection
in io.WriteCloser
out io.ReadCloser
running bool
OnFinish func()
}
type TGCallsOpts struct {
Cmd *TGCallsCmdOpts
JoinAs tg.InputPeerClass
InviteHash string
}
type TGCallsCmdOpts struct {
Name string
Args []string
}
func New(
ctx context.Context,
chat *tg.InputChannel,
api *tg.Client,
opts *TGCallsOpts,
) *TGCalls {
return &TGCalls{
ctx: ctx,
chat: chat,
api: api,
opts: opts,
}
}
func Start(calls *TGCalls) error {
if calls.running {
return nil
}
name := DefaultName
args := DefaultArgs
if calls.opts != nil {
if calls.opts.Cmd != nil {
name = calls.opts.Cmd.Name
args = calls.opts.Cmd.Args
}
}
cmd := exec.Command(name, args...)
out, err := cmd.StdoutPipe()
if err != nil {
return err
}
in, err := cmd.StdinPipe()
if err != nil {
return err
}
err = cmd.Start()
if err != nil {
return err
}
calls.cmd = cmd
calls.out = out
calls.in = in
calls.conn = connection.New(out, in)
calls.conn.Handle(
"joinCall",
func(request connection.Request) (interface{}, error) {
return calls.joinCall(request.Params)
},
)
calls.conn.Handle("finish", func(request connection.Request) (interface{}, error) {
if calls.OnFinish != nil {
calls.OnFinish()
}
return nil, nil
})
calls.conn.Start()
calls.running = true
return nil
}
func Stop(calls *TGCalls) error {
if !calls.running {
return nil
}
calls.conn.Stop()
err := calls.cmd.Process.Kill()
if err != nil {
return err
}
calls.cmd = nil
calls.out = nil
calls.in = nil
calls.conn = nil
calls.running = false
return nil
}