diff options
author | George Goldberg <george@gberg.me> | 2016-11-03 19:04:01 +0000 |
---|---|---|
committer | Christopher Speller <crspeller@gmail.com> | 2016-11-03 15:04:01 -0400 |
commit | 7d91f179144def7c58cde48a47fc29164930d3a3 (patch) | |
tree | 755ef7be797d807e498e6ff4a7060270085dfc24 /api/slackimport.go | |
parent | e6f8f44f58331303c9d8d1bbe0580edcaf5f6435 (diff) | |
download | chat-7d91f179144def7c58cde48a47fc29164930d3a3.tar.gz chat-7d91f179144def7c58cde48a47fc29164930d3a3.tar.bz2 chat-7d91f179144def7c58cde48a47fc29164930d3a3.zip |
Import Slack bot_message type posts. (#4261)
This includes all messages from integrations, as far as I can tell.
Messages are "owned" by a special user that is deactivated once the
import completes.
Override User Names are only shown where the individual Slack posts have
a username override in them. Ones set centrally through the Slack Web
Hooks administration, or by Slack-official integrations, aren't known so
we can't set them on the imported posts. Same for icons.
The attachment "colors" aren't imported as Mattermost does not appear to
have any equivalent feature.
Fixes PLT-48
Diffstat (limited to 'api/slackimport.go')
-rw-r--r-- | api/slackimport.go | 111 |
1 files changed, 96 insertions, 15 deletions
diff --git a/api/slackimport.go b/api/slackimport.go index af27b0d30..f6ee9fc4c 100644 --- a/api/slackimport.go +++ b/api/slackimport.go @@ -38,16 +38,17 @@ type SlackFile struct { } type SlackPost struct { - User string `json:"user"` - BotId string `json:"bot_id"` - BotUsername string `json:"username"` - Text string `json:"text"` - TimeStamp string `json:"ts"` - Type string `json:"type"` - SubType string `json:"subtype"` - Comment *SlackComment `json:"comment"` - Upload bool `json:"upload"` - File *SlackFile `json:"file"` + User string `json:"user"` + BotId string `json:"bot_id"` + BotUsername string `json:"username"` + Text string `json:"text"` + TimeStamp string `json:"ts"` + Type string `json:"type"` + SubType string `json:"subtype"` + Comment *SlackComment `json:"comment"` + Upload bool `json:"upload"` + File *SlackFile `json:"file"` + Attachments []SlackAttachment `json:"attachments"` } type SlackComment struct { @@ -55,6 +56,13 @@ type SlackComment struct { Comment string `json:"comment"` } +type SlackAttachment struct { + Id int `json:"id"` + Text string `json:"text"` + Pretext string `json:"pretext"` + Fields []map[string]interface{} `json:"fields"` +} + func SlackConvertTimeStamp(ts string) int64 { timeString := strings.SplitN(ts, ".", 2)[0] @@ -167,7 +175,37 @@ func SlackAddUsers(teamId string, slackusers []SlackUser, log *bytes.Buffer) map return addedUsers } -func SlackAddPosts(teamId string, channel *model.Channel, posts []SlackPost, users map[string]*model.User, uploads map[string]*zip.File) { +func SlackAddBotUser(teamId string, log *bytes.Buffer) *model.User { + var team *model.Team + if result := <-Srv.Store.Team().Get(teamId); result.Err != nil { + log.WriteString(utils.T("api.slackimport.slack_import.team_fail")) + return nil + } else { + team = result.Data.(*model.Team) + } + + password := model.NewId() + username := "slackimportuser_" + model.NewId() + email := username + "@localhost" + + botUser := model.User{ + Username: username, + FirstName: "", + LastName: "", + Email: email, + Password: password, + } + + if mUser := ImportUser(team, &botUser); mUser != nil { + log.WriteString(utils.T("api.slackimport.slack_add_bot_user.email_pwd", map[string]interface{}{"Email": botUser.Email, "Password": password})) + return mUser + } else { + log.WriteString(utils.T("api.slackimport.slack_add_bot_user.unable_import", map[string]interface{}{"Username": username})) + return nil + } +} + +func SlackAddPosts(teamId string, channel *model.Channel, posts []SlackPost, users map[string]*model.User, uploads map[string]*zip.File, botUser *model.User) { for _, sPost := range posts { switch { case sPost.Type == "message" && (sPost.SubType == "" || sPost.SubType == "file_share"): @@ -216,7 +254,37 @@ func SlackAddPosts(teamId string, channel *model.Channel, posts []SlackPost, use } ImportPost(&newPost) case sPost.Type == "message" && sPost.SubType == "bot_message": - continue + if botUser == nil { + l4g.Warn(utils.T("api.slackimport.slack_add_posts.bot_user_no_exists.warn")) + continue + } else if sPost.BotId == "" { + l4g.Warn(utils.T("api.slackimport.slack_add_posts.no_bot_id.warn")) + continue + } + + props := make(model.StringInterface) + props["override_username"] = sPost.BotUsername + if len(sPost.Attachments) > 0 { + var mAttachments []interface{} + for _, attachment := range sPost.Attachments { + mAttachments = append(mAttachments, map[string]interface{}{ + "text": attachment.Text, + "pretext": attachment.Pretext, + "fields": attachment.Fields, + }) + } + props["attachments"] = mAttachments + } + + post := &model.Post{ + UserId: botUser.Id, + ChannelId: channel.Id, + CreateAt: SlackConvertTimeStamp(sPost.TimeStamp), + Message: sPost.Text, + Type: model.POST_SLACK_ATTACHMENT, + } + + ImportIncomingWebhookPost(post, props) case sPost.Type == "message" && (sPost.SubType == "channel_join" || sPost.SubType == "channel_leave"): if sPost.User == "" { l4g.Debug(utils.T("api.slackimport.slack_add_posts.msg_no_usr.debug")) @@ -281,6 +349,13 @@ func SlackUploadFile(sPost SlackPost, uploads map[string]*zip.File, teamId strin } } +func deactivateSlackBotUser(user *model.User) { + _, err := UpdateActive(user, false) + if err != nil { + l4g.Warn(utils.T("api.slackimport.slack_deactivate_bot_user.failed_to_deactivate", err)) + } +} + func addSlackUsersToChannel(members []string, users map[string]*model.User, channel *model.Channel, log *bytes.Buffer) { for _, member := range members { if user, ok := users[member]; !ok { @@ -293,7 +368,7 @@ func addSlackUsersToChannel(members []string, users map[string]*model.User, chan } } -func SlackAddChannels(teamId string, slackchannels []SlackChannel, posts map[string][]SlackPost, users map[string]*model.User, uploads map[string]*zip.File, log *bytes.Buffer) map[string]*model.Channel { +func SlackAddChannels(teamId string, slackchannels []SlackChannel, posts map[string][]SlackPost, users map[string]*model.User, uploads map[string]*zip.File, botUser *model.User, log *bytes.Buffer) map[string]*model.Channel { // Write Header log.WriteString(utils.T("api.slackimport.slack_add_channels.added")) log.WriteString("=================\r\n\r\n") @@ -323,7 +398,7 @@ func SlackAddChannels(teamId string, slackchannels []SlackChannel, posts map[str addSlackUsersToChannel(sChannel.Members, users, mChannel, log) log.WriteString(newChannel.DisplayName + "\r\n") addedChannels[sChannel.Id] = mChannel - SlackAddPosts(teamId, mChannel, posts[sChannel.Name], users, uploads) + SlackAddPosts(teamId, mChannel, posts[sChannel.Name], users, uploads, botUser) } return addedChannels @@ -424,7 +499,13 @@ func SlackImport(fileData multipart.File, fileSize int64, teamID string) (*model posts = SlackConvertChannelMentions(channels, posts) addedUsers := SlackAddUsers(teamID, users, log) - SlackAddChannels(teamID, channels, posts, addedUsers, uploads, log) + botUser := SlackAddBotUser(teamID, log) + + SlackAddChannels(teamID, channels, posts, addedUsers, uploads, botUser, log) + + if botUser != nil { + deactivateSlackBotUser(botUser) + } log.WriteString(utils.T("api.slackimport.slack_import.notes")) log.WriteString("=======\r\n\r\n") |