Browse Source

Replace mautrix.Client usage with BotClient for all services to use the

e2ee-enabled client

Signed-off-by: Nikos Filippakis <me@nfil.dev>
pull/324/head
Nikos Filippakis 4 years ago
parent
commit
4bc4f3a4cf
No known key found for this signature in database GPG Key ID: 7110E4356101F017
  1. 3
      api/handlers/service.go
  2. 23
      clients/bot_client.go
  3. 34
      clients/clients.go
  4. 4
      clients/clients_test.go
  5. 4
      go.mod
  6. 6
      go.sum
  7. 8
      services/alertmanager/alertmanager.go
  8. 2
      services/alertmanager/alertmanager_test.go
  9. 3
      services/echo/echo.go
  10. 5
      services/giphy/giphy.go
  11. 7
      services/github/github.go
  12. 7
      services/github/github_webhook.go
  13. 6
      services/google/google.go
  14. 5
      services/guggy/guggy.go
  15. 5
      services/imgur/imgur.go
  16. 9
      services/jira/jira.go
  17. 10
      services/rssbot/rssbot.go
  18. 6
      services/slackapi/slackapi.go
  19. 8
      services/travisci/travisci.go
  20. 5
      services/wikipedia/wikipedia.go
  21. 30
      types/service.go

3
api/handlers/service.go

@ -16,7 +16,6 @@ import (
"github.com/matrix-org/go-neb/types"
"github.com/matrix-org/util"
log "github.com/sirupsen/logrus"
"maunium.net/go/mautrix"
)
// ConfigureService represents an HTTP handler which can process /admin/configureService requests.
@ -225,7 +224,7 @@ func (h *GetService) OnIncomingRequest(req *http.Request) util.JSONResponse {
}
}
func checkClientForService(service types.Service, client *mautrix.Client) error {
func checkClientForService(service types.Service, client *clients.BotClient) error {
// If there are any commands or expansions for this Service then the service user ID
// MUST be a syncing client or else the Service will never get the incoming command/expansion!
cmds := service.Commands(client)

23
clients/bot_client.go

@ -14,8 +14,8 @@ import (
// It can be used for sending messages and retrieving information about the rooms that
// the client has joined.
type BotClient struct {
*mautrix.Client
config api.ClientConfig
client *mautrix.Client
olmMachine *crypto.OlmMachine
stateStore *NebStateStore
}
@ -68,34 +68,31 @@ func (botClient *BotClient) DecryptMegolmEvent(evt *mevt.Event) (*mevt.Event, er
// SendMessageEvent sends the given content to the given room ID using this BotClient as a message event.
// If the target room has enabled encryption, a megolm session is created if one doesn't already exist
// and the message is sent after being encrypted.
func (botClient *BotClient) SendMessageEvent(content interface{}, roomID id.RoomID) error {
evtType := mevt.EventMessage
func (botClient *BotClient) SendMessageEvent(roomID id.RoomID, evtType mevt.Type, content interface{},
extra ...mautrix.ReqSendEvent) (*mautrix.RespSendEvent, error) {
olmMachine := botClient.olmMachine
if olmMachine.StateStore.IsEncrypted(roomID) {
// Check if there is already a megolm session
if sess, err := olmMachine.CryptoStore.GetOutboundGroupSession(roomID); err != nil {
return err
return nil, err
} else if sess == nil || sess.Expired() || !sess.Shared {
// No error but valid, shared session does not exist
memberIDs, err := botClient.stateStore.GetJoinedMembers(roomID)
if err != nil {
return err
return nil, err
}
// Share group session with room members
if err = olmMachine.ShareGroupSession(roomID, memberIDs); err != nil {
return err
return nil, err
}
}
msgContent := mevt.Content{Parsed: content}
enc, err := olmMachine.EncryptMegolmEvent(roomID, mevt.EventMessage, msgContent)
enc, err := olmMachine.EncryptMegolmEvent(roomID, mevt.EventMessage, content)
if err != nil {
return err
return nil, err
}
content = enc
evtType = mevt.EventEncrypted
}
if _, err := botClient.client.SendMessageEvent(roomID, evtType, content); err != nil {
return err
}
return nil
return botClient.Client.SendMessageEvent(roomID, evtType, content, extra...)
}

34
clients/clients.go

@ -40,13 +40,13 @@ func New(db database.Storer, cli *http.Client) *Clients {
}
// Client gets a client for the userID
func (c *Clients) Client(userID id.UserID) (*mautrix.Client, error) {
func (c *Clients) Client(userID id.UserID) (*BotClient, error) {
entry := c.getClient(userID)
if entry.client != nil {
return entry.client, nil
if entry.Client != nil {
return &entry, nil
}
entry, err := c.loadClientFromDB(userID)
return entry.client, err
return &entry, err
}
// Update updates the config for a matrix client
@ -88,7 +88,7 @@ func (c *Clients) loadClientFromDB(userID id.UserID) (entry BotClient, err error
defer c.dbMutex.Unlock()
entry = c.getClient(userID)
if entry.client != nil {
if entry.Client != nil {
return
}
@ -112,7 +112,7 @@ func (c *Clients) updateClientInDB(newConfig api.ClientConfig) (new, old BotClie
defer c.dbMutex.Unlock()
old = c.getClient(newConfig.UserID)
if old.client != nil && old.config == newConfig {
if old.Client != nil && old.config == newConfig {
// Already have a client with that config.
new = old
return
@ -126,7 +126,7 @@ func (c *Clients) updateClientInDB(newConfig api.ClientConfig) (new, old BotClie
// set the new display name if they differ
if old.config.DisplayName != new.config.DisplayName {
if err := new.client.SetDisplayName(new.config.DisplayName); err != nil {
if err := new.SetDisplayName(new.config.DisplayName); err != nil {
// whine about it but don't stop: this isn't fatal.
log.WithFields(log.Fields{
log.ErrorKey: err,
@ -137,12 +137,12 @@ func (c *Clients) updateClientInDB(newConfig api.ClientConfig) (new, old BotClie
}
if old.config, err = c.db.StoreMatrixClientConfig(new.config); err != nil {
new.client.StopSync()
new.StopSync()
return
}
if old.client != nil {
old.client.StopSync()
if old.Client != nil {
old.Client.StopSync()
return
}
@ -151,12 +151,12 @@ func (c *Clients) updateClientInDB(newConfig api.ClientConfig) (new, old BotClie
}
func (c *Clients) onMessageEvent(botClient *BotClient, event *mevt.Event) {
services, err := c.db.LoadServicesForUser(botClient.client.UserID)
services, err := c.db.LoadServicesForUser(botClient.UserID)
if err != nil {
log.WithFields(log.Fields{
log.ErrorKey: err,
"room_id": event.RoomID,
"service_user_id": botClient.client.UserID,
"service_user_id": botClient.UserID,
}).Warn("Error loading services")
}
@ -191,17 +191,17 @@ func (c *Clients) onMessageEvent(botClient *BotClient, event *mevt.Event) {
args = strings.Split(body[1:], " ")
}
if response := runCommandForService(service.Commands(botClient.client), event, args); response != nil {
if response := runCommandForService(service.Commands(botClient), event, args); response != nil {
responses = append(responses, response)
}
} else { // message isn't a command, it might need expanding
expansions := runExpansionsForService(service.Expansions(botClient.client), event, body)
expansions := runExpansionsForService(service.Expansions(botClient), event, body)
responses = append(responses, expansions...)
}
}
for _, content := range responses {
if err := botClient.SendMessageEvent(content, event.RoomID); err != nil {
if _, err := botClient.SendMessageEvent(event.RoomID, mevt.EventMessage, content); err != nil {
log.WithFields(log.Fields{
"room_id": event.RoomID,
"content": content,
@ -344,7 +344,7 @@ func (c *Clients) initClient(botClient *BotClient) error {
client.Client = c.httpClient
client.DeviceID = config.DeviceID
botClient.client = client
botClient.Client = client
syncer := client.Syncer.(*mautrix.DefaultSyncer)
@ -369,7 +369,7 @@ func (c *Clients) initClient(botClient *BotClient) error {
})
syncer.OnEventType(mevt.Type{Type: "m.room.bot.options", Class: mevt.UnknownEventType}, func(_ mautrix.EventSource, event *mevt.Event) {
c.onBotOptionsEvent(botClient.client, event)
c.onBotOptionsEvent(botClient.Client, event)
})
if config.AutoJoinRooms {

4
clients/clients_test.go

@ -30,7 +30,7 @@ type MockService struct {
commands []types.Command
}
func (s *MockService) Commands(cli *mautrix.Client) []types.Command {
func (s *MockService) Commands(cli types.MatrixClient) []types.Command {
return s.commands
}
@ -76,7 +76,7 @@ func TestCommandParsing(t *testing.T) {
clients := New(&store, cli)
mxCli, _ := mautrix.NewClient("https://someplace.somewhere", "@service:user", "token")
mxCli.Client = cli
botClient := BotClient{client: mxCli}
botClient := BotClient{Client: mxCli}
for _, input := range commandParseTests {
executedCmdArgs = []string{}

4
go.mod

@ -23,7 +23,7 @@ require (
github.com/json-iterator/go v1.1.9 // indirect
github.com/julienschmidt/httprouter v1.2.0 // indirect
github.com/kr/pretty v0.1.0 // indirect
github.com/lib/pq v1.3.0
github.com/lib/pq v1.7.0
github.com/matrix-org/dugong v0.0.0-20180820122854-51a565b5666b
github.com/matrix-org/util v0.0.0-20190711121626-527ce5ddefc7
github.com/mattn/go-shellwords v1.0.10
@ -51,5 +51,5 @@ require (
gopkg.in/alecthomas/kingpin.v2 v2.2.6 // indirect
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
gopkg.in/yaml.v2 v2.3.0
maunium.net/go/mautrix v0.5.0-rc.1
maunium.net/go/mautrix v0.5.5
)

6
go.sum

@ -79,6 +79,8 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kyokomi/emoji v2.2.2+incompatible/go.mod h1:mZ6aGCD7yk8j6QY6KICwnZ2pxoszVseX1DNoGtU2tBA=
github.com/lib/pq v1.3.0 h1:/qkRGz8zljWiDcFvgpwUpwIAPu3r07TDvs3Rws+o/pU=
github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.7.0 h1:h93mCPfUSkaul3Ka/VG8uZdmW1uMHDGxzu0NWHuJmHY=
github.com/lib/pq v1.7.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/lithammer/fuzzysearch v1.1.0/go.mod h1:Bqx4wo8lTOFcJr3ckpY6HA9lEIOO0H5HrkJ5CsN56HQ=
github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/matrix-org/dugong v0.0.0-20180820122854-51a565b5666b h1:xpcmnpfUImRC4O2SAS/dmTcJENDXvGmLUzey76V1R3Q=
@ -94,6 +96,7 @@ github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m
github.com/mattn/go-shellwords v1.0.10 h1:Y7Xqm8piKOO3v10Thp7Z36h4FYFjt5xB//6XvOrs2Gw=
github.com/mattn/go-shellwords v1.0.10/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
github.com/mattn/go-sqlite3 v1.13.0 h1:LnJI81JidiW9r7pS/hXe6cFeO5EXNq7KbfvoJLRI69c=
github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus=
github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U=
github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
@ -208,6 +211,7 @@ golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a h1:GuSPYbZzB5/dcLNCwLQLsg3obCJtX9IJhpXkvY7kzk0=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200505041828-1ed23360d12c h1:zJ0mtu4jCalhKg6Oaukv6iIkb+cOvDrajDH9DH46Q4M=
golang.org/x/net v0.0.0-20200505041828-1ed23360d12c/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200602114024-627f9648deb9 h1:pNX+40auqi2JqRfOP1akLGtYcn15TUbkhwuCO3foqqM=
@ -264,5 +268,7 @@ maunium.net/go/mautrix v0.4.7 h1:jpclbeGcuiHPIWZFZhQJoxgZKP9f+9OLBPtcDNMFV/o=
maunium.net/go/mautrix v0.4.7/go.mod h1:8Y+NqmROJyWYvvP4yPfX9tLM59VCfgE/kcQ0SeX68ho=
maunium.net/go/mautrix v0.5.0-rc.1 h1:Ux2rwQfgf044lXjzCXmaY6VVJPcLioNzdN3okbOVIlg=
maunium.net/go/mautrix v0.5.0-rc.1/go.mod h1:LnkFnB1yjCbb8V+upoEHDGvI/F38NHSTWYCe2RRJgSY=
maunium.net/go/mautrix v0.5.5 h1:e0Pql1FdxoNUudx2oXo1gZHMrqIh5MC72cdXEPIrYLA=
maunium.net/go/mautrix v0.5.5/go.mod h1:FLbMANzwqlsX2Fgm7SDe+E4I3wSa4UxJRKqS5wGkCwA=
maunium.net/go/mauview v0.1.1/go.mod h1:3QBUiuLct9moP1LgDhCGIg0Ovxn38Bd2sGndnUOuj4o=
maunium.net/go/tcell v0.2.0/go.mod h1:9Apcb3lNNS6C6lCqKT9UFp7BTRzHXfWE+/tgufsAMho=

8
services/alertmanager/alertmanager.go

@ -13,7 +13,6 @@ import (
"github.com/matrix-org/go-neb/database"
"github.com/matrix-org/go-neb/types"
log "github.com/sirupsen/logrus"
"maunium.net/go/mautrix"
mevt "maunium.net/go/mautrix/event"
"maunium.net/go/mautrix/id"
)
@ -78,7 +77,7 @@ type WebhookNotification struct {
}
// OnReceiveWebhook receives requests from Alertmanager and sends requests to Matrix as a result.
func (s *Service) OnReceiveWebhook(w http.ResponseWriter, req *http.Request, cli *mautrix.Client) {
func (s *Service) OnReceiveWebhook(w http.ResponseWriter, req *http.Request, cli types.MatrixClient) {
decoder := json.NewDecoder(req.Body)
var notif WebhookNotification
if err := decoder.Decode(&notif); err != nil {
@ -144,7 +143,7 @@ func (s *Service) OnReceiveWebhook(w http.ResponseWriter, req *http.Request, cli
}
// Register makes sure the Config information supplied is valid.
func (s *Service) Register(oldService types.Service, client *mautrix.Client) error {
func (s *Service) Register(oldService types.Service, client types.MatrixClient) error {
s.WebhookURL = s.webhookEndpointURL
for _, templates := range s.Rooms {
// validate that we have at least a plain text template
@ -191,13 +190,12 @@ func (s *Service) PostRegister(oldService types.Service) {
}
}
func (s *Service) joinRooms(client *mautrix.Client) {
func (s *Service) joinRooms(client types.MatrixClient) {
for roomID := range s.Rooms {
if _, err := client.JoinRoom(roomID.String(), "", nil); err != nil {
log.WithFields(log.Fields{
log.ErrorKey: err,
"room_id": roomID,
"user_id": client.UserID,
}).Error("Failed to join room")
}
}

2
services/alertmanager/alertmanager_test.go

@ -93,7 +93,7 @@ func TestNotify(t *testing.T) {
}
}
func buildTestClient(msgs *[]mevt.MessageEventContent) *mautrix.Client {
func buildTestClient(msgs *[]mevt.MessageEventContent) types.MatrixClient {
matrixTrans := struct{ testutils.MockTransport }{}
matrixTrans.RT = func(req *http.Request) (*http.Response, error) {
if !strings.Contains(req.URL.String(), "/send/m.room.message") {

3
services/echo/echo.go

@ -5,7 +5,6 @@ import (
"strings"
"github.com/matrix-org/go-neb/types"
"maunium.net/go/mautrix"
mevt "maunium.net/go/mautrix/event"
"maunium.net/go/mautrix/id"
)
@ -21,7 +20,7 @@ type Service struct {
// Commands supported:
// !echo some message
// Responds with a notice of "some message".
func (e *Service) Commands(cli *mautrix.Client) []types.Command {
func (e *Service) Commands(cli types.MatrixClient) []types.Command {
return []types.Command{
{
Path: []string{"echo"},

5
services/giphy/giphy.go

@ -11,7 +11,6 @@ import (
"github.com/matrix-org/go-neb/types"
log "github.com/sirupsen/logrus"
"maunium.net/go/mautrix"
"maunium.net/go/mautrix/event"
mevt "maunium.net/go/mautrix/event"
"maunium.net/go/mautrix/id"
@ -61,7 +60,7 @@ type Service struct {
// Commands supported:
// !giphy some search query without quotes
// Responds with a suitable GIF into the same room as the command.
func (s *Service) Commands(client *mautrix.Client) []types.Command {
func (s *Service) Commands(client types.MatrixClient) []types.Command {
return []types.Command{
types.Command{
Path: []string{"giphy"},
@ -72,7 +71,7 @@ func (s *Service) Commands(client *mautrix.Client) []types.Command {
}
}
func (s *Service) cmdGiphy(client *mautrix.Client, roomID id.RoomID, userID id.UserID, args []string) (interface{}, error) {
func (s *Service) cmdGiphy(client types.MatrixClient, roomID id.RoomID, userID id.UserID, args []string) (interface{}, error) {
// only 1 arg which is the text to search for.
query := strings.Join(args, " ")
gifResult, err := s.searchGiphy(query)

7
services/github/github.go

@ -22,7 +22,6 @@ import (
"github.com/matrix-org/go-neb/services/github/client"
"github.com/matrix-org/go-neb/types"
log "github.com/sirupsen/logrus"
"maunium.net/go/mautrix"
mevt "maunium.net/go/mautrix/event"
"maunium.net/go/mautrix/id"
)
@ -563,7 +562,7 @@ func (s *Service) expandCommit(roomID id.RoomID, userID id.UserID, owner, repo,
// Responds with the outcome of the issue comment creation request. This command requires
// a Github account to be linked to the Matrix user ID issuing the command. If there
// is no link, it will return a Starter Link instead.
func (s *Service) Commands(cli *mautrix.Client) []types.Command {
func (s *Service) Commands(cli types.MatrixClient) []types.Command {
return []types.Command{
{
Path: []string{"github", "search"},
@ -632,7 +631,7 @@ func (s *Service) Commands(cli *mautrix.Client) []types.Command {
// it will also expand strings of the form:
// #12
// using the default repository.
func (s *Service) Expansions(cli *mautrix.Client) []types.Expansion {
func (s *Service) Expansions(cli types.MatrixClient) []types.Expansion {
return []types.Expansion{
types.Expansion{
Regexp: ownerRepoIssueRegex,
@ -718,7 +717,7 @@ func (s *Service) Expansions(cli *mautrix.Client) []types.Expansion {
}
// Register makes sure that the given realm ID maps to a github realm.
func (s *Service) Register(oldService types.Service, client *mautrix.Client) error {
func (s *Service) Register(oldService types.Service, client types.MatrixClient) error {
if s.RealmID == "" {
return fmt.Errorf("RealmID is required")
}

7
services/github/github_webhook.go

@ -13,7 +13,6 @@ import (
"github.com/matrix-org/go-neb/services/github/webhook"
"github.com/matrix-org/go-neb/types"
log "github.com/sirupsen/logrus"
"maunium.net/go/mautrix"
"maunium.net/go/mautrix/event"
"maunium.net/go/mautrix/id"
)
@ -82,7 +81,7 @@ type WebhookService struct {
//
// If the "owner/repo" string doesn't exist in this Service config, then the webhook will be deleted from
// Github.
func (s *WebhookService) OnReceiveWebhook(w http.ResponseWriter, req *http.Request, cli *mautrix.Client) {
func (s *WebhookService) OnReceiveWebhook(w http.ResponseWriter, req *http.Request, cli types.MatrixClient) {
evType, repo, msg, err := webhook.OnReceiveRequest(req, s.SecretToken)
if err != nil {
w.WriteHeader(err.Code)
@ -146,7 +145,7 @@ func (s *WebhookService) OnReceiveWebhook(w http.ResponseWriter, req *http.Reque
//
// Hooks can get out of sync if a user manually deletes a hook in the Github UI. In this case, toggling the repo configuration will
// force NEB to recreate the hook.
func (s *WebhookService) Register(oldService types.Service, client *mautrix.Client) error {
func (s *WebhookService) Register(oldService types.Service, client types.MatrixClient) error {
if s.RealmID == "" || s.ClientUserID == "" {
return fmt.Errorf("RealmID and ClientUserID is required")
}
@ -252,7 +251,7 @@ func (s *WebhookService) PostRegister(oldService types.Service) {
}
}
func (s *WebhookService) joinWebhookRooms(client *mautrix.Client) error {
func (s *WebhookService) joinWebhookRooms(client types.MatrixClient) error {
for roomID := range s.Rooms {
if _, err := client.JoinRoom(roomID.String(), "", nil); err != nil {
// TODO: Leave the rooms we successfully joined?

6
services/google/google.go

@ -13,7 +13,6 @@ import (
"github.com/matrix-org/go-neb/types"
log "github.com/sirupsen/logrus"
"maunium.net/go/mautrix"
mevt "maunium.net/go/mautrix/event"
"maunium.net/go/mautrix/id"
)
@ -70,7 +69,7 @@ type Service struct {
// Commands supported:
// !google image some_search_query_without_quotes
// Responds with a suitable image into the same room as the command.
func (s *Service) Commands(client *mautrix.Client) []types.Command {
func (s *Service) Commands(client types.MatrixClient) []types.Command {
return []types.Command{
{
Path: []string{"google", "image"},
@ -101,7 +100,8 @@ func usageMessage() *mevt.MessageEventContent {
}
}
func (s *Service) cmdGoogleImgSearch(client *mautrix.Client, roomID id.RoomID, userID id.UserID, args []string) (interface{}, error) {
func (s *Service) cmdGoogleImgSearch(client types.MatrixClient, roomID id.RoomID, userID id.UserID,
args []string) (interface{}, error) {
if len(args) < 1 {
return usageMessage(), nil

5
services/guggy/guggy.go

@ -12,7 +12,6 @@ import (
"github.com/matrix-org/go-neb/types"
log "github.com/sirupsen/logrus"
"maunium.net/go/mautrix"
mevt "maunium.net/go/mautrix/event"
"maunium.net/go/mautrix/id"
)
@ -51,7 +50,7 @@ type Service struct {
// Commands supported:
// !guggy some search query without quotes
// Responds with a suitable GIF into the same room as the command.
func (s *Service) Commands(client *mautrix.Client) []types.Command {
func (s *Service) Commands(client types.MatrixClient) []types.Command {
return []types.Command{
{
Path: []string{"guggy"},
@ -61,7 +60,7 @@ func (s *Service) Commands(client *mautrix.Client) []types.Command {
},
}
}
func (s *Service) cmdGuggy(client *mautrix.Client, roomID id.RoomID, userID id.UserID, args []string) (interface{}, error) {
func (s *Service) cmdGuggy(client types.MatrixClient, roomID id.RoomID, userID id.UserID, args []string) (interface{}, error) {
// only 1 arg which is the text to search for.
querySentence := strings.Join(args, " ")
gifResult, err := s.text2gifGuggy(querySentence)

5
services/imgur/imgur.go

@ -12,7 +12,6 @@ import (
"github.com/matrix-org/go-neb/types"
log "github.com/sirupsen/logrus"
"maunium.net/go/mautrix"
mevt "maunium.net/go/mautrix/event"
"maunium.net/go/mautrix/id"
)
@ -116,7 +115,7 @@ type Service struct {
// Commands supported:
// !imgur some_search_query_without_quotes
// Responds with a suitable image into the same room as the command.
func (s *Service) Commands(client *mautrix.Client) []types.Command {
func (s *Service) Commands(client types.MatrixClient) []types.Command {
return []types.Command{
{
Path: []string{"imgur", "help"},
@ -142,7 +141,7 @@ func usageMessage() *mevt.MessageEventContent {
}
// Search Imgur for a relevant image and upload it to matrix
func (s *Service) cmdImgSearch(client *mautrix.Client, roomID id.RoomID, userID id.UserID, args []string) (interface{}, error) {
func (s *Service) cmdImgSearch(client types.MatrixClient, roomID id.RoomID, userID id.UserID, args []string) (interface{}, error) {
// Check for query text
if len(args) < 1 {
return usageMessage(), nil

9
services/jira/jira.go

@ -21,7 +21,6 @@ import (
"github.com/matrix-org/go-neb/services/utils"
"github.com/matrix-org/go-neb/types"
log "github.com/sirupsen/logrus"
"maunium.net/go/mautrix"
mevt "maunium.net/go/mautrix/event"
"maunium.net/go/mautrix/id"
)
@ -76,7 +75,7 @@ type Service struct {
// Register ensures that the given realm IDs are valid JIRA realms and registers webhooks
// with those JIRA endpoints.
func (s *Service) Register(oldService types.Service, client *mautrix.Client) error {
func (s *Service) Register(oldService types.Service, client types.MatrixClient) error {
// We only ever make 1 JIRA webhook which listens for all projects and then filter
// on receive. So we simply need to know if we need to make a webhook or not. We
// need to do this for each unique realm.
@ -242,7 +241,7 @@ func (s *Service) expandIssue(roomID id.RoomID, userID id.UserID, issueKeyGroups
// same project key, which project is chosen is undefined. If there
// is no JIRA account linked to the Matrix user ID, it will return a Starter Link
// if there is a known public project with that project key.
func (s *Service) Commands(cli *mautrix.Client) []types.Command {
func (s *Service) Commands(cli types.MatrixClient) []types.Command {
return []types.Command{
types.Command{
Path: []string{"jira", "create"},
@ -259,7 +258,7 @@ func (s *Service) Commands(cli *mautrix.Client) []types.Command {
// to map the project key to a realm, and subsequently the JIRA endpoint to hit.
// If there are multiple projects with the same project key in the Service Config, one will
// be chosen arbitrarily.
func (s *Service) Expansions(cli *mautrix.Client) []types.Expansion {
func (s *Service) Expansions(cli types.MatrixClient) []types.Expansion {
return []types.Expansion{
{
Regexp: issueKeyRegex,
@ -271,7 +270,7 @@ func (s *Service) Expansions(cli *mautrix.Client) []types.Expansion {
}
// OnReceiveWebhook receives requests from JIRA and possibly sends requests to Matrix as a result.
func (s *Service) OnReceiveWebhook(w http.ResponseWriter, req *http.Request, cli *mautrix.Client) {
func (s *Service) OnReceiveWebhook(w http.ResponseWriter, req *http.Request, cli types.MatrixClient) {
eventProjectKey, event, httpErr := webhook.OnReceiveRequest(req)
if httpErr != nil {
log.Print("Failed to handle JIRA webhook")

10
services/rssbot/rssbot.go

@ -19,7 +19,6 @@ import (
"github.com/mmcdole/gofeed"
"github.com/prometheus/client_golang/prometheus"
log "github.com/sirupsen/logrus"
"maunium.net/go/mautrix"
mevt "maunium.net/go/mautrix/event"
"maunium.net/go/mautrix/id"
)
@ -102,7 +101,7 @@ type Service struct {
}
// Register will check the liveness of each RSS feed given. If all feeds check out okay, no error is returned.
func (s *Service) Register(oldService types.Service, client *mautrix.Client) error {
func (s *Service) Register(oldService types.Service, client types.MatrixClient) error {
if len(s.Feeds) == 0 {
// this is an error UNLESS the old service had some feeds in which case they are deleting us :(
var numOldFeeds int
@ -131,7 +130,7 @@ func (s *Service) Register(oldService types.Service, client *mautrix.Client) err
return nil
}
func (s *Service) joinRooms(client *mautrix.Client) {
func (s *Service) joinRooms(client types.MatrixClient) {
roomSet := make(map[id.RoomID]bool)
for _, feedInfo := range s.Feeds {
for _, roomID := range feedInfo.Rooms {
@ -144,7 +143,6 @@ func (s *Service) joinRooms(client *mautrix.Client) {
log.WithFields(log.Fields{
log.ErrorKey: err,
"room_id": roomID,
"user_id": client.UserID,
}).Error("Failed to join room")
}
}
@ -175,7 +173,7 @@ func (s *Service) PostRegister(oldService types.Service) {
// - Else if there is a Title field, use it as the GUID.
//
// Returns a timestamp representing when this Service should have OnPoll called again.
func (s *Service) OnPoll(cli *mautrix.Client) time.Time {
func (s *Service) OnPoll(cli types.MatrixClient) time.Time {
logger := log.WithFields(log.Fields{
"service_id": s.ServiceID(),
"service_type": s.ServiceType(),
@ -408,7 +406,7 @@ func (s *Service) newItems(feedURL string, allItems []*gofeed.Item) (items []gof
return
}
func (s *Service) sendToRooms(cli *mautrix.Client, feedURL string, feed *gofeed.Feed, item gofeed.Item) error {
func (s *Service) sendToRooms(cli types.MatrixClient, feedURL string, feed *gofeed.Feed, item gofeed.Item) error {
logger := log.WithFields(log.Fields{
"feed_url": feedURL,
"title": item.Title,

6
services/slackapi/slackapi.go

@ -6,7 +6,6 @@ import (
"github.com/matrix-org/go-neb/types"
log "github.com/sirupsen/logrus"
"maunium.net/go/mautrix"
"maunium.net/go/mautrix/event"
"maunium.net/go/mautrix/id"
)
@ -37,7 +36,7 @@ type Service struct {
// to Matrix as a result.
//
// This requires that the WebhookURL is given to an outgoing slack webhook (see https://api.slack.com/outgoing-webhooks)
func (s *Service) OnReceiveWebhook(w http.ResponseWriter, req *http.Request, cli *mautrix.Client) {
func (s *Service) OnReceiveWebhook(w http.ResponseWriter, req *http.Request, cli types.MatrixClient) {
segments := strings.Split(req.URL.Path, "/")
if len(segments) < 2 {
@ -72,13 +71,12 @@ func (s *Service) OnReceiveWebhook(w http.ResponseWriter, req *http.Request, cli
}
// Register joins the configured room and sets the public WebhookURL
func (s *Service) Register(oldService types.Service, client *mautrix.Client) error {
func (s *Service) Register(oldService types.Service, client types.MatrixClient) error {
s.WebhookURL = s.webhookEndpointURL
if _, err := client.JoinRoom(s.RoomID.String(), "", nil); err != nil {
log.WithFields(log.Fields{
log.ErrorKey: err,
"room_id": s.RoomID,
"user_id": client.UserID,
}).Error("Failed to join room")
}
return nil

8
services/travisci/travisci.go

@ -13,7 +13,6 @@ import (
"github.com/matrix-org/go-neb/database"
"github.com/matrix-org/go-neb/types"
log "github.com/sirupsen/logrus"
"maunium.net/go/mautrix"
mevt "maunium.net/go/mautrix/event"
"maunium.net/go/mautrix/id"
)
@ -180,7 +179,7 @@ func outputForTemplate(travisTmpl string, tmpl map[string]string) (out string) {
// webhooks: http://go-neb-endpoint.com/notifications
//
// See https://docs.travis-ci.com/user/notifications#Webhook-notifications for more information.
func (s *Service) OnReceiveWebhook(w http.ResponseWriter, req *http.Request, cli *mautrix.Client) {
func (s *Service) OnReceiveWebhook(w http.ResponseWriter, req *http.Request, cli types.MatrixClient) {
if err := req.ParseForm(); err != nil {
log.WithError(err).Error("Failed to read incoming Travis-CI webhook form")
w.WriteHeader(400)
@ -243,7 +242,7 @@ func (s *Service) OnReceiveWebhook(w http.ResponseWriter, req *http.Request, cli
}
// Register makes sure the Config information supplied is valid.
func (s *Service) Register(oldService types.Service, client *mautrix.Client) error {
func (s *Service) Register(oldService types.Service, client types.MatrixClient) error {
s.WebhookURL = s.webhookEndpointURL
for _, roomData := range s.Rooms {
for repo := range roomData.Repos {
@ -275,13 +274,12 @@ func (s *Service) PostRegister(oldService types.Service) {
}
}
func (s *Service) joinRooms(client *mautrix.Client) {
func (s *Service) joinRooms(client types.MatrixClient) {
for roomID := range s.Rooms {
if _, err := client.JoinRoom(roomID.String(), "", nil); err != nil {
log.WithFields(log.Fields{
log.ErrorKey: err,
"room_id": roomID,
"user_id": client.UserID,
}).Error("Failed to join room")
}
}

5
services/wikipedia/wikipedia.go

@ -12,7 +12,6 @@ import (
"github.com/jaytaylor/html2text"
"github.com/matrix-org/go-neb/types"
log "github.com/sirupsen/logrus"
"maunium.net/go/mautrix"
mevt "maunium.net/go/mautrix/event"
"maunium.net/go/mautrix/id"
)
@ -51,7 +50,7 @@ type Service struct {
// Commands supported:
// !wikipedia some_search_query_without_quotes
// Responds with a suitable article extract and link to the referenced page into the same room as the command.
func (s *Service) Commands(client *mautrix.Client) []types.Command {
func (s *Service) Commands(client types.MatrixClient) []types.Command {
return []types.Command{
{
Path: []string{"wikipedia"},
@ -70,7 +69,7 @@ func usageMessage() *mevt.MessageEventContent {
}
}
func (s *Service) cmdWikipediaSearch(client *mautrix.Client, roomID id.RoomID, userID id.UserID, args []string) (interface{}, error) {
func (s *Service) cmdWikipediaSearch(client types.MatrixClient, roomID id.RoomID, userID id.UserID, args []string) (interface{}, error) {
// Check for query text
if len(args) < 1 {
return usageMessage(), nil

30
types/service.go

@ -9,6 +9,7 @@ import (
"time"
"maunium.net/go/mautrix"
"maunium.net/go/mautrix/event"
"maunium.net/go/mautrix/id"
)
@ -24,7 +25,18 @@ type BotOptions struct {
type Poller interface {
// OnPoll is called when the poller should poll. Return the timestamp when you want to be polled again.
// Return 0 to never be polled again.
OnPoll(client *mautrix.Client) time.Time
OnPoll(client MatrixClient) time.Time
}
// MatrixClient represents an object that can communicate with a Matrix server in certain ways that services require.
type MatrixClient interface {
// Join a room by ID or alias. Content can optionally specify the request body.
JoinRoom(roomIDorAlias, serverName string, content interface{}) (resp *mautrix.RespJoinRoom, err error)
// Send a message event to a room.
SendMessageEvent(roomID id.RoomID, eventType event.Type, contentJSON interface{},
extra ...mautrix.ReqSendEvent) (resp *mautrix.RespSendEvent, err error)
// Upload an HTTP URL.
UploadLink(link string) (*mautrix.RespMediaUpload, error)
}
// A Service is the configuration for a bot service.
@ -35,14 +47,14 @@ type Service interface {
ServiceID() string
// Return the type of service. This string MUST NOT change.
ServiceType() string
Commands(cli *mautrix.Client) []Command
Expansions(cli *mautrix.Client) []Expansion
OnReceiveWebhook(w http.ResponseWriter, req *http.Request, cli *mautrix.Client)
Commands(cli MatrixClient) []Command
Expansions(cli MatrixClient) []Expansion
OnReceiveWebhook(w http.ResponseWriter, req *http.Request, cli MatrixClient)
// A lifecycle function which is invoked when the service is being registered. The old service, if one exists, is provided,
// along with a Client instance for ServiceUserID(). If this function returns an error, the service will not be registered
// or persisted to the database, and the user's request will fail. This can be useful if you depend on external factors
// such as registering webhooks.
Register(oldService Service, client *mautrix.Client) error
Register(oldService Service, client MatrixClient) error
// A lifecycle function which is invoked after the service has been successfully registered and persisted to the database.
// This function is invoked within the critical section for configuring services, guaranteeing that there will not be
// concurrent modifications to this service whilst this function executes. This lifecycle hook should be used to clean
@ -83,23 +95,23 @@ func (s *DefaultService) ServiceType() string {
}
// Commands returns no commands.
func (s *DefaultService) Commands(cli *mautrix.Client) []Command {
func (s *DefaultService) Commands(cli MatrixClient) []Command {
return []Command{}
}
// Expansions returns no expansions.
func (s *DefaultService) Expansions(cli *mautrix.Client) []Expansion {
func (s *DefaultService) Expansions(cli MatrixClient) []Expansion {
return []Expansion{}
}
// Register does nothing and returns no error.
func (s *DefaultService) Register(oldService Service, client *mautrix.Client) error { return nil }
func (s *DefaultService) Register(oldService Service, cli MatrixClient) error { return nil }
// PostRegister does nothing.
func (s *DefaultService) PostRegister(oldService Service) {}
// OnReceiveWebhook does nothing but 200 OK the request.
func (s *DefaultService) OnReceiveWebhook(w http.ResponseWriter, req *http.Request, cli *mautrix.Client) {
func (s *DefaultService) OnReceiveWebhook(w http.ResponseWriter, req *http.Request, cli MatrixClient) {
w.WriteHeader(200) // Do nothing
}

Loading…
Cancel
Save