Sender Utility
This documentation mentions "Sender Utilitility" multiple times. This 'utility' is actually a set of extension classes for any IWolfClient that handle common sending functionalities, and abstract concerns like Message classes or using cache.
Sender class itself is included in Wolfringo.Utilities package (which is automatically included if you install Wolfringo metapackage), and is in TehGM.Wolfringo namespace so it's always easy to access when using any IWolfClient.
Tip
All of the methods in Sender class support optional CancellationToken.
Logging in and out
Logging in is one of the most important steps your bot will need to take in order to work. This can be done using LoginAsync. This method returns a LoginResponse, which includes profile of the user that logged in with User property.
Once logged in, you most likely want to subscribe to incoming messages - otherwise, your client won't get any of them. You can do it using SubscribeAllMessagesAsync method.
After logging in, you can set your online state (such as Online/Busy/Invisible etc) after logging in using SetOnlineStateAsync method.
private static async void OnWelcome(WelcomeEvent message)
{
// if reusing the token, user might be already logged in, so check that before requesting login
if (message.LoggedInUser == null)
{
// note: it is recommended to not hardcode username and password, and use .gitignore-d config file instead
await _client.LoginAsync("BotEmail", "BotPassword", WolfLoginType.Email);
}
await _client.SubscribeAllMessagesAsync(); // without this, bot will not receive any messages
await _client.SetOnlineStateAsync(WolfOnlineState.Busy); // this is optional - if you don't do this, you'll login as online
}
Logging out is also simple - just use LogoutAsync method!
await _client.LogoutAsync();
Sending messages
Sending messages is 2nd most important task almost any bot will perform, so naturally Sender Utility has methods for that as well.
There are numerous methods for this in Sender class:
- SendPrivateTextMessageAsync - sends a private message to a user, with text content.
- SendGroupTextMessageAsync - sends a message to a group, with text content.
- SendPrivateImageMessageAsync - sends a private message to a user, with image content.
- SendGroupImageMessageAsync - sends a message to a group, with image content.
- SendPrivateVoiceMessageAsync - sends a private message to a user, with voice content.
- SendGroupVoiceMessageAsync - sends a message to a group, with voice content.
byte[] myImageBytes = ...
await _client.SendPrivateTextMessageAsync(1234, "I will send an image in group ID 4321!");
await _client.SendGroupImageMessageAsync(4321, myImageBytes);
There also are methods that take a ChatMessage as a parameter - these will send a message to pm or group, depending on the type of incoming message:
- ReplyTextAsync - replies with a text message.
- ReplyImageAsync - replies with an image.
- ReplyVoiceAsync - replies with a voice message.
private async void OnChatMessage(ChatMessage message)
{
await _client.ReplyTextAsync(message, "Okay, will do!");
}
All of these tasks return ChatResponse - you can use it to get the server-assigned Timestamp, or check if a private message was SpamFiltered.
Retrieving entities
Sender class has multiple methods to retrieve entites. Most of these methods will check cache first - if the entity is cached, it won't be requested from the server.
WolfUser
GetUserAsync is the primary method to retrieve a WolfUser. The user will be retrieved by their ID.
If you want to retrieve multiple users at once, it is recommended to use GetUsersAsync instead.
WolfUser oneUser = await _client.GetUserAsync(2644384);
IEnumerable<WolfUser> multipleUsers = await _client.GetUsersAsync(new uint[] { 2644384, 39404842 });
You can also retrieve bot's profile using GetCurrentUserAsync, or bot's contacts using GetContactListAsync.
WolfGroup
GetGroupAsync is the primary method to retrieve a WolfGroup. The group can be retrieved by its ID or name.
If you want to retrieve multiple groups at once, it is recommended to use GetGroupsAsync instead.
WolfGroup oneGroup = await _client.GetGroupAsync("wolf");
IEnumerable<WolfGroup> multipleGroups = await _client.GetGroupsAsync(new uint[] { 2, 1234 });
You can also retrieve all groups that the bot is in using GetCurrentUserGroupsAsync.
Warning
Sender Utility will make an attempt to automatically retrieve all group's members when retrieving a group. Unfortunately there is a bug in WOLF protocol, which sometimes causes server to not send group members even when requested.
If you need to access WolfGroup's Members but the dictionary is empty, you can try requesting the group again - Sender Utility will notice that cached Members list is empty, and will attempt to retrieve it again.
Admin Actions
If the user has sufficent privileges in a group, it can use Sender Utility to perform admin actions:
- AdminUserAsync - gives an another user Admin privileges in a group.
- ModUserAsync - gives an another user Mod privileges in a group.
- ResetUserAsync - resets an another user in a group.
- SilenceUserAsync - silences an another user in a group.
- KickUserAsync - kicks an another user from a group.
- BanUserAsync - bans an another user from a group.
[Command("kick")]
[GroupOnly]
[RequireBotGroupMod]
private async Task KickAsync(CommandContext context, uint userID)
{
await context.Client.KickUserAsync(userID, context.Message.RecipientID);
}
Updating Profiles
Updating bot's nickname (display name) and status is really easy - just use UpdateNicknameAsync and UpdateStatusAsync.
await _client.UpdateNicknameAsync("MyBot");
await _client.UpdateStatusAsync("Hi! Send \"!mybot help\" to check what I can do!");
If you want to update bot's (or any groups' that the bot has admin privileges in) profiles, you can use special Sender's methods that take action as their parameter. These actions provide a special builder instance, that will be executed to construct an update message.
Sender Utility uses this approach to construct an update message that includes even data that will not be changed - this is required, as nulls would make WOLF server simply erase that data.
await _client.UpdateProfileAsync(profile =>
{
profile.About = "Hello, I am a bot! Feel free to send me \"!mybot help\" to check what I can do!".
profile.Language = WolfLanguage.English;
});
Group updates function in a similar manner - but you need to also provide ID of the group that you want to update:
await _client.UpdateGroupAsync(1234, group =>
{
profile.Description = "Group for testing MyBot!";
profile.Language = WolfLanguage.English;
});
Other functionalities
I listed just the most common usages of the Sender Utility. Sender class contains many more methods that you can use - check them in API Reference!
Next Steps
Now you know how to send messages using Wolfringo. However the server might return an error sometimes - for example when your bot has no admin privileges when it tries to perform an admin action. Check Errors Handling guide to see how to deal with them.
An another important feature that can improve your work with Wolfringo is Commands System, so make sure you check it out!
Wolfringo.Utilities also includes support for interactive commands - check Interactive Commands guide for a tutorial.