Skip to content

Commit

Permalink
added matrix message sending
Browse files Browse the repository at this point in the history
  • Loading branch information
Paz committed Jan 2, 2025
1 parent df4f7a2 commit a9ff956
Show file tree
Hide file tree
Showing 7 changed files with 265 additions and 3 deletions.
143 changes: 143 additions & 0 deletions internal/matrix/service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
package matrix

import (
"bytes"
"encoding/json"
"errors"
"fmt"
"net/http"
"time"

"github.com/pazifical/onyx/logging"
)

type Service struct {
credentials Credentials
roomID string
accessToken string
}

func NewService(credentials Credentials, roomID string) Service {
return Service{
credentials: credentials,
roomID: roomID,
}
}

func (s *Service) Authenticate() error {
endpoint := "https://matrix.org/_matrix/client/v3/login"

loginRequestData := LoginRequestData{
Type: "m.login.password",
Password: s.credentials.Password,
Identifier: UserData{
Type: "m.id.user",
User: s.credentials.Username,
},
}

data, err := json.Marshal(loginRequestData)
if err != nil {
logging.Error(err.Error())
return err
}

request, err := http.NewRequest("POST", endpoint, bytes.NewBuffer(data))
if err != nil {
logging.Error(err.Error())
return err
}

request.Header.Set("Content-Type", "application/json")

client := http.Client{
Timeout: 10 * time.Second,
}

response, err := client.Do(request)
if err != nil {
logging.Error(err.Error())
return err
}

defer response.Body.Close()
if response.StatusCode != http.StatusOK {
logging.Warning(fmt.Sprintf("response status %d from Matrix", response.StatusCode))

var errorData interface{}
err = json.NewDecoder(response.Body).Decode(&errorData)
if err != nil {
return err
}

jsonData, err := json.Marshal(errorData)
if err != nil {
return err
}
return errors.New(string(jsonData))
}

var loginResponseData LoginResponseData
err = json.NewDecoder(response.Body).Decode(&loginResponseData)
if err != nil {
logging.Error(err.Error())
return err
}

s.accessToken = loginResponseData.AccessToken

return nil
}

func (s *Service) SendMessage(text string) error {
endpoint := fmt.Sprintf("https://matrix.org/_matrix/client/v3/rooms/%s/send/m.room.message", s.roomID)

message := MessageData{
MsgType: "m.text",
Body: text,
}

data, err := json.Marshal(message)
if err != nil {
logging.Error(err.Error())
return err
}

request, err := http.NewRequest("POST", endpoint, bytes.NewBuffer(data))
if err != nil {
logging.Error(err.Error())
return err
}

request.Header.Set("Content-Type", "application/json")
request.Header.Set("Authorization", fmt.Sprintf("Bearer %s", s.accessToken))

client := http.Client{
Timeout: 10 * time.Second,
}

response, err := client.Do(request)
if err != nil {
logging.Error(err.Error())
return err
}

defer response.Body.Close()
if response.StatusCode != http.StatusOK {
logging.Warning(fmt.Sprintf("response status %d from Matrix", response.StatusCode))

var errorData interface{}
err = json.NewDecoder(response.Body).Decode(&errorData)
if err != nil {
return err
}

jsonData, err := json.Marshal(errorData)
if err != nil {
return err
}
return errors.New(string(jsonData))
}

return nil
}
30 changes: 30 additions & 0 deletions internal/matrix/types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package matrix

type Credentials struct {
Username string
Password string
}

type LoginRequestData struct {
Type string `json:"type"`
Identifier UserData `json:"identifier"`
Password string `json:"password"`
}

type LoginResponseData struct {
AccessToken string `json:"access_token"`
DeviceID string `json:"device_id"`
ExpiresInMs int `json:"expires_in_ms"`
RefreshToken string `json:"refresh_token"`
UserID string `json:"user_id"`
}

type UserData struct {
Type string `json:"type"`
User string `json:"user"`
}

type MessageData struct {
MsgType string `json:"msgtype"`
Body string `json:"body"`
}
7 changes: 7 additions & 0 deletions internal/onyx/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,11 @@ package onyx
type Config struct {
Port int
MarkdownDirectory string
MatrixConfig MatrixConfig
}

type MatrixConfig struct {
Username string
Password string
RoomID string
}
5 changes: 5 additions & 0 deletions internal/onyx/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"net/http"

"github.com/pazifical/onyx/internal/database"
"github.com/pazifical/onyx/internal/matrix"
"github.com/pazifical/onyx/internal/reminder"
"github.com/pazifical/onyx/logging"
)
Expand Down Expand Up @@ -45,6 +46,10 @@ func NewServer(config Config, frontendFS embed.FS) *Server {
return &server
}

func (s *Server) AddMatrixService(matrixService *matrix.Service) {
s.monitoringService.InitializeMatrixService(matrixService)
}

func (s *Server) Start() error {
go s.monitoringService.Start()

Expand Down
42 changes: 40 additions & 2 deletions internal/reminder/monitor.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package reminder

import (
"fmt"
"log"
"regexp"
"strings"
"time"

"github.com/pazifical/onyx/internal/database"
"github.com/pazifical/onyx/internal/matrix"
"github.com/pazifical/onyx/internal/types"
"github.com/pazifical/onyx/logging"
)
Expand All @@ -24,8 +26,9 @@ func init() {
}

type MonitoringService struct {
repository *database.NoteRepository
reminders []Reminder
repository *database.NoteRepository
reminders []Reminder
matrixService *matrix.Service
}

func NewMonitoringService(repository *database.NoteRepository) MonitoringService {
Expand All @@ -34,6 +37,10 @@ func NewMonitoringService(repository *database.NoteRepository) MonitoringService
}
}

func (ms *MonitoringService) InitializeMatrixService(matrixService *matrix.Service) {
ms.matrixService = matrixService
}

func (ms *MonitoringService) GetAllReminders() []Reminder {
return ms.reminders
}
Expand Down Expand Up @@ -64,6 +71,37 @@ func (ms *MonitoringService) searchForReminders() error {
}
}

if ms.matrixService != nil {
err = ms.matrixService.Authenticate()
if err != nil {
logging.Error(err.Error())
}

err = ms.sendMatrixMessages(ms.reminders)
if err != nil {
logging.Error(err.Error())
}
}

return nil
}

func (ms *MonitoringService) sendMatrixMessages(reminders []Reminder) error {
err := ms.matrixService.Authenticate()
if err != nil {
return err
}

var builder strings.Builder
for _, reminder := range reminders {
builder.WriteString(fmt.Sprintf("%s\n%s\n(%s)\n\n\n", reminder.Date, reminder.ToDo, reminder.Source))
}

err = ms.matrixService.SendMessage(builder.String())
if err != nil {
return err
}

return nil
}

Expand Down
39 changes: 39 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,18 @@ import (
"os"
"strconv"

"github.com/pazifical/onyx/internal/matrix"
"github.com/pazifical/onyx/internal/onyx"
"github.com/pazifical/onyx/logging"
)

var defaultMarkdownDirectory = "markdown"
var defaultPort = 80

var matrixRoomID string
var matrixUsername string
var matrixPassword string

//go:embed frontend/dist
var frontendFS embed.FS

Expand Down Expand Up @@ -48,6 +53,31 @@ func init() {
if !fi.IsDir() {
log.Fatalf("given markdown directory is not a directory: %s", defaultMarkdownDirectory)
}

initMatrixConfigFromEnv()
}

func initMatrixConfigFromEnv() {
roomID := os.Getenv("ONYX_MATRIX_ROOM_ID")
if roomID == "" {
logging.Info("Please provide a Matrix room id via env ONYX_MATRIX_ROOM_ID")
return
}
matrixRoomID = roomID

username := os.Getenv("ONYX_MATRIX_USERNAME")
if username == "" {
logging.Info("Please provide a Matrix username via env ONYX_MATRIX_USERNAME")
return
}
matrixUsername = username

password := os.Getenv("ONYX_MATRIX_PASSWORD")
if password == "" {
logging.Info("Please provide a Matrix user password id via env ONYX_MATRIX_PASSWORD")
return
}
matrixPassword = password
}

func main() {
Expand All @@ -57,6 +87,15 @@ func main() {
}

server := onyx.NewServer(config, frontendFS)

if matrixPassword != "" && matrixUsername != "" && matrixRoomID != "" {
matrixService := matrix.NewService(matrix.Credentials{
Username: matrixUsername,
Password: matrixPassword,
}, matrixRoomID)
server.AddMatrixService(&matrixService)
}

err := server.Start()
if err != nil {
log.Fatal(err)
Expand Down
2 changes: 1 addition & 1 deletion onyx.env
Original file line number Diff line number Diff line change
@@ -1 +1 @@
ONYX_VERSION=0.2.3
ONYX_VERSION=0.2.4

0 comments on commit a9ff956

Please sign in to comment.