diff --git a/config.go b/config.go index fbb2f3f..9ddb4c5 100644 --- a/config.go +++ b/config.go @@ -25,16 +25,25 @@ type SatelChangeType struct { changeType satel.ChangeType } +type MatterbridgeConfig struct { + URI string `yaml:"uri"` + Token string `yaml:"token"` + Gateway string `yaml:"gateway"` + /// Username from which the messages will appear + Username string `yaml:"username"` +} + type AppConfig struct { - SatelAddr string `yaml:"satel-addr"` - ChatIds []int64 `yaml:"tg-chat-ids"` - AllowedTypes []SatelChangeType `yaml:"allowed-types"` - AllowedIndexes []int `yaml:"allowed-indexes"` - PoolInterval OwnDuration `yaml:"pool-interval"` - ArmCallbackUrls []string `yaml:"arm-callback-urls"` - DisarmCallbackUrls []string `yaml:"disarm-callback-urls"` - AlarmCallbackUrls []string `yaml:"alarm-callback-urls"` - WriteMemoryProfile bool `yaml:"write-memory-profile"` + SatelAddr string `yaml:"satel-addr"` + ChatIds []int64 `yaml:"tg-chat-ids"` + AllowedTypes []SatelChangeType `yaml:"allowed-types"` + AllowedIndexes []int `yaml:"allowed-indexes"` + PoolInterval OwnDuration `yaml:"pool-interval"` + ArmCallbackUrls []string `yaml:"arm-callback-urls"` + DisarmCallbackUrls []string `yaml:"disarm-callback-urls"` + AlarmCallbackUrls []string `yaml:"alarm-callback-urls"` + WriteMemoryProfile bool `yaml:"write-memory-profile"` + Matterbridge MatterbridgeConfig `yaml:"matterbridge"` } func (m *SatelChangeType) UnmarshalYAML(unmarshal func(interface{}) error) error { diff --git a/main.go b/main.go index 89abb86..8c9c8db 100644 --- a/main.go +++ b/main.go @@ -69,14 +69,17 @@ func main() { tgSender := TgSender{bot, s, log.New(os.Stderr, "TgFormatter", log.Lmicroseconds), config.ChatIds} - tpl := template.Must(template.New("TelegramMessage").Parse(TelegramMessageTemplate)) + tgTpl := template.Must(template.New("TelegramMessage").Parse(TelegramMessageTemplate)) + ircTpl := template.Must(template.New("IRCMessage").Parse(IRCMessageTemplate)) dataStore := MakeDataStore(log.New(os.Stderr, "DataStore", log.Lmicroseconds), getPersistenceFilePath()) Consume( - SendToTg(Throttle(NotifyViaHTTP(tgEvents, config, &wg, log.New(os.Stderr, "HTTPNotify", log.Lmicroseconds)), - &wg, sleeper, log.New(os.Stderr, "MessageThrottle", log.Lmicroseconds)), - tgSender, &wg, log.New(os.Stderr, "SendToTg", log.Lmicroseconds), tpl), + SendToMatterbridge( + SendToTg(Throttle(NotifyViaHTTP(tgEvents, config, &wg, log.New(os.Stderr, "HTTPNotify", log.Lmicroseconds)), + &wg, sleeper, log.New(os.Stderr, "MessageThrottle", log.Lmicroseconds)), + tgSender, &wg, log.New(os.Stderr, "SendToTg", log.Lmicroseconds), tgTpl), + s, config, &wg, log.New(os.Stderr, "SendToMatterbridge", log.Lmicroseconds), ircTpl), ) go CloseSatelOnCtrlC(s, &cleanShutdown) diff --git a/sender_worker.go b/sender_worker.go index 0578b85..85d2d98 100644 --- a/sender_worker.go +++ b/sender_worker.go @@ -1,6 +1,9 @@ package main import ( + "bytes" + "encoding/json" + "fmt" "html/template" "log" "net/http" @@ -108,3 +111,40 @@ func NotifyViaHTTP(events <-chan GenericMessage, config AppConfig, wg *sync.Wait return returnEvents } + +type MatterbridgeMessage struct { + Text string `json:"text"` + Username string `json:"username"` + Gateway string `json:"gateway"` +} + +func SendToMatterbridge(events <-chan GenericMessage, s SatelNameGetter, config AppConfig, wg *sync.WaitGroup, logger *log.Logger, tpl *template.Template) <-chan GenericMessage { + returnEvents := make(chan GenericMessage) + + go func() { + wg.Add(1) + defer wg.Done() + for e := range events { + returnEvents <- e + body, err := json.Marshal(MatterbridgeMessage{ + Text: e.Format(tpl, s, logger), + Username: config.Matterbridge.Username, + Gateway: config.Matterbridge.Gateway, + }) + if err != nil { + logger.Fatal("Could not marshal a JSON message: ", err) + } + req, err := http.NewRequest(http.MethodPost, config.Matterbridge.URI, bytes.NewBuffer(body)) + req.Header["Authorization"] = []string{fmt.Sprint("Bearer ", config.Matterbridge.Token)} + res, err := http.DefaultClient.Do(req) + if err != nil { + logger.Print("Could not POST ", config.Matterbridge.URI, ": ", err) + return + } + logger.Print("Notified via Matterbridge with result ", res.StatusCode) + } + close(returnEvents) + }() + + return returnEvents +} diff --git a/templates.go b/templates.go index 1226a5d..762fb43 100644 --- a/templates.go +++ b/templates.go @@ -5,3 +5,7 @@ const TelegramMessageTemplate = `{{- range .Messages}} {{- else -}} Huh, no messages - this is a bug {{- end}}` + +const IRCMessageTemplate = `{{- range .Messages}} {{.GetName}}: {{.FormatEvent}}; {{- else -}} +Huh, no messages - this is a bug +{{- end}}` diff --git a/templates_test.go b/templates_test.go index 4a3cd22..032f959 100644 --- a/templates_test.go +++ b/templates_test.go @@ -53,3 +53,17 @@ func TestTelegramTemplate(t *testing.T) { // assert.Equal(t, "siemka", mockSender.message) } + +func TestIRCTemplate(t *testing.T) { + testEvents := make(chan GenericMessage) + wg := sync.WaitGroup{} + mockSender := MockTemplateSender{s: MockSatelNameGetter{"mockPart"}} + tpl, err := template.New("TestIRCTemplate").Parse(IRCMessageTemplate) + assert.NoError(t, err) + Consume(SendToTg(testEvents, &mockSender, &wg, log.New(io.Discard, "", log.Ltime), tpl)) + testEvents <- GenericMessage{[]satel.BasicEventElement{tplMessageTest1, tplMessageTest2}} + close(testEvents) + wg.Wait() + + // assert.Equal(t, "siemka", mockSender.message) +}