Files
mostlymatter/plugin/helpers_channels.go
Ankit R. Gadiya 5aa24aedc8 MM-16809: Added EnsureChannel Helper (#11852)
This PR adds EnsureChannel helper analogous to EnsureBot helper which creates a new channel if not exists and update the meta data of the channel if exists. Also, it will throw error
if the type of existing channel do not match the type of new channel.
2019-09-03 22:18:08 +02:00

112 строки
3.4 KiB
Go

// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
package plugin
import (
"github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/utils"
"github.com/pkg/errors"
)
func (p *HelpersImpl) EnsureChannel(channel *model.Channel) (retChannelId string, retErr error) {
// Must provide a channel with a name and teadId
if channel == nil || len(channel.Name) < 1 || len(channel.TeamId) < 1 {
return "", errors.New("passed a bad channel, nil or no name or no team id")
}
// If we fail for any reason, this could be a race between creation of channel and
// retrieval from another EnsureChannel. Just try the basic retrieve existing again.
defer func() {
if retChannelId == "" || retErr != nil {
var err error
var channelIdBytes []byte
err = utils.ProgressiveRetry(func() error {
channelIdBytes, err = p.API.KVGet(CHANNEL_KEY)
if err != nil {
return err
}
return nil
})
if err == nil && channelIdBytes != nil {
retChannelId = string(channelIdBytes)
retErr = nil
}
}
}()
// Fetch channel ID from key value store
channelIdBytes, kvGetErr := p.API.KVGet(CHANNEL_KEY)
if kvGetErr != nil {
// Failed to retrive the value of channel
return "", errors.Wrap(kvGetErr, "failed to get channel ID")
}
var existingChannel *model.Channel
var channelGetErr *model.AppError
// If channel ID exists, get existing channel by ID else get it by Name
if channelIdBytes != nil {
existingChannel, channelGetErr = p.API.GetChannel(string(channelIdBytes))
if channelGetErr != nil {
return "", errors.Wrap(channelGetErr, "failed to get channel by ID")
}
} else {
existingChannel, channelGetErr = p.API.GetChannelByName(channel.TeamId, channel.Name, false)
if channelGetErr != nil {
return "", errors.Wrap(channelGetErr, "failed to get channel by name")
}
}
// If channel exists, update the metadata
if existingChannel != nil {
return updateChannel(p, existingChannel, channel)
}
// Create a new channel
createdChannel, createChannelErr := p.API.CreateChannel(channel)
if createChannelErr != nil {
return "", errors.Wrap(createChannelErr, "failed to create channel")
}
// Set the new channel id in key value store
if kvSetErr := p.API.KVSet(CHANNEL_KEY, []byte(createdChannel.Id)); kvSetErr != nil {
p.API.LogWarn("Failed to set created channel id.", "channelid", createdChannel.Id, "err", kvSetErr)
}
return createdChannel.Id, nil
}
func updateChannel(p *HelpersImpl, existing *model.Channel, new *model.Channel) (string, error) {
// Update metadata of the channel
if updateErr := updateChannelMeta(existing, new); updateErr != nil {
return "", errors.Wrap(updateErr, "Failed to update the metadata of existing channel")
}
// Send the updates to API
updatedChannel, channelUpdateErr := p.API.UpdateChannel(existing)
if channelUpdateErr != nil {
return "", errors.Wrap(channelUpdateErr, "Failed to update the existing channel")
}
// Channel exists!
return updatedChannel.Id, nil
}
func updateChannelMeta(existing *model.Channel, new *model.Channel) error {
// Check if channels are of different types
if existing.Type != new.Type {
return errors.New("Channel type cannot be updated")
}
// Update metadata of channel
existing.Name = new.Name
existing.DisplayName = new.DisplayName
existing.Purpose = new.Purpose
existing.Header = new.Header
return nil
}