mirror of
https://gitlab.com/Kwoth/nadekobot.git
synced 2025-09-11 09:48:26 -04:00
NadekoBot Patronage system, Search commands improvements + fixes
This commit is contained in:
@@ -1,8 +1,11 @@
|
||||
#nullable disable
|
||||
using NadekoBot.Common.ModuleBehaviors;
|
||||
using NadekoBot.Db.Models;
|
||||
using NadekoBot.Modules.Games.Common.ChatterBot;
|
||||
using NadekoBot.Modules.Permissions;
|
||||
using NadekoBot.Modules.Permissions.Common;
|
||||
using NadekoBot.Modules.Permissions.Services;
|
||||
using NadekoBot.Modules.Utility.Patronage;
|
||||
|
||||
namespace NadekoBot.Modules.Games.Services;
|
||||
|
||||
@@ -13,6 +16,8 @@ public class ChatterBotService : IExecOnMessage
|
||||
public int Priority
|
||||
=> 1;
|
||||
|
||||
private readonly FeatureLimitKey _flKey;
|
||||
|
||||
private readonly DiscordSocketClient _client;
|
||||
private readonly PermissionService _perms;
|
||||
private readonly CommandHandler _cmd;
|
||||
@@ -20,6 +25,8 @@ public class ChatterBotService : IExecOnMessage
|
||||
private readonly IBotCredentials _creds;
|
||||
private readonly IEmbedBuilderService _eb;
|
||||
private readonly IHttpClientFactory _httpFactory;
|
||||
private readonly IPatronageService _ps;
|
||||
private readonly CmdCdService _ccs;
|
||||
|
||||
public ChatterBotService(
|
||||
DiscordSocketClient client,
|
||||
@@ -29,7 +36,9 @@ public class ChatterBotService : IExecOnMessage
|
||||
IBotStrings strings,
|
||||
IHttpClientFactory factory,
|
||||
IBotCredentials creds,
|
||||
IEmbedBuilderService eb)
|
||||
IEmbedBuilderService eb,
|
||||
IPatronageService ps,
|
||||
CmdCdService cmdCdService)
|
||||
{
|
||||
_client = client;
|
||||
_perms = perms;
|
||||
@@ -38,8 +47,17 @@ public class ChatterBotService : IExecOnMessage
|
||||
_creds = creds;
|
||||
_eb = eb;
|
||||
_httpFactory = factory;
|
||||
_ps = ps;
|
||||
_ccs = cmdCdService;
|
||||
|
||||
ChatterBotGuilds = new(bot.AllGuildConfigs.Where(gc => gc.CleverbotEnabled)
|
||||
_flKey = new FeatureLimitKey()
|
||||
{
|
||||
Key = CleverBotResponseStr.CLEVERBOT_RESPONSE,
|
||||
PrettyName = "Cleverbot Replies"
|
||||
};
|
||||
|
||||
ChatterBotGuilds = new(bot.AllGuildConfigs
|
||||
.Where(gc => gc.CleverbotEnabled)
|
||||
.ToDictionary(gc => gc.GuildId,
|
||||
_ => new Lazy<IChatterBotSession>(() => CreateSession(), true)));
|
||||
}
|
||||
@@ -48,7 +66,9 @@ public class ChatterBotService : IExecOnMessage
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(_creds.CleverbotApiKey))
|
||||
return new OfficialCleverbotSession(_creds.CleverbotApiKey, _httpFactory);
|
||||
return new CleverbotIoSession("GAh3wUfzDCpDpdpT", "RStKgqn7tcO9blbrv4KbXM8NDlb7H37C", _httpFactory);
|
||||
|
||||
Log.Information("Cleverbot will not work as the api key is missing.");
|
||||
return null;
|
||||
}
|
||||
|
||||
public string PrepareMessage(IUserMessage msg, out IChatterBotSession cleverbot)
|
||||
@@ -78,27 +98,11 @@ public class ChatterBotService : IExecOnMessage
|
||||
return message;
|
||||
}
|
||||
|
||||
public async Task<bool> TryAsk(IChatterBotSession cleverbot, ITextChannel channel, string message)
|
||||
{
|
||||
await channel.TriggerTypingAsync();
|
||||
|
||||
var response = await cleverbot.Think(message);
|
||||
try
|
||||
{
|
||||
await channel.SendConfirmAsync(_eb, response.SanitizeMentions(true));
|
||||
}
|
||||
catch
|
||||
{
|
||||
await channel.SendConfirmAsync(_eb, response.SanitizeMentions(true)); // try twice :\
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task<bool> ExecOnMessageAsync(IGuild guild, IUserMessage usrMsg)
|
||||
{
|
||||
if (guild is not SocketGuild sg)
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
var message = PrepareMessage(usrMsg, out var cbs);
|
||||
@@ -106,7 +110,10 @@ public class ChatterBotService : IExecOnMessage
|
||||
return false;
|
||||
|
||||
var pc = _perms.GetCacheFor(guild.Id);
|
||||
if (!pc.Permissions.CheckPermissions(usrMsg, "cleverbot", "Games".ToLowerInvariant(), out var index))
|
||||
if (!pc.Permissions.CheckPermissions(usrMsg,
|
||||
"cleverbot",
|
||||
"games",
|
||||
out var index))
|
||||
{
|
||||
if (pc.Verbose)
|
||||
{
|
||||
@@ -122,24 +129,78 @@ public class ChatterBotService : IExecOnMessage
|
||||
return true;
|
||||
}
|
||||
|
||||
var cleverbotExecuted = await TryAsk(cbs, (ITextChannel)usrMsg.Channel, message);
|
||||
if (cleverbotExecuted)
|
||||
if (await _ccs.TryBlock(sg, usrMsg.Author, CleverBotResponseStr.CLEVERBOT_RESPONSE))
|
||||
{
|
||||
Log.Information(@"CleverBot Executed
|
||||
return true;
|
||||
}
|
||||
|
||||
var channel = (ITextChannel)usrMsg.Channel;
|
||||
var conf = _ps.GetConfig();
|
||||
if (conf.IsEnabled)
|
||||
{
|
||||
var quota = await _ps.TryGetFeatureLimitAsync(_flKey, sg.OwnerId, 0);
|
||||
|
||||
uint? daily = quota.Quota is int dVal and < 0
|
||||
? (uint)-dVal
|
||||
: null;
|
||||
|
||||
uint? monthly = quota.Quota is int mVal and >= 0
|
||||
? (uint)mVal
|
||||
: null;
|
||||
|
||||
var maybeLimit = await _ps.TryIncrementQuotaCounterAsync(sg.OwnerId,
|
||||
sg.OwnerId == usrMsg.Author.Id,
|
||||
FeatureType.Limit,
|
||||
_flKey.Key,
|
||||
null,
|
||||
daily,
|
||||
monthly);
|
||||
|
||||
if (maybeLimit.TryPickT1(out var ql, out var counters))
|
||||
{
|
||||
if (ql.Quota == 0)
|
||||
{
|
||||
await channel.SendErrorAsync(_eb,
|
||||
null!,
|
||||
text:
|
||||
"In order to use the cleverbot feature, the owner of this server should be [Patron Tier X](https://patreon.com/join/nadekobot) on patreon.",
|
||||
footer:
|
||||
"You may disable the cleverbot feature, and this message via '.cleverbot' command");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
await channel.SendErrorAsync(_eb,
|
||||
null!,
|
||||
$"You've reached your quota limit of **{ql.Quota}** responses {ql.QuotaPeriod.ToFullName()} for the cleverbot feature.",
|
||||
footer: "You may wait for the quota reset or .");
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
_ = channel.TriggerTypingAsync();
|
||||
var response = await cbs.Think(message);
|
||||
await channel.SendConfirmAsync(_eb,
|
||||
title: null,
|
||||
response.SanitizeMentions(true)
|
||||
// , footer: counter > 0 ? counter.ToString() : null
|
||||
);
|
||||
|
||||
Log.Information(@"CleverBot Executed
|
||||
Server: {GuildName} [{GuildId}]
|
||||
Channel: {ChannelName} [{ChannelId}]
|
||||
UserId: {Author} [{AuthorId}]
|
||||
Message: {Content}",
|
||||
guild.Name,
|
||||
guild.Id,
|
||||
usrMsg.Channel?.Name,
|
||||
usrMsg.Channel?.Id,
|
||||
usrMsg.Author,
|
||||
usrMsg.Author.Id,
|
||||
usrMsg.Content);
|
||||
guild.Name,
|
||||
guild.Id,
|
||||
usrMsg.Channel?.Name,
|
||||
usrMsg.Channel?.Id,
|
||||
usrMsg.Author,
|
||||
usrMsg.Author.Id,
|
||||
usrMsg.Content);
|
||||
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@@ -14,7 +14,6 @@ public partial class Games
|
||||
public ChatterBotCommands(DbService db)
|
||||
=> _db = db;
|
||||
|
||||
[NoPublicBot]
|
||||
[Cmd]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
[UserPerm(GuildPerm.ManageMessages)]
|
||||
|
@@ -1,34 +0,0 @@
|
||||
#nullable disable
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace NadekoBot.Modules.Games.Common.ChatterBot;
|
||||
|
||||
public class ChatterBotSession : IChatterBotSession
|
||||
{
|
||||
private static NadekoRandom Rng { get; } = new();
|
||||
|
||||
private string ApiEndpoint
|
||||
=> "http://api.program-o.com/v2/chatbot/"
|
||||
+ $"?bot_id={_botId}&"
|
||||
+ "say={0}&"
|
||||
+ $"convo_id=nadekobot_{_chatterBotId}&"
|
||||
+ "format=json";
|
||||
|
||||
private readonly string _chatterBotId;
|
||||
private readonly IHttpClientFactory _httpFactory;
|
||||
private readonly int _botId = 6;
|
||||
|
||||
public ChatterBotSession(IHttpClientFactory httpFactory)
|
||||
{
|
||||
_chatterBotId = Rng.Next(0, 1000000).ToString().ToBase64();
|
||||
_httpFactory = httpFactory;
|
||||
}
|
||||
|
||||
public async Task<string> Think(string message)
|
||||
{
|
||||
using var http = _httpFactory.CreateClient();
|
||||
var res = await http.GetStringAsync(string.Format(ApiEndpoint, message));
|
||||
var cbr = JsonConvert.DeserializeObject<ChatterBotResponse>(res);
|
||||
return cbr.BotSay.Replace("<br/>", "\n", StringComparison.InvariantCulture);
|
||||
}
|
||||
}
|
@@ -5,16 +5,4 @@ public class CleverbotResponse
|
||||
{
|
||||
public string Cs { get; set; }
|
||||
public string Output { get; set; }
|
||||
}
|
||||
|
||||
public class CleverbotIoCreateResponse
|
||||
{
|
||||
public string Status { get; set; }
|
||||
public string Nick { get; set; }
|
||||
}
|
||||
|
||||
public class CleverbotIoAskResponse
|
||||
{
|
||||
public string Status { get; set; }
|
||||
public string Response { get; set; }
|
||||
}
|
@@ -35,57 +35,4 @@ public class OfficialCleverbotSession : IChatterBotSession
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class CleverbotIoSession : IChatterBotSession
|
||||
{
|
||||
private readonly string _key;
|
||||
private readonly string _user;
|
||||
private readonly IHttpClientFactory _httpFactory;
|
||||
private readonly AsyncLazy<string> _nick;
|
||||
|
||||
private readonly string _createEndpoint = "https://cleverbot.io/1.0/create";
|
||||
private readonly string _askEndpoint = "https://cleverbot.io/1.0/ask";
|
||||
|
||||
public CleverbotIoSession(string user, string key, IHttpClientFactory factory)
|
||||
{
|
||||
_key = key;
|
||||
_user = user;
|
||||
_httpFactory = factory;
|
||||
|
||||
_nick = new(GetNick);
|
||||
}
|
||||
|
||||
private async Task<string> GetNick()
|
||||
{
|
||||
using var http = _httpFactory.CreateClient();
|
||||
using var msg = new FormUrlEncodedContent(new[]
|
||||
{
|
||||
new KeyValuePair<string, string>("user", _user), new KeyValuePair<string, string>("key", _key)
|
||||
});
|
||||
using var data = await http.PostAsync(_createEndpoint, msg);
|
||||
var str = await data.Content.ReadAsStringAsync();
|
||||
var obj = JsonConvert.DeserializeObject<CleverbotIoCreateResponse>(str);
|
||||
if (obj.Status != "success")
|
||||
throw new OperationCanceledException(obj.Status);
|
||||
|
||||
return obj.Nick;
|
||||
}
|
||||
|
||||
public async Task<string> Think(string input)
|
||||
{
|
||||
using var http = _httpFactory.CreateClient();
|
||||
using var msg = new FormUrlEncodedContent(new[]
|
||||
{
|
||||
new KeyValuePair<string, string>("user", _user), new KeyValuePair<string, string>("key", _key),
|
||||
new KeyValuePair<string, string>("nick", await _nick), new KeyValuePair<string, string>("text", input)
|
||||
});
|
||||
using var data = await http.PostAsync(_askEndpoint, msg);
|
||||
var str = await data.Content.ReadAsStringAsync();
|
||||
var obj = JsonConvert.DeserializeObject<CleverbotIoAskResponse>(str);
|
||||
if (obj.Status != "success")
|
||||
throw new OperationCanceledException(obj.Status);
|
||||
|
||||
return obj.Response;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user