github.com/fretkak/mattermost-mattermost-server@v5.11.1+incompatible/cmd/mattermost/commands/channel.go (about)

     1  // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
     2  // See License.txt for license information.
     3  
     4  package commands
     5  
     6  import (
     7  	"fmt"
     8  
     9  	"github.com/mattermost/mattermost-server/app"
    10  	"github.com/mattermost/mattermost-server/model"
    11  	"github.com/pkg/errors"
    12  	"github.com/spf13/cobra"
    13  )
    14  
    15  var ChannelCmd = &cobra.Command{
    16  	Use:   "channel",
    17  	Short: "Management of channels",
    18  }
    19  
    20  var ChannelCreateCmd = &cobra.Command{
    21  	Use:   "create",
    22  	Short: "Create a channel",
    23  	Long:  `Create a channel.`,
    24  	Example: `  channel create --team myteam --name mynewchannel --display_name "My New Channel"
    25    channel create --team myteam --name mynewprivatechannel --display_name "My New Private Channel" --private`,
    26  	RunE: createChannelCmdF,
    27  }
    28  
    29  var ChannelRenameCmd = &cobra.Command{
    30  	Use:     "rename",
    31  	Short:   "Rename a channel",
    32  	Long:    `Rename a channel.`,
    33  	Example: `"  channel rename myteam:mychannel newchannelname --display_name "New Display Name"`,
    34  	Args:    cobra.MinimumNArgs(2),
    35  	RunE:    renameChannelCmdF,
    36  }
    37  
    38  var RemoveChannelUsersCmd = &cobra.Command{
    39  	Use:   "remove [channel] [users]",
    40  	Short: "Remove users from channel",
    41  	Long:  "Remove some users from channel",
    42  	Example: `  channel remove myteam:mychannel user@example.com username
    43    channel remove myteam:mychannel --all-users`,
    44  	RunE: removeChannelUsersCmdF,
    45  }
    46  
    47  var AddChannelUsersCmd = &cobra.Command{
    48  	Use:     "add [channel] [users]",
    49  	Short:   "Add users to channel",
    50  	Long:    "Add some users to channel",
    51  	Example: "  channel add myteam:mychannel user@example.com username",
    52  	Args:    cobra.MinimumNArgs(2),
    53  	RunE:    addChannelUsersCmdF,
    54  }
    55  
    56  var ArchiveChannelsCmd = &cobra.Command{
    57  	Use:   "archive [channels]",
    58  	Short: "Archive channels",
    59  	Long: `Archive some channels.
    60  Archive a channel along with all related information including posts from the database.
    61  Channels can be specified by [team]:[channel]. ie. myteam:mychannel or by channel ID.`,
    62  	Example: "  channel archive myteam:mychannel",
    63  	Args:    cobra.MinimumNArgs(1),
    64  	RunE:    archiveChannelsCmdF,
    65  }
    66  
    67  var DeleteChannelsCmd = &cobra.Command{
    68  	Use:   "delete [channels]",
    69  	Short: "Delete channels",
    70  	Long: `Permanently delete some channels.
    71  Permanently deletes a channel along with all related information including posts from the database.
    72  Channels can be specified by [team]:[channel]. ie. myteam:mychannel or by channel ID.`,
    73  	Example: "  channel delete myteam:mychannel",
    74  	Args:    cobra.MinimumNArgs(1),
    75  	RunE:    deleteChannelsCmdF,
    76  }
    77  
    78  var ListChannelsCmd = &cobra.Command{
    79  	Use:   "list [teams]",
    80  	Short: "List all channels on specified teams.",
    81  	Long: `List all channels on specified teams.
    82  Archived channels are appended with ' (archived)'.`,
    83  	Example: "  channel list myteam",
    84  	Args:    cobra.MinimumNArgs(1),
    85  	RunE:    listChannelsCmdF,
    86  }
    87  
    88  var MoveChannelsCmd = &cobra.Command{
    89  	Use:   "move [team] [channels] --username [user]",
    90  	Short: "Moves channels to the specified team",
    91  	Long: `Moves the provided channels to the specified team.
    92  Validates that all users in the channel belong to the target team. Incoming/Outgoing webhooks are moved along with the channel.
    93  Channels can be specified by [team]:[channel]. ie. myteam:mychannel or by channel ID.`,
    94  	Example: "  channel move newteam oldteam:mychannel --username myusername",
    95  	Args:    cobra.MinimumNArgs(2),
    96  	RunE:    moveChannelsCmdF,
    97  }
    98  
    99  var RestoreChannelsCmd = &cobra.Command{
   100  	Use:   "restore [channels]",
   101  	Short: "Restore some channels",
   102  	Long: `Restore a previously deleted channel
   103  Channels can be specified by [team]:[channel]. ie. myteam:mychannel or by channel ID.`,
   104  	Example: "  channel restore myteam:mychannel",
   105  	Args:    cobra.MinimumNArgs(1),
   106  	RunE:    restoreChannelsCmdF,
   107  }
   108  
   109  var ModifyChannelCmd = &cobra.Command{
   110  	Use:   "modify [channel] [flags] --username [user]",
   111  	Short: "Modify a channel's public/private type",
   112  	Long: `Change the public/private type of a channel.
   113  Channel can be specified by [team]:[channel]. ie. myteam:mychannel or by channel ID.`,
   114  	Example: "  channel modify myteam:mychannel --private --username myusername",
   115  	Args:    cobra.MinimumNArgs(1),
   116  	RunE:    modifyChannelCmdF,
   117  }
   118  
   119  var SearchChannelCmd = &cobra.Command{
   120  	Use:   "search [channel]\n  mattermost search --team [team] [channel]",
   121  	Short: "Search a channel",
   122  	Long: `Search a channel by channel name.
   123  Channel can be specified by team. ie. --team myTeam myChannel or by team ID.`,
   124  	Example: `  channel search myChannel
   125    channel search --team myTeam myChannel`,
   126  	Args: cobra.ExactArgs(1),
   127  	RunE: searchChannelCmdF,
   128  }
   129  
   130  func init() {
   131  	ChannelCreateCmd.Flags().String("name", "", "Channel Name")
   132  	ChannelCreateCmd.Flags().String("display_name", "", "Channel Display Name")
   133  	ChannelCreateCmd.Flags().String("team", "", "Team name or ID")
   134  	ChannelCreateCmd.Flags().String("header", "", "Channel header")
   135  	ChannelCreateCmd.Flags().String("purpose", "", "Channel purpose")
   136  	ChannelCreateCmd.Flags().Bool("private", false, "Create a private channel.")
   137  
   138  	MoveChannelsCmd.Flags().String("username", "", "Required. Username who is moving the channel.")
   139  	MoveChannelsCmd.Flags().Bool("remove-deactivated-users", false, "Automatically remove any deactivated users from the channel before moving it.")
   140  
   141  	DeleteChannelsCmd.Flags().Bool("confirm", false, "Confirm you really want to delete the channels.")
   142  
   143  	ModifyChannelCmd.Flags().Bool("private", false, "Convert the channel to a private channel")
   144  	ModifyChannelCmd.Flags().Bool("public", false, "Convert the channel to a public channel")
   145  	ModifyChannelCmd.Flags().String("username", "", "Required. Username who changes the channel privacy.")
   146  
   147  	ChannelRenameCmd.Flags().String("display_name", "", "Channel Display Name")
   148  	SearchChannelCmd.Flags().String("team", "", "Team name or ID")
   149  
   150  	RemoveChannelUsersCmd.Flags().Bool("all-users", false, "Remove all users from the indicated channel.")
   151  
   152  	ChannelCmd.AddCommand(
   153  		ChannelCreateCmd,
   154  		RemoveChannelUsersCmd,
   155  		AddChannelUsersCmd,
   156  		ArchiveChannelsCmd,
   157  		DeleteChannelsCmd,
   158  		ListChannelsCmd,
   159  		MoveChannelsCmd,
   160  		RestoreChannelsCmd,
   161  		ModifyChannelCmd,
   162  		ChannelRenameCmd,
   163  		SearchChannelCmd,
   164  	)
   165  
   166  	RootCmd.AddCommand(ChannelCmd)
   167  }
   168  
   169  func createChannelCmdF(command *cobra.Command, args []string) error {
   170  	a, err := InitDBCommandContextCobra(command)
   171  	if err != nil {
   172  		return err
   173  	}
   174  	defer a.Shutdown()
   175  
   176  	name, errn := command.Flags().GetString("name")
   177  	if errn != nil || name == "" {
   178  		return errors.New("Name is required")
   179  	}
   180  	displayname, errdn := command.Flags().GetString("display_name")
   181  	if errdn != nil || displayname == "" {
   182  		return errors.New("Display Name is required")
   183  	}
   184  	teamArg, errteam := command.Flags().GetString("team")
   185  	if errteam != nil || teamArg == "" {
   186  		return errors.New("Team is required")
   187  	}
   188  	header, _ := command.Flags().GetString("header")
   189  	purpose, _ := command.Flags().GetString("purpose")
   190  	useprivate, _ := command.Flags().GetBool("private")
   191  
   192  	channelType := model.CHANNEL_OPEN
   193  	if useprivate {
   194  		channelType = model.CHANNEL_PRIVATE
   195  	}
   196  
   197  	team := getTeamFromTeamArg(a, teamArg)
   198  	if team == nil {
   199  		return errors.New("Unable to find team: " + teamArg)
   200  	}
   201  
   202  	channel := &model.Channel{
   203  		TeamId:      team.Id,
   204  		Name:        name,
   205  		DisplayName: displayname,
   206  		Header:      header,
   207  		Purpose:     purpose,
   208  		Type:        channelType,
   209  		CreatorId:   "",
   210  	}
   211  
   212  	createdChannel, errCreatedChannel := a.CreateChannel(channel, false)
   213  	if errCreatedChannel != nil {
   214  		return errCreatedChannel
   215  	}
   216  
   217  	CommandPrettyPrintln("Id: " + createdChannel.Id)
   218  	CommandPrettyPrintln("Name: " + createdChannel.Name)
   219  	CommandPrettyPrintln("Display Name: " + createdChannel.DisplayName)
   220  	return nil
   221  }
   222  
   223  func removeChannelUsersCmdF(command *cobra.Command, args []string) error {
   224  	a, err := InitDBCommandContextCobra(command)
   225  	if err != nil {
   226  		return err
   227  	}
   228  	defer a.Shutdown()
   229  
   230  	allUsers, _ := command.Flags().GetBool("all-users")
   231  
   232  	if allUsers && len(args) != 1 {
   233  		return errors.New("individual users must not be specified in conjunction with the --all-users flag")
   234  	}
   235  
   236  	if !allUsers && len(args) < 2 {
   237  		return errors.New("you must specify some users to remove from the channel, or use the --all-users flag to remove them all")
   238  	}
   239  
   240  	channel := getChannelFromChannelArg(a, args[0])
   241  	if channel == nil {
   242  		return errors.New("Unable to find channel '" + args[0] + "'")
   243  	}
   244  
   245  	if allUsers {
   246  		removeAllUsersFromChannel(a, channel)
   247  	} else {
   248  		users := getUsersFromUserArgs(a, args[1:])
   249  		for i, user := range users {
   250  			removeUserFromChannel(a, channel, user, args[i+1])
   251  		}
   252  	}
   253  
   254  	return nil
   255  }
   256  
   257  func removeUserFromChannel(a *app.App, channel *model.Channel, user *model.User, userArg string) {
   258  	if user == nil {
   259  		CommandPrintErrorln("Can't find user '" + userArg + "'")
   260  		return
   261  	}
   262  	if err := a.RemoveUserFromChannel(user.Id, "", channel); err != nil {
   263  		CommandPrintErrorln("Unable to remove '" + userArg + "' from " + channel.Name + ". Error: " + err.Error())
   264  	}
   265  }
   266  
   267  func removeAllUsersFromChannel(a *app.App, channel *model.Channel) {
   268  	if result := <-a.Srv.Store.Channel().PermanentDeleteMembersByChannel(channel.Id); result.Err != nil {
   269  		CommandPrintErrorln("Unable to remove all users from " + channel.Name + ". Error: " + result.Err.Error())
   270  	}
   271  }
   272  
   273  func addChannelUsersCmdF(command *cobra.Command, args []string) error {
   274  	a, err := InitDBCommandContextCobra(command)
   275  	if err != nil {
   276  		return err
   277  	}
   278  	defer a.Shutdown()
   279  
   280  	channel := getChannelFromChannelArg(a, args[0])
   281  	if channel == nil {
   282  		return errors.New("Unable to find channel '" + args[0] + "'")
   283  	}
   284  
   285  	users := getUsersFromUserArgs(a, args[1:])
   286  	for i, user := range users {
   287  		addUserToChannel(a, channel, user, args[i+1])
   288  	}
   289  
   290  	return nil
   291  }
   292  
   293  func addUserToChannel(a *app.App, channel *model.Channel, user *model.User, userArg string) {
   294  	if user == nil {
   295  		CommandPrintErrorln("Can't find user '" + userArg + "'")
   296  		return
   297  	}
   298  	if _, err := a.AddUserToChannel(user, channel); err != nil {
   299  		CommandPrintErrorln("Unable to add '" + userArg + "' from " + channel.Name + ". Error: " + err.Error())
   300  	}
   301  }
   302  
   303  func archiveChannelsCmdF(command *cobra.Command, args []string) error {
   304  	a, err := InitDBCommandContextCobra(command)
   305  	if err != nil {
   306  		return err
   307  	}
   308  	defer a.Shutdown()
   309  
   310  	channels := getChannelsFromChannelArgs(a, args)
   311  	for i, channel := range channels {
   312  		if channel == nil {
   313  			CommandPrintErrorln("Unable to find channel '" + args[i] + "'")
   314  			continue
   315  		}
   316  		if result := <-a.Srv.Store.Channel().Delete(channel.Id, model.GetMillis()); result.Err != nil {
   317  			CommandPrintErrorln("Unable to archive channel '" + channel.Name + "' error: " + result.Err.Error())
   318  		}
   319  	}
   320  
   321  	return nil
   322  }
   323  
   324  func deleteChannelsCmdF(command *cobra.Command, args []string) error {
   325  	a, err := InitDBCommandContextCobra(command)
   326  	if err != nil {
   327  		return err
   328  	}
   329  	defer a.Shutdown()
   330  
   331  	confirmFlag, _ := command.Flags().GetBool("confirm")
   332  	if !confirmFlag {
   333  		var confirm string
   334  		CommandPrettyPrintln("Are you sure you want to delete the channels specified?  All data will be permanently deleted? (YES/NO): ")
   335  		fmt.Scanln(&confirm)
   336  		if confirm != "YES" {
   337  			return errors.New("ABORTED: You did not answer YES exactly, in all capitals.")
   338  		}
   339  	}
   340  
   341  	channels := getChannelsFromChannelArgs(a, args)
   342  	for i, channel := range channels {
   343  		if channel == nil {
   344  			CommandPrintErrorln("Unable to find channel '" + args[i] + "'")
   345  			continue
   346  		}
   347  		if err := deleteChannel(a, channel); err != nil {
   348  			CommandPrintErrorln("Unable to delete channel '" + channel.Name + "' error: " + err.Error())
   349  		} else {
   350  			CommandPrettyPrintln("Deleted channel '" + channel.Name + "'")
   351  		}
   352  	}
   353  
   354  	return nil
   355  }
   356  
   357  func deleteChannel(a *app.App, channel *model.Channel) *model.AppError {
   358  	return a.PermanentDeleteChannel(channel)
   359  }
   360  
   361  func moveChannelsCmdF(command *cobra.Command, args []string) error {
   362  	a, err := InitDBCommandContextCobra(command)
   363  	if err != nil {
   364  		return err
   365  	}
   366  	defer a.Shutdown()
   367  
   368  	team := getTeamFromTeamArg(a, args[0])
   369  	if team == nil {
   370  		return errors.New("Unable to find destination team '" + args[0] + "'")
   371  	}
   372  
   373  	username, erru := command.Flags().GetString("username")
   374  	if erru != nil || username == "" {
   375  		return errors.New("Username is required.")
   376  	}
   377  	user := getUserFromUserArg(a, username)
   378  
   379  	removeDeactivatedMembers, _ := command.Flags().GetBool("remove-deactivated-users")
   380  
   381  	channels := getChannelsFromChannelArgs(a, args[1:])
   382  	for i, channel := range channels {
   383  		if channel == nil {
   384  			CommandPrintErrorln("Unable to find channel '" + args[i+1] + "'")
   385  			continue
   386  		}
   387  		originTeamID := channel.TeamId
   388  		if err := moveChannel(a, team, channel, user, removeDeactivatedMembers); err != nil {
   389  			CommandPrintErrorln("Unable to move channel '" + channel.Name + "' error: " + err.Error())
   390  		} else {
   391  			CommandPrettyPrintln("Moved channel '" + channel.Name + "' to " + team.Name + "(" + team.Id + ") from " + originTeamID + ".")
   392  		}
   393  	}
   394  
   395  	return nil
   396  }
   397  
   398  func moveChannel(a *app.App, team *model.Team, channel *model.Channel, user *model.User, removeDeactivatedMembers bool) *model.AppError {
   399  	oldTeamId := channel.TeamId
   400  
   401  	if err := a.MoveChannel(team, channel, user, removeDeactivatedMembers); err != nil {
   402  		return err
   403  	}
   404  
   405  	if incomingWebhooks, err := a.GetIncomingWebhooksForTeamPage(oldTeamId, 0, 10000000); err != nil {
   406  		return err
   407  	} else {
   408  		for _, webhook := range incomingWebhooks {
   409  			if webhook.ChannelId == channel.Id {
   410  				webhook.TeamId = team.Id
   411  				if result := <-a.Srv.Store.Webhook().UpdateIncoming(webhook); result.Err != nil {
   412  					CommandPrintErrorln("Failed to move incoming webhook '" + webhook.Id + "' to new team.")
   413  				}
   414  			}
   415  		}
   416  	}
   417  
   418  	if outgoingWebhooks, err := a.GetOutgoingWebhooksForTeamPage(oldTeamId, 0, 10000000); err != nil {
   419  		return err
   420  	} else {
   421  		for _, webhook := range outgoingWebhooks {
   422  			if webhook.ChannelId == channel.Id {
   423  				webhook.TeamId = team.Id
   424  				if result := <-a.Srv.Store.Webhook().UpdateOutgoing(webhook); result.Err != nil {
   425  					CommandPrintErrorln("Failed to move outgoing webhook '" + webhook.Id + "' to new team.")
   426  				}
   427  			}
   428  		}
   429  	}
   430  
   431  	return nil
   432  }
   433  
   434  func listChannelsCmdF(command *cobra.Command, args []string) error {
   435  	a, err := InitDBCommandContextCobra(command)
   436  	if err != nil {
   437  		return err
   438  	}
   439  	defer a.Shutdown()
   440  
   441  	teams := getTeamsFromTeamArgs(a, args)
   442  	for i, team := range teams {
   443  		if team == nil {
   444  			CommandPrintErrorln("Unable to find team '" + args[i] + "'")
   445  			continue
   446  		}
   447  		if result := <-a.Srv.Store.Channel().GetAll(team.Id); result.Err != nil {
   448  			CommandPrintErrorln("Unable to list channels for '" + args[i] + "'")
   449  		} else {
   450  			channels := result.Data.([]*model.Channel)
   451  
   452  			for _, channel := range channels {
   453  				if channel.DeleteAt > 0 {
   454  					CommandPrettyPrintln(channel.Name + " (archived)")
   455  				} else {
   456  					CommandPrettyPrintln(channel.Name)
   457  				}
   458  			}
   459  		}
   460  	}
   461  
   462  	return nil
   463  }
   464  
   465  func restoreChannelsCmdF(command *cobra.Command, args []string) error {
   466  	a, err := InitDBCommandContextCobra(command)
   467  	if err != nil {
   468  		return err
   469  	}
   470  	defer a.Shutdown()
   471  
   472  	channels := getChannelsFromChannelArgs(a, args)
   473  	for i, channel := range channels {
   474  		if channel == nil {
   475  			CommandPrintErrorln("Unable to find channel '" + args[i] + "'")
   476  			continue
   477  		}
   478  		if result := <-a.Srv.Store.Channel().SetDeleteAt(channel.Id, 0, model.GetMillis()); result.Err != nil {
   479  			CommandPrintErrorln("Unable to restore channel '" + args[i] + "'")
   480  		}
   481  	}
   482  
   483  	return nil
   484  }
   485  
   486  func modifyChannelCmdF(command *cobra.Command, args []string) error {
   487  	a, err := InitDBCommandContextCobra(command)
   488  	if err != nil {
   489  		return err
   490  	}
   491  	defer a.Shutdown()
   492  
   493  	username, erru := command.Flags().GetString("username")
   494  	if erru != nil || username == "" {
   495  		return errors.New("Username is required.")
   496  	}
   497  
   498  	public, _ := command.Flags().GetBool("public")
   499  	private, _ := command.Flags().GetBool("private")
   500  
   501  	if public == private {
   502  		return errors.New("You must specify only one of --public or --private")
   503  	}
   504  
   505  	channel := getChannelFromChannelArg(a, args[0])
   506  	if channel == nil {
   507  		return errors.New("Unable to find channel '" + args[0] + "'")
   508  	}
   509  
   510  	if !(channel.Type == model.CHANNEL_OPEN || channel.Type == model.CHANNEL_PRIVATE) {
   511  		return errors.New("You can only change the type of public/private channels.")
   512  	}
   513  
   514  	channel.Type = model.CHANNEL_OPEN
   515  	if private {
   516  		channel.Type = model.CHANNEL_PRIVATE
   517  	}
   518  
   519  	user := getUserFromUserArg(a, username)
   520  	if _, err := a.UpdateChannelPrivacy(channel, user); err != nil {
   521  		return errors.Wrapf(err, "Failed to update channel ('%s') privacy", args[0])
   522  	}
   523  
   524  	return nil
   525  }
   526  
   527  func renameChannelCmdF(command *cobra.Command, args []string) error {
   528  	a, err := InitDBCommandContextCobra(command)
   529  	var newDisplayName, newChannelName string
   530  	if err != nil {
   531  		return err
   532  	}
   533  	defer a.Shutdown()
   534  
   535  	channel := getChannelFromChannelArg(a, args[0])
   536  	if channel == nil {
   537  		return errors.New("Unable to find channel '" + args[0] + "'")
   538  	}
   539  
   540  	newChannelName = args[1]
   541  	newDisplayName, errdn := command.Flags().GetString("display_name")
   542  	if errdn != nil {
   543  		return errdn
   544  	}
   545  
   546  	_, errch := a.RenameChannel(channel, newChannelName, newDisplayName)
   547  	if errch != nil {
   548  		return errors.Wrapf(errch, "Error in updating channel from %s to %s", channel.Name, newChannelName)
   549  	}
   550  
   551  	return nil
   552  }
   553  
   554  func searchChannelCmdF(command *cobra.Command, args []string) error {
   555  
   556  	a, err := InitDBCommandContextCobra(command)
   557  	if err != nil {
   558  		return errors.Wrap(err, "failed to InitDBCommandContextCobra")
   559  	}
   560  	defer a.Shutdown()
   561  
   562  	var channel *model.Channel
   563  
   564  	if teamArg, _ := command.Flags().GetString("team"); teamArg != "" {
   565  		team := getTeamFromTeamArg(a, teamArg)
   566  		if team == nil {
   567  			CommandPrettyPrintln(fmt.Sprintf("Team %s is not found", teamArg))
   568  			return nil
   569  		}
   570  
   571  		var aErr *model.AppError
   572  		channel, aErr = a.GetChannelByName(args[0], team.Id, true)
   573  		if aErr != nil || channel == nil {
   574  			CommandPrettyPrintln(fmt.Sprintf("Channel %s is not found in team %s", args[0], teamArg))
   575  			return nil
   576  		}
   577  	} else {
   578  		teams, aErr := a.GetAllTeams()
   579  		if aErr != nil {
   580  			return errors.Wrap(err, "failed to GetAllTeams")
   581  		}
   582  
   583  		for _, team := range teams {
   584  			channel, _ = a.GetChannelByName(args[0], team.Id, true)
   585  			if channel != nil && channel.Name == args[0] {
   586  				break
   587  			}
   588  		}
   589  
   590  		if channel == nil {
   591  			CommandPrettyPrintln(fmt.Sprintf("Channel %s is not found in any team", args[0]))
   592  			return nil
   593  		}
   594  	}
   595  
   596  	if channel.DeleteAt > 0 {
   597  		CommandPrettyPrintln(fmt.Sprintf(`Channel Name :%s, Display Name :%s, Channel ID :%s (archived)`, channel.Name, channel.DisplayName, channel.Id))
   598  	} else {
   599  		CommandPrettyPrintln(fmt.Sprintf(`Channel Name :%s, Display Name :%s, Channel ID :%s`, channel.Name, channel.DisplayName, channel.Id))
   600  	}
   601  	return nil
   602  }