Update: Bot reports interactions in admin channel
This commit is contained in:
parent
f801cb082e
commit
200de1d7f7
|
@ -28,7 +28,13 @@
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return $"{Eth} Eth";
|
var weiOnly = Wei % TokensIntExtensions.WeiPerEth;
|
||||||
|
|
||||||
|
var tokens = new List<string>();
|
||||||
|
if (Eth > 0) tokens.Add($"{Eth} Eth");
|
||||||
|
if (weiOnly > 0) tokens.Add($"{weiOnly} Wei");
|
||||||
|
|
||||||
|
return string.Join(" + ", tokens);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,9 +27,9 @@ namespace BiblioTech
|
||||||
return channel.Id == Program.Config.AdminChannelId;
|
return channel.Id == Program.Config.AdminChannelId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ISocketMessageChannel GetAdminChannel()
|
public async Task SendInAdminChannel(string msg)
|
||||||
{
|
{
|
||||||
return adminChannel;
|
await adminChannel.SendMessageAsync(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetAdminChannel(ISocketMessageChannel adminChannel)
|
public void SetAdminChannel(ISocketMessageChannel adminChannel)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using Discord.WebSocket;
|
using Discord.WebSocket;
|
||||||
using BiblioTech.Options;
|
using BiblioTech.Options;
|
||||||
using Discord;
|
using Discord;
|
||||||
|
using k8s.KubeConfigModels;
|
||||||
|
|
||||||
namespace BiblioTech
|
namespace BiblioTech
|
||||||
{
|
{
|
||||||
|
@ -25,16 +26,13 @@ namespace BiblioTech
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
var msg = "Failed with exception: " + ex;
|
var msg = "Failed with exception: " + ex;
|
||||||
if (IsInAdminChannel(command))
|
|
||||||
{
|
|
||||||
await command.FollowupAsync(msg.Substring(0, Math.Min(1900, msg.Length)));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
await command.FollowupAsync("Something failed while trying to do that...", ephemeral: true);
|
|
||||||
await Program.AdminChecker.GetAdminChannel().SendMessageAsync(msg);
|
|
||||||
}
|
|
||||||
Program.Log.Error(msg);
|
Program.Log.Error(msg);
|
||||||
|
|
||||||
|
if (!IsInAdminChannel(command))
|
||||||
|
{
|
||||||
|
await command.FollowupAsync("Something failed while trying to do that... (error details posted in admin channel)", ephemeral: true);
|
||||||
|
}
|
||||||
|
await Program.AdminChecker.SendInAdminChannel(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,5 +60,20 @@ namespace BiblioTech
|
||||||
if (IsSenderAdmin(context.Command) && targetUser != null) return targetUser;
|
if (IsSenderAdmin(context.Command) && targetUser != null) return targetUser;
|
||||||
return context.Command.User;
|
return context.Command.User;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected string Mention(SocketUser user)
|
||||||
|
{
|
||||||
|
return Mention(user.Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected string Mention(IUser user)
|
||||||
|
{
|
||||||
|
return Mention(user.Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected string Mention(ulong userId)
|
||||||
|
{
|
||||||
|
return $"<@{userId}>";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ namespace BiblioTech.Commands
|
||||||
if (addr == null)
|
if (addr == null)
|
||||||
{
|
{
|
||||||
await context.Followup($"No address has been set for this user. Please use '/{userAssociateCommand.Name}' to set it first.");
|
await context.Followup($"No address has been set for this user. Please use '/{userAssociateCommand.Name}' to set it first.");
|
||||||
|
await Program.AdminChecker.SendInAdminChannel($"User {Mention(userId)} used '/{Name}' but address has not been set.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@ namespace BiblioTech.Commands
|
||||||
if (addr == null)
|
if (addr == null)
|
||||||
{
|
{
|
||||||
await context.Followup($"No address has been set for this user. Please use '/{userAssociateCommand.Name}' to set it first.");
|
await context.Followup($"No address has been set for this user. Please use '/{userAssociateCommand.Name}' to set it first.");
|
||||||
|
await Program.AdminChecker.SendInAdminChannel($"User {Mention(userId)} used '/{Name}' but address has not been set.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,9 +43,17 @@ namespace BiblioTech.Commands
|
||||||
mintedTokens = ProcessTokens(contracts, addr, report);
|
mintedTokens = ProcessTokens(contracts, addr, report);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var reportLine = string.Join(Environment.NewLine, report);
|
||||||
Program.UserRepo.AddMintEventForUser(userId, addr, sentEth, mintedTokens);
|
Program.UserRepo.AddMintEventForUser(userId, addr, sentEth, mintedTokens);
|
||||||
|
await Program.AdminChecker.SendInAdminChannel($"User {Mention(userId)} used '/{Name}' successfully. ({reportLine})");
|
||||||
|
|
||||||
await context.Followup(string.Join(Environment.NewLine, report));
|
await context.Followup(reportLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
private string Format<T>(Transaction<T>? transaction)
|
||||||
|
{
|
||||||
|
if (transaction == null) return "-";
|
||||||
|
return transaction.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Transaction<TestToken>? ProcessTokens(ICodexContracts contracts, EthAddress addr, List<string> report)
|
private Transaction<TestToken>? ProcessTokens(ICodexContracts contracts, EthAddress addr, List<string> report)
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
using BiblioTech.Options;
|
using BiblioTech.Options;
|
||||||
|
using Discord;
|
||||||
|
using GethPlugin;
|
||||||
|
using k8s.KubeConfigModels;
|
||||||
|
using NBitcoin.Secp256k1;
|
||||||
|
|
||||||
namespace BiblioTech.Commands
|
namespace BiblioTech.Commands
|
||||||
{
|
{
|
||||||
|
@ -23,30 +27,56 @@ namespace BiblioTech.Commands
|
||||||
protected override async Task Invoke(CommandContext context)
|
protected override async Task Invoke(CommandContext context)
|
||||||
{
|
{
|
||||||
var user = GetUserFromCommand(optionalUser, context);
|
var user = GetUserFromCommand(optionalUser, context);
|
||||||
var data = await ethOption.Parse(context);
|
var newAddress = await ethOption.Parse(context);
|
||||||
if (data == null) return;
|
if (newAddress == null) return;
|
||||||
|
|
||||||
var currentAddress = Program.UserRepo.GetCurrentAddressForUser(user);
|
var currentAddress = Program.UserRepo.GetCurrentAddressForUser(user);
|
||||||
if (currentAddress != null && !IsSenderAdmin(context.Command))
|
if (currentAddress != null && !IsSenderAdmin(context.Command))
|
||||||
{
|
{
|
||||||
await context.Followup($"You've already set your Ethereum address to {currentAddress}.");
|
await context.Followup($"You've already set your Ethereum address to {currentAddress}.");
|
||||||
|
await Program.AdminChecker.SendInAdminChannel($"User {Mention(user)} used '/{Name}' but already has an address set. ({currentAddress})");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = Program.UserRepo.AssociateUserWithAddress(user, data);
|
var result = Program.UserRepo.AssociateUserWithAddress(user, newAddress);
|
||||||
if (result)
|
switch (result)
|
||||||
{
|
{
|
||||||
await context.Followup(new string[]
|
case SetAddressResponse.OK:
|
||||||
{
|
await ResponseOK(context, user, newAddress);
|
||||||
|
break;
|
||||||
|
case SetAddressResponse.AddressAlreadyInUse:
|
||||||
|
await ResponseAlreadyUsed(context, user, newAddress);
|
||||||
|
break;
|
||||||
|
case SetAddressResponse.CreateUserFailed:
|
||||||
|
await ResponseCreateUserFailed(context, user);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception("Unknown SetAddressResponse mode");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task ResponseCreateUserFailed(CommandContext context, IUser user)
|
||||||
|
{
|
||||||
|
await context.Followup("Internal error. Error details sent to admin.");
|
||||||
|
await Program.AdminChecker.SendInAdminChannel($"User {Mention(user)} used '/{Name}' but failed to create new user.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task ResponseAlreadyUsed(CommandContext context, IUser user, EthAddress newAddress)
|
||||||
|
{
|
||||||
|
await context.Followup("This address is already in use by another user.");
|
||||||
|
await Program.AdminChecker.SendInAdminChannel($"User {Mention(user)} used '/{Name}' but the provided address is already in use by another user. (address: {newAddress})");
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task ResponseOK(CommandContext context, IUser user, GethPlugin.EthAddress newAddress)
|
||||||
|
{
|
||||||
|
await context.Followup(new string[]
|
||||||
|
{
|
||||||
"Done! Thank you for joining the test net!",
|
"Done! Thank you for joining the test net!",
|
||||||
"By default, the bot will @-mention you with test-net reward related notifications.",
|
"By default, the bot will @-mention you with test-net related notifications.",
|
||||||
$"You can enable/disable this behavior with the '/{notifyCommand.Name}' command."
|
$"You can enable/disable this behavior with the '/{notifyCommand.Name}' command."
|
||||||
});
|
});
|
||||||
}
|
|
||||||
else
|
await Program.AdminChecker.SendInAdminChannel($"User {Mention(user)} used '/{Name}' successfully. ({newAddress})");
|
||||||
{
|
|
||||||
await context.Followup("That didn't work.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,5 +10,11 @@
|
||||||
|
|
||||||
public T TokenAmount { get; }
|
public T TokenAmount { get; }
|
||||||
public string TransactionHash { get; }
|
public string TransactionHash { get; }
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
if (TokenAmount == null) return "NULL";
|
||||||
|
return TokenAmount.ToString()!;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ namespace BiblioTech
|
||||||
private readonly object repoLock = new object();
|
private readonly object repoLock = new object();
|
||||||
private readonly Dictionary<ulong, UserData> cache = new Dictionary<ulong, UserData>();
|
private readonly Dictionary<ulong, UserData> cache = new Dictionary<ulong, UserData>();
|
||||||
|
|
||||||
public bool AssociateUserWithAddress(IUser user, EthAddress address)
|
public SetAddressResponse AssociateUserWithAddress(IUser user, EthAddress address)
|
||||||
{
|
{
|
||||||
lock (repoLock)
|
lock (repoLock)
|
||||||
{
|
{
|
||||||
|
@ -134,18 +134,19 @@ namespace BiblioTech
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool SetUserAddress(IUser user, EthAddress? address)
|
private SetAddressResponse SetUserAddress(IUser user, EthAddress? address)
|
||||||
{
|
{
|
||||||
if (GetUserDataForAddress(address) != null)
|
if (GetUserDataForAddress(address) != null)
|
||||||
{
|
{
|
||||||
return false;
|
return SetAddressResponse.AddressAlreadyInUse;
|
||||||
}
|
}
|
||||||
|
|
||||||
var userData = GetOrCreate(user);
|
var userData = GetOrCreate(user);
|
||||||
|
if (userData == null) return SetAddressResponse.CreateUserFailed;
|
||||||
userData.CurrentAddress = address;
|
userData.CurrentAddress = address;
|
||||||
userData.AssociateEvents.Add(new UserAssociateAddressEvent(DateTime.UtcNow, address));
|
userData.AssociateEvents.Add(new UserAssociateAddressEvent(DateTime.UtcNow, address));
|
||||||
SaveUserData(userData);
|
SaveUserData(userData);
|
||||||
return true;
|
return SetAddressResponse.OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetUserNotification(IUser user, bool notifyEnabled)
|
private void SetUserNotification(IUser user, bool notifyEnabled)
|
||||||
|
@ -245,4 +246,11 @@ namespace BiblioTech
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum SetAddressResponse
|
||||||
|
{
|
||||||
|
OK,
|
||||||
|
AddressAlreadyInUse,
|
||||||
|
CreateUserFailed
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue