Skip to content

Commit 200de1d

Browse files
committed
Update: Bot reports interactions in admin channel
1 parent f801cb0 commit 200de1d

File tree

8 files changed

+102
-29
lines changed

8 files changed

+102
-29
lines changed

ProjectPlugins/GethPlugin/EthTokenExtensions.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,13 @@ public override int GetHashCode()
2828

2929
public override string ToString()
3030
{
31-
return $"{Eth} Eth";
31+
var weiOnly = Wei % TokensIntExtensions.WeiPerEth;
32+
33+
var tokens = new List<string>();
34+
if (Eth > 0) tokens.Add($"{Eth} Eth");
35+
if (weiOnly > 0) tokens.Add($"{weiOnly} Wei");
36+
37+
return string.Join(" + ", tokens);
3238
}
3339
}
3440

Tools/BiblioTech/AdminChecker.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ public bool IsAdminChannel(IChannel channel)
2727
return channel.Id == Program.Config.AdminChannelId;
2828
}
2929

30-
public ISocketMessageChannel GetAdminChannel()
30+
public async Task SendInAdminChannel(string msg)
3131
{
32-
return adminChannel;
32+
await adminChannel.SendMessageAsync(msg);
3333
}
3434

3535
public void SetAdminChannel(ISocketMessageChannel adminChannel)

Tools/BiblioTech/BaseCommand.cs

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using Discord.WebSocket;
22
using BiblioTech.Options;
33
using Discord;
4+
using k8s.KubeConfigModels;
45

56
namespace BiblioTech
67
{
@@ -25,16 +26,13 @@ public async Task SlashCommandHandler(SocketSlashCommand command)
2526
catch (Exception ex)
2627
{
2728
var msg = "Failed with exception: " + ex;
28-
if (IsInAdminChannel(command))
29-
{
30-
await command.FollowupAsync(msg.Substring(0, Math.Min(1900, msg.Length)));
31-
}
32-
else
29+
Program.Log.Error(msg);
30+
31+
if (!IsInAdminChannel(command))
3332
{
34-
await command.FollowupAsync("Something failed while trying to do that...", ephemeral: true);
35-
await Program.AdminChecker.GetAdminChannel().SendMessageAsync(msg);
33+
await command.FollowupAsync("Something failed while trying to do that... (error details posted in admin channel)", ephemeral: true);
3634
}
37-
Program.Log.Error(msg);
35+
await Program.AdminChecker.SendInAdminChannel(msg);
3836
}
3937
}
4038

@@ -62,5 +60,20 @@ protected IUser GetUserFromCommand(UserOption userOption, CommandContext context
6260
if (IsSenderAdmin(context.Command) && targetUser != null) return targetUser;
6361
return context.Command.User;
6462
}
63+
64+
protected string Mention(SocketUser user)
65+
{
66+
return Mention(user.Id);
67+
}
68+
69+
protected string Mention(IUser user)
70+
{
71+
return Mention(user.Id);
72+
}
73+
74+
protected string Mention(ulong userId)
75+
{
76+
return $"<@{userId}>";
77+
}
6578
}
6679
}

Tools/BiblioTech/Commands/GetBalanceCommand.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ protected override async Task Execute(CommandContext context, IGethNode gethNode
2828
if (addr == null)
2929
{
3030
await context.Followup($"No address has been set for this user. Please use '/{userAssociateCommand.Name}' to set it first.");
31+
await Program.AdminChecker.SendInAdminChannel($"User {Mention(userId)} used '/{Name}' but address has not been set.");
3132
return;
3233
}
3334

Tools/BiblioTech/Commands/MintCommand.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ protected override async Task Execute(CommandContext context, IGethNode gethNode
2828
if (addr == null)
2929
{
3030
await context.Followup($"No address has been set for this user. Please use '/{userAssociateCommand.Name}' to set it first.");
31+
await Program.AdminChecker.SendInAdminChannel($"User {Mention(userId)} used '/{Name}' but address has not been set.");
3132
return;
3233
}
3334

@@ -42,9 +43,17 @@ await Task.Run(() =>
4243
mintedTokens = ProcessTokens(contracts, addr, report);
4344
});
4445

46+
var reportLine = string.Join(Environment.NewLine, report);
4547
Program.UserRepo.AddMintEventForUser(userId, addr, sentEth, mintedTokens);
48+
await Program.AdminChecker.SendInAdminChannel($"User {Mention(userId)} used '/{Name}' successfully. ({reportLine})");
4649

47-
await context.Followup(string.Join(Environment.NewLine, report));
50+
await context.Followup(reportLine);
51+
}
52+
53+
private string Format<T>(Transaction<T>? transaction)
54+
{
55+
if (transaction == null) return "-";
56+
return transaction.ToString();
4857
}
4958

5059
private Transaction<TestToken>? ProcessTokens(ICodexContracts contracts, EthAddress addr, List<string> report)

Tools/BiblioTech/Commands/UserAssociateCommand.cs

Lines changed: 43 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
using BiblioTech.Options;
2+
using Discord;
3+
using GethPlugin;
4+
using k8s.KubeConfigModels;
5+
using NBitcoin.Secp256k1;
26

37
namespace BiblioTech.Commands
48
{
@@ -23,30 +27,56 @@ public UserAssociateCommand(NotifyCommand notifyCommand)
2327
protected override async Task Invoke(CommandContext context)
2428
{
2529
var user = GetUserFromCommand(optionalUser, context);
26-
var data = await ethOption.Parse(context);
27-
if (data == null) return;
30+
var newAddress = await ethOption.Parse(context);
31+
if (newAddress == null) return;
2832

2933
var currentAddress = Program.UserRepo.GetCurrentAddressForUser(user);
3034
if (currentAddress != null && !IsSenderAdmin(context.Command))
3135
{
3236
await context.Followup($"You've already set your Ethereum address to {currentAddress}.");
37+
await Program.AdminChecker.SendInAdminChannel($"User {Mention(user)} used '/{Name}' but already has an address set. ({currentAddress})");
3338
return;
3439
}
3540

36-
var result = Program.UserRepo.AssociateUserWithAddress(user, data);
37-
if (result)
41+
var result = Program.UserRepo.AssociateUserWithAddress(user, newAddress);
42+
switch (result)
3843
{
39-
await context.Followup(new string[]
40-
{
44+
case SetAddressResponse.OK:
45+
await ResponseOK(context, user, newAddress);
46+
break;
47+
case SetAddressResponse.AddressAlreadyInUse:
48+
await ResponseAlreadyUsed(context, user, newAddress);
49+
break;
50+
case SetAddressResponse.CreateUserFailed:
51+
await ResponseCreateUserFailed(context, user);
52+
break;
53+
default:
54+
throw new Exception("Unknown SetAddressResponse mode");
55+
}
56+
}
57+
58+
private async Task ResponseCreateUserFailed(CommandContext context, IUser user)
59+
{
60+
await context.Followup("Internal error. Error details sent to admin.");
61+
await Program.AdminChecker.SendInAdminChannel($"User {Mention(user)} used '/{Name}' but failed to create new user.");
62+
}
63+
64+
private async Task ResponseAlreadyUsed(CommandContext context, IUser user, EthAddress newAddress)
65+
{
66+
await context.Followup("This address is already in use by another user.");
67+
await Program.AdminChecker.SendInAdminChannel($"User {Mention(user)} used '/{Name}' but the provided address is already in use by another user. (address: {newAddress})");
68+
}
69+
70+
private async Task ResponseOK(CommandContext context, IUser user, GethPlugin.EthAddress newAddress)
71+
{
72+
await context.Followup(new string[]
73+
{
4174
"Done! Thank you for joining the test net!",
42-
"By default, the bot will @-mention you with test-net reward related notifications.",
75+
"By default, the bot will @-mention you with test-net related notifications.",
4376
$"You can enable/disable this behavior with the '/{notifyCommand.Name}' command."
44-
});
45-
}
46-
else
47-
{
48-
await context.Followup("That didn't work.");
49-
}
77+
});
78+
79+
await Program.AdminChecker.SendInAdminChannel($"User {Mention(user)} used '/{Name}' successfully. ({newAddress})");
5080
}
5181
}
5282
}

Tools/BiblioTech/Transaction.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,11 @@ public Transaction(T tokenAmount, string transactionHash)
1010

1111
public T TokenAmount { get; }
1212
public string TransactionHash { get; }
13+
14+
public override string ToString()
15+
{
16+
if (TokenAmount == null) return "NULL";
17+
return TokenAmount.ToString()!;
18+
}
1319
}
1420
}

Tools/BiblioTech/UserRepo.cs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ public class UserRepo
1010
private readonly object repoLock = new object();
1111
private readonly Dictionary<ulong, UserData> cache = new Dictionary<ulong, UserData>();
1212

13-
public bool AssociateUserWithAddress(IUser user, EthAddress address)
13+
public SetAddressResponse AssociateUserWithAddress(IUser user, EthAddress address)
1414
{
1515
lock (repoLock)
1616
{
@@ -134,18 +134,19 @@ public string[] GetUserReport(EthAddress ethAddress)
134134
return null;
135135
}
136136

137-
private bool SetUserAddress(IUser user, EthAddress? address)
137+
private SetAddressResponse SetUserAddress(IUser user, EthAddress? address)
138138
{
139139
if (GetUserDataForAddress(address) != null)
140140
{
141-
return false;
141+
return SetAddressResponse.AddressAlreadyInUse;
142142
}
143143

144144
var userData = GetOrCreate(user);
145+
if (userData == null) return SetAddressResponse.CreateUserFailed;
145146
userData.CurrentAddress = address;
146147
userData.AssociateEvents.Add(new UserAssociateAddressEvent(DateTime.UtcNow, address));
147148
SaveUserData(userData);
148-
return true;
149+
return SetAddressResponse.OK;
149150
}
150151

151152
private void SetUserNotification(IUser user, bool notifyEnabled)
@@ -245,4 +246,11 @@ private void LoadAllUserData()
245246
}
246247
}
247248
}
249+
250+
public enum SetAddressResponse
251+
{
252+
OK,
253+
AddressAlreadyInUse,
254+
CreateUserFailed
255+
}
248256
}

0 commit comments

Comments
 (0)