summaryrefslogtreecommitdiffstats
path: root/bridge/rocketchat/handlers.go
blob: 03b66eac0741ed5036f71f88f65882cb854b2599 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
package brocketchat

import (
	"fmt"

	"github.com/42wim/matterbridge/bridge/config"
	"github.com/42wim/matterbridge/bridge/helper"
	"github.com/matterbridge/Rocket.Chat.Go.SDK/models"
)

func (b *Brocketchat) handleRocket() {
	messages := make(chan *config.Message)
	if b.GetString("WebhookBindAddress") != "" {
		b.Log.Debugf("Choosing webhooks based receiving")
		go b.handleRocketHook(messages)
	} else {
		b.Log.Debugf("Choosing login/password based receiving")
		go b.handleRocketClient(messages)
	}
	for message := range messages {
		message.Account = b.Account
		b.Log.Debugf("<= Sending message from %s on %s to gateway", message.Username, b.Account)
		b.Log.Debugf("<= Message is %#v", message)
		b.Remote <- *message
	}
}

func (b *Brocketchat) handleRocketHook(messages chan *config.Message) {
	for {
		message := b.rh.Receive()
		b.Log.Debugf("Receiving from rockethook %#v", message)
		// do not loop
		if message.UserName == b.GetString("Nick") {
			continue
		}
		messages <- &config.Message{
			UserID:   message.UserID,
			Username: message.UserName,
			Text:     message.Text,
			Channel:  message.ChannelName,
		}
	}
}

func (b *Brocketchat) handleStatusEvent(ev models.Message, rmsg *config.Message) bool {
	switch ev.Type {
	case "":
		// this is a normal message, no processing needed
		// return true so the message is not dropped
		return true
	case sUserJoined, sUserLeft:
		rmsg.Event = config.EventJoinLeave
		return true
	case sRoomChangedTopic:
		rmsg.Event = config.EventTopicChange
		return true
	}
	b.Log.Debugf("Dropping message with unknown type: %s", ev.Type)
	return false
}

func (b *Brocketchat) handleRocketClient(messages chan *config.Message) {
	for message := range b.messageChan {
		message := message
		// skip messages with same ID, apparently messages get duplicated for an unknown reason
		if _, ok := b.cache.Get(message.ID); ok {
			continue
		}
		b.cache.Add(message.ID, true)
		b.Log.Debugf("message %#v", message)
		m := message
		if b.skipMessage(&m) {
			b.Log.Debugf("Skipped message: %#v", message)
			continue
		}

		rmsg := &config.Message{Text: message.Msg,
			Username: message.User.UserName,
			Channel:  b.getChannelName(message.RoomID),
			Account:  b.Account,
			UserID:   message.User.ID,
			ID:       message.ID,
			Extra:    make(map[string][]interface{}),
		}

		b.handleAttachments(&message, rmsg)

		// handleStatusEvent returns false if the message should be dropped
		// in that case it is probably some modification to the channel we do not want to relay
		if b.handleStatusEvent(m, rmsg) {
			messages <- rmsg
		}
	}
}

func (b *Brocketchat) handleAttachments(message *models.Message, rmsg *config.Message) {
	if rmsg.Text == "" {
		for _, attachment := range message.Attachments {
			if attachment.Title != "" {
				rmsg.Text = attachment.Title + "\n"
			}
			if attachment.Title != "" && attachment.Text != "" {
				rmsg.Text += "\n"
			}
			if attachment.Text != "" {
				rmsg.Text += attachment.Text
			}
		}
	}

	for i := range message.Attachments {
		if err := b.handleDownloadFile(rmsg, &message.Attachments[i]); err != nil {
			b.Log.Errorf("Could not download incoming file: %#v", err)
		}
	}
}

func (b *Brocketchat) handleDownloadFile(rmsg *config.Message, file *models.Attachment) error {
	downloadURL := b.GetString("server") + file.TitleLink
	data, err := helper.DownloadFileAuthRocket(downloadURL, b.user.Token, b.user.ID)
	if err != nil {
		return fmt.Errorf("download %s failed %#v", downloadURL, err)
	}
	helper.HandleDownloadData(b.Log, rmsg, file.Title, rmsg.Text, downloadURL, data, b.General)
	return nil
}

func (b *Brocketchat) handleUploadFile(msg *config.Message) error {
	for _, f := range msg.Extra["file"] {
		fi := f.(config.FileInfo)
		if err := b.uploadFile(&fi, b.getChannelID(msg.Channel)); err != nil {
			return err
		}
	}
	return nil
}