939 lines
30 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
}