From d46701d9042810204d2c708055be0a2d73050dca Mon Sep 17 00:00:00 2001 From: caneleex Date: Thu, 8 Dec 2022 15:51:41 +0100 Subject: [PATCH 1/5] add role connections --- discord/application.go | 58 ++++++++++--------- .../application_role_connection_metadata.go | 23 ++++++++ discord/user.go | 12 ++++ rest/applications.go | 13 +++++ rest/oauth2.go | 13 +++++ rest/rest_endpoints.go | 25 ++++---- 6 files changed, 106 insertions(+), 38 deletions(-) create mode 100644 discord/application_role_connection_metadata.go diff --git a/discord/application.go b/discord/application.go index 03443bac..d8f05998 100644 --- a/discord/application.go +++ b/discord/application.go @@ -9,27 +9,28 @@ import ( ) type Application struct { - ID snowflake.ID `json:"id"` - Name string `json:"name"` - Icon *string `json:"icon,omitempty"` - Description string `json:"description"` - RPCOrigins []string `json:"rpc_origins"` - BotPublic bool `json:"bot_public"` - BotRequireCodeGrant bool `json:"bot_require_code_grant"` - TermsOfServiceURL *string `json:"terms_of_service_url,omitempty"` - PrivacyPolicyURL *string `json:"privacy_policy_url,omitempty"` - CustomInstallationURL *string `json:"custom_install_url,omitempty"` - InstallationParams *InstallationParams `json:"install_params"` - Tags []string `json:"tags"` - Owner *User `json:"owner,omitempty"` - Summary string `json:"summary"` - VerifyKey string `json:"verify_key"` - Team *Team `json:"team,omitempty"` - GuildID *snowflake.ID `json:"guild_id,omitempty"` - PrimarySkuID *snowflake.ID `json:"primary_sku_id,omitempty"` - Slug *string `json:"slug,omitempty"` - Cover *string `json:"cover_image,omitempty"` - Flags ApplicationFlags `json:"flags,omitempty"` + ID snowflake.ID `json:"id"` + Name string `json:"name"` + Icon *string `json:"icon,omitempty"` + Description string `json:"description"` + RPCOrigins []string `json:"rpc_origins"` + BotPublic bool `json:"bot_public"` + BotRequireCodeGrant bool `json:"bot_require_code_grant"` + TermsOfServiceURL *string `json:"terms_of_service_url,omitempty"` + PrivacyPolicyURL *string `json:"privacy_policy_url,omitempty"` + CustomInstallationURL *string `json:"custom_install_url,omitempty"` + RoleConnectionsVerificationURL *string `json:"role_connections_verification_url"` + InstallationParams *InstallationParams `json:"install_params"` + Tags []string `json:"tags"` + Owner *User `json:"owner,omitempty"` + Summary string `json:"summary"` + VerifyKey string `json:"verify_key"` + Team *Team `json:"team,omitempty"` + GuildID *snowflake.ID `json:"guild_id,omitempty"` + PrimarySkuID *snowflake.ID `json:"primary_sku_id,omitempty"` + Slug *string `json:"slug,omitempty"` + Cover *string `json:"cover_image,omitempty"` + Flags ApplicationFlags `json:"flags,omitempty"` } func (a Application) IconURL(opts ...CDNOpt) *string { @@ -100,13 +101,14 @@ const ( OAuth2ScopeGuildsMembersRead OAuth2Scope = "guilds.members.read" OAuth2ScopeGDMJoin OAuth2Scope = "gdm.join" - OAuth2ScopeRelationshipsRead OAuth2Scope = "relationships.read" - OAuth2ScopeIdentify OAuth2Scope = "identify" - OAuth2ScopeEmail OAuth2Scope = "email" - OAuth2ScopeConnections OAuth2Scope = "connections" - OAuth2ScopeBot OAuth2Scope = "bot" - OAuth2ScopeMessagesRead OAuth2Scope = "messages.read" - OAuth2ScopeWebhookIncoming OAuth2Scope = "webhook.incoming" + OAuth2ScopeRelationshipsRead OAuth2Scope = "relationships.read" + OAuth2ScopeRoleConnectionsWrite OAuth2Scope = "role_connections.write" + OAuth2ScopeIdentify OAuth2Scope = "identify" + OAuth2ScopeEmail OAuth2Scope = "email" + OAuth2ScopeConnections OAuth2Scope = "connections" + OAuth2ScopeBot OAuth2Scope = "bot" + OAuth2ScopeMessagesRead OAuth2Scope = "messages.read" + OAuth2ScopeWebhookIncoming OAuth2Scope = "webhook.incoming" ) func (s OAuth2Scope) String() string { diff --git a/discord/application_role_connection_metadata.go b/discord/application_role_connection_metadata.go new file mode 100644 index 00000000..822a0fb4 --- /dev/null +++ b/discord/application_role_connection_metadata.go @@ -0,0 +1,23 @@ +package discord + +type ApplicationRoleConnectionMetadata struct { + Type ApplicationRoleConnectionMetadataType `json:"type"` + Key string `json:"key"` + Name string `json:"name"` + NameLocalizations map[Locale]string `json:"name_localizations,omitempty"` + Description string `json:"description"` + DescriptionLocalizations map[Locale]string `json:"description_localizations,omitempty"` +} + +type ApplicationRoleConnectionMetadataType int + +const ( + IntegerLessThanOrEqual ApplicationRoleConnectionMetadataType = iota + 1 + IntegerGreaterThanOrEqual + IntegerEqual + IntegerNotEqual + DateTimeLessThanOrEqual + DateTimeGreaterThanOrEqual + BooleanEqual + BooleanNotEqual +) diff --git a/discord/user.go b/discord/user.go index f03be2ef..e4ea2b9e 100644 --- a/discord/user.go +++ b/discord/user.go @@ -170,3 +170,15 @@ type SelfUserUpdate struct { Username string `json:"username,omitempty"` Avatar *json.Nullable[Icon] `json:"avatar,omitempty"` } + +type ApplicationRoleConnection struct { + PlatformName *string `json:"platform_name"` + PlatformUsername *string `json:"platform_username"` + Metadata ApplicationRoleConnectionMetadata `json:"metadata"` +} + +type ApplicationRoleConnectionUpdate struct { + PlatformName *string `json:"platform_name,omitempty"` + PlatformUsername *string `json:"platform_username,omitempty"` + Metadata *ApplicationRoleConnectionMetadata `json:"metadata,omitempty"` +} diff --git a/rest/applications.go b/rest/applications.go index d20d425e..411c52fa 100644 --- a/rest/applications.go +++ b/rest/applications.go @@ -28,6 +28,9 @@ type Applications interface { GetGuildCommandsPermissions(applicationID snowflake.ID, guildID snowflake.ID, opts ...RequestOpt) ([]discord.ApplicationCommandPermissions, error) GetGuildCommandPermissions(applicationID snowflake.ID, guildID snowflake.ID, commandID snowflake.ID, opts ...RequestOpt) (*discord.ApplicationCommandPermissions, error) + + GetApplicationRoleConnectionMetadataRecords(applicationID snowflake.ID, opts ...RequestOpt) ([]discord.ApplicationRoleConnectionMetadata, error) + UpdateApplicationRoleConnectionMetadataRecords(applicationID snowflake.ID, newRecords []discord.ApplicationRoleConnectionMetadata, opts ...RequestOpt) ([]discord.ApplicationRoleConnectionMetadata, error) } type applicationsImpl struct { @@ -142,6 +145,16 @@ func (s *applicationsImpl) GetGuildCommandPermissions(applicationID snowflake.ID return } +func (s *applicationsImpl) GetApplicationRoleConnectionMetadataRecords(applicationID snowflake.ID, opts ...RequestOpt) (metadata []discord.ApplicationRoleConnectionMetadata, err error) { + err = s.client.Do(GetApplicationRoleConnectionMetadataRecords.Compile(nil, applicationID), nil, &metadata, opts...) + return +} + +func (s *applicationsImpl) UpdateApplicationRoleConnectionMetadataRecords(applicationID snowflake.ID, newRecords []discord.ApplicationRoleConnectionMetadata, opts ...RequestOpt) (metadata []discord.ApplicationRoleConnectionMetadata, err error) { + err = s.client.Do(UpdateApplicationRoleConnectionMetadataRecords.Compile(nil, applicationID), newRecords, &metadata, opts...) + return +} + func unmarshalApplicationCommandsToApplicationCommands(unmarshalCommands []discord.UnmarshalApplicationCommand) []discord.ApplicationCommand { commands := make([]discord.ApplicationCommand, len(unmarshalCommands)) for i := range unmarshalCommands { diff --git a/rest/oauth2.go b/rest/oauth2.go index d5fe8623..18a1bcb9 100644 --- a/rest/oauth2.go +++ b/rest/oauth2.go @@ -25,6 +25,9 @@ type OAuth2 interface { SetGuildCommandPermissions(bearerToken string, applicationID snowflake.ID, guildID snowflake.ID, commandID snowflake.ID, commandPermissions []discord.ApplicationCommandPermission, opts ...RequestOpt) (*discord.ApplicationCommandPermissions, error) + GetCurrentUserApplicationRoleConnection(applicationID snowflake.ID, opts ...RequestOpt) (discord.ApplicationRoleConnection, error) + UpdateCurrentUserApplicationRoleConnection(applicationID snowflake.ID, connectionUpdate discord.ApplicationRoleConnectionUpdate, opts ...RequestOpt) (discord.ApplicationRoleConnection, error) + GetAccessToken(clientID snowflake.ID, clientSecret string, code string, redirectURI string, opts ...RequestOpt) (*discord.AccessTokenResponse, error) RefreshAccessToken(clientID snowflake.ID, clientSecret string, refreshToken string, opts ...RequestOpt) (*discord.AccessTokenResponse, error) } @@ -97,6 +100,16 @@ func (s *oAuth2Impl) SetGuildCommandPermissions(bearerToken string, applicationI return } +func (s *oAuth2Impl) GetCurrentUserApplicationRoleConnection(applicationID snowflake.ID, opts ...RequestOpt) (connection discord.ApplicationRoleConnection, err error) { + err = s.client.Do(GetCurrentUserApplicationRoleConnection.Compile(nil, applicationID), nil, &connection, opts...) + return +} + +func (s *oAuth2Impl) UpdateCurrentUserApplicationRoleConnection(applicationID snowflake.ID, connectionUpdate discord.ApplicationRoleConnectionUpdate, opts ...RequestOpt) (connection discord.ApplicationRoleConnection, err error) { + err = s.client.Do(UpdateCurrentUserApplicationRoleConnection.Compile(nil, applicationID), connectionUpdate, &connection, opts...) + return +} + func (s *oAuth2Impl) exchangeAccessToken(clientID snowflake.ID, clientSecret string, grantType discord.GrantType, codeOrRefreshToken string, redirectURI string, opts ...RequestOpt) (exchange *discord.AccessTokenResponse, err error) { values := url.Values{ "client_id": []string{clientID.String()}, diff --git a/rest/rest_endpoints.go b/rest/rest_endpoints.go index c63b1be3..72f20954 100644 --- a/rest/rest_endpoints.go +++ b/rest/rest_endpoints.go @@ -35,15 +35,17 @@ var ( // Users var ( - GetUser = NewEndpoint(http.MethodGet, "/users/{user.id}") - GetCurrentUser = NewEndpoint(http.MethodGet, "/users/@me") - GetCurrentMember = NewEndpoint(http.MethodGet, "/users/@me/guilds/{guild.id}/member") - UpdateSelfUser = NewEndpoint(http.MethodPatch, "/users/@me") - GetCurrentUserConnections = NewNoBotAuthEndpoint(http.MethodGet, "/users/@me/connections") - GetCurrentUserGuilds = NewNoBotAuthEndpoint(http.MethodGet, "/users/@me/guilds") - LeaveGuild = NewEndpoint(http.MethodDelete, "/users/@me/guilds/{guild.id}") - GetDMChannels = NewEndpoint(http.MethodGet, "/users/@me/channels") - CreateDMChannel = NewEndpoint(http.MethodPost, "/users/@me/channels") + GetUser = NewEndpoint(http.MethodGet, "/users/{user.id}") + GetCurrentUser = NewEndpoint(http.MethodGet, "/users/@me") + GetCurrentMember = NewEndpoint(http.MethodGet, "/users/@me/guilds/{guild.id}/member") + UpdateSelfUser = NewEndpoint(http.MethodPatch, "/users/@me") + GetCurrentUserConnections = NewNoBotAuthEndpoint(http.MethodGet, "/users/@me/connections") + GetCurrentUserGuilds = NewNoBotAuthEndpoint(http.MethodGet, "/users/@me/guilds") + GetCurrentUserApplicationRoleConnection = NewNoBotAuthEndpoint(http.MethodGet, "/users/@me/applications/{application.id}/role-connection") + UpdateCurrentUserApplicationRoleConnection = NewNoBotAuthEndpoint(http.MethodPut, "/users/@me/applications/{application.id}/role-connection") + LeaveGuild = NewEndpoint(http.MethodDelete, "/users/@me/guilds/{guild.id}") + GetDMChannels = NewEndpoint(http.MethodGet, "/users/@me/channels") + CreateDMChannel = NewEndpoint(http.MethodPost, "/users/@me/channels") ) // Guilds @@ -249,7 +251,7 @@ var ( GetChannelInvites = NewEndpoint(http.MethodGet, "/channels/{channel.id}/invites") ) -// Interactions +// Applications var ( GetGlobalCommands = NewEndpoint(http.MethodGet, "/applications/{application.id}/commands") GetGlobalCommand = NewEndpoint(http.MethodGet, "/applications/{application.id}/command/{command.id}") @@ -278,6 +280,9 @@ var ( CreateFollowupMessage = NewNoBotAuthEndpoint(http.MethodPost, "/webhooks/{application.id}/{interaction.token}") UpdateFollowupMessage = NewNoBotAuthEndpoint(http.MethodPatch, "/webhooks/{application.id}/{interaction.token}/messages/{message.id}") DeleteFollowupMessage = NewNoBotAuthEndpoint(http.MethodDelete, "/webhooks/{application.id}/{interaction.token}/messages/{message.id}") + + GetApplicationRoleConnectionMetadataRecords = NewEndpoint(http.MethodGet, "/applications/{application.id}/role-connections/metadata") + UpdateApplicationRoleConnectionMetadataRecords = NewEndpoint(http.MethodPut, "/applications/{application.id}/role-connections/metadata") ) // NewEndpoint returns a new Endpoint which requires bot auth with the given http method & route. From a779ffe2c2e3a1e2f81755dfa7ae5be90679c3e7 Mon Sep 17 00:00:00 2001 From: caneleex Date: Thu, 8 Dec 2022 19:47:49 +0100 Subject: [PATCH 2/5] fix borked merge --- discord/application.go | 44 +++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/discord/application.go b/discord/application.go index 95cb2583..8d4e1186 100644 --- a/discord/application.go +++ b/discord/application.go @@ -9,28 +9,28 @@ import ( ) type Application struct { - ID snowflake.ID `json:"id"` - Name string `json:"name"` - Icon *string `json:"icon,omitempty"` - Description string `json:"description"` - RPCOrigins []string `json:"rpc_origins"` - BotPublic bool `json:"bot_public"` - BotRequireCodeGrant bool `json:"bot_require_code_grant"` - TermsOfServiceURL *string `json:"terms_of_service_url,omitempty"` - PrivacyPolicyURL *string `json:"privacy_policy_url,omitempty"` - CustomInstallURL *string `json:"custom_install_url,omitempty"` - RoleConnectionsVerificationURL *string `json:"role_connections_verification_url"` - InstallParams *InstallParams `json:"install_params"` - Tags []string `json:"tags"` - Owner *User `json:"owner,omitempty"` - Summary string `json:"summary"` - VerifyKey string `json:"verify_key"` - Team *Team `json:"team,omitempty"` - GuildID *snowflake.ID `json:"guild_id,omitempty"` - PrimarySkuID *snowflake.ID `json:"primary_sku_id,omitempty"` - Slug *string `json:"slug,omitempty"` - Cover *string `json:"cover_image,omitempty"` - Flags ApplicationFlags `json:"flags,omitempty"` + ID snowflake.ID `json:"id"` + Name string `json:"name"` + Icon *string `json:"icon,omitempty"` + Description string `json:"description"` + RPCOrigins []string `json:"rpc_origins"` + BotPublic bool `json:"bot_public"` + BotRequireCodeGrant bool `json:"bot_require_code_grant"` + TermsOfServiceURL *string `json:"terms_of_service_url,omitempty"` + PrivacyPolicyURL *string `json:"privacy_policy_url,omitempty"` + CustomInstallURL *string `json:"custom_install_url,omitempty"` + RoleConnectionsVerificationURL *string `json:"role_connections_verification_url"` + InstallParams *InstallParams `json:"install_params"` + Tags []string `json:"tags"` + Owner *User `json:"owner,omitempty"` + Summary string `json:"summary"` + VerifyKey string `json:"verify_key"` + Team *Team `json:"team,omitempty"` + GuildID *snowflake.ID `json:"guild_id,omitempty"` + PrimarySkuID *snowflake.ID `json:"primary_sku_id,omitempty"` + Slug *string `json:"slug,omitempty"` + CoverImage *string `json:"cover_image,omitempty"` + Flags ApplicationFlags `json:"flags,omitempty"` } func (a Application) IconURL(opts ...CDNOpt) *string { From e5b76a4e7d4e013961ac28bee87a0ba329d427e4 Mon Sep 17 00:00:00 2001 From: caneleex Date: Tue, 13 Dec 2022 07:19:06 +0100 Subject: [PATCH 3/5] address reviews --- discord/application_role_connection_metadata.go | 16 ++++++++-------- rest/applications.go | 12 ++++++------ rest/rest_endpoints.go | 4 ++-- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/discord/application_role_connection_metadata.go b/discord/application_role_connection_metadata.go index 822a0fb4..825d1029 100644 --- a/discord/application_role_connection_metadata.go +++ b/discord/application_role_connection_metadata.go @@ -12,12 +12,12 @@ type ApplicationRoleConnectionMetadata struct { type ApplicationRoleConnectionMetadataType int const ( - IntegerLessThanOrEqual ApplicationRoleConnectionMetadataType = iota + 1 - IntegerGreaterThanOrEqual - IntegerEqual - IntegerNotEqual - DateTimeLessThanOrEqual - DateTimeGreaterThanOrEqual - BooleanEqual - BooleanNotEqual + ApplicationRoleConnectionMetadataTypeIntegerLessThanOrEqual ApplicationRoleConnectionMetadataType = iota + 1 + ApplicationRoleConnectionMetadataTypeIntegerGreaterThanOrEqual + ApplicationRoleConnectionMetadataTypeIntegerEqual + ApplicationRoleConnectionMetadataTypeIntegerNotEqual + ApplicationRoleConnectionMetadataTypeDateTimeLessThanOrEqual + ApplicationRoleConnectionMetadataTypeDateTimeGreaterThanOrEqual + ApplicationRoleConnectionMetadataTypeBooleanEqual + ApplicationRoleConnectionMetadataTypeBooleanNotEqual ) diff --git a/rest/applications.go b/rest/applications.go index 411c52fa..c11e411c 100644 --- a/rest/applications.go +++ b/rest/applications.go @@ -29,8 +29,8 @@ type Applications interface { GetGuildCommandsPermissions(applicationID snowflake.ID, guildID snowflake.ID, opts ...RequestOpt) ([]discord.ApplicationCommandPermissions, error) GetGuildCommandPermissions(applicationID snowflake.ID, guildID snowflake.ID, commandID snowflake.ID, opts ...RequestOpt) (*discord.ApplicationCommandPermissions, error) - GetApplicationRoleConnectionMetadataRecords(applicationID snowflake.ID, opts ...RequestOpt) ([]discord.ApplicationRoleConnectionMetadata, error) - UpdateApplicationRoleConnectionMetadataRecords(applicationID snowflake.ID, newRecords []discord.ApplicationRoleConnectionMetadata, opts ...RequestOpt) ([]discord.ApplicationRoleConnectionMetadata, error) + GetApplicationRoleConnectionMetadata(applicationID snowflake.ID, opts ...RequestOpt) ([]discord.ApplicationRoleConnectionMetadata, error) + UpdateApplicationRoleConnectionMetadata(applicationID snowflake.ID, newRecords []discord.ApplicationRoleConnectionMetadata, opts ...RequestOpt) ([]discord.ApplicationRoleConnectionMetadata, error) } type applicationsImpl struct { @@ -145,13 +145,13 @@ func (s *applicationsImpl) GetGuildCommandPermissions(applicationID snowflake.ID return } -func (s *applicationsImpl) GetApplicationRoleConnectionMetadataRecords(applicationID snowflake.ID, opts ...RequestOpt) (metadata []discord.ApplicationRoleConnectionMetadata, err error) { - err = s.client.Do(GetApplicationRoleConnectionMetadataRecords.Compile(nil, applicationID), nil, &metadata, opts...) +func (s *applicationsImpl) GetApplicationRoleConnectionMetadata(applicationID snowflake.ID, opts ...RequestOpt) (metadata []discord.ApplicationRoleConnectionMetadata, err error) { + err = s.client.Do(GetApplicationRoleConnectionMetadata.Compile(nil, applicationID), nil, &metadata, opts...) return } -func (s *applicationsImpl) UpdateApplicationRoleConnectionMetadataRecords(applicationID snowflake.ID, newRecords []discord.ApplicationRoleConnectionMetadata, opts ...RequestOpt) (metadata []discord.ApplicationRoleConnectionMetadata, err error) { - err = s.client.Do(UpdateApplicationRoleConnectionMetadataRecords.Compile(nil, applicationID), newRecords, &metadata, opts...) +func (s *applicationsImpl) UpdateApplicationRoleConnectionMetadata(applicationID snowflake.ID, newRecords []discord.ApplicationRoleConnectionMetadata, opts ...RequestOpt) (metadata []discord.ApplicationRoleConnectionMetadata, err error) { + err = s.client.Do(UpdateApplicationRoleConnectionMetadata.Compile(nil, applicationID), newRecords, &metadata, opts...) return } diff --git a/rest/rest_endpoints.go b/rest/rest_endpoints.go index 72f20954..bf789506 100644 --- a/rest/rest_endpoints.go +++ b/rest/rest_endpoints.go @@ -281,8 +281,8 @@ var ( UpdateFollowupMessage = NewNoBotAuthEndpoint(http.MethodPatch, "/webhooks/{application.id}/{interaction.token}/messages/{message.id}") DeleteFollowupMessage = NewNoBotAuthEndpoint(http.MethodDelete, "/webhooks/{application.id}/{interaction.token}/messages/{message.id}") - GetApplicationRoleConnectionMetadataRecords = NewEndpoint(http.MethodGet, "/applications/{application.id}/role-connections/metadata") - UpdateApplicationRoleConnectionMetadataRecords = NewEndpoint(http.MethodPut, "/applications/{application.id}/role-connections/metadata") + GetApplicationRoleConnectionMetadata = NewEndpoint(http.MethodGet, "/applications/{application.id}/role-connections/metadata") + UpdateApplicationRoleConnectionMetadata = NewEndpoint(http.MethodPut, "/applications/{application.id}/role-connections/metadata") ) // NewEndpoint returns a new Endpoint which requires bot auth with the given http method & route. From 3ef2632f6386a44a6309db7ec932f4efa2a12b95 Mon Sep 17 00:00:00 2001 From: TopiSenpai Date: Wed, 14 Dec 2022 18:37:02 +0100 Subject: [PATCH 4/5] fix application role connection routes not accepting a bearer token, add new routes to oauth2 client & fix ApplicationRoleConnection metadata type --- _examples/verified_roles/main.go | 113 +++++++++++++++++++++++++++++++ discord/user.go | 12 ++-- oauth2/client.go | 4 ++ oauth2/client_impl.go | 50 ++++++++------ rest/oauth2.go | 12 ++-- 5 files changed, 160 insertions(+), 31 deletions(-) create mode 100644 _examples/verified_roles/main.go diff --git a/_examples/verified_roles/main.go b/_examples/verified_roles/main.go new file mode 100644 index 00000000..390c1794 --- /dev/null +++ b/_examples/verified_roles/main.go @@ -0,0 +1,113 @@ +package main + +import ( + "math/rand" + "net/http" + "os" + "strconv" + + "github.com/disgoorg/disgo" + "github.com/disgoorg/disgo/bot" + "github.com/disgoorg/disgo/discord" + "github.com/disgoorg/disgo/oauth2" + "github.com/disgoorg/json" + "github.com/disgoorg/log" +) + +var ( + letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") + token = os.Getenv("disgo_token") + clientSecret = os.Getenv("disgo_client_secret") + baseURL = os.Getenv("disgo_base_url") + client bot.Client + oAuth2Client oauth2.Client +) + +func main() { + log.SetLevel(log.LevelDebug) + log.Info("starting example...") + log.Infof("disgo %s", disgo.Version) + + var err error + client, err = disgo.New(token) + if err != nil { + log.Panic(err) + } + + _, _ = client.Rest().UpdateApplicationRoleConnectionMetadata(client.ApplicationID(), []discord.ApplicationRoleConnectionMetadata{ + { + Type: discord.ApplicationRoleConnectionMetadataTypeIntegerGreaterThanOrEqual, + Key: "cookies_eaten", + Name: "Cookies Eaten", + Description: "How many cookies have you eaten?", + }, + }) + + oAuth2Client = oauth2.New(client.ApplicationID(), clientSecret) + + mux := http.NewServeMux() + mux.HandleFunc("/verify", handleVerify) + mux.HandleFunc("/callback", handleCallback) + _ = http.ListenAndServe(":6969", mux) +} + +func handleVerify(w http.ResponseWriter, r *http.Request) { + http.Redirect(w, r, oAuth2Client.GenerateAuthorizationURL(baseURL+"/callback", discord.PermissionsNone, 0, false, discord.OAuth2ScopeIdentify, discord.OAuth2ScopeRoleConnectionsWrite), http.StatusTemporaryRedirect) +} + +func handleCallback(w http.ResponseWriter, r *http.Request) { + var ( + query = r.URL.Query() + code = query.Get("code") + state = query.Get("state") + ) + if code != "" && state != "" { + identifier := randStr(32) + session, err := oAuth2Client.StartSession(code, state, identifier) + if err != nil { + writeError(w, "error while starting session", err) + return + } + + user, err := oAuth2Client.GetUser(session) + if err != nil { + writeError(w, "error while getting user", err) + return + } + + _, err = oAuth2Client.UpdateApplicationRoleConnection(session, client.ApplicationID(), discord.ApplicationRoleConnectionUpdate{ + PlatformName: json.Ptr("Cookie Monster " + user.Username), + PlatformUsername: json.Ptr("Cookie Monster " + user.Tag()), + Metadata: &map[string]string{ + "cookies_eaten": strconv.Itoa(rand.Intn(100)), + }, + }) + if err != nil { + writeError(w, "error while updating role connection", err) + return + } + + metadata, err := oAuth2Client.GetApplicationRoleConnection(session, client.ApplicationID()) + if err != nil { + writeError(w, "error while getting role connection", err) + return + } + + data, _ := json.MarshalIndent(metadata, "", "\t") + _, _ = w.Write([]byte("updated role connection:\n" + string(data))) + + } +} + +func writeError(w http.ResponseWriter, text string, err error) { + w.WriteHeader(http.StatusInternalServerError) + _, _ = w.Write([]byte(text + ": " + err.Error())) +} + +func randStr(n int) string { + b := make([]rune, n) + for i := range b { + b[i] = letters[rand.Intn(len(letters))] + } + return string(b) +} diff --git a/discord/user.go b/discord/user.go index e4ea2b9e..42f9c63d 100644 --- a/discord/user.go +++ b/discord/user.go @@ -172,13 +172,13 @@ type SelfUserUpdate struct { } type ApplicationRoleConnection struct { - PlatformName *string `json:"platform_name"` - PlatformUsername *string `json:"platform_username"` - Metadata ApplicationRoleConnectionMetadata `json:"metadata"` + PlatformName *string `json:"platform_name"` + PlatformUsername *string `json:"platform_username"` + Metadata map[string]string `json:"metadata"` } type ApplicationRoleConnectionUpdate struct { - PlatformName *string `json:"platform_name,omitempty"` - PlatformUsername *string `json:"platform_username,omitempty"` - Metadata *ApplicationRoleConnectionMetadata `json:"metadata,omitempty"` + PlatformName *string `json:"platform_name,omitempty"` + PlatformUsername *string `json:"platform_username,omitempty"` + Metadata *map[string]string `json:"metadata,omitempty"` } diff --git a/oauth2/client.go b/oauth2/client.go index ab4c6657..83e0d642 100644 --- a/oauth2/client.go +++ b/oauth2/client.go @@ -55,4 +55,8 @@ type Client interface { GetGuilds(session Session, opts ...rest.RequestOpt) ([]discord.OAuth2Guild, error) // GetConnections returns the discord.Connection(s) the user has connected. This requires the discord.OAuth2ScopeConnections scope in the Session GetConnections(session Session, opts ...rest.RequestOpt) ([]discord.Connection, error) + // GetApplicationRoleConnection returns the discord.ApplicationRoleConnection for the given application. This requires the discord.OAuth2ScopeRoleConnectionsWrite scope in the Session + GetApplicationRoleConnection(session Session, applicationID snowflake.ID, opts ...rest.RequestOpt) (*discord.ApplicationRoleConnection, error) + // UpdateApplicationRoleConnection updates the discord.ApplicationRoleConnection for the given application. This requires the discord.OAuth2ScopeRoleConnectionsWrite scope in the Session + UpdateApplicationRoleConnection(session Session, applicationID snowflake.ID, update discord.ApplicationRoleConnectionUpdate, opts ...rest.RequestOpt) (*discord.ApplicationRoleConnection, error) } diff --git a/oauth2/client_impl.go b/oauth2/client_impl.go index 33902e6f..7d3ba4ab 100644 --- a/oauth2/client_impl.go +++ b/oauth2/client_impl.go @@ -90,41 +90,53 @@ func (c *clientImpl) RefreshSession(identifier string, session Session, opts ... } func (c *clientImpl) GetUser(session Session, opts ...rest.RequestOpt) (*discord.OAuth2User, error) { - if session.Expiration().Before(time.Now()) { - return nil, ErrAccessTokenExpired - } - if !discord.HasScope(discord.OAuth2ScopeIdentify, session.Scopes()...) { - return nil, ErrMissingOAuth2Scope(discord.OAuth2ScopeIdentify) + if err := checkSession(session, discord.OAuth2ScopeIdentify); err != nil { + return nil, err } return c.Rest().GetCurrentUser(session.AccessToken(), opts...) } func (c *clientImpl) GetMember(session Session, guildID snowflake.ID, opts ...rest.RequestOpt) (*discord.Member, error) { - if session.Expiration().Before(time.Now()) { - return nil, ErrAccessTokenExpired - } - if !discord.HasScope(discord.OAuth2ScopeGuildsMembersRead, session.Scopes()...) { - return nil, ErrMissingOAuth2Scope(discord.OAuth2ScopeGuildsMembersRead) + if err := checkSession(session, discord.OAuth2ScopeGuildsMembersRead); err != nil { + return nil, err } return c.Rest().GetCurrentMember(session.AccessToken(), guildID, opts...) } func (c *clientImpl) GetGuilds(session Session, opts ...rest.RequestOpt) ([]discord.OAuth2Guild, error) { - if session.Expiration().Before(time.Now()) { - return nil, ErrAccessTokenExpired - } - if !discord.HasScope(discord.OAuth2ScopeGuilds, session.Scopes()...) { - return nil, ErrMissingOAuth2Scope(discord.OAuth2ScopeGuilds) + if err := checkSession(session, discord.OAuth2ScopeGuilds); err != nil { + return nil, err } return c.Rest().GetCurrentUserGuilds(session.AccessToken(), 0, 0, 0, opts...) } func (c *clientImpl) GetConnections(session Session, opts ...rest.RequestOpt) ([]discord.Connection, error) { + if err := checkSession(session, discord.OAuth2ScopeConnections); err != nil { + return nil, err + } + return c.Rest().GetCurrentUserConnections(session.AccessToken(), opts...) +} + +func (c *clientImpl) GetApplicationRoleConnection(session Session, applicationID snowflake.ID, opts ...rest.RequestOpt) (*discord.ApplicationRoleConnection, error) { + if err := checkSession(session, discord.OAuth2ScopeRoleConnectionsWrite); err != nil { + return nil, err + } + return c.Rest().GetCurrentUserApplicationRoleConnection(session.AccessToken(), applicationID, opts...) +} + +func (c *clientImpl) UpdateApplicationRoleConnection(session Session, applicationID snowflake.ID, update discord.ApplicationRoleConnectionUpdate, opts ...rest.RequestOpt) (*discord.ApplicationRoleConnection, error) { + if err := checkSession(session, discord.OAuth2ScopeRoleConnectionsWrite); err != nil { + return nil, err + } + return c.Rest().UpdateCurrentUserApplicationRoleConnection(session.AccessToken(), applicationID, update, opts...) +} + +func checkSession(session Session, scope discord.OAuth2Scope) error { if session.Expiration().Before(time.Now()) { - return nil, ErrAccessTokenExpired + return ErrAccessTokenExpired } - if !discord.HasScope(discord.OAuth2ScopeConnections, session.Scopes()...) { - return nil, ErrMissingOAuth2Scope(discord.OAuth2ScopeConnections) + if !discord.HasScope(scope, session.Scopes()...) { + return ErrMissingOAuth2Scope(scope) } - return c.Rest().GetCurrentUserConnections(session.AccessToken(), opts...) + return nil } diff --git a/rest/oauth2.go b/rest/oauth2.go index 18a1bcb9..94203996 100644 --- a/rest/oauth2.go +++ b/rest/oauth2.go @@ -25,8 +25,8 @@ type OAuth2 interface { SetGuildCommandPermissions(bearerToken string, applicationID snowflake.ID, guildID snowflake.ID, commandID snowflake.ID, commandPermissions []discord.ApplicationCommandPermission, opts ...RequestOpt) (*discord.ApplicationCommandPermissions, error) - GetCurrentUserApplicationRoleConnection(applicationID snowflake.ID, opts ...RequestOpt) (discord.ApplicationRoleConnection, error) - UpdateCurrentUserApplicationRoleConnection(applicationID snowflake.ID, connectionUpdate discord.ApplicationRoleConnectionUpdate, opts ...RequestOpt) (discord.ApplicationRoleConnection, error) + GetCurrentUserApplicationRoleConnection(bearerToken string, applicationID snowflake.ID, opts ...RequestOpt) (*discord.ApplicationRoleConnection, error) + UpdateCurrentUserApplicationRoleConnection(bearerToken string, applicationID snowflake.ID, connectionUpdate discord.ApplicationRoleConnectionUpdate, opts ...RequestOpt) (*discord.ApplicationRoleConnection, error) GetAccessToken(clientID snowflake.ID, clientSecret string, code string, redirectURI string, opts ...RequestOpt) (*discord.AccessTokenResponse, error) RefreshAccessToken(clientID snowflake.ID, clientSecret string, refreshToken string, opts ...RequestOpt) (*discord.AccessTokenResponse, error) @@ -100,13 +100,13 @@ func (s *oAuth2Impl) SetGuildCommandPermissions(bearerToken string, applicationI return } -func (s *oAuth2Impl) GetCurrentUserApplicationRoleConnection(applicationID snowflake.ID, opts ...RequestOpt) (connection discord.ApplicationRoleConnection, err error) { - err = s.client.Do(GetCurrentUserApplicationRoleConnection.Compile(nil, applicationID), nil, &connection, opts...) +func (s *oAuth2Impl) GetCurrentUserApplicationRoleConnection(bearerToken string, applicationID snowflake.ID, opts ...RequestOpt) (connection *discord.ApplicationRoleConnection, err error) { + err = s.client.Do(GetCurrentUserApplicationRoleConnection.Compile(nil, applicationID), nil, &connection, withBearerToken(bearerToken, opts)...) return } -func (s *oAuth2Impl) UpdateCurrentUserApplicationRoleConnection(applicationID snowflake.ID, connectionUpdate discord.ApplicationRoleConnectionUpdate, opts ...RequestOpt) (connection discord.ApplicationRoleConnection, err error) { - err = s.client.Do(UpdateCurrentUserApplicationRoleConnection.Compile(nil, applicationID), connectionUpdate, &connection, opts...) +func (s *oAuth2Impl) UpdateCurrentUserApplicationRoleConnection(bearerToken string, applicationID snowflake.ID, connectionUpdate discord.ApplicationRoleConnectionUpdate, opts ...RequestOpt) (connection *discord.ApplicationRoleConnection, err error) { + err = s.client.Do(UpdateCurrentUserApplicationRoleConnection.Compile(nil, applicationID), connectionUpdate, &connection, withBearerToken(bearerToken, opts)...) return } From f3a4a027da63404ba7fb242f04f4b5185cec940a Mon Sep 17 00:00:00 2001 From: TopiSenpai Date: Thu, 15 Dec 2022 17:11:30 +0100 Subject: [PATCH 5/5] add description field to roles --- discord/role.go | 1 + 1 file changed, 1 insertion(+) diff --git a/discord/role.go b/discord/role.go index 83717987..d106df59 100644 --- a/discord/role.go +++ b/discord/role.go @@ -13,6 +13,7 @@ var _ Mentionable = (*Role)(nil) type Role struct { ID snowflake.ID `json:"id"` Name string `json:"name"` + Description *string `json:"description,omitempty"` Color int `json:"color"` Hoist bool `json:"hoist"` Position int `json:"position"`