private async Task <string> BuildMentionMessage(ChatMessage message, MentionConfig config, CancellationToken cancellationToken = default) { StringBuilder builder = new StringBuilder(config.MessageTemplate ?? _mentionsOptions.CurrentValue.DefaultMessageTemplate); WolfUser user = await _client.GetUserAsync(message.SenderID.Value, cancellationToken).ConfigureAwait(false); WolfGroup group = await _client.GetGroupAsync(message.RecipientID, cancellationToken).ConfigureAwait(false); // metadata builder.Replace("{{UserID}}", user.ID.ToString()); builder.Replace("{{UserName}}", user.Nickname); builder.Replace("{{GroupID}}", group.ID.ToString()); builder.Replace("{{GroupName}}", group.Name); // trim text if too long string txt = message.Text; if (txt.Length > _mentionsOptions.CurrentValue.MaxTextLength) { txt = txt.Remove(_mentionsOptions.CurrentValue.MaxTextLength) + "..."; } builder.Replace("{{Message}}", txt); // return results return(builder.ToString()); }
/// <summary>Gets group members dictionary as editable.</summary> /// <param name="group">Group to extract members dictionary from.</param> /// <returns>Editable version of group members dictionary.</returns> /// <exception cref="ArgumentNullException"><paramref name="group"/> is null.</exception> /// <exception cref="NotSupportedException">Group members dictionary is read only.</exception> private static IDictionary <uint, WolfGroupMember> GetGroupMembersDictionary(WolfGroup group) { if (!(group.Members is IDictionary <uint, WolfGroupMember> membersDictionary) || membersDictionary.IsReadOnly) { throw new NotSupportedException($"Members dictionary for group {group.ID} is read-only"); } return(membersDictionary); }
/// <summary>Removes group member from group member list.</summary> /// <remarks>It's not recommended to use this method at all, unless it's required for writing a custom client or serializer implementation.</remarks> /// <param name="group">Group to remove member from.</param> /// <param name="memberID">User ID of member to remove.</param> /// <exception cref="ArgumentNullException"><paramref name="group"/> is null.</exception> public static void RemoveGroupMember(WolfGroup group, uint memberID) { if (group == null) { throw new ArgumentNullException(nameof(group)); } IDictionary <uint, WolfGroupMember> collection = GetGroupMembersDictionary(group); collection.Remove(memberID); }
/// <summary>Updates one group member with provided entity.</summary> /// <remarks>It's not recommended to use this method at all, unless it's required for writing a custom client or serializer implementation.</remarks> /// <param name="group">Group to update group member in.</param> /// <param name="member">New member to add or update.</param> /// <exception cref="ArgumentNullException"><paramref name="group"/> or <paramref name="member"/> is null.</exception> public static void SetGroupMember(WolfGroup group, WolfGroupMember member) { if (group == null) { throw new ArgumentNullException(nameof(group)); } if (member == null) { throw new ArgumentNullException(nameof(member)); } IDictionary <uint, WolfGroupMember> collection = GetGroupMembersDictionary(group); collection[member.UserID] = member; }
/// <summary>Create a new builder for <see cref="GroupUpdateMessage"/>.</summary> /// <param name="group">Group to update.</param> public Builder(WolfGroup group) { if (group == null) { throw new ArgumentNullException(nameof(group)); } this.ID = group.ID; this.Description = group.Description; this.IsPeekable = group.IsPeekable; this.IsExtendedAdminEnabled = group.IsExtendedAdminEnabled ?? false; this.IsDiscoverable = group.IsDiscoverable ?? false; this.EntryReputationLevel = group.EntryReputationLevel; this.Language = group.Language; this.LongDescription = group.LongDescription; }
private async Task <WolfGroupMember> GetGroupMemberAsync(CommandContext context, CancellationToken cancellationToken = default) { WolfGroup group = await context.GetRecipientAsync <WolfGroup>(cancellationToken).ConfigureAwait(false); if (group == null) { return(null); } if (group.Members.TryGetValue(context.Message.SenderID.Value, out WolfGroupMember result)) { return(result); } else { return(null); } }
/// <summary>Checks if user has a specified privilege.</summary> /// <param name="context">Context of the command execution.</param> /// <param name="userID">ID of the user.</param> /// <param name="privileges">Required privileges flags.</param> /// <param name="cancellationToken">Cancellation token for cancelling the task.</param> /// <returns>True if user has at least one of specified privileges; otherwise false.</returns> public static async Task <bool> CheckPrivilegeAsync(ICommandContext context, uint userID, WolfGroupCapabilities privileges, CancellationToken cancellationToken = default) { WolfGroup group = await context.GetRecipientAsync <WolfGroup>(cancellationToken).ConfigureAwait(false); if (!group.Members.TryGetValue(userID, out WolfGroupMember member) && group.Members?.Any() != true) { GroupMembersListResponse membersResponse = await context.Client.SendAsync <GroupMembersListResponse>( new GroupMembersListMessage(group.ID), cancellationToken).ConfigureAwait(false); member = membersResponse.GroupMembers.FirstOrDefault(u => u.UserID == userID); } if (member == null) { return(false); } return((privileges & member.Capabilities) == member.Capabilities); }
/// <summary>Replaces al group members with provided entities.</summary> /// <remarks>It's not recommended to use this method at all, unless it's required for writing a custom client or serializer implementation.</remarks> /// <param name="group">Group to replace members of.</param> /// <param name="members">Members to set as group members.</param> /// <exception cref="ArgumentNullException"><paramref name="group"/> or <paramref name="members"/> is null.</exception> public static void ReplaceAllGroupMembers(WolfGroup group, IEnumerable <WolfGroupMember> members) { if (group == null) { throw new ArgumentNullException(nameof(group)); } if (members == null) { throw new ArgumentNullException(nameof(members)); } IDictionary <uint, WolfGroupMember> collection = GetGroupMembersDictionary(group); collection.Clear(); foreach (WolfGroupMember member in members) { collection[member.UserID] = member; } }
private async Task CmdJoinAsync(CommandContext context, [MissingError("(n) Please provide group name.")] string groupName, CancellationToken cancellationToken = default) { if (string.IsNullOrWhiteSpace(groupName)) { await context.ReplyTextAsync("(n) Please provide group name.", cancellationToken).ConfigureAwait(false); return; } try { WolfGroup group = await context.Client.JoinGroupAsync(groupName, cancellationToken).ConfigureAwait(false); await context.ReplyTextAsync($"(y) Joined [{group.Name}].", cancellationToken).ConfigureAwait(false); } catch (MessageSendingException ex) { if (ex.Response is WolfResponse response && response.ErrorCode != null) { await context.ReplyTextAsync($"(n) Failed joining group: {response.ErrorCode.Value.GetDescription(ex.SentMessage.EventName)}", cancellationToken).ConfigureAwait(false); }
/// <summary>Checks if group members are downloaded. If not, it'll attempt to repopulate it.</summary> /// <param name="client">Client to request group members with.</param> /// <param name="group">Group to validate members of.</param> /// <param name="cancellationToken">Token to cancel the task.</param> /// <returns>True if members list is valid after the operation; otherwise false.</returns> public static async Task <bool> RevalidateGroupMembersAsync(this IWolfClient client, WolfGroup group, CancellationToken cancellationToken = default) { if (group == null) { throw new ArgumentNullException(nameof(group)); } if (group.Members?.Any() == true) { return(true); } if (client == null) { throw new ArgumentNullException(nameof(client)); } try { GroupMembersListResponse membersResponse = await client.SendAsync <GroupMembersListResponse>( new GroupMembersListMessage(group.ID), cancellationToken).ConfigureAwait(false); // client should be configured to intercept this response // however, just in case it's not (like when caching is disabled), do it here as well if (membersResponse?.GroupMembers?.Any() == true) { try { EntityModificationHelper.ReplaceAllGroupMembers(group, membersResponse.GroupMembers); } catch (NotSupportedException) { return(false); } return(true); } } // handle case when requesting profiles for group the user is not in catch (MessageSendingException ex) when(ex.StatusCode == System.Net.HttpStatusCode.Forbidden) { } return(false); }
/// <summary>Downloads bytes of group avatar.</summary> /// <param name="group">Group to download avatar of.</param> /// <param name="size">Size of the avatar to request.</param> /// <param name="cancellationToken">Token to cancel the request.</param> /// <remarks>This method creates a temporary HttpClient just for the request. This might be performance heavy, and therefore it's recommended to provide your own client from own cache, or using a client factory.</remarks> /// <returns>Bytes of group avatar. Null if group of avatar not found.</returns> public static async Task <byte[]> DownloadAvatarAsync(this WolfGroup group, uint size = 500, CancellationToken cancellationToken = default) { using (HttpClient client = GetDefaultClient()) return(await DownloadAvatarAsync(group, client, size, cancellationToken).ConfigureAwait(false)); }
/// <summary>Gets URL for retrieving group avatar.</summary> /// <param name="group">Group to get avatar URL for.</param> /// <param name="size">Size of the avatar to retrieve.</param> /// <remarks><para>This method will return URL to group avatar. You can use this URL with <see cref="HttpClient"/> to download the avatar, or use for any other purpose.</para> /// <para><paramref name="size"/> is only a requested size of the avatar. It is not guaranteed that URL will contain avatar with this size.</para></remarks> /// <returns>URL to group's avatar.</returns> public static string GetAvatarURL(this WolfGroup group, uint size = 500) => GetGroupAvatarURL(group.ID, group.Icon, size);
/// <summary>Downloads bytes of group avatar.</summary> /// <param name="group">Group to download avatar of.</param> /// <param name="client">Http Client to request avatar bytes with.</param> /// <param name="size">Size of the avatar to request.</param> /// <param name="cancellationToken">Token to cancel the request.</param> /// <returns>Bytes of group avatar. Null if group of avatar not found.</returns> public static Task <byte[]> DownloadAvatarAsync(this WolfGroup group, HttpClient client, uint size = 500, CancellationToken cancellationToken = default) => DownloadAvatarAsync(GetAvatarURL(group, size), client, cancellationToken);