/// <inheritdoc />
        public override async Task <IRetrieveRestEntityResult <IInvite> > GetInviteAsync
        (
            string inviteCode,
            Optional <bool> withCounts = default,
            CancellationToken ct       = default
        )
        {
            var key = KeyHelpers.CreateInviteCacheKey(inviteCode);

            if (_cacheService.TryGetValue <IInvite>(key, out var cachedInstance))
            {
                return(RetrieveRestEntityResult <IInvite> .FromSuccess(cachedInstance));
            }

            var getInvite = await base.GetInviteAsync(inviteCode, withCounts, ct);

            if (!getInvite.IsSuccess)
            {
                return(getInvite);
            }

            var invite = getInvite.Entity;

            _cacheService.Cache(key, invite);

            return(getInvite);
        }
Example #2
0
        /// <inheritdoc />
        public override async Task <IRetrieveRestEntityResult <IApplication> > GetCurrentApplicationInformationAsync
        (
            CancellationToken ct = default
        )
        {
            var key = KeyHelpers.CreateCurrentApplicationCacheKey();

            if (_cacheService.TryGetValue <IApplication>(key, out var cachedInstance))
            {
                return(RetrieveRestEntityResult <IApplication> .FromSuccess(cachedInstance));
            }

            var getCurrent = await base.GetCurrentApplicationInformationAsync(ct);

            if (!getCurrent.IsSuccess)
            {
                return(getCurrent);
            }

            var application = getCurrent.Entity;

            _cacheService.Cache(key, application);

            return(getCurrent);
        }
        /// <inheritdoc />
        public override async Task <IRetrieveRestEntityResult <IBan> > GetGuildBanAsync
        (
            Snowflake guildID,
            Snowflake userID,
            CancellationToken ct = default
        )
        {
            var key = KeyHelpers.CreateGuildBanCacheKey(guildID, userID);

            if (_cacheService.TryGetValue <IBan>(key, out var cachedInstance))
            {
                return(RetrieveRestEntityResult <IBan> .FromSuccess(cachedInstance));
            }

            var getResult = await base.GetGuildBanAsync(guildID, userID, ct);

            if (!getResult.IsSuccess)
            {
                return(getResult);
            }

            var ban = getResult.Entity;

            _cacheService.Cache(key, ban);

            return(getResult);
        }
        /// <inheritdoc />
        public override async Task <IRetrieveRestEntityResult <IReadOnlyList <IChannel> > > GetGuildChannelsAsync
        (
            Snowflake guildID,
            CancellationToken ct = default
        )
        {
            var key = KeyHelpers.CreateGuildChannelsCacheKey(guildID);

            if (_cacheService.TryGetValue <IReadOnlyList <IChannel> >(key, out var cachedInstance))
            {
                return(RetrieveRestEntityResult <IReadOnlyList <IChannel> > .FromSuccess(cachedInstance));
            }

            var getResult = await base.GetGuildChannelsAsync(guildID, ct);

            if (!getResult.IsSuccess)
            {
                return(getResult);
            }

            var channels = getResult.Entity;

            _cacheService.Cache(key, channels);

            foreach (var channel in channels)
            {
                var channelKey = KeyHelpers.CreateChannelCacheKey(channel.ID);
                _cacheService.Cache(channelKey, channel);
            }

            return(getResult);
        }
        /// <inheritdoc />
        public override async Task <IRetrieveRestEntityResult <IUser> > GetUserAsync
        (
            Snowflake userID,
            CancellationToken ct = default
        )
        {
            var key = KeyHelpers.CreateUserCacheKey(userID);

            if (_cacheService.TryGetValue <IUser>(key, out var cachedInstance))
            {
                return(RetrieveRestEntityResult <IUser> .FromSuccess(cachedInstance));
            }

            var getUser = await base.GetUserAsync(userID, ct);

            if (!getUser.IsSuccess)
            {
                return(getUser);
            }

            var user = getUser.Entity;

            _cacheService.Cache(key, user);

            return(getUser);
        }
Example #6
0
        /// <summary>
        /// Performs a GET request to the Discord REST API at the given endpoint.
        /// </summary>
        /// <param name="endpoint">The endpoint.</param>
        /// <param name="configureRequestBuilder">The request builder for the request.</param>
        /// <param name="allowNullReturn">Whether to allow null return values inside the creation result.</param>
        /// <param name="ct">The cancellation token for this operation.</param>
        /// <typeparam name="TEntity">The entity type to retrieve.</typeparam>
        /// <returns>A retrieval result which may or may not have succeeded.</returns>
        public async Task <IRetrieveRestEntityResult <TEntity> > GetAsync <TEntity>
        (
            string endpoint,
            Action <RestRequestBuilder>?configureRequestBuilder = null,
            bool allowNullReturn = false,
            CancellationToken ct = default
        )
        {
            configureRequestBuilder ??= _ => { };

            var requestBuilder = new RestRequestBuilder(endpoint);

            configureRequestBuilder(requestBuilder);

            requestBuilder.WithMethod(HttpMethod.Get);

            try
            {
                using var request  = requestBuilder.Build();
                using var response = await _httpClient.SendAsync
                                     (
                          request,
                          HttpCompletionOption.ResponseHeadersRead,
                          ct
                                     );

                return(await UnpackResponseAsync <TEntity>(response, allowNullReturn, ct));
            }
            catch (Exception e)
            {
                return(RetrieveRestEntityResult <TEntity> .FromError(e));
            }
        }
        /// <inheritdoc />
        public override async Task <IRetrieveRestEntityResult <IGuild> > GetGuildAsync
        (
            Snowflake guildID,
            Optional <bool> withCounts = default,
            CancellationToken ct       = default
        )
        {
            var key = KeyHelpers.CreateGuildCacheKey(guildID);

            if (_cacheService.TryGetValue <IGuild>(key, out var cachedInstance))
            {
                return(RetrieveRestEntityResult <IGuild> .FromSuccess(cachedInstance));
            }

            var getResult = await base.GetGuildAsync(guildID, withCounts, ct);

            if (!getResult.IsSuccess)
            {
                return(getResult);
            }

            var guild = getResult.Entity;

            _cacheService.Cache(key, guild);

            return(getResult);
        }
        /// <inheritdoc />
        public override async Task <IRetrieveRestEntityResult <IReadOnlyList <IChannel> > > GetUserDMsAsync
        (
            CancellationToken ct = default
        )
        {
            var key = KeyHelpers.CreateCurrentUserDMsCacheKey();

            if (_cacheService.TryGetValue <IReadOnlyList <IChannel> >(key, out var cachedInstance))
            {
                return(RetrieveRestEntityResult <IReadOnlyList <IChannel> > .FromSuccess(cachedInstance));
            }

            var getUserDMs = await base.GetUserDMsAsync(ct);

            if (!getUserDMs.IsSuccess)
            {
                return(getUserDMs);
            }

            var userDMs = getUserDMs.Entity;

            _cacheService.Cache(key, userDMs);

            foreach (var dm in userDMs)
            {
                var channelKey = KeyHelpers.CreateChannelCacheKey(dm.ID);
                _cacheService.Cache(channelKey, dm);
            }

            return(getUserDMs);
        }
        /// <inheritdoc />
        public override async Task <IRetrieveRestEntityResult <ITemplate> > GetTemplateAsync
        (
            string templateCode,
            CancellationToken ct = default
        )
        {
            var key = KeyHelpers.CreateTemplateCacheKey(templateCode);

            if (_cacheService.TryGetValue <ITemplate>(key, out var cachedInstance))
            {
                return(RetrieveRestEntityResult <ITemplate> .FromSuccess(cachedInstance));
            }

            var getTemplate = await base.GetTemplateAsync(templateCode, ct);

            if (!getTemplate.IsSuccess)
            {
                return(getTemplate);
            }

            var template = getTemplate.Entity;

            _cacheService.Cache(key, template);

            return(getTemplate);
        }
Example #10
0
        /// <inheritdoc />
        public override async Task <IRetrieveRestEntityResult <IReadOnlyList <IMessage> > > GetPinnedMessagesAsync
        (
            Snowflake channelID,
            CancellationToken ct = default
        )
        {
            var key = KeyHelpers.CreatePinnedMessagesCacheKey(channelID);

            if (_cacheService.TryGetValue <IReadOnlyList <IMessage> >(key, out var cachedInstance))
            {
                return(RetrieveRestEntityResult <IReadOnlyList <IMessage> > .FromSuccess(cachedInstance));
            }

            var getResult = await base.GetPinnedMessagesAsync(channelID, ct);

            if (!getResult.IsSuccess)
            {
                return(getResult);
            }

            var messages = getResult.Entity;

            _cacheService.Cache(key, messages);

            foreach (var message in messages)
            {
                var messageKey = KeyHelpers.CreateMessageCacheKey(channelID, message.ID);
                _cacheService.Cache(messageKey, message);
            }

            return(getResult);
        }
Example #11
0
        /// <inheritdoc />
        public override async Task <IRetrieveRestEntityResult <IChannel> > GetChannelAsync
        (
            Snowflake channelID,
            CancellationToken ct = default
        )
        {
            var key = KeyHelpers.CreateChannelCacheKey(channelID);

            if (_cacheService.TryGetValue <IChannel>(key, out var cachedInstance))
            {
                return(RetrieveRestEntityResult <IChannel> .FromSuccess(cachedInstance));
            }

            var getChannel = await base.GetChannelAsync(channelID, ct);

            if (!getChannel.IsSuccess)
            {
                return(getChannel);
            }

            var channel = getChannel.Entity;

            _cacheService.Cache(key, channel);

            return(getChannel);
        }
        /// <inheritdoc />
        public override async Task <IRetrieveRestEntityResult <IUser> > GetCurrentUserAsync(CancellationToken ct = default)
        {
            var key = KeyHelpers.CreateCurrentUserCacheKey();

            if (_cacheService.TryGetValue <IUser>(key, out var cachedInstance))
            {
                return(RetrieveRestEntityResult <IUser> .FromSuccess(cachedInstance));
            }

            var getUser = await base.GetCurrentUserAsync(ct);

            if (!getUser.IsSuccess)
            {
                return(getUser);
            }

            var user    = getUser.Entity;
            var userKey = KeyHelpers.CreateUserCacheKey(user.ID);

            // Cache this as both a normal user and our current user
            _cacheService.Cache(key, user);
            _cacheService.Cache(userKey, user);

            return(getUser);
        }
Example #13
0
        /// <inheritdoc />
        public override async Task <IRetrieveRestEntityResult <IMessage> > GetChannelMessageAsync
        (
            Snowflake channelID,
            Snowflake messageID,
            CancellationToken ct = default
        )
        {
            var key = KeyHelpers.CreateMessageCacheKey(channelID, messageID);

            if (_cacheService.TryGetValue <IMessage>(key, out var cachedInstance))
            {
                return(RetrieveRestEntityResult <IMessage> .FromSuccess(cachedInstance));
            }

            var getMessage = await base.GetChannelMessageAsync(channelID, messageID, ct);

            if (!getMessage.IsSuccess)
            {
                return(getMessage);
            }

            var message = getMessage.Entity;

            _cacheService.Cache(key, message);

            return(getMessage);
        }
        /// <inheritdoc />
        public override async Task <IRetrieveRestEntityResult <IWebhook> > GetWebhookWithTokenAsync
        (
            Snowflake webhookID,
            string token,
            CancellationToken ct = default
        )
        {
            var key = KeyHelpers.CreateWebhookCacheKey(webhookID);

            if (_cacheService.TryGetValue <IWebhook>(key, out var cachedInstance))
            {
                return(RetrieveRestEntityResult <IWebhook> .FromSuccess(cachedInstance));
            }

            var getWebhook = await base.GetWebhookWithTokenAsync(webhookID, token, ct);

            if (!getWebhook.IsSuccess)
            {
                return(getWebhook);
            }

            var webhook = getWebhook.Entity;

            _cacheService.Cache(key, webhook);

            return(getWebhook);
        }
        /// <inheritdoc />
        public override async Task <IRetrieveRestEntityResult <IReadOnlyList <IWebhook> > > GetGuildWebhooksAsync
        (
            Snowflake guildID, CancellationToken ct = default
        )
        {
            var key = KeyHelpers.CreateGuildWebhooksCacheKey(guildID);

            if (_cacheService.TryGetValue <IReadOnlyList <IWebhook> >(key, out var cachedInstance))
            {
                return(RetrieveRestEntityResult <IReadOnlyList <IWebhook> > .FromSuccess(cachedInstance));
            }

            var getWebhooks = await base.GetGuildWebhooksAsync(guildID, ct);

            if (!getWebhooks.IsSuccess)
            {
                return(getWebhooks);
            }

            var webhooks = getWebhooks.Entity;

            _cacheService.Cache(key, webhooks);

            foreach (var webhook in webhooks)
            {
                var webhookKey = KeyHelpers.CreateWebhookCacheKey(webhook.ID);
                _cacheService.Cache(webhookKey, webhook);
            }

            return(getWebhooks);
        }
        /// <inheritdoc />
        public override async Task <IRetrieveRestEntityResult <IReadOnlyList <IVoiceRegion> > > ListVoiceRegionsAsync
        (
            CancellationToken ct = default
        )
        {
            var key = KeyHelpers.CreateVoiceRegionsCacheKey();

            if (_cacheService.TryGetValue <IReadOnlyList <IVoiceRegion> >(key, out var cachedInstance))
            {
                return(RetrieveRestEntityResult <IReadOnlyList <IVoiceRegion> > .FromSuccess(cachedInstance));
            }

            var listRegions = await base.ListVoiceRegionsAsync(ct);

            if (!listRegions.IsSuccess)
            {
                return(listRegions);
            }

            var regions = listRegions.Entity;

            _cacheService.Cache(key, regions);

            foreach (var voiceRegion in regions)
            {
                var regionKey = KeyHelpers.CreateVoiceRegionCacheKey(voiceRegion.ID);
                _cacheService.Cache(regionKey, voiceRegion);
            }

            return(listRegions);
        }
        /// <inheritdoc />
        public override async Task <IRetrieveRestEntityResult <IReadOnlyList <IRole> > > GetGuildRolesAsync
        (
            Snowflake guildID,
            CancellationToken ct = default
        )
        {
            var collectionKey = KeyHelpers.CreateGuildRolesCacheKey(guildID);

            if (_cacheService.TryGetValue <IReadOnlyList <IRole> >(collectionKey, out var cachedInstance))
            {
                return(RetrieveRestEntityResult <IReadOnlyList <IRole> > .FromSuccess(cachedInstance));
            }

            var getRoles = await base.GetGuildRolesAsync(guildID, ct);

            if (!getRoles.IsSuccess)
            {
                return(getRoles);
            }

            var roles = getRoles.Entity;

            _cacheService.Cache(collectionKey, roles);

            foreach (var role in roles)
            {
                var key = KeyHelpers.CreateGuildRoleCacheKey(guildID, role.ID);
                _cacheService.Cache(key, role);
            }

            return(getRoles);
        }
        /// <inheritdoc />
        public override async Task <IRetrieveRestEntityResult <IReadOnlyList <IConnection> > > GetUserConnectionsAsync
        (
            CancellationToken ct = default
        )
        {
            var key = KeyHelpers.CreateCurrentUserConnectionsCacheKey();

            if (_cacheService.TryGetValue <IReadOnlyList <IConnection> >(key, out var cachedInstance))
            {
                return(RetrieveRestEntityResult <IReadOnlyList <IConnection> > .FromSuccess(cachedInstance));
            }

            var getUserConnections = await base.GetUserConnectionsAsync(ct);

            if (!getUserConnections.IsSuccess)
            {
                return(getUserConnections);
            }

            var connections = getUserConnections.Entity;

            _cacheService.Cache(key, connections);

            foreach (var connection in connections)
            {
                var connectionKey = KeyHelpers.CreateConnectionCacheKey(connection.ID);
                _cacheService.Cache(connectionKey, connection);
            }

            return(getUserConnections);
        }
Example #19
0
        /// <inheritdoc />
        public virtual async Task <IRetrieveRestEntityResult <IReadOnlyList <IMessage> > > GetChannelMessagesAsync
        (
            Snowflake channelID,
            Optional <Snowflake> around = default,
            Optional <Snowflake> before = default,
            Optional <Snowflake> after  = default,
            Optional <int> limit        = default,
            CancellationToken ct        = default
        )
        {
            var hasAny         = around.HasValue || before.HasValue || after.HasValue;
            var hasStrictlyOne = around.HasValue ^ before.HasValue ^ after.HasValue;

            if (hasAny && !hasStrictlyOne)
            {
                return(RetrieveRestEntityResult <IReadOnlyList <IMessage> > .FromError
                       (
                           $"{nameof(around)}, {nameof(before)}, and {nameof(after)} are mutually exclusive."
                       ));
            }

            if (limit.HasValue && (limit.Value > 100 || limit.Value < 1))
            {
                return(RetrieveRestEntityResult <IReadOnlyList <IMessage> > .FromError
                       (
                           "The message limit must be between 1 and 100."
                       ));
            }

            return(await _discordHttpClient.GetAsync <IReadOnlyList <IMessage> >
                   (
                       $"channels/{channelID}/messages",
                       b =>
            {
                if (around.HasValue)
                {
                    b.AddQueryParameter("around", around.Value.ToString());
                }

                if (before.HasValue)
                {
                    b.AddQueryParameter("before", before.Value.ToString());
                }

                if (after.HasValue)
                {
                    b.AddQueryParameter("after", after.Value.ToString());
                }

                if (limit.HasValue)
                {
                    b.AddQueryParameter("limit", limit.Value.ToString());
                }
            },
                       ct : ct
                   ));
        }
        /// <inheritdoc />
        public virtual async Task <IRetrieveRestEntityResult <ITemplate> > SyncGuildTemplateAsync
        (
            Snowflake guildID,
            string templateCode,
            CancellationToken ct = default
        )
        {
            var createResult = await _discordHttpClient.PutAsync <ITemplate>
                               (
                $"guilds/{guildID}/templates/{templateCode}",
                ct : ct
                               );

            return(createResult.IsSuccess
                ? RetrieveRestEntityResult <ITemplate> .FromSuccess(createResult.Entity)
                : RetrieveRestEntityResult <ITemplate> .FromError(createResult));
        }
        /// <inheritdoc />
        public virtual async Task <IRetrieveRestEntityResult <IAuditLog> > GetAuditLogAsync
        (
            Snowflake guildID,
            Optional <Snowflake> userID         = default,
            Optional <AuditLogEvent> actionType = default,
            Optional <Snowflake> before         = default,
            Optional <byte> limit = default,
            CancellationToken ct  = default
        )
        {
            if (limit.HasValue && (limit.Value > 100 || limit.Value == 0))
            {
                return(RetrieveRestEntityResult <IAuditLog> .FromError
                       (
                           $"Invalid value for {nameof(limit)}; only values between 1 and 100 are allowed."
                       ));
            }

            return(await _discordHttpClient.GetAsync <IAuditLog>
                   (
                       $"guilds/{guildID}/audit-logs",
                       b =>
            {
                if (userID.HasValue)
                {
                    b.AddQueryParameter("user_id", userID.Value.ToString());
                }

                if (actionType.HasValue)
                {
                    b.AddQueryParameter("action_type", ((int)actionType.Value).ToString());
                }

                if (before.HasValue)
                {
                    b.AddQueryParameter("before", before.Value.ToString());
                }

                if (limit.HasValue)
                {
                    b.AddQueryParameter("limit", limit.Value.ToString());
                }
            },
                       ct : ct
                   ));
        }
Example #22
0
        /// <summary>
        /// Performs a GET request to the Discord REST API at the given endpoint.
        /// </summary>
        /// <param name="endpoint">The endpoint.</param>
        /// <param name="configureRequestBuilder">The request builder for the request.</param>
        /// <param name="ct">The cancellation token for this operation.</param>
        /// <returns>A retrieval result which may or may not have succeeded.</returns>
        public async Task <IRetrieveRestEntityResult <Stream> > GetContentAsync
        (
            string endpoint,
            Action <RestRequestBuilder>?configureRequestBuilder = null,
            CancellationToken ct = default
        )
        {
            configureRequestBuilder ??= _ => { };

            var requestBuilder = new RestRequestBuilder(endpoint);

            configureRequestBuilder(requestBuilder);

            requestBuilder.WithMethod(HttpMethod.Get);

            try
            {
                using var request  = requestBuilder.Build();
                using var response = await _httpClient.SendAsync
                                     (
                          request,
                          HttpCompletionOption.ResponseHeadersRead,
                          ct
                                     );

                var unpackedResponse = await UnpackResponseAsync(response, ct);

                if (!unpackedResponse.IsSuccess)
                {
                    return(RetrieveRestEntityResult <Stream> .FromError(unpackedResponse));
                }

                var responseContent = await response.Content.ReadAsStreamAsync();

                return(RetrieveRestEntityResult <Stream> .FromSuccess(responseContent));
            }
            catch (Exception e)
            {
                return(RetrieveRestEntityResult <Stream> .FromError(e));
            }
        }
Example #23
0
        /// <inheritdoc />
        public virtual async Task <IRetrieveRestEntityResult <IReadOnlyList <IPartialGuild> > > GetCurrentUserGuildsAsync
        (
            Optional <Snowflake> before = default,
            Optional <Snowflake> after  = default,
            Optional <int> limit        = default,
            CancellationToken ct        = default
        )
        {
            if (limit.HasValue && (limit.Value < 1 || limit.Value > 100))
            {
                return(RetrieveRestEntityResult <IReadOnlyList <IPartialGuild> > .FromError
                       (
                           "The limit must be between 1 and 100."
                       ));
            }

            return(await _discordHttpClient.GetAsync <IReadOnlyList <IPartialGuild> >
                   (
                       "users/@me/guilds",
                       b =>
            {
                if (before.HasValue)
                {
                    b.AddQueryParameter("before", before.Value.ToString());
                }

                if (after.HasValue)
                {
                    b.AddQueryParameter("after", after.Value.ToString());
                }

                if (limit.HasValue)
                {
                    b.AddQueryParameter("limit", limit.Value.ToString());
                }
            },
                       ct : ct
                   ));
        }
        /// <inheritdoc />
        public override async Task <IRetrieveRestEntityResult <IReadOnlyList <IGuildMember> > > ListGuildMembersAsync
        (
            Snowflake guildID,
            Optional <int> limit       = default,
            Optional <Snowflake> after = default,
            CancellationToken ct       = default
        )
        {
            var collectionKey = KeyHelpers.CreateGuildMembersKey(guildID, limit, after);

            if (_cacheService.TryGetValue <IReadOnlyList <IGuildMember> >(collectionKey, out var cachedInstance))
            {
                return(RetrieveRestEntityResult <IReadOnlyList <IGuildMember> > .FromSuccess(cachedInstance));
            }

            var getResult = await base.ListGuildMembersAsync(guildID, limit, after, ct);

            if (!getResult.IsSuccess)
            {
                return(getResult);
            }

            var members = getResult.Entity;

            _cacheService.Cache(collectionKey, members);

            foreach (var member in members)
            {
                if (!member.User.HasValue)
                {
                    continue;
                }

                var key = KeyHelpers.CreateGuildMemberKey(guildID, member.User.Value !.ID);
                _cacheService.Cache(key, member);
            }

            return(getResult);
        }