93 lines
No EOL
2.4 KiB
Go
93 lines
No EOL
2.4 KiB
Go
package server
|
|
|
|
import (
|
|
"fmt"
|
|
"bytes"
|
|
mqtt "github.com/eclipse/paho.mqtt.golang"
|
|
"heckel.io/ntfy/log"
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
)
|
|
|
|
type mqttBackend struct {
|
|
config *Config
|
|
handler func(http.ResponseWriter, *http.Request)
|
|
client mqtt.Client
|
|
}
|
|
|
|
type mqttMessage struct {
|
|
Topic string `json:"topic"`
|
|
Title string `json:"title"`
|
|
Message string `json:"message"`
|
|
Priority string `json:"priority"`
|
|
Tags string `json:"tags"`
|
|
Actions string `json:"actions"`
|
|
}
|
|
|
|
func newMqttBackend(conf *Config, handler func(http.ResponseWriter, *http.Request)) *mqttBackend {
|
|
return &mqttBackend{
|
|
config: conf,
|
|
handler: handler,
|
|
}
|
|
}
|
|
|
|
func (b *mqttBackend) Connect() () {
|
|
opts := mqtt.NewClientOptions()
|
|
opts.AddBroker(fmt.Sprintf("tcp://%s:%d", b.config.MqttServer, b.config.MqttPort))
|
|
opts.SetClientID("ntfy")
|
|
opts.SetUsername(b.config.MqttUsername)
|
|
opts.SetPassword(b.config.MqttPassword)
|
|
log.Info("[mqtt] Connect to mqtt server %s:%d", b.config.MqttServer, b.config.MqttPort)
|
|
client := mqtt.NewClient(opts)
|
|
if token := client.Connect(); token.Wait() && token.Error() != nil {
|
|
log.Debug("[mqtt] Can not connect")
|
|
return
|
|
}
|
|
b.client = client
|
|
return
|
|
}
|
|
|
|
func (b *mqttBackend) Subscribe() () {
|
|
b.client.Subscribe(b.config.MqttTopic+"/message", 0, func(client mqtt.Client, msg mqtt.Message) {
|
|
log.Debug("[mqtt] Received message [%s] %s ", msg.Topic(), string(msg.Payload()))
|
|
var m mqttMessage
|
|
if err := json.NewDecoder(bytes.NewReader(msg.Payload())).Decode(&m); err != nil {
|
|
log.Info("[mqtt] not a valide json")
|
|
return
|
|
}
|
|
if !topicRegex.MatchString(m.Topic) {
|
|
log.Info("[mqtt] not a valide topic")
|
|
return
|
|
}
|
|
if m.Message == "" {
|
|
m.Message = emptyMessageBody
|
|
}
|
|
url := fmt.Sprintf("%s/%s", b.config.BaseURL, m.Topic)
|
|
req, err := http.NewRequest("POST", url, strings.NewReader(m.Message))
|
|
req.RequestURI = "/" + m.Topic
|
|
req.RemoteAddr = "127.0.0.1"
|
|
if err != nil {
|
|
return
|
|
}
|
|
if m.Title != "" {
|
|
req.Header.Set("Title", m.Title)
|
|
}
|
|
if m.Priority != "" {
|
|
req.Header.Set("Priority",m.Priority)
|
|
}
|
|
if m.Tags != "" {
|
|
req.Header.Set("Tags",m.Tags)
|
|
}
|
|
if m.Actions != "" {
|
|
req.Header.Set("Actions",m.Actions)
|
|
}
|
|
rr := httptest.NewRecorder()
|
|
b.handler(rr, req)
|
|
if rr.Code != http.StatusOK {
|
|
return
|
|
}
|
|
})
|
|
log.Info("[mqtt] Subscribed to topic %s/message", b.config.MqttTopic)
|
|
} |