mirror of
https://github.com/thegeeklab/wp-matrix.git
synced 2024-11-21 14:20:41 +00:00
refactor: use dedicated matrix package (#111)
This commit is contained in:
parent
117f681b10
commit
3c3fb393b8
@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
all: True
|
all: True
|
||||||
dir: mocks
|
dir: "{{.PackageName}}/mocks"
|
||||||
outpkg: "mocks"
|
outpkg: "mocks"
|
||||||
packages:
|
packages:
|
||||||
github.com/thegeeklab/wp-matrix/plugin:
|
github.com/thegeeklab/wp-matrix/matrix:
|
||||||
|
4
Makefile
4
Makefile
@ -11,13 +11,14 @@ IMPORT := github.com/thegeeklab/$(EXECUTABLE)
|
|||||||
|
|
||||||
GO ?= go
|
GO ?= go
|
||||||
CWD ?= $(shell pwd)
|
CWD ?= $(shell pwd)
|
||||||
PACKAGES ?= $(shell go list ./... | grep -Ev 'mocks')
|
PACKAGES ?= $(shell go list ./... | grep -Ev '/mocks$$')
|
||||||
SOURCES ?= $(shell find . -name "*.go" -type f)
|
SOURCES ?= $(shell find . -name "*.go" -type f)
|
||||||
|
|
||||||
GOFUMPT_PACKAGE ?= mvdan.cc/gofumpt@$(GOFUMPT_PACKAGE_VERSION)
|
GOFUMPT_PACKAGE ?= mvdan.cc/gofumpt@$(GOFUMPT_PACKAGE_VERSION)
|
||||||
GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/cmd/golangci-lint@$(GOLANGCI_LINT_PACKAGE_VERSION)
|
GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/cmd/golangci-lint@$(GOLANGCI_LINT_PACKAGE_VERSION)
|
||||||
XGO_PACKAGE ?= src.techknowlogick.com/xgo@latest
|
XGO_PACKAGE ?= src.techknowlogick.com/xgo@latest
|
||||||
GOTESTSUM_PACKAGE ?= gotest.tools/gotestsum@latest
|
GOTESTSUM_PACKAGE ?= gotest.tools/gotestsum@latest
|
||||||
|
MOCKERY_PACKAGE ?= github.com/vektra/mockery/v2@latest
|
||||||
|
|
||||||
XGO_VERSION := go-1.22.x
|
XGO_VERSION := go-1.22.x
|
||||||
XGO_TARGETS ?= linux/amd64,linux/arm-6,linux/arm-7,linux/arm64
|
XGO_TARGETS ?= linux/amd64,linux/arm-6,linux/arm-7,linux/arm64
|
||||||
@ -65,6 +66,7 @@ lint: golangci-lint
|
|||||||
.PHONY: generate
|
.PHONY: generate
|
||||||
generate:
|
generate:
|
||||||
$(GO) generate $(PACKAGES)
|
$(GO) generate $(PACKAGES)
|
||||||
|
$(GO) run $(MOCKERY_PACKAGE)
|
||||||
|
|
||||||
.PHONY: test
|
.PHONY: test
|
||||||
test:
|
test:
|
||||||
|
14
matrix/api.go
Normal file
14
matrix/api.go
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
package matrix
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"maunium.net/go/mautrix"
|
||||||
|
"maunium.net/go/mautrix/event"
|
||||||
|
"maunium.net/go/mautrix/id"
|
||||||
|
)
|
||||||
|
|
||||||
|
//nolint:lll
|
||||||
|
type APIClient interface {
|
||||||
|
SendMessageEvent(ctx context.Context, roomID id.RoomID, eventType event.Type, contentJSON interface{}, extra ...mautrix.ReqSendEvent) (resp *mautrix.RespSendEvent, err error)
|
||||||
|
}
|
89
matrix/matrix.go
Normal file
89
matrix/matrix.go
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
package matrix
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/microcosm-cc/bluemonday"
|
||||||
|
"maunium.net/go/mautrix"
|
||||||
|
"maunium.net/go/mautrix/event"
|
||||||
|
"maunium.net/go/mautrix/format"
|
||||||
|
"maunium.net/go/mautrix/id"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Client struct {
|
||||||
|
client APIClient
|
||||||
|
Message *Message
|
||||||
|
}
|
||||||
|
|
||||||
|
type Message struct {
|
||||||
|
client APIClient
|
||||||
|
Opt MessageOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
type MessageOptions struct {
|
||||||
|
RoomID id.RoomID
|
||||||
|
Message string
|
||||||
|
TemplateUnsafe bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewClient creates a new Matrix client with the given parameters and joins the specified room.
|
||||||
|
// It authenticates the user if the userID and token are not provided, and returns a Client struct
|
||||||
|
// that can be used to send messages to the room.
|
||||||
|
func NewClient(ctx context.Context, url, roomID, userID, token, username, password string) (*Client, error) {
|
||||||
|
muid := id.NewUserID(EnsurePrefix("@", userID), url)
|
||||||
|
|
||||||
|
c, err := mautrix.NewClient(url, muid, token)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if userID == "" || token == "" {
|
||||||
|
_, err := c.Login(
|
||||||
|
ctx,
|
||||||
|
&mautrix.ReqLogin{
|
||||||
|
Type: "m.login.password",
|
||||||
|
Identifier: mautrix.UserIdentifier{Type: mautrix.IdentifierTypeUser, User: username},
|
||||||
|
Password: password,
|
||||||
|
InitialDeviceDisplayName: "Woodpecker CI",
|
||||||
|
StoreCredentials: true,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to authenticate user: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
joinResp, err := c.JoinRoom(ctx, EnsurePrefix("!", roomID), "", nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to join room: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &Client{
|
||||||
|
client: c,
|
||||||
|
Message: &Message{
|
||||||
|
client: c,
|
||||||
|
Opt: MessageOptions{
|
||||||
|
RoomID: joinResp.RoomID,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send sends a message to the specified room. It sanitizes the message content
|
||||||
|
// to remove potentially unsafe HTML.
|
||||||
|
func (m *Message) Send(ctx context.Context) error {
|
||||||
|
content := format.RenderMarkdown(m.Opt.Message, true, m.Opt.TemplateUnsafe)
|
||||||
|
|
||||||
|
if content.FormattedBody != "" {
|
||||||
|
content.Body = format.HTMLToMarkdown(bluemonday.UGCPolicy().Sanitize(content.FormattedBody))
|
||||||
|
content.FormattedBody = bluemonday.UGCPolicy().Sanitize(content.FormattedBody)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := m.client.SendMessageEvent(ctx, m.Opt.RoomID, event.EventMessage, content)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package plugin
|
package matrix
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@ -6,21 +6,21 @@ import (
|
|||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/mock"
|
"github.com/stretchr/testify/mock"
|
||||||
"github.com/thegeeklab/wp-matrix/plugin/mocks"
|
"github.com/thegeeklab/wp-matrix/matrix/mocks"
|
||||||
"maunium.net/go/mautrix"
|
"maunium.net/go/mautrix"
|
||||||
"maunium.net/go/mautrix/event"
|
"maunium.net/go/mautrix/event"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMatrixMessageSend(t *testing.T) {
|
func TestMessageSend(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
messageOpt MatrixMessageOpt
|
messageOpt MessageOptions
|
||||||
want event.MessageEventContent
|
want event.MessageEventContent
|
||||||
wantErr bool
|
wantErr bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "plain text message",
|
name: "plain text message",
|
||||||
messageOpt: MatrixMessageOpt{
|
messageOpt: MessageOptions{
|
||||||
RoomID: "test-room",
|
RoomID: "test-room",
|
||||||
Message: "hello world",
|
Message: "hello world",
|
||||||
},
|
},
|
||||||
@ -31,7 +31,7 @@ func TestMatrixMessageSend(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "markdown message",
|
name: "markdown message",
|
||||||
messageOpt: MatrixMessageOpt{
|
messageOpt: MessageOptions{
|
||||||
RoomID: "test-room",
|
RoomID: "test-room",
|
||||||
Message: "**hello world**",
|
Message: "**hello world**",
|
||||||
},
|
},
|
||||||
@ -44,7 +44,7 @@ func TestMatrixMessageSend(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "html message",
|
name: "html message",
|
||||||
messageOpt: MatrixMessageOpt{
|
messageOpt: MessageOptions{
|
||||||
RoomID: "test-room",
|
RoomID: "test-room",
|
||||||
Message: "hello<br>world",
|
Message: "hello<br>world",
|
||||||
TemplateUnsafe: true,
|
TemplateUnsafe: true,
|
||||||
@ -58,7 +58,7 @@ func TestMatrixMessageSend(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "safe html message",
|
name: "safe html message",
|
||||||
messageOpt: MatrixMessageOpt{
|
messageOpt: MessageOptions{
|
||||||
RoomID: "test-room",
|
RoomID: "test-room",
|
||||||
Message: "hello world<script>alert('XSS')</script>",
|
Message: "hello world<script>alert('XSS')</script>",
|
||||||
TemplateUnsafe: false,
|
TemplateUnsafe: false,
|
||||||
@ -72,7 +72,7 @@ func TestMatrixMessageSend(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "unsafe html message",
|
name: "unsafe html message",
|
||||||
messageOpt: MatrixMessageOpt{
|
messageOpt: MessageOptions{
|
||||||
RoomID: "test-room",
|
RoomID: "test-room",
|
||||||
Message: "hello world<script>alert('XSS')</script>",
|
Message: "hello world<script>alert('XSS')</script>",
|
||||||
TemplateUnsafe: true,
|
TemplateUnsafe: true,
|
||||||
@ -89,8 +89,8 @@ func TestMatrixMessageSend(t *testing.T) {
|
|||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
mockClient := mocks.NewMockMautrixClient(t)
|
mockClient := mocks.NewMockAPIClient(t)
|
||||||
m := &MatrixMessage{
|
m := &Message{
|
||||||
Opt: tt.messageOpt,
|
Opt: tt.messageOpt,
|
||||||
client: mockClient,
|
client: mockClient,
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
// Code generated by mockery v2.42.1. DO NOT EDIT.
|
// Code generated by mockery v2.43.0. DO NOT EDIT.
|
||||||
|
|
||||||
package mocks
|
package mocks
|
||||||
|
|
||||||
@ -13,21 +13,21 @@ import (
|
|||||||
mock "github.com/stretchr/testify/mock"
|
mock "github.com/stretchr/testify/mock"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MockMautrixClient is an autogenerated mock type for the MautrixClient type
|
// MockAPIClient is an autogenerated mock type for the APIClient type
|
||||||
type MockMautrixClient struct {
|
type MockAPIClient struct {
|
||||||
mock.Mock
|
mock.Mock
|
||||||
}
|
}
|
||||||
|
|
||||||
type MockMautrixClient_Expecter struct {
|
type MockAPIClient_Expecter struct {
|
||||||
mock *mock.Mock
|
mock *mock.Mock
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_m *MockMautrixClient) EXPECT() *MockMautrixClient_Expecter {
|
func (_m *MockAPIClient) EXPECT() *MockAPIClient_Expecter {
|
||||||
return &MockMautrixClient_Expecter{mock: &_m.Mock}
|
return &MockAPIClient_Expecter{mock: &_m.Mock}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SendMessageEvent provides a mock function with given fields: ctx, roomID, eventType, contentJSON, extra
|
// SendMessageEvent provides a mock function with given fields: ctx, roomID, eventType, contentJSON, extra
|
||||||
func (_m *MockMautrixClient) SendMessageEvent(ctx context.Context, roomID id.RoomID, eventType event.Type, contentJSON interface{}, extra ...mautrix.ReqSendEvent) (*mautrix.RespSendEvent, error) {
|
func (_m *MockAPIClient) SendMessageEvent(ctx context.Context, roomID id.RoomID, eventType event.Type, contentJSON interface{}, extra ...mautrix.ReqSendEvent) (*mautrix.RespSendEvent, error) {
|
||||||
_va := make([]interface{}, len(extra))
|
_va := make([]interface{}, len(extra))
|
||||||
for _i := range extra {
|
for _i := range extra {
|
||||||
_va[_i] = extra[_i]
|
_va[_i] = extra[_i]
|
||||||
@ -63,8 +63,8 @@ func (_m *MockMautrixClient) SendMessageEvent(ctx context.Context, roomID id.Roo
|
|||||||
return r0, r1
|
return r0, r1
|
||||||
}
|
}
|
||||||
|
|
||||||
// MockMautrixClient_SendMessageEvent_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SendMessageEvent'
|
// MockAPIClient_SendMessageEvent_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SendMessageEvent'
|
||||||
type MockMautrixClient_SendMessageEvent_Call struct {
|
type MockAPIClient_SendMessageEvent_Call struct {
|
||||||
*mock.Call
|
*mock.Call
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,12 +74,12 @@ type MockMautrixClient_SendMessageEvent_Call struct {
|
|||||||
// - eventType event.Type
|
// - eventType event.Type
|
||||||
// - contentJSON interface{}
|
// - contentJSON interface{}
|
||||||
// - extra ...mautrix.ReqSendEvent
|
// - extra ...mautrix.ReqSendEvent
|
||||||
func (_e *MockMautrixClient_Expecter) SendMessageEvent(ctx interface{}, roomID interface{}, eventType interface{}, contentJSON interface{}, extra ...interface{}) *MockMautrixClient_SendMessageEvent_Call {
|
func (_e *MockAPIClient_Expecter) SendMessageEvent(ctx interface{}, roomID interface{}, eventType interface{}, contentJSON interface{}, extra ...interface{}) *MockAPIClient_SendMessageEvent_Call {
|
||||||
return &MockMautrixClient_SendMessageEvent_Call{Call: _e.mock.On("SendMessageEvent",
|
return &MockAPIClient_SendMessageEvent_Call{Call: _e.mock.On("SendMessageEvent",
|
||||||
append([]interface{}{ctx, roomID, eventType, contentJSON}, extra...)...)}
|
append([]interface{}{ctx, roomID, eventType, contentJSON}, extra...)...)}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_c *MockMautrixClient_SendMessageEvent_Call) Run(run func(ctx context.Context, roomID id.RoomID, eventType event.Type, contentJSON interface{}, extra ...mautrix.ReqSendEvent)) *MockMautrixClient_SendMessageEvent_Call {
|
func (_c *MockAPIClient_SendMessageEvent_Call) Run(run func(ctx context.Context, roomID id.RoomID, eventType event.Type, contentJSON interface{}, extra ...mautrix.ReqSendEvent)) *MockAPIClient_SendMessageEvent_Call {
|
||||||
_c.Call.Run(func(args mock.Arguments) {
|
_c.Call.Run(func(args mock.Arguments) {
|
||||||
variadicArgs := make([]mautrix.ReqSendEvent, len(args)-4)
|
variadicArgs := make([]mautrix.ReqSendEvent, len(args)-4)
|
||||||
for i, a := range args[4:] {
|
for i, a := range args[4:] {
|
||||||
@ -92,23 +92,23 @@ func (_c *MockMautrixClient_SendMessageEvent_Call) Run(run func(ctx context.Cont
|
|||||||
return _c
|
return _c
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_c *MockMautrixClient_SendMessageEvent_Call) Return(resp *mautrix.RespSendEvent, err error) *MockMautrixClient_SendMessageEvent_Call {
|
func (_c *MockAPIClient_SendMessageEvent_Call) Return(resp *mautrix.RespSendEvent, err error) *MockAPIClient_SendMessageEvent_Call {
|
||||||
_c.Call.Return(resp, err)
|
_c.Call.Return(resp, err)
|
||||||
return _c
|
return _c
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_c *MockMautrixClient_SendMessageEvent_Call) RunAndReturn(run func(context.Context, id.RoomID, event.Type, interface{}, ...mautrix.ReqSendEvent) (*mautrix.RespSendEvent, error)) *MockMautrixClient_SendMessageEvent_Call {
|
func (_c *MockAPIClient_SendMessageEvent_Call) RunAndReturn(run func(context.Context, id.RoomID, event.Type, interface{}, ...mautrix.ReqSendEvent) (*mautrix.RespSendEvent, error)) *MockAPIClient_SendMessageEvent_Call {
|
||||||
_c.Call.Return(run)
|
_c.Call.Return(run)
|
||||||
return _c
|
return _c
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewMockMautrixClient creates a new instance of MockMautrixClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
|
// NewMockAPIClient creates a new instance of MockAPIClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
|
||||||
// The first argument is typically a *testing.T value.
|
// The first argument is typically a *testing.T value.
|
||||||
func NewMockMautrixClient(t interface {
|
func NewMockAPIClient(t interface {
|
||||||
mock.TestingT
|
mock.TestingT
|
||||||
Cleanup(func())
|
Cleanup(func())
|
||||||
}) *MockMautrixClient {
|
}) *MockAPIClient {
|
||||||
mock := &MockMautrixClient{}
|
mock := &MockAPIClient{}
|
||||||
mock.Mock.Test(t)
|
mock.Mock.Test(t)
|
||||||
|
|
||||||
t.Cleanup(func() { mock.AssertExpectations(t) })
|
t.Cleanup(func() { mock.AssertExpectations(t) })
|
@ -1,4 +1,4 @@
|
|||||||
package plugin
|
package matrix
|
||||||
|
|
||||||
import "strings"
|
import "strings"
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package plugin
|
package matrix
|
||||||
|
|
||||||
import "testing"
|
import "testing"
|
||||||
|
|
@ -12,9 +12,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
|
"github.com/thegeeklab/wp-matrix/matrix"
|
||||||
"github.com/thegeeklab/wp-plugin-go/v2/template"
|
"github.com/thegeeklab/wp-plugin-go/v2/template"
|
||||||
"maunium.net/go/mautrix"
|
|
||||||
"maunium.net/go/mautrix/id"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var ErrAuthSourceNotSet = errors.New("either username and password or userid and accesstoken are required")
|
var ErrAuthSourceNotSet = errors.New("either username and password or userid and accesstoken are required")
|
||||||
@ -44,44 +43,26 @@ func (p *Plugin) Validate() error {
|
|||||||
|
|
||||||
// Execute provides the implementation of the plugin.
|
// Execute provides the implementation of the plugin.
|
||||||
func (p *Plugin) Execute() error {
|
func (p *Plugin) Execute() error {
|
||||||
muid := id.NewUserID(EnsurePrefix("@", p.Settings.UserID), p.Settings.Homeserver)
|
|
||||||
|
|
||||||
matrix, err := mautrix.NewClient(p.Settings.Homeserver, muid, p.Settings.AccessToken)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to initialize client: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if p.Settings.UserID == "" || p.Settings.AccessToken == "" {
|
|
||||||
_, err := matrix.Login(
|
|
||||||
p.Network.Context,
|
|
||||||
&mautrix.ReqLogin{
|
|
||||||
Type: "m.login.password",
|
|
||||||
Identifier: mautrix.UserIdentifier{Type: mautrix.IdentifierTypeUser, User: p.Settings.Username},
|
|
||||||
Password: p.Settings.Password,
|
|
||||||
InitialDeviceDisplayName: "Woodpecker CI",
|
|
||||||
StoreCredentials: true,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to authenticate user: %w", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Info().Msg("logged in successfully")
|
|
||||||
|
|
||||||
joinResp, err := matrix.JoinRoom(p.Network.Context, EnsurePrefix("!", p.Settings.RoomID), "", nil)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to join room: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
msg, err := p.CreateMessage()
|
msg, err := p.CreateMessage()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create message: %w", err)
|
return fmt.Errorf("failed to create message: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
client := NewMatrixClient(matrix)
|
client, err := matrix.NewClient(
|
||||||
client.Message.Opt = MatrixMessageOpt{
|
p.Network.Context,
|
||||||
RoomID: joinResp.RoomID,
|
p.Settings.Homeserver,
|
||||||
|
p.Settings.RoomID,
|
||||||
|
p.Settings.UserID,
|
||||||
|
p.Settings.AccessToken,
|
||||||
|
p.Settings.Username,
|
||||||
|
p.Settings.Password,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to initialize client: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
client.Message.Opt = matrix.MessageOptions{
|
||||||
|
RoomID: client.Message.Opt.RoomID,
|
||||||
Message: msg,
|
Message: msg,
|
||||||
TemplateUnsafe: p.Settings.TemplateUnsafe,
|
TemplateUnsafe: p.Settings.TemplateUnsafe,
|
||||||
}
|
}
|
||||||
|
@ -1,62 +0,0 @@
|
|||||||
package plugin
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/microcosm-cc/bluemonday"
|
|
||||||
"maunium.net/go/mautrix"
|
|
||||||
"maunium.net/go/mautrix/event"
|
|
||||||
"maunium.net/go/mautrix/format"
|
|
||||||
"maunium.net/go/mautrix/id"
|
|
||||||
)
|
|
||||||
|
|
||||||
//nolint:lll
|
|
||||||
type MautrixClient interface {
|
|
||||||
SendMessageEvent(ctx context.Context, roomID id.RoomID, eventType event.Type, contentJSON interface{}, extra ...mautrix.ReqSendEvent) (resp *mautrix.RespSendEvent, err error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type MatrixClient struct {
|
|
||||||
client MautrixClient
|
|
||||||
Message *MatrixMessage
|
|
||||||
}
|
|
||||||
|
|
||||||
type MatrixMessage struct {
|
|
||||||
client MautrixClient
|
|
||||||
Opt MatrixMessageOpt
|
|
||||||
}
|
|
||||||
|
|
||||||
type MatrixMessageOpt struct {
|
|
||||||
RoomID id.RoomID
|
|
||||||
Message string
|
|
||||||
TemplateUnsafe bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewMatrixClient creates a new MatrixClient instance with the provided mautrix.Client.
|
|
||||||
func NewMatrixClient(client *mautrix.Client) *MatrixClient {
|
|
||||||
return &MatrixClient{
|
|
||||||
client: client,
|
|
||||||
Message: &MatrixMessage{
|
|
||||||
client: client,
|
|
||||||
Opt: MatrixMessageOpt{},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send sends a message to the specified room. It sanitizes the message content
|
|
||||||
// to remove potentially unsafe HTML.
|
|
||||||
func (m *MatrixMessage) Send(ctx context.Context) error {
|
|
||||||
content := format.RenderMarkdown(m.Opt.Message, true, m.Opt.TemplateUnsafe)
|
|
||||||
|
|
||||||
if content.FormattedBody != "" {
|
|
||||||
content.Body = format.HTMLToMarkdown(bluemonday.UGCPolicy().Sanitize(content.FormattedBody))
|
|
||||||
content.FormattedBody = bluemonday.UGCPolicy().Sanitize(content.FormattedBody)
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := m.client.SendMessageEvent(ctx, m.Opt.RoomID, event.EventMessage, content)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to send message: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
@ -13,7 +13,6 @@ import (
|
|||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:generate mockery
|
|
||||||
//go:generate go run ../internal/doc/main.go -output=../docs/data/data-raw.yaml
|
//go:generate go run ../internal/doc/main.go -output=../docs/data/data-raw.yaml
|
||||||
|
|
||||||
//nolint:lll
|
//nolint:lll
|
||||||
|
Loading…
Reference in New Issue
Block a user