227 lines
4.9 KiB
Go
227 lines
4.9 KiB
Go
package actions
|
|
|
|
import (
|
|
"fmt"
|
|
"encoding/json"
|
|
|
|
"context"
|
|
"errors"
|
|
"sync"
|
|
"time"
|
|
|
|
_ "github.com/mattn/go-sqlite3"
|
|
|
|
"maunium.net/go/mautrix"
|
|
"maunium.net/go/mautrix/id"
|
|
"maunium.net/go/mautrix/crypto/cryptohelper"
|
|
|
|
"github.com/k4lipso/gokill/internal"
|
|
)
|
|
|
|
type SendMatrix struct {
|
|
Homeserver string `json:"homeserver"`
|
|
Username string `json:"username"`
|
|
Password string `json:"password"`
|
|
Database string `json:"database"`
|
|
RoomId string `json:"roomId"`
|
|
Message string `json:"message"`
|
|
TestMessage string `json:"testMessage"`
|
|
ActionChan ActionResultChan
|
|
}
|
|
|
|
func (s SendMatrix) sendMessage(message string) error {
|
|
client, err := mautrix.NewClient(s.Homeserver, "", "")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
cryptoHelper, err := cryptohelper.NewCryptoHelper(client, []byte("meow"), s.Database)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
cryptoHelper.LoginAs = &mautrix.ReqLogin{
|
|
Type: mautrix.AuthTypePassword,
|
|
Identifier: mautrix.UserIdentifier{Type: mautrix.IdentifierTypeUser, User: s.Username},
|
|
Password: s.Password,
|
|
}
|
|
|
|
err = cryptoHelper.Init()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
client.Crypto = cryptoHelper
|
|
|
|
internal.LogDoc(s).Info("Matrix Client Now running")
|
|
syncCtx, cancelSync := context.WithCancel(context.Background())
|
|
var syncStopWait sync.WaitGroup
|
|
syncStopWait.Add(1)
|
|
|
|
go func() {
|
|
err = client.SyncWithContext(syncCtx)
|
|
defer syncStopWait.Done()
|
|
if err != nil && !errors.Is(err, context.Canceled) {
|
|
return
|
|
}
|
|
}()
|
|
|
|
time.Sleep(5 * time.Second)
|
|
resp, err := client.SendText(id.RoomID(s.RoomId), message)
|
|
|
|
if err != nil {
|
|
return fmt.Errorf("Failed to send event")
|
|
} else {
|
|
internal.LogDoc(s).Info("Matrix Client: Message sent")
|
|
internal.LogDoc(s).Infof("Matrix Client: event_id: %s", resp.EventID.String())
|
|
}
|
|
|
|
cancelSync()
|
|
syncStopWait.Wait()
|
|
err = cryptoHelper.Close()
|
|
if err != nil {
|
|
return fmt.Errorf("Error closing database")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (s SendMatrix) DryExecute() {
|
|
internal.LogDoc(s).Info("SendMatrix: Trying to send test message")
|
|
err := s.sendMessage(s.TestMessage)
|
|
|
|
if err != nil {
|
|
internal.LogDoc(s).Info("SendMatrix: failed to send test message")
|
|
}
|
|
|
|
s.ActionChan <- err
|
|
}
|
|
|
|
func (s SendMatrix) Execute() {
|
|
internal.LogDoc(s).Info("SendMatrix: Trying to send message")
|
|
err := s.sendMessage(s.Message)
|
|
|
|
if err != nil {
|
|
internal.LogDoc(s).Info("SendMatrix: failed to send message")
|
|
}
|
|
|
|
s.ActionChan <- err
|
|
}
|
|
|
|
func CreateSendMatrix(config internal.ActionConfig, c ActionResultChan) (SendMatrix, error) {
|
|
result := SendMatrix{}
|
|
|
|
err := json.Unmarshal(config.Options, &result)
|
|
|
|
if err != nil {
|
|
return SendMatrix{}, err
|
|
}
|
|
|
|
if result.Homeserver == "" {
|
|
return SendMatrix{}, internal.OptionMissingError{"homeserver"}
|
|
}
|
|
|
|
if result.Username == "" {
|
|
return SendMatrix{}, internal.OptionMissingError{"username"}
|
|
}
|
|
|
|
if result.Password == "" {
|
|
return SendMatrix{}, internal.OptionMissingError{"password"}
|
|
}
|
|
|
|
if result.Database == "" {
|
|
return SendMatrix{}, internal.OptionMissingError{"database"}
|
|
}
|
|
|
|
if result.RoomId == "" {
|
|
return SendMatrix{}, internal.OptionMissingError{"roomId"}
|
|
}
|
|
|
|
if result.Message == "" {
|
|
return SendMatrix{}, internal.OptionMissingError{"message"}
|
|
}
|
|
|
|
if result.TestMessage == "" {
|
|
return SendMatrix{}, internal.OptionMissingError{"testMessage"}
|
|
}
|
|
|
|
result.ActionChan = c
|
|
return result, nil
|
|
}
|
|
|
|
func (s SendMatrix) Create(config internal.ActionConfig, c ActionResultChan) (Action, error) {
|
|
return CreateSendMatrix(config, c)
|
|
}
|
|
|
|
func (p SendMatrix) GetName() string {
|
|
return "SendMatrix"
|
|
}
|
|
|
|
func (p SendMatrix) GetDescription() string {
|
|
return "Sends a message to a given room. The user needs to be part of that room already."
|
|
}
|
|
|
|
func (p SendMatrix) GetExample() string {
|
|
return `
|
|
{
|
|
"type": "SendMatrix",
|
|
"options": {
|
|
"homeserver": "matrix.org",
|
|
"username": "testuser",
|
|
"password": "super-secret",
|
|
"database": "/etc/gokill/matrix.db",
|
|
"roomId": "!Balrthajskensaw:matrix.org",
|
|
"message": "attention, intruders got my device!",
|
|
"testMessage": "this is just a test, no worries"
|
|
}
|
|
}
|
|
`
|
|
}
|
|
|
|
func (p SendMatrix) GetOptions() []internal.ConfigOption {
|
|
return []internal.ConfigOption{
|
|
{
|
|
Name: "homeserver",
|
|
Type: "string",
|
|
Description: "homeserver address.",
|
|
Default: "",
|
|
},
|
|
{
|
|
Name: "username",
|
|
Type: "string",
|
|
Description: "username (localpart, wihout homeserver address)",
|
|
Default: "",
|
|
},
|
|
{
|
|
Name: "password",
|
|
Type: "string",
|
|
Description: "password in clear text",
|
|
Default: "",
|
|
},
|
|
{
|
|
Name: "database",
|
|
Type: "string",
|
|
Description: "path to database file, will be created if not existing. this is necessary to sync keys for encryption.",
|
|
Default: "",
|
|
},
|
|
{
|
|
Name: "roomId",
|
|
Type: "string",
|
|
Description: "",
|
|
Default: "",
|
|
},
|
|
{
|
|
Name: "message",
|
|
Type: "string",
|
|
Description: "actual message that should be sent",
|
|
Default: "",
|
|
},
|
|
{
|
|
Name: "testMessage",
|
|
Type: "string",
|
|
Description: "message sent during test run",
|
|
Default: "",
|
|
},
|
|
}
|
|
}
|