package main import ( "errors" "fmt" "github.com/larkox/mattermost-plugin-badges/badgesmodel" commandparser "github.com/larkox/mattermost-plugin-badges/server/command_parser" "github.com/mattermost/mattermost-server/v5/model" "github.com/mattermost/mattermost-server/v5/plugin" "github.com/spf13/pflag" ) func getHelp() string { return `Available Commands: ` } func (p *Plugin) getCommand() *model.Command { return &model.Command{ Trigger: "badges", DisplayName: "Achievements Bot", Description: "Achievements", AutoComplete: true, AutoCompleteDesc: "Available commands:", AutoCompleteHint: "[command]", AutocompleteData: p.getAutocompleteData(), } } func (p *Plugin) postCommandResponse(args *model.CommandArgs, text string) { post := &model.Post{ UserId: p.BotUserID, ChannelId: args.ChannelId, Message: text, } p.mm.Post.SendEphemeralPost(args.UserId, post) } func commandError(text string) (bool, *model.CommandResponse, error) { return true, &model.CommandResponse{}, errors.New(text) } // ExecuteCommand executes a given command and returns a command response. func (p *Plugin) ExecuteCommand(c *plugin.Context, args *model.CommandArgs) (*model.CommandResponse, *model.AppError) { stringArgs := commandparser.Parse(args.Command) lengthOfArgs := len(stringArgs) restOfArgs := []string{} var handler func([]string, *model.CommandArgs) (bool, *model.CommandResponse, error) if lengthOfArgs == 1 { p.postCommandResponse(args, getHelp()) return &model.CommandResponse{}, nil } command := stringArgs[1] if lengthOfArgs > 2 { restOfArgs = stringArgs[2:] } switch command { case "test-clean": handler = p.runClean case "grant": handler = p.runGrant case "edit": handler = p.runEdit case "create": handler = p.runCreate case "subscription": handler = p.runSubscription default: p.postCommandResponse(args, getHelp()) return &model.CommandResponse{}, nil } isUserError, resp, err := handler(restOfArgs, args) if err != nil { if isUserError { p.postCommandResponse(args, fmt.Sprintf("__Error: %s__", err.Error())) } else { p.mm.Log.Error(err.Error()) u, _ := p.mm.User.Get(args.UserId) locale := "ru" if u != nil { locale = u.Locale } T := p.getT(locale) p.postCommandResponse(args, T("badges.error.unknown", "Произошла неизвестная ошибка. Обратитесь к системному администратору.")) } } if resp != nil { return resp, nil } return &model.CommandResponse{}, nil } func (p *Plugin) runClean(args []string, extra *model.CommandArgs) (bool, *model.CommandResponse, error) { user, err := p.mm.User.Get(extra.UserId) if err != nil { return false, &model.CommandResponse{Text: "Cannot get user."}, nil } T := p.getT(user.Locale) if !user.IsSystemAdmin() { return false, &model.CommandResponse{Text: T("badges.error.only_sysadmin_clean", "Только системный администратор может очистить базу значков.")}, nil } _ = p.mm.KV.DeleteAll() return false, &model.CommandResponse{Text: T("badges.success.clean", "Очищено")}, nil } func (p *Plugin) runCreate(args []string, extra *model.CommandArgs) (bool, *model.CommandResponse, error) { lengthOfArgs := len(args) restOfArgs := []string{} var handler func([]string, *model.CommandArgs) (bool, *model.CommandResponse, error) if lengthOfArgs == 0 { u, _ := p.mm.User.Get(extra.UserId) locale := "ru" if u != nil { locale = u.Locale } T := p.getT(locale) return false, &model.CommandResponse{Text: T("badges.error.specify_create", "Укажите, что вы хотите создать.")}, nil } command := args[0] if lengthOfArgs > 1 { restOfArgs = args[1:] } switch command { case "badge": handler = p.runCreateBadge case "type": handler = p.runCreateType default: u, _ := p.mm.User.Get(extra.UserId) locale := "ru" if u != nil { locale = u.Locale } T := p.getT(locale) return false, &model.CommandResponse{Text: T("badges.error.create_badge_or_type", "Можно создать badge или type")}, nil } return handler(restOfArgs, extra) } func (p *Plugin) runCreateBadge(args []string, extra *model.CommandArgs) (bool, *model.CommandResponse, error) { u, err := p.mm.User.Get(extra.UserId) if err != nil { return commandError(err.Error()) } T := p.getT(u.Locale) typeSuggestions, err := p.filterCreateBadgeTypes(u) if err != nil { return commandError(err.Error()) } typeOptions := []*model.PostActionOptions{} for _, typeSuggestion := range typeSuggestions { id := string(typeSuggestion.ID) typeOptions = append(typeOptions, &model.PostActionOptions{Text: typeSuggestion.Name, Value: id}) } if len(typeOptions) == 0 { return commandError(T("badges.error.no_types_available", "Вы не можете создать значки ни одного типа.")) } err = p.mm.Frontend.OpenInteractiveDialog(model.OpenDialogRequest{ TriggerId: extra.TriggerId, URL: p.getDialogURL() + DialogPathCreateBadge, Dialog: model.Dialog{ Title: T("badges.dialog.create_badge.title", "Создать значок"), SubmitLabel: T("badges.dialog.create_badge.submit", "Создать"), Elements: []model.DialogElement{ { DisplayName: T("badges.field.name", "Название"), Type: "text", Name: DialogFieldBadgeName, MaxLength: badgesmodel.NameMaxLength, }, { DisplayName: T("badges.field.description", "Описание"), Type: "text", Name: DialogFieldBadgeDescription, MaxLength: badgesmodel.DescriptionMaxLength, }, { DisplayName: T("badges.field.image", "Изображение"), Type: "text", Name: DialogFieldBadgeImage, HelpText: T("badges.field.image.help", "Введите название эмодзи"), }, { DisplayName: T("badges.field.type", "Тип"), Type: "select", Name: DialogFieldBadgeType, Options: typeOptions, }, { DisplayName: T("badges.field.multiple", "Многократный"), Type: "bool", Name: DialogFieldBadgeMultiple, HelpText: T("badges.field.multiple.help", "Можно ли выдавать этот значок несколько раз"), Optional: true, }, }, }, }) if err != nil { return commandError(err.Error()) } return false, &model.CommandResponse{}, nil } func (p *Plugin) runEdit(args []string, extra *model.CommandArgs) (bool, *model.CommandResponse, error) { lengthOfArgs := len(args) restOfArgs := []string{} var handler func([]string, *model.CommandArgs) (bool, *model.CommandResponse, error) if lengthOfArgs == 0 { u, _ := p.mm.User.Get(extra.UserId) locale := "ru" if u != nil { locale = u.Locale } T := p.getT(locale) return false, &model.CommandResponse{Text: T("badges.error.specify_edit", "Укажите, что вы хотите отредактировать.")}, nil } command := args[0] if lengthOfArgs > 1 { restOfArgs = args[1:] } switch command { case "badge": handler = p.runEditBadge case "type": handler = p.runEditType default: u, _ := p.mm.User.Get(extra.UserId) locale := "ru" if u != nil { locale = u.Locale } T := p.getT(locale) return false, &model.CommandResponse{Text: T("badges.error.edit_badge_or_type", "Можно редактировать badge или type")}, nil } return handler(restOfArgs, extra) } func (p *Plugin) runEditBadge(args []string, extra *model.CommandArgs) (bool, *model.CommandResponse, error) { u, err := p.mm.User.Get(extra.UserId) if err != nil { return commandError(err.Error()) } T := p.getT(u.Locale) var badgeIDStr string fs := pflag.NewFlagSet("", pflag.ContinueOnError) fs.StringVar(&badgeIDStr, "id", "", "ID of the badge") if err = fs.Parse(args); err != nil { return commandError(err.Error()) } if badgeIDStr == "" { return commandError(T("badges.error.must_set_badge_id", "Необходимо указать ID значка")) } badge, err := p.store.GetBadge(badgesmodel.BadgeID(badgeIDStr)) if err != nil { return commandError(err.Error()) } if !canEditBadge(u, p.badgeAdminUserID, badge) { return commandError(T("badges.error.cannot_edit_badge", "У вас нет прав на редактирование этого значка")) } typeSuggestions, err := p.filterCreateBadgeTypes(u) if err != nil { return commandError(err.Error()) } typeOptions := []*model.PostActionOptions{} for _, typeSuggestion := range typeSuggestions { id := string(typeSuggestion.ID) typeOptions = append(typeOptions, &model.PostActionOptions{Text: typeSuggestion.Name, Value: id}) } if len(typeOptions) == 0 { return commandError(T("badges.error.no_types_available", "Вы не можете создать значки ни одного типа.")) } err = p.mm.Frontend.OpenInteractiveDialog(model.OpenDialogRequest{ TriggerId: extra.TriggerId, URL: p.getDialogURL() + DialogPathEditBadge, Dialog: model.Dialog{ Title: T("badges.dialog.edit_badge.title", "Редактировать значок"), SubmitLabel: T("badges.dialog.edit_badge.submit", "Сохранить"), State: string(badge.ID), Elements: []model.DialogElement{ { DisplayName: T("badges.field.name", "Название"), Type: "text", Name: DialogFieldBadgeName, MaxLength: badgesmodel.NameMaxLength, Default: badge.Name, }, { DisplayName: T("badges.field.description", "Описание"), Type: "text", Name: DialogFieldBadgeDescription, MaxLength: badgesmodel.DescriptionMaxLength, Default: badge.Description, }, { DisplayName: T("badges.field.image", "Изображение"), Type: "text", Name: DialogFieldBadgeImage, HelpText: T("badges.field.image.help", "Введите название эмодзи"), Default: badge.Image, }, { DisplayName: T("badges.field.type", "Тип"), Type: "select", Name: DialogFieldBadgeType, Options: typeOptions, Default: string(badge.Type), }, { DisplayName: T("badges.field.multiple", "Многократный"), Type: "bool", Name: DialogFieldBadgeMultiple, HelpText: T("badges.field.multiple.help", "Можно ли выдавать этот значок несколько раз"), Optional: true, Default: getBooleanString(badge.Multiple), }, { DisplayName: T("badges.field.delete_badge", "Удалить значок"), Type: "bool", Name: DialogFieldBadgeDelete, HelpText: T("badges.field.delete_badge.help", "ВНИМАНИЕ: если отметить, значок будет удалён безвозвратно."), Optional: true, }, }, }, }) if err != nil { return commandError(err.Error()) } return false, &model.CommandResponse{}, nil } func (p *Plugin) runEditType(args []string, extra *model.CommandArgs) (bool, *model.CommandResponse, error) { u, err := p.mm.User.Get(extra.UserId) if err != nil { return commandError(err.Error()) } T := p.getT(u.Locale) if !canCreateType(u, p.badgeAdminUserID, false) { return commandError(T("badges.error.no_permissions_edit_type", "У вас нет прав на редактирование типа значков.")) } var badgeTypeStr string fs := pflag.NewFlagSet("", pflag.ContinueOnError) fs.StringVar(&badgeTypeStr, "type", "", "ID of the type") if err = fs.Parse(args); err != nil { return commandError(err.Error()) } if badgeTypeStr == "" { return commandError(T("badges.error.must_provide_type_id", "Необходимо указать ID типа")) } typeDefinition, err := p.store.GetType(badgesmodel.BadgeType(badgeTypeStr)) if err != nil { return commandError(err.Error()) } if !canEditType(u, p.badgeAdminUserID, typeDefinition) { return commandError(T("badges.error.cannot_edit_type", "У вас нет прав на редактирование этого типа")) } canGrantAllowList := "" for uID, allowed := range typeDefinition.CanGrant.AllowList { if !allowed { continue } var allowedUser *model.User allowedUser, err = p.mm.User.Get(uID) if err != nil { continue } if canGrantAllowList == "" { canGrantAllowList += allowedUser.Username continue } canGrantAllowList += ", " + allowedUser.Username } canCreateAllowList := "" for uID, allowed := range typeDefinition.CanCreate.AllowList { if !allowed { continue } var allowedUser *model.User allowedUser, err = p.mm.User.Get(uID) if err != nil { continue } if canCreateAllowList == "" { canCreateAllowList += allowedUser.Username continue } canCreateAllowList += ", " + allowedUser.Username } err = p.mm.Frontend.OpenInteractiveDialog(model.OpenDialogRequest{ TriggerId: extra.TriggerId, URL: p.getDialogURL() + DialogPathEditType, Dialog: model.Dialog{ Title: T("badges.dialog.edit_type.title", "Редактировать тип"), SubmitLabel: T("badges.dialog.edit_type.submit", "Сохранить"), State: badgeTypeStr, Elements: []model.DialogElement{ { DisplayName: T("badges.field.name", "Название"), Type: "text", Name: DialogFieldTypeName, MaxLength: badgesmodel.NameMaxLength, Default: typeDefinition.Name, }, { DisplayName: T("badges.field.everyone_can_create", "Все могут создавать значки"), Type: "bool", Name: DialogFieldTypeEveryoneCanCreate, HelpText: T("badges.field.everyone_can_create.help", "Любой пользователь может создать значок этого типа"), Optional: true, Default: getBooleanString(typeDefinition.CanCreate.Everyone), }, { DisplayName: T("badges.field.allowlist_create", "Список допущенных к созданию"), Type: "text", Name: DialogFieldTypeAllowlistCanCreate, HelpText: T("badges.field.allowlist_create.help", "Укажите имена пользователей через запятую (,), которые могут создавать значки этого типа."), Placeholder: "user-1, user-2, user-3", Optional: true, Default: canCreateAllowList, }, { DisplayName: T("badges.field.everyone_can_grant", "Все могут выдавать значки"), Type: "bool", Name: DialogFieldTypeEveryoneCanGrant, HelpText: T("badges.field.everyone_can_grant.help", "Любой пользователь может выдать значок этого типа"), Optional: true, Default: getBooleanString(typeDefinition.CanGrant.Everyone), }, { DisplayName: T("badges.field.allowlist_grant", "Список допущенных к выдаче"), Type: "text", Name: DialogFieldTypeAllowlistCanGrant, HelpText: T("badges.field.allowlist_grant.help", "Укажите имена пользователей через запятую (,), которые могут выдавать значки этого типа."), Placeholder: "user-1, user-2, user-3", Optional: true, Default: canGrantAllowList, }, { DisplayName: T("badges.field.delete_type", "Удалить тип"), Type: "bool", Name: DialogFieldTypeDelete, HelpText: T("badges.field.delete_type.help", "ВНИМАНИЕ: если отметить, этот тип и все связанные значки будут удалены безвозвратно."), Optional: true, }, }, }, }) if err != nil { return commandError(err.Error()) } return false, &model.CommandResponse{}, nil } func (p *Plugin) runCreateType(args []string, extra *model.CommandArgs) (bool, *model.CommandResponse, error) { u, err := p.mm.User.Get(extra.UserId) if err != nil { return commandError(err.Error()) } T := p.getT(u.Locale) if !canCreateType(u, p.badgeAdminUserID, false) { return commandError(T("badges.error.no_permissions_create_type", "У вас нет прав на создание типа значков.")) } err = p.mm.Frontend.OpenInteractiveDialog(model.OpenDialogRequest{ TriggerId: extra.TriggerId, URL: p.getDialogURL() + DialogPathCreateType, Dialog: model.Dialog{ Title: T("badges.dialog.create_type.title", "Создать тип"), SubmitLabel: T("badges.dialog.create_type.submit", "Создать"), Elements: []model.DialogElement{ { DisplayName: T("badges.field.name", "Название"), Type: "text", Name: DialogFieldTypeName, MaxLength: badgesmodel.NameMaxLength, }, { DisplayName: T("badges.field.everyone_can_create", "Все могут создавать значки"), Type: "bool", Name: DialogFieldTypeEveryoneCanCreate, HelpText: T("badges.field.everyone_can_create.help", "Любой пользователь может создать значок этого типа"), Optional: true, }, { DisplayName: T("badges.field.allowlist_create", "Список допущенных к созданию"), Type: "text", Name: DialogFieldTypeAllowlistCanCreate, HelpText: T("badges.field.allowlist_create.help", "Укажите имена пользователей через запятую (,), которые могут создавать значки этого типа."), Placeholder: "user-1, user-2, user-3", Optional: true, }, { DisplayName: T("badges.field.everyone_can_grant", "Все могут выдавать значки"), Type: "bool", Name: DialogFieldTypeEveryoneCanGrant, HelpText: T("badges.field.everyone_can_grant.help", "Любой пользователь может выдать значок этого типа"), Optional: true, }, { DisplayName: T("badges.field.allowlist_grant", "Список допущенных к выдаче"), Type: "text", Name: DialogFieldTypeAllowlistCanGrant, HelpText: T("badges.field.allowlist_grant.help", "Укажите имена пользователей через запятую (,), которые могут выдавать значки этого типа."), Placeholder: "user-1, user-2, user-3", Optional: true, }, }, }, }) if err != nil { return commandError(err.Error()) } return false, &model.CommandResponse{}, nil } func (p *Plugin) runGrant(args []string, extra *model.CommandArgs) (bool, *model.CommandResponse, error) { badgeStr := "" username := "" fs := pflag.NewFlagSet("", pflag.ContinueOnError) fs.StringVar(&badgeStr, "badge", "", "ID of the badge") fs.StringVar(&username, "user", "", "Username to grant to") if err := fs.Parse(args); err != nil { return commandError(err.Error()) } if username != "" && badgeStr != "" { if username[0] == '@' { username = username[1:] } granter, err := p.mm.User.Get(extra.UserId) if err != nil { return commandError(err.Error()) } T := p.getT(granter.Locale) badge, err := p.store.GetBadge(badgesmodel.BadgeID(badgeStr)) if err != nil { return commandError(err.Error()) } badgeType, err := p.store.GetType(badge.Type) if err != nil { return commandError(err.Error()) } if !canGrantBadge(granter, p.badgeAdminUserID, badge, badgeType) { return commandError(T("badges.error.no_permissions_grant", "У вас нет прав на выдачу этого значка")) } user, err := p.mm.User.GetByUsername(username) if err != nil { return commandError(err.Error()) } shouldNotify, err := p.store.GrantBadge(badgesmodel.BadgeID(badgeStr), user.Id, extra.UserId, "") if err != nil { return commandError(err.Error()) } if shouldNotify { p.notifyGrant(badgesmodel.BadgeID(badgeStr), extra.UserId, user, false, "", "") } p.postCommandResponse(extra, T("badges.success.granted", "Выдано")) return false, &model.CommandResponse{}, nil } actingUser, err := p.mm.User.Get(extra.UserId) if err != nil { return commandError(err.Error()) } T := p.getT(actingUser.Locale) elements := []model.DialogElement{} stateText := "" introductionText := "" if username != "" { if username[0] == '@' { username = username[1:] } user, err := p.mm.User.GetByUsername(username) if err != nil { return commandError(err.Error()) } introductionText = T("badges.dialog.grant.intro", "Выдать значок пользователю @%s", username) stateText = user.Id } if stateText == "" { elements = append(elements, model.DialogElement{ DisplayName: T("badges.field.user", "Пользователь"), Type: "select", Name: DialogFieldUser, DataSource: "users", }) } options := []*model.PostActionOptions{} grantableBadges, err := p.filterGrantBadges(actingUser) if err != nil { return commandError(err.Error()) } for _, badge := range grantableBadges { options = append(options, &model.PostActionOptions{Text: badge.Name, Value: string(badge.ID)}) } badgeElement := model.DialogElement{ DisplayName: T("badges.field.badge", "Значок"), Type: "select", Name: DialogFieldBadge, Options: options, } if badgeStr != "" { found := false for _, badge := range grantableBadges { if badgeStr == string(badge.ID) { found = true break } } if !found { return commandError(T("badges.error.cannot_grant_badge", "Вы не можете выдать этот значок")) } badgeElement.Default = badgeStr } elements = append(elements, badgeElement) elements = append(elements, model.DialogElement{ DisplayName: T("badges.field.reason", "Причина"), Name: DialogFieldGrantReason, Optional: true, HelpText: T("badges.field.reason.help", "Причина выдачи значка. Будет видна пользователю и в уведомлениях о выдаче (например, в подписках)."), Type: "text", }) elements = append(elements, model.DialogElement{ DisplayName: T("badges.field.notify_here", "Уведомить в этом канале"), Name: DialogFieldNotifyHere, Type: "bool", HelpText: T("badges.field.notify_here.help", "Если отметить, бот отправит сообщение в этот канал о том, что вы выдали значок этому пользователю."), Optional: true, }) err = p.mm.Frontend.OpenInteractiveDialog(model.OpenDialogRequest{ TriggerId: extra.TriggerId, URL: p.getDialogURL() + DialogPathGrant, Dialog: model.Dialog{ Title: T("badges.dialog.grant.title", "Выдать значок"), IntroductionText: introductionText, SubmitLabel: T("badges.dialog.grant.submit", "Выдать"), Elements: elements, State: stateText, }, }) if err != nil { return commandError(err.Error()) } return false, &model.CommandResponse{}, nil } func (p *Plugin) runSubscription(args []string, extra *model.CommandArgs) (bool, *model.CommandResponse, error) { lengthOfArgs := len(args) restOfArgs := []string{} var handler func([]string, *model.CommandArgs) (bool, *model.CommandResponse, error) if lengthOfArgs == 0 { u, _ := p.mm.User.Get(extra.UserId) locale := "ru" if u != nil { locale = u.Locale } T := p.getT(locale) return false, &model.CommandResponse{Text: T("badges.error.specify_subscription", "Укажите, что вы хотите сделать.")}, nil } command := args[0] if lengthOfArgs > 1 { restOfArgs = args[1:] } switch command { case "create": handler = p.runCreateSubscription case "remove": handler = p.runDeleteSubscription default: u, _ := p.mm.User.Get(extra.UserId) locale := "ru" if u != nil { locale = u.Locale } T := p.getT(locale) return false, &model.CommandResponse{Text: T("badges.error.create_or_delete_subscription", "Можно создать или удалить подписку")}, nil } return handler(restOfArgs, extra) } func (p *Plugin) runCreateSubscription(args []string, extra *model.CommandArgs) (bool, *model.CommandResponse, error) { typeStr := "" fs := pflag.NewFlagSet("", pflag.ContinueOnError) fs.StringVar(&typeStr, "type", "", "ID of the badge") if err := fs.Parse(args); err != nil { return commandError(err.Error()) } actingUser, err := p.mm.User.Get(extra.UserId) if err != nil { return commandError(err.Error()) } T := p.getT(actingUser.Locale) if !canCreateSubscription(actingUser, p.badgeAdminUserID, extra.ChannelId) { return commandError(T("badges.error.cannot_create_subscription", "Вы не можете создавать подписки")) } if typeStr != "" { err = p.store.AddSubscription(badgesmodel.BadgeType(typeStr), extra.ChannelId) if err != nil { return commandError(err.Error()) } p.postCommandResponse(extra, T("badges.success.granted", "Выдано")) return false, &model.CommandResponse{}, nil } options := []*model.PostActionOptions{} typesDefinitions, err := p.filterEditTypes(actingUser) if err != nil { return commandError(err.Error()) } for _, typeDefinition := range typesDefinitions { options = append(options, &model.PostActionOptions{Text: typeDefinition.Name, Value: string(typeDefinition.ID)}) } err = p.mm.Frontend.OpenInteractiveDialog(model.OpenDialogRequest{ TriggerId: extra.TriggerId, URL: p.getDialogURL() + DialogPathCreateSubscription, Dialog: model.Dialog{ Title: T("badges.dialog.create_subscription.title", "Создать подписку"), IntroductionText: T("badges.dialog.create_subscription.intro", "Выберите тип значка, на который хотите подписать этот канал."), SubmitLabel: T("badges.dialog.create_subscription.submit", "Добавить"), Elements: []model.DialogElement{ { DisplayName: T("badges.field.type", "Тип"), Type: "select", Name: DialogFieldBadgeType, Options: options, }, }, }, }) if err != nil { return commandError(err.Error()) } return false, &model.CommandResponse{}, nil } func (p *Plugin) runDeleteSubscription(args []string, extra *model.CommandArgs) (bool, *model.CommandResponse, error) { typeStr := "" fs := pflag.NewFlagSet("", pflag.ContinueOnError) fs.StringVar(&typeStr, "type", "", "ID of the badge") if err := fs.Parse(args); err != nil { return commandError(err.Error()) } actingUser, err := p.mm.User.Get(extra.UserId) if err != nil { return commandError(err.Error()) } T := p.getT(actingUser.Locale) if !canCreateSubscription(actingUser, p.badgeAdminUserID, extra.ChannelId) { return commandError(T("badges.error.cannot_create_subscription", "Вы не можете создавать подписки")) } if typeStr != "" { err = p.store.RemoveSubscriptions(badgesmodel.BadgeType(typeStr), extra.ChannelId) if err != nil { return commandError(err.Error()) } p.postCommandResponse(extra, T("badges.success.removed", "Удалено")) return false, &model.CommandResponse{}, nil } options := []*model.PostActionOptions{} typesDefinitions, err := p.store.GetChannelSubscriptions(extra.ChannelId) if err != nil { return commandError(err.Error()) } for _, typeDefinition := range typesDefinitions { options = append(options, &model.PostActionOptions{Text: typeDefinition.Name, Value: string(typeDefinition.ID)}) } err = p.mm.Frontend.OpenInteractiveDialog(model.OpenDialogRequest{ TriggerId: extra.TriggerId, URL: p.getDialogURL() + DialogPathDeleteSubscription, Dialog: model.Dialog{ Title: T("badges.dialog.delete_subscription.title", "Удалить подписку"), IntroductionText: T("badges.dialog.delete_subscription.intro", "Выберите тип значка, подписку на который хотите удалить из этого канала."), SubmitLabel: T("badges.dialog.delete_subscription.submit", "Удалить"), Elements: []model.DialogElement{ { DisplayName: T("badges.field.type", "Тип"), Type: "select", Name: DialogFieldBadgeType, Options: options, }, }, }, }) if err != nil { return commandError(err.Error()) } return false, &model.CommandResponse{}, nil } func (p *Plugin) getAutocompleteData() *model.AutocompleteData { badges := model.NewAutocompleteData("badges", "[command]", "Available commands: grant") grant := model.NewAutocompleteData("grant", "--user @username --badge id", "Grant a badge to a user") grant.AddNamedDynamicListArgument("badge", "--badge badgeID", getAutocompletePath(AutocompletePathBadgeSuggestions), true) grant.AddNamedTextArgument("user", "User to grant the badge to", "--user @username", "", true) badges.AddCommand(grant) create := model.NewAutocompleteData("create", "badge | type", "Create a badge or a type") badge := model.NewAutocompleteData( "badge", "", "Create a badge", ) create.AddCommand(badge) createType := model.NewAutocompleteData( "type", "", "Create a badge type", ) create.AddCommand(createType) badges.AddCommand(create) edit := model.NewAutocompleteData("edit", "badge | type", "Edit a badge or a type") editBadge := model.NewAutocompleteData( "badge", "", "Edit a badge", ) editBadge.AddNamedDynamicListArgument("id", "--id badgeID", getAutocompletePath(AutocompletePathEditBadgeSuggestions), true) edit.AddCommand(editBadge) editType := model.NewAutocompleteData( "type", "", "Edit a badge type", ) editType.AddNamedDynamicListArgument("type", "--type typeID", getAutocompletePath(AutocompletePathEditTypeSuggestions), true) edit.AddCommand(editType) badges.AddCommand(edit) subscription := model.NewAutocompleteData("subscription", "create | remove", "Manage this channel subscriptions") createSubscription := model.NewAutocompleteData( "create", "", "Create a subscription", ) subscription.AddCommand(createSubscription) deleteSubscription := model.NewAutocompleteData( "remove", "", "Remove a subscription", ) subscription.AddCommand(deleteSubscription) badges.AddCommand(subscription) return badges } func getAutocompletePath(path string) string { return "plugins/" + manifest.Id + AutocompletePath + path }