Skip to content

Commit

Permalink
change event action
Browse files Browse the repository at this point in the history
  • Loading branch information
CubicrootXYZ committed Jan 28, 2024
1 parent 9880813 commit 36f5ef0
Show file tree
Hide file tree
Showing 5 changed files with 170 additions and 0 deletions.
121 changes: 121 additions & 0 deletions internal/connectors/matrix/actions/message/change_event.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package message

// TODO add tests!

import (
"regexp"

"github.com/CubicrootXYZ/gologger"
"github.com/CubicrootXYZ/matrix-reminder-and-calendar-bot/internal/connectors/matrix"
matrixdb "github.com/CubicrootXYZ/matrix-reminder-and-calendar-bot/internal/connectors/matrix/database"
"github.com/CubicrootXYZ/matrix-reminder-and-calendar-bot/internal/connectors/matrix/format"
"github.com/CubicrootXYZ/matrix-reminder-and-calendar-bot/internal/connectors/matrix/mautrixcl"
"github.com/CubicrootXYZ/matrix-reminder-and-calendar-bot/internal/connectors/matrix/messenger"
"github.com/CubicrootXYZ/matrix-reminder-and-calendar-bot/internal/connectors/matrix/msghelper"
"github.com/CubicrootXYZ/matrix-reminder-and-calendar-bot/internal/database"
)

var changeEventActionRegex = regexp.MustCompile("(?i)(^(change|update|set)[ ]+(reminder|reminder id|)[ ]*[0-9]+)")

// ChangeEventAction for changing an existing event.
type ChangeEventAction struct {
logger gologger.Logger
client mautrixcl.Client
messenger messenger.Messenger
matrixDB matrixdb.Service
db database.Service
storer *msghelper.Storer
}

// Configure is called on startup and sets all dependencies.
func (action *ChangeEventAction) Configure(logger gologger.Logger, client mautrixcl.Client, messenger messenger.Messenger, matrixDB matrixdb.Service, db database.Service, _ *matrix.BridgeServices) {
action.logger = logger
action.client = client
action.matrixDB = matrixDB
action.db = db
action.messenger = messenger
action.storer = msghelper.NewStorer(matrixDB, messenger, logger)
}

// Name of the action
func (action *ChangeEventAction) Name() string {
return "Change event"
}

func (action *ChangeEventAction) GetDocu() (title, explaination string, examples []string) {
return "Change event",
"Change an existing Event.",
[]string{"change reminder 1 to tomorrow", "update 68 to Saturday 4 pm"}
}

// Selector defines a regex on what messages the action should be used.
func (action *ChangeEventAction) Selector() *regexp.Regexp {
return changeEventActionRegex
}

// HandleEvent is where the message event get's send to if it matches the Selector.
func (action *ChangeEventAction) HandleEvent(event *matrix.MessageEvent) {
match := changeEventActionRegex.Find([]byte(event.Content.Body))
if match == nil {
go action.storer.SendAndStoreResponse(
"Ups, seems like there is a reminder ID missing in your message.",
matrixdb.MessageTypeChangeEventError,
*event,
)
return
}

eventID, err := format.GetSuffixInt(string(match))
if err != nil {
go action.storer.SendAndStoreResponse(
"Ups, seems like there is a reminder ID missing in your message.",
matrixdb.MessageTypeChangeEventError,
*event,
)
return
}

newTime, err := format.ParseTime(event.Content.Body, event.Room.TimeZone, false)
if err != nil {
go action.storer.SendAndStoreResponse(
"Ehm, sorry to say that, but I was not able to understand the time to schedule the reminder to.",
matrixdb.MessageTypeChangeEventError,
*event,
)
return
}

events, err := action.db.ListEvents(&database.ListEventsOpts{
IDs: []uint{uint(eventID)},
ChannelID: &event.Channel.ID,
})
if err != nil || len(events) == 0 {
go action.storer.SendAndStoreResponse(
"This reminder is not in my database.",
matrixdb.MessageTypeChangeEvent,
*event,
)
return
}

evt := &events[0]
evt.Time = newTime
evt, err = action.db.UpdateEvent(evt)
if err != nil || len(events) == 0 {
go action.storer.SendAndStoreResponse(
"Whups, this did not work, sorry.",
matrixdb.MessageTypeChangeEventError,
*event,
)
return
}

msgFormater := format.Formater{}
msgFormater.TextLine("I rescheduled your reminder")
msgFormater.QuoteLine(evt.Message)
msgFormater.Text("to ")
msgFormater.Text(format.ToLocalTime(newTime, event.Room.TimeZone))
msg, formattedMsg := msgFormater.Build()

go action.storer.SendAndStoreMessage(msg, formattedMsg, matrixdb.MessageTypeChangeEvent, *event)
}
1 change: 1 addition & 0 deletions internal/connectors/matrix/database/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ var (
MessageTypeEventDelete = MatrixMessageType("EVENT_DELETE")
MessageTypeAddUser = MatrixMessageType("USER_ADD")
MessageTypeChangeEvent = MatrixMessageType("EVENT_CHANGE")
MessageTypeChangeEventError = MatrixMessageType("EVENT_CHANGE_ERROR")
MessageTypeIcalExportEnable = MatrixMessageType("ICAL_ENABLE")
MessageTypeIcalRegenToken = MatrixMessageType("ICAL_REGEN")
MessageTypeEventList = MatrixMessageType("EVENT_LIST")
Expand Down
19 changes: 19 additions & 0 deletions internal/connectors/matrix/format/numbers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package format

import (
"errors"
"strconv"
"strings"
)

// GetSuffixInt returns a suffixed integer in the given string value
func GetSuffixInt(value string) (int, error) {
splitUp := strings.Split(value, " ")
if len(splitUp) == 0 {
return 0, errors.New("empty string does not contain integer")
}

integerString := splitUp[len(splitUp)-1]

return strconv.Atoi(integerString)
}
28 changes: 28 additions & 0 deletions internal/connectors/matrix/format/numbers_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package format_test

import (
"testing"

"github.com/CubicrootXYZ/matrix-reminder-and-calendar-bot/internal/connectors/matrix/format"
"github.com/stretchr/testify/assert"
)

func Test_GetSuffixIntOnSuccess(t *testing.T) {
result, err := format.GetSuffixInt("Well, this is a very long sentencen: please add some more characters and an integer like 203")
assert.NoError(t, err)
assert.Equal(t, 203, result)
}

func Test_GetSuffixIntOnFailure(t *testing.T) {
t.Run("missing number", func(t *testing.T) {
result, err := format.GetSuffixInt("Well, this is a very long sentencen: please add some more characters and an integer like two hundred")
assert.Error(t, err)
assert.Equal(t, 0, result)
})

t.Run("empty string", func(t *testing.T) {
result, err := format.GetSuffixInt("")
assert.Error(t, err)
assert.Equal(t, 0, result)
})
}
1 change: 1 addition & 0 deletions internal/connectors/matrix/msghelper/send_and_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ func (storer *Storer) SendAndStoreMessage(message, messageFormatted string, mess
// ResponseOpts defines a type for response options.
type ResponseOpts func(msg *matrixdb.MatrixMessage)

// TODO sometimes is called async, needs to be taken care of in shutdown!
// SendAndStoreResponse outsources response sending and storing. Call it asynchronous with "go SendAndStoreMessage(...)"
func (storer *Storer) SendAndStoreResponse(message string, messageType matrixdb.MatrixMessageType, event matrix.MessageEvent, opts ...ResponseOpts) {
resp, err := storer.messenger.SendResponse(messenger.PlainTextResponse(
Expand Down

0 comments on commit 36f5ef0

Please sign in to comment.