-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathconfig.go
155 lines (132 loc) · 4.05 KB
/
config.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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
package main
import (
"encoding/json"
mapset "github.com/deckarep/golang-set/v2"
tdlib "github.com/zelenin/go-tdlib/client"
"log"
"os"
"regexp"
)
type Config struct {
ApiHash string `json:"api_hash"`
ApiId int32 `json:"api_id"`
UseTestDc bool `json:"use_test_dc"`
StateDir string `json:"state_dir"`
LogVerbosityLevel int32 `json:"log_verbosity_level"`
ForwardingConfig ForwardingConfig `json:"forwarding_config"`
}
type ForwardingConfig struct {
Sources []ParticipantConfig
Destinations []ParticipantConfig
Filter RegexFilterConfig
Forward bool
}
type RegexFilterConfig struct {
Regex string `json:"regex"`
}
type ForwardingConfigResolved struct {
Sources mapset.Set[int64]
Destinations []Participant
Filter MessageFilter
Forward bool
}
type MessageFilter interface {
Passes(msg *tdlib.Message) bool
Describe() string
}
type ParticipantConfig interface {
}
type ParticipantWithNameConfig struct {
Username string `json:"username"`
}
type ParticipantWithIdConfig struct {
ChatId int64 `json:"chat_id"`
}
type Participant struct {
ChatId int64
Name string
}
func (p *ParticipantWithNameConfig) ParticipantType() string {
return "name"
}
func (p *ParticipantWithIdConfig) ParticipantType() string {
return "id"
}
func parseConfig() *Config {
configFile := os.Getenv("CONFIG_FILE")
if configFile == "" {
configFile = "simple-telegram-forwarder.config.json"
}
bytes, err := os.ReadFile(configFile)
if err != nil {
panic(err)
}
var config Config
err = json.Unmarshal(bytes, &config)
if err != nil {
panic(err)
}
if config.StateDir == "" {
config.StateDir = "."
}
config.validate()
return &config
}
func (config *Config) resolveForwardingConfig(client *tdlib.Client) *ForwardingConfigResolved {
fc := config.ForwardingConfig
var resolved ForwardingConfigResolved
resolvedSources := make([]Participant, len(fc.Sources))
for i, source := range fc.Sources {
resolvedSources[i] = config.resolveParticipantConfig("source", client, source)
}
resolved.Sources = mapset.NewSetWithSize[int64](len(resolvedSources))
for _, source := range resolvedSources {
resolved.Sources.Add(source.ChatId)
}
resolved.Destinations = make([]Participant, len(fc.Destinations))
for i, receiver := range fc.Destinations {
resolved.Destinations[i] = config.resolveParticipantConfig("destination", client, receiver)
}
resolved.Forward = fc.Forward
if fc.Filter.Regex != "" {
r := regexp.MustCompile(fc.Filter.Regex)
resolved.Filter = &RegexFilter{regex: r}
log.Printf("Loaded filter %s", resolved.Filter.Describe())
} else {
resolved.Filter = &EmptyFilter{}
}
if fc.Forward {
log.Printf("Will forward messages instead of sending a copy")
}
return &resolved
}
func (config *Config) resolveParticipantConfig(participantType string, client *tdlib.Client, pc ParticipantConfig) Participant {
idConfig, ok := pc.(*ParticipantWithIdConfig)
if !ok {
name := pc.(*ParticipantWithNameConfig).Username
chat, err := client.SearchPublicChat(&tdlib.SearchPublicChatRequest{Username: name})
if err == nil {
log.Printf(
"Resolved %s participant with name='%s' to a chat with title='%s', chatId=%d\n",
participantType, name, chat.Title, chat.Id)
return Participant{ChatId: chat.Id, Name: chat.Title}
}
log.Fatalf("Could not find chat for username '%s'. %v", name, err)
}
chat, err := client.GetChat(&tdlib.GetChatRequest{ChatId: idConfig.ChatId})
if err != nil {
log.Fatalf("Could not find chat with id=%d. %v", idConfig.ChatId, err)
} else {
log.Printf("Resolved %s participant with chatId=%d to a chat with title='%s'\n",
participantType, idConfig.ChatId, chat.Title)
}
return Participant{ChatId: idConfig.ChatId, Name: chat.Title}
}
func (config *Config) validate() {
if config.ForwardingConfig.Sources == nil || len(config.ForwardingConfig.Sources) == 0 {
log.Fatalln("Missing forwarding_config.source")
}
if len(config.ForwardingConfig.Destinations) == 0 {
log.Fatalln("forwarding_config.destinations is empty")
}
}