1package matterclient
2
3import (
4	"strings"
5
6	"github.com/mattermost/mattermost-server/v5/model"
7)
8
9func (m *MMClient) parseActionPost(rmsg *Message) {
10	// add post to cache, if it already exists don't relay this again.
11	// this should fix reposts
12	if ok, _ := m.lruCache.ContainsOrAdd(digestString(rmsg.Raw.Data["post"].(string)), true); ok {
13		m.logger.Debugf("message %#v in cache, not processing again", rmsg.Raw.Data["post"].(string))
14		rmsg.Text = ""
15		return
16	}
17	data := model.PostFromJson(strings.NewReader(rmsg.Raw.Data["post"].(string)))
18	// we don't have the user, refresh the userlist
19	if m.GetUser(data.UserId) == nil {
20		m.logger.Infof("User '%v' is not known, ignoring message '%#v'",
21			data.UserId, data)
22		return
23	}
24	rmsg.Username = m.GetUserName(data.UserId)
25	rmsg.Channel = m.GetChannelName(data.ChannelId)
26	rmsg.UserID = data.UserId
27	rmsg.Type = data.Type
28	teamid, _ := rmsg.Raw.Data["team_id"].(string)
29	// edit messsages have no team_id for some reason
30	if teamid == "" {
31		// we can find the team_id from the channelid
32		teamid = m.GetChannelTeamId(data.ChannelId)
33		rmsg.Raw.Data["team_id"] = teamid
34	}
35	if teamid != "" {
36		rmsg.Team = m.GetTeamName(teamid)
37	}
38	// direct message
39	if rmsg.Raw.Data["channel_type"] == "D" {
40		rmsg.Channel = m.GetUser(data.UserId).Username
41	}
42	rmsg.Text = data.Message
43	rmsg.Post = data
44}
45
46func (m *MMClient) parseMessage(rmsg *Message) {
47	switch rmsg.Raw.Event {
48	case model.WEBSOCKET_EVENT_POSTED, model.WEBSOCKET_EVENT_POST_EDITED, model.WEBSOCKET_EVENT_POST_DELETED:
49		m.parseActionPost(rmsg)
50	case "user_updated":
51		user := rmsg.Raw.Data["user"].(map[string]interface{})
52		if _, ok := user["id"].(string); ok {
53			m.UpdateUser(user["id"].(string))
54		}
55	case "group_added":
56		if err := m.UpdateChannels(); err != nil {
57			m.logger.Errorf("failed to update channels: %#v", err)
58		}
59		/*
60			case model.ACTION_USER_REMOVED:
61				m.handleWsActionUserRemoved(&rmsg)
62			case model.ACTION_USER_ADDED:
63				m.handleWsActionUserAdded(&rmsg)
64		*/
65	}
66}
67
68func (m *MMClient) parseResponse(rmsg model.WebSocketResponse) {
69	if rmsg.Data != nil {
70		// ping reply
71		if rmsg.Data["text"].(string) == "pong" {
72			m.WsPingChan <- &rmsg
73		}
74	}
75}
76
77func (m *MMClient) DeleteMessage(postId string) error { //nolint:golint
78	_, resp := m.Client.DeletePost(postId)
79	if resp.Error != nil {
80		return resp.Error
81	}
82	return nil
83}
84
85func (m *MMClient) EditMessage(postId string, text string) (string, error) { //nolint:golint
86	post := &model.Post{Message: text, Id: postId}
87	res, resp := m.Client.UpdatePost(postId, post)
88	if resp.Error != nil {
89		return "", resp.Error
90	}
91	return res.Id, nil
92}
93
94func (m *MMClient) GetFileLinks(filenames []string) []string {
95	uriScheme := "https://"
96	if m.NoTLS {
97		uriScheme = "http://"
98	}
99
100	var output []string
101	for _, f := range filenames {
102		res, resp := m.Client.GetFileLink(f)
103		if resp.Error != nil {
104			// public links is probably disabled, create the link ourselves
105			output = append(output, uriScheme+m.Credentials.Server+model.API_URL_SUFFIX_V4+"/files/"+f)
106			continue
107		}
108		output = append(output, res)
109	}
110	return output
111}
112
113func (m *MMClient) GetPosts(channelId string, limit int) *model.PostList { //nolint:golint
114	res, resp := m.Client.GetPostsForChannel(channelId, 0, limit, "")
115	if resp.Error != nil {
116		return nil
117	}
118	return res
119}
120
121func (m *MMClient) GetPostsSince(channelId string, time int64) *model.PostList { //nolint:golint
122	res, resp := m.Client.GetPostsSince(channelId, time)
123	if resp.Error != nil {
124		return nil
125	}
126	return res
127}
128
129func (m *MMClient) GetPublicLink(filename string) string {
130	res, resp := m.Client.GetFileLink(filename)
131	if resp.Error != nil {
132		return ""
133	}
134	return res
135}
136
137func (m *MMClient) GetPublicLinks(filenames []string) []string {
138	var output []string
139	for _, f := range filenames {
140		res, resp := m.Client.GetFileLink(f)
141		if resp.Error != nil {
142			continue
143		}
144		output = append(output, res)
145	}
146	return output
147}
148
149func (m *MMClient) PostMessage(channelId string, text string, rootId string) (string, error) { //nolint:golint
150	post := &model.Post{ChannelId: channelId, Message: text, RootId: rootId}
151	res, resp := m.Client.CreatePost(post)
152	if resp.Error != nil {
153		return "", resp.Error
154	}
155	return res.Id, nil
156}
157
158func (m *MMClient) PostMessageWithFiles(channelId string, text string, rootId string, fileIds []string) (string, error) { //nolint:golint
159	post := &model.Post{ChannelId: channelId, Message: text, RootId: rootId, FileIds: fileIds}
160	res, resp := m.Client.CreatePost(post)
161	if resp.Error != nil {
162		return "", resp.Error
163	}
164	return res.Id, nil
165}
166
167func (m *MMClient) SearchPosts(query string) *model.PostList {
168	res, resp := m.Client.SearchPosts(m.Team.Id, query, false)
169	if resp.Error != nil {
170		return nil
171	}
172	return res
173}
174
175// SendDirectMessage sends a direct message to specified user
176func (m *MMClient) SendDirectMessage(toUserId string, msg string, rootId string) { //nolint:golint
177	m.SendDirectMessageProps(toUserId, msg, rootId, nil)
178}
179
180func (m *MMClient) SendDirectMessageProps(toUserId string, msg string, rootId string, props map[string]interface{}) { //nolint:golint
181	m.logger.Debugf("SendDirectMessage to %s, msg %s", toUserId, msg)
182	// create DM channel (only happens on first message)
183	_, resp := m.Client.CreateDirectChannel(m.User.Id, toUserId)
184	if resp.Error != nil {
185		m.logger.Debugf("SendDirectMessage to %#v failed: %s", toUserId, resp.Error)
186		return
187	}
188	channelName := model.GetDMNameFromIds(toUserId, m.User.Id)
189
190	// update our channels
191	if err := m.UpdateChannels(); err != nil {
192		m.logger.Errorf("failed to update channels: %#v", err)
193	}
194
195	// build & send the message
196	msg = strings.Replace(msg, "\r", "", -1)
197	post := &model.Post{ChannelId: m.GetChannelId(channelName, m.Team.Id), Message: msg, RootId: rootId, Props: props}
198	m.Client.CreatePost(post)
199}
200
201func (m *MMClient) UploadFile(data []byte, channelId string, filename string) (string, error) { //nolint:golint
202	f, resp := m.Client.UploadFile(data, channelId, filename)
203	if resp.Error != nil {
204		return "", resp.Error
205	}
206	return f.FileInfos[0].Id, nil
207}
208