diff --git a/go.mod b/go.mod
index ecf52239e313738e3ad735c51ad67eeef0cd7400..7de22ef75509d5ab83bc4b311d79c74f3db7da15 100644
--- a/go.mod
+++ b/go.mod
@@ -4,11 +4,11 @@ go 1.23.4
 
 require (
 	gorm.io/gorm v1.25.12
-	jonasled.dev/firehouse-smokedetection/plugin-interface v0.0.2
+	jonasled.dev/firehouse-smokedetection/plugin-interface v0.0.4
 )
 
 require (
 	github.com/jinzhu/inflection v1.0.0 // indirect
 	github.com/jinzhu/now v1.1.5 // indirect
-	golang.org/x/text v0.14.0 // indirect
+	golang.org/x/text v0.23.0 // indirect
 )
diff --git a/go.sum b/go.sum
index 6f7b5f1997abebebe69a2dce1e79f10a4826284f..0d1eade7f86e0f01a38aea25a9dc434b6feabca7 100644
--- a/go.sum
+++ b/go.sum
@@ -2,9 +2,9 @@ github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD
 github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
 github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
 github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
-golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
-golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
+golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
+golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
 gorm.io/gorm v1.25.12 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8=
 gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=
-jonasled.dev/firehouse-smokedetection/plugin-interface v0.0.2 h1:niJPRYkwj73qVb7Tz3xW3qQwd4WDNQW7tSo+xmoOEJE=
-jonasled.dev/firehouse-smokedetection/plugin-interface v0.0.2/go.mod h1:NzMtk6LMykQSPijoPTM/7+lWgpeizioNrC9gHhWU75U=
+jonasled.dev/firehouse-smokedetection/plugin-interface v0.0.4 h1:QOzFtkQTzqAp7l9R4aHsZruZ/Xtm/B3yhgKfkuxNn7k=
+jonasled.dev/firehouse-smokedetection/plugin-interface v0.0.4/go.mod h1:7OmpERugGg+B1OKE5R2glhdbbF2XmYP0OTfbdNNBm40=
diff --git a/main.go b/main.go
index 10e909142818cf207be745bbd0befe5511fbfd92..197a4aa2b24fc4dcbddd54ecf2fe06200e6982d0 100644
--- a/main.go
+++ b/main.go
@@ -1,20 +1,20 @@
 package main
 
 import (
+	"bytes"
+	"encoding/json"
 	"errors"
-	"time"
+	"net/http"
+	"text/template"
 
 	"gorm.io/gorm"
 	plugininterface "jonasled.dev/firehouse-smokedetection/plugin-interface"
 )
 
-type GotifyPluginConfig struct {
-	ID              uint `gorm:"primaryKey"`
-	CreatedAt       time.Time
-	UpdatedAt       time.Time
-	Name            string
-	GotifyUrl       string
-	MessageTemplate string
+type GotifyMessage struct {
+	Title    string `json:"title"`
+	Message  string `json:"message"`
+	Priority int    `json:"priority"`
 }
 
 type GotifyPlugin struct {
@@ -27,14 +27,53 @@ func (g *GotifyPlugin) Setup(db *gorm.DB) error {
 	return db.AutoMigrate(&GotifyPluginConfig{})
 }
 
-func (g *GotifyPlugin) Alarm(smokeSensor string, target uint) error {
+func (g *GotifyPlugin) Alarm(smokeSensor plugininterface.AlarmSmokeSensor, target uint) error {
 	var pluginConfig GotifyPluginConfig
 	tx := g.db.Where(GotifyPluginConfig{ID: target}).First(&pluginConfig)
 	if tx.RowsAffected == 0 {
 		return errors.New("No matching target found")
 	}
 
-	return nil
+	message, err := g.templateString(smokeSensor, pluginConfig.MessageTemplate)
+	if err != nil {
+		return err
+	}
+
+	title, err := g.templateString(smokeSensor, pluginConfig.TitleTemplate)
+	if err != nil {
+		return err
+	}
+
+	gotifyMessage := GotifyMessage{
+		Title:    title,
+		Message:  message,
+		Priority: pluginConfig.Priority,
+	}
+
+	postBody, _ := json.Marshal(&gotifyMessage)
+	responseBody := bytes.NewBuffer(postBody)
+	gotifyUrl, err := pluginConfig.GetGotifyUrl()
+	if err != nil {
+		return err
+	}
+
+	_, err = http.Post(gotifyUrl, "application/json", responseBody)
+	return err
+}
+
+func (g *GotifyPlugin) templateString(smokeSensor plugininterface.AlarmSmokeSensor, templateString string) (string, error) {
+	t, err := template.New("alarmMessage").Parse(templateString)
+	if err != nil {
+		return "", err
+	}
+	var tpl bytes.Buffer
+	err = t.Execute(&tpl, smokeSensor)
+	if err != nil {
+		return "", err
+	}
+
+	return tpl.String(), nil
+
 }
 
 var Plugin = GotifyPlugin{
diff --git a/pluginConfig.go b/pluginConfig.go
new file mode 100644
index 0000000000000000000000000000000000000000..107a7256dbdb251d011e1f03d21a03137dc89f2d
--- /dev/null
+++ b/pluginConfig.go
@@ -0,0 +1,32 @@
+package main
+
+import (
+	"net/url"
+	"time"
+)
+
+type GotifyPluginConfig struct {
+	ID              uint `gorm:"primaryKey"`
+	CreatedAt       time.Time
+	UpdatedAt       time.Time
+	Name            string
+	GotifyUrl       string
+	GotifyToken     string
+	MessageTemplate string
+	TitleTemplate   string
+	Priority        int
+}
+
+func (g GotifyPluginConfig) GetGotifyUrl() (string, error) {
+	url, err := url.Parse(g.GotifyUrl)
+	if err != nil {
+		return "", err
+	}
+
+	url.Path = url.Path + "/message"
+	queryParams := url.Query()
+	queryParams.Set("token", g.GotifyToken)
+	url.RawQuery = queryParams.Encode()
+
+	return url.String(), nil
+}