1
0
Fork 0
mirror of https://github.com/diamondburned/arikawa.git synced 2024-11-27 09:12:53 +00:00

discord: Add localization to Application Commands (#322)

* discord: Add localization to Application Commands
* discord: Created Language type and renamed field.
* discord: Added comments
* api: Add *Client.WithLocale
* discord: Use StringLocales, tweak naming

Co-authored-by: Neo <65282986+Neoration@users.noreply.github.com>
This commit is contained in:
diamondburned 2022-04-11 21:30:25 -07:00 committed by GitHub
parent c9a96f671a
commit f249715c9d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 203 additions and 47 deletions

View file

@ -7,6 +7,7 @@ import (
"net/http"
"github.com/diamondburned/arikawa/v3/api/rate"
"github.com/diamondburned/arikawa/v3/discord"
"github.com/diamondburned/arikawa/v3/utils/httputil"
"github.com/diamondburned/arikawa/v3/utils/httputil/httpdriver"
)
@ -49,6 +50,22 @@ func NewCustomClient(token string, httpClient *httputil.Client) *Client {
return c
}
// WithLocale creates a copy of Client with an explicitly stated language locale
// using the X-Discord-Locale HTTP header.
func (c *Client) WithLocale(language discord.Language) *Client {
client := c.Client.Copy()
client.OnRequest = append(client.OnRequest, func(r httpdriver.Request) error {
r.AddHeader(http.Header{"X-Discord-Locale": []string{string(language)}})
return nil
})
return &Client{
Client: client,
Session: c.Session,
AcquireOptions: c.AcquireOptions,
}
}
// WithContext returns a shallow copy of Client with the given context. It's
// used for method timeouts and such. This method is thread-safe.
func (c *Client) WithContext(ctx context.Context) *Client {

View file

@ -33,9 +33,16 @@ type Command struct {
// GuildID is the guild id of the command, if not global.
GuildID GuildID `json:"guild_id,omitempty"`
// Name is the 1-32 lowercase character name matching ^[\w-]{1,32}$.
Name string `json:"name"`
Name string `json:"name"`
NameLocalizations StringLocales `json:"name_localizations,omitempty"`
// Description is the 1-100 character description.
Description string `json:"description"`
Description string `json:"description"`
DescriptionLocalizations StringLocales `json:"description_localizations,omitempty"`
// LocalizedName is only populated when this is received from Discord's API.
LocalizedName string `json:"name_localized,omitempty"`
// LocalizedDescription is only populated when this is received from
// Discord's API.
LocalizedDescription string `json:"description_localized,omitempty"`
// Options are the parameters for the command. Its types are value types,
// which can either be a SubcommandOption or a SubcommandGroupOption.
//
@ -53,6 +60,49 @@ type Command struct {
Version Snowflake `json:"version,omitempty"`
}
// Language is a string type for language codes, such as "en-US" or "fr". Refer
// to the constants for valid language codes.
//
// The list of all valid language codes are at
// https://discord.com/developers/docs/reference#locales
type Language string
// StringLocales is the map mapping a language code to a localized string.
type StringLocales map[Language]string
const (
Danish Language = "da"
German Language = "de"
EnglishUK Language = "en-GB"
EnglishUS Language = "en-US"
Spanish Language = "es-ES"
French Language = "fr"
Croatian Language = "hr"
Italian Language = "it"
Lithuanian Language = "lt"
Hungarian Language = "hu"
Dutch Language = "nl"
Norwegian Language = "no"
Polish Language = "pl"
PortugueseBR Language = "pt-BR"
Romanian Language = "ro"
Finnish Language = "fi"
Swedish Language = "sv-SE"
Vietnamses Language = "vi"
Turkish Language = "tr"
Czech Language = "cs"
Greek Language = "el"
Bulgarian Language = "bg"
Russian Language = "ru"
Ukrainian Language = "uk"
Hindi Language = "hi"
Thai Language = "th"
ChineseChina Language = "zh-CN"
Japanese Language = "ja"
ChineseTaiwan Language = "zh-TW"
Korean Language = "ko"
)
// CreatedAt returns a time object representing when the command was created.
func (c *Command) CreatedAt() time.Time {
return c.ID.Time()
@ -281,10 +331,18 @@ type CommandOption interface {
// SubcommandGroupOption is a subcommand group that fits into a CommandOption.
type SubcommandGroupOption struct {
OptionName string `json:"name"`
Description string `json:"description"`
Required bool `json:"required"`
Subcommands []*SubcommandOption `json:"options"`
OptionName string `json:"name"`
OptionNameLocalizations StringLocales `json:"name_localizations,omitempty"`
Description string `json:"description"`
DescriptionLocalizations StringLocales `json:"description_localizations,omitempty"`
Required bool `json:"required"`
Subcommands []*SubcommandOption `json:"options"`
// LocalizedOptionName is only populated when this is received from
// Discord's API.
LocalizedOptionName string `json:"name_localized,omitempty"`
// LocalizedDescription is only populated when this is received from
// Discord's API.
LocalizedDescription string `json:"description_localized,omitempty"`
}
// Name implements CommandOption.
@ -295,13 +353,21 @@ func (s *SubcommandGroupOption) Type() CommandOptionType { return SubcommandGrou
// SubcommandOption is a subcommand option that fits into a CommandOption.
type SubcommandOption struct {
OptionName string `json:"name"`
Description string `json:"description"`
Required bool `json:"required"`
OptionName string `json:"name"`
OptionNameLocalizations StringLocales `json:"name_localizations,omitempty"`
Description string `json:"description"`
DescriptionLocalizations StringLocales `json:"description_localizations,omitempty"`
Required bool `json:"required"`
// Options contains command option values. All CommandOption types except
// for SubcommandOption and SubcommandGroupOption will implement this
// interface.
Options []CommandOptionValue `json:"options"`
// LocalizedOptionName is only populated when this is received from
// Discord's API.
LocalizedOptionName string `json:"name_localized,omitempty"`
// LocalizedDescription is only populated when this is received from
// Discord's API.
LocalizedDescription string `json:"description_localized,omitempty"`
}
// Name implements CommandOption.
@ -363,12 +429,20 @@ type CommandOptionValue interface {
// StringOption is a subcommand option that fits into a CommandOptionValue.
type StringOption struct {
OptionName string `json:"name"`
Description string `json:"description"`
Required bool `json:"required"`
Choices []StringChoice `json:"choices,omitempty"`
OptionName string `json:"name"`
OptionNameLocalizations StringLocales `json:"name_localizations,omitempty"`
Description string `json:"description"`
DescriptionLocalizations StringLocales `json:"description_localizations,omitempty"`
Required bool `json:"required"`
Choices []StringChoice `json:"choices,omitempty"`
// Autocomplete must not be true if Choices are present.
Autocomplete bool `json:"autocomplete"`
// LocalizedOptionName is only populated when this is received from
// Discord's API.
LocalizedOptionName string `json:"name_localized,omitempty"`
// LocalizedDescription is only populated when this is received from
// Discord's API.
LocalizedDescription string `json:"description_localized,omitempty"`
}
// Name implements CommandOption.
@ -380,20 +454,31 @@ func (s *StringOption) _val() {}
// StringChoice is a pair of string key to a string.
type StringChoice struct {
Name string `json:"name"`
Value string `json:"value"`
Name string `json:"name"`
NameLocalizations StringLocales `json:"name_localizations,omitempty"`
Value string `json:"value"`
// LocalizedName is only populated when this is received from Discord's API.
LocalizedName string `json:"name_localized,omitempty"`
}
// IntegerOption is a subcommand option that fits into a CommandOptionValue.
type IntegerOption struct {
OptionName string `json:"name"`
Description string `json:"description"`
Required bool `json:"required"`
Min option.Int `json:"min_value,omitempty"`
Max option.Int `json:"max_value,omitempty"`
Choices []IntegerChoice `json:"choices,omitempty"`
OptionName string `json:"name"`
OptionNameLocalizations StringLocales `json:"name_localizations,omitempty"`
Description string `json:"description"`
DescriptionLocalizations StringLocales `json:"description_localizations,omitempty"`
Required bool `json:"required"`
Min option.Int `json:"min_value,omitempty"`
Max option.Int `json:"max_value,omitempty"`
Choices []IntegerChoice `json:"choices,omitempty"`
// Autocomplete must not be true if Choices are present.
Autocomplete bool `json:"autocomplete"`
// LocalizedOptionName is only populated when this is received from
// Discord's API.
LocalizedOptionName string `json:"name_localized,omitempty"`
// LocalizedDescription is only populated when this is received from
// Discord's API.
LocalizedDescription string `json:"description_localized,omitempty"`
}
// Name implements CommandOption.
@ -405,15 +490,26 @@ func (i *IntegerOption) _val() {}
// IntegerChoice is a pair of string key to an integer.
type IntegerChoice struct {
Name string `json:"name"`
Value int `json:"value"`
Name string `json:"name"`
NameLocalizations StringLocales `json:"name_localizations,omitempty"`
Value int `json:"value"`
// LocalizedName is only populated when this is received from Discord's API.
LocalizedName string `json:"name_localized,omitempty"`
}
// BooleanOption is a subcommand option that fits into a CommandOptionValue.
type BooleanOption struct {
OptionName string `json:"name"`
Description string `json:"description"`
Required bool `json:"required"`
OptionName string `json:"name"`
OptionNameLocalizations StringLocales `json:"name_localizations,omitempty"`
Description string `json:"description"`
DescriptionLocalizations StringLocales `json:"description_localizations,omitempty"`
Required bool `json:"required"`
// LocalizedOptionName is only populated when this is received from
// Discord's API.
LocalizedOptionName string `json:"name_localized,omitempty"`
// LocalizedDescription is only populated when this is received from
// Discord's API.
LocalizedDescription string `json:"description_localized,omitempty"`
}
// Name implements CommandOption.
@ -425,9 +521,17 @@ func (b *BooleanOption) _val() {}
// UserOption is a subcommand option that fits into a CommandOptionValue.
type UserOption struct {
OptionName string `json:"name"`
Description string `json:"description"`
Required bool `json:"required"`
OptionName string `json:"name"`
OptionNameLocalizations StringLocales `json:"name_localizations,omitempty"`
Description string `json:"description"`
DescriptionLocalizations StringLocales `json:"description_localizations,omitempty"`
Required bool `json:"required"`
// LocalizedOptionName is only populated when this is received from
// Discord's API.
LocalizedOptionName string `json:"name_localized,omitempty"`
// LocalizedDescription is only populated when this is received from
// Discord's API.
LocalizedDescription string `json:"description_localized,omitempty"`
}
// Name implements CommandOption.
@ -439,10 +543,18 @@ func (u *UserOption) _val() {}
// ChannelOption is a subcommand option that fits into a CommandOptionValue.
type ChannelOption struct {
OptionName string `json:"name"`
Description string `json:"description"`
Required bool `json:"required"`
ChannelTypes []ChannelType `json:"channel_types,omitempty"`
OptionName string `json:"name"`
OptionNameLocalizations StringLocales `json:"name_localizations,omitempty"`
Description string `json:"description"`
DescriptionLocalizations StringLocales `json:"description_localizations,omitempty"`
Required bool `json:"required"`
ChannelTypes []ChannelType `json:"channel_types,omitempty"`
// LocalizedOptionName is only populated when this is received from
// Discord's API.
LocalizedOptionName string `json:"name_localized,omitempty"`
// LocalizedDescription is only populated when this is received from
// Discord's API.
LocalizedDescription string `json:"description_localized,omitempty"`
}
// Name implements CommandOption.
@ -454,9 +566,17 @@ func (c *ChannelOption) _val() {}
// RoleOption is a subcommand option that fits into a CommandOptionValue.
type RoleOption struct {
OptionName string `json:"name"`
Description string `json:"description"`
Required bool `json:"required"`
OptionName string `json:"name"`
OptionNameLocalizations StringLocales `json:"name_localizations,omitempty"`
Description string `json:"description"`
DescriptionLocalizations StringLocales `json:"description_localizations,omitempty"`
Required bool `json:"required"`
// LocalizedOptionName is only populated when this is received from
// Discord's API.
LocalizedOptionName string `json:"name_localized,omitempty"`
// LocalizedDescription is only populated when this is received from
// Discord's API.
LocalizedDescription string `json:"description_localized,omitempty"`
}
// Name implements CommandOption.
@ -468,9 +588,17 @@ func (r *RoleOption) _val() {}
// MentionableOption is a subcommand option that fits into a CommandOptionValue.
type MentionableOption struct {
OptionName string `json:"name"`
Description string `json:"description"`
Required bool `json:"required"`
OptionName string `json:"name"`
OptionNameLocalizations StringLocales `json:"name_localizations,omitempty"`
Description string `json:"description"`
DescriptionLocalizations StringLocales `json:"description_localizations,omitempty"`
Required bool `json:"required"`
// LocalizedOptionName is only populated when this is received from
// Discord's API.
LocalizedOptionName string `json:"name_localized,omitempty"`
// LocalizedDescription is only populated when this is received from
// Discord's API.
LocalizedDescription string `json:"description_localized,omitempty"`
}
// Name implements CommandOption.
@ -482,14 +610,22 @@ func (m *MentionableOption) _val() {}
// NumberOption is a subcommand option that fits into a CommandOptionValue.
type NumberOption struct {
OptionName string `json:"name"`
Description string `json:"description"`
Required bool `json:"required"`
Min option.Float `json:"min_value,omitempty"`
Max option.Float `json:"max_value,omitempty"`
Choices []NumberChoice `json:"choices,omitempty"`
OptionName string `json:"name"`
OptionNameLocalizations StringLocales `json:"name_localizations,omitempty"`
Description string `json:"description"`
DescriptionLocalizations StringLocales `json:"description_localizations,omitempty"`
Required bool `json:"required"`
Min option.Float `json:"min_value,omitempty"`
Max option.Float `json:"max_value,omitempty"`
Choices []NumberChoice `json:"choices,omitempty"`
// Autocomplete must not be true if Choices are present.
Autocomplete bool `json:"autocomplete"`
// LocalizedOptionName is only populated when this is received from
// Discord's API.
LocalizedOptionName string `json:"name_localized,omitempty"`
// LocalizedDescription is only populated when this is received from
// Discord's API.
LocalizedDescription string `json:"description_localized,omitempty"`
}
// Name implements CommandOption.
@ -501,8 +637,11 @@ func (n *NumberOption) _val() {}
// NumberChoice is a pair of string key to a float64 values.
type NumberChoice struct {
Name string `json:"name"`
Value float64 `json:"value"`
Name string `json:"name"`
NameLocalizations StringLocales `json:"name_localizations,omitempty"`
Value float64 `json:"value"`
// LocalizedName is only populated when this is received from Discord's API.
LocalizedName string `json:"name_localized,omitempty"`
}
// NewCommand creates a new command.