Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
77f6928c9e
46
Bot.cs
46
Bot.cs
@ -19,7 +19,8 @@ namespace RSSBot {
|
|||||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||||
private static HashSet<RegexHandler> Handlers;
|
private static HashSet<RegexHandler> Handlers;
|
||||||
|
|
||||||
private static void Main(string[] args) {
|
private static void Main(string[] args)
|
||||||
|
{
|
||||||
Configuration.Parse();
|
Configuration.Parse();
|
||||||
BotClient = new TelegramBotClient(Configuration.BotToken);
|
BotClient = new TelegramBotClient(Configuration.BotToken);
|
||||||
try {
|
try {
|
||||||
@ -77,12 +78,15 @@ namespace RSSBot {
|
|||||||
Save();
|
Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ReadAllFeeds() {
|
private static void ReadAllFeeds()
|
||||||
|
{
|
||||||
RedisValue[] allFeedUrls = Configuration.Database.SetMembers($"{Configuration.RedisHash}:feeds");
|
RedisValue[] allFeedUrls = Configuration.Database.SetMembers($"{Configuration.RedisHash}:feeds");
|
||||||
foreach (RedisValue feedUrl in allFeedUrls) {
|
foreach (RedisValue feedUrl in allFeedUrls) {
|
||||||
HashSet<long> subs = new HashSet<long>();
|
HashSet<long> subs = new HashSet<long>();
|
||||||
RedisValue[] allSubs = Configuration.Database.SetMembers($"{Configuration.RedisHash}:{feedUrl}:subs");
|
RedisValue[] allSubs = Configuration.Database.SetMembers($"{Configuration.RedisHash}:{feedUrl}:subs");
|
||||||
foreach (RedisValue sub in allSubs) subs.Add(Convert.ToInt64(sub));
|
foreach (RedisValue sub in allSubs) {
|
||||||
|
subs.Add(Convert.ToInt64(sub));
|
||||||
|
}
|
||||||
|
|
||||||
string lastEntry = Configuration.Database.HashGet($"{Configuration.RedisHash}:{feedUrl}", "last_entry");
|
string lastEntry = Configuration.Database.HashGet($"{Configuration.RedisHash}:{feedUrl}", "last_entry");
|
||||||
|
|
||||||
@ -91,29 +95,43 @@ namespace RSSBot {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void OnProcessExit(object? sender, EventArgs e) {
|
private static void OnProcessExit(object? sender, EventArgs e)
|
||||||
|
{
|
||||||
Save();
|
Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void Bot_OnMessage(object? sender, MessageEventArgs messageEventArgs) {
|
private static void Bot_OnMessage(object? sender, MessageEventArgs messageEventArgs)
|
||||||
|
{
|
||||||
Message message = messageEventArgs.Message;
|
Message message = messageEventArgs.Message;
|
||||||
if (message == null || message.Type != MessageType.Text) return;
|
if (message == null || message.Type != MessageType.Text) {
|
||||||
if (!Configuration.Admins.Contains(message.From.Id)) return;
|
return;
|
||||||
|
|
||||||
foreach (RegexHandler handler in Handlers.Where(handler => handler.HandleUpdate(message)))
|
|
||||||
handler.ProcessUpdate(message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async void Save() {
|
if (!Configuration.Admins.Contains(message.From.Id)) {
|
||||||
if (RssBotFeeds.Count > 0)
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (RegexHandler handler in Handlers.Where(handler => handler.HandleUpdate(message))) {
|
||||||
|
handler.ProcessUpdate(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async void Save()
|
||||||
|
{
|
||||||
|
if (RssBotFeeds.Count > 0) {
|
||||||
/* Logger.Info("Speichere Daten..."); */
|
/* Logger.Info("Speichere Daten..."); */
|
||||||
|
}
|
||||||
|
|
||||||
foreach (RssBotFeed feed in RssBotFeeds) {
|
foreach (RssBotFeed feed in RssBotFeeds) {
|
||||||
string feedKey = $"{Configuration.RedisHash}:{feed.Url}";
|
string feedKey = $"{Configuration.RedisHash}:{feed.Url}";
|
||||||
if (string.IsNullOrWhiteSpace(feed.LastEntry)) continue;
|
if (string.IsNullOrWhiteSpace(feed.LastEntry)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
await Configuration.Database.HashSetAsync(feedKey, "last_entry", feed.LastEntry);
|
await Configuration.Database.HashSetAsync(feedKey, "last_entry", feed.LastEntry);
|
||||||
foreach (long chatId in feed.Subs) await Configuration.Database.SetAddAsync($"{feedKey}:subs", chatId);
|
foreach (long chatId in feed.Subs) {
|
||||||
|
await Configuration.Database.SetAddAsync($"{feedKey}:subs", chatId);
|
||||||
|
}
|
||||||
|
|
||||||
await Configuration.Database.SetAddAsync($"{Configuration.RedisHash}:feeds", feed.Url);
|
await Configuration.Database.SetAddAsync($"{Configuration.RedisHash}:feeds", feed.Url);
|
||||||
}
|
}
|
||||||
|
90
Commands.cs
90
Commands.cs
@ -17,7 +17,8 @@ namespace RSSBot {
|
|||||||
public static class Commands {
|
public static class Commands {
|
||||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
public static async void Welcome(Message message, GroupCollection matches) {
|
public static async void Welcome(Message message, GroupCollection matches)
|
||||||
|
{
|
||||||
await Bot.BotClient.SendTextMessageAsync(
|
await Bot.BotClient.SendTextMessageAsync(
|
||||||
message.Chat,
|
message.Chat,
|
||||||
"<b>Willkommen bei RikoBot!</b>\nSende /help, um zu starten.",
|
"<b>Willkommen bei RikoBot!</b>\nSende /help, um zu starten.",
|
||||||
@ -25,7 +26,8 @@ namespace RSSBot {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async void Help(Message message, GroupCollection matches) {
|
public static async void Help(Message message, GroupCollection matches)
|
||||||
|
{
|
||||||
await Bot.BotClient.SendTextMessageAsync(
|
await Bot.BotClient.SendTextMessageAsync(
|
||||||
message.Chat,
|
message.Chat,
|
||||||
"<b>/rss</b> <i>[Chat]</i>: Abonnierte Feeds anzeigen\n" +
|
"<b>/rss</b> <i>[Chat]</i>: Abonnierte Feeds anzeigen\n" +
|
||||||
@ -37,7 +39,8 @@ namespace RSSBot {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async void Subscribe(Message message, GroupCollection args) {
|
public static async void Subscribe(Message message, GroupCollection args)
|
||||||
|
{
|
||||||
string url = args[1].Value;
|
string url = args[1].Value;
|
||||||
long chatId = message.Chat.Id;
|
long chatId = message.Chat.Id;
|
||||||
RssBotFeed feed = new RssBotFeed(url);
|
RssBotFeed feed = new RssBotFeed(url);
|
||||||
@ -49,20 +52,21 @@ namespace RSSBot {
|
|||||||
string chatName = args[2].Value;
|
string chatName = args[2].Value;
|
||||||
bool isId = long.TryParse(chatName, out chatId);
|
bool isId = long.TryParse(chatName, out chatId);
|
||||||
|
|
||||||
if (isId)
|
if (isId) {
|
||||||
try {
|
try {
|
||||||
chatInfo = await Bot.BotClient.GetChatAsync(chatId);
|
chatInfo = await Bot.BotClient.GetChatAsync(chatId);
|
||||||
} catch {
|
} catch {
|
||||||
await Bot.BotClient.SendTextMessageAsync(message.Chat, "❌ Dieser Kanal existiert nicht.");
|
await Bot.BotClient.SendTextMessageAsync(message.Chat, "❌ Dieser Kanal existiert nicht.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
} else {
|
||||||
try {
|
try {
|
||||||
chatInfo = await Bot.BotClient.GetChatAsync(chatName);
|
chatInfo = await Bot.BotClient.GetChatAsync(chatName);
|
||||||
} catch {
|
} catch {
|
||||||
await Bot.BotClient.SendTextMessageAsync(message.Chat, "❌ Dieser Kanal existiert nicht.");
|
await Bot.BotClient.SendTextMessageAsync(message.Chat, "❌ Dieser Kanal existiert nicht.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
chatId = chatInfo.Id;
|
chatId = chatInfo.Id;
|
||||||
|
|
||||||
@ -86,10 +90,11 @@ namespace RSSBot {
|
|||||||
// Check if we already have the feed
|
// Check if we already have the feed
|
||||||
RssBotFeed existingFeed = Bot.RssBotFeeds
|
RssBotFeed existingFeed = Bot.RssBotFeeds
|
||||||
.FirstOrDefault(x => x.Url.ToLower().Equals(feed.Url.ToLower()));
|
.FirstOrDefault(x => x.Url.ToLower().Equals(feed.Url.ToLower()));
|
||||||
if (existingFeed == null)
|
if (existingFeed == null) {
|
||||||
Bot.RssBotFeeds.Add(feed);
|
Bot.RssBotFeeds.Add(feed);
|
||||||
else
|
} else {
|
||||||
feed = existingFeed;
|
feed = existingFeed;
|
||||||
|
}
|
||||||
|
|
||||||
// Check if chat already subscribed
|
// Check if chat already subscribed
|
||||||
if (feed.Subs.Contains(chatId)) {
|
if (feed.Subs.Contains(chatId)) {
|
||||||
@ -101,7 +106,8 @@ namespace RSSBot {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async void Unsubscribe(Message message, GroupCollection args) {
|
public static async void Unsubscribe(Message message, GroupCollection args)
|
||||||
|
{
|
||||||
string url = args[1].Value;
|
string url = args[1].Value;
|
||||||
long chatId = message.Chat.Id;
|
long chatId = message.Chat.Id;
|
||||||
RssBotFeed feed = Bot.RssBotFeeds
|
RssBotFeed feed = Bot.RssBotFeeds
|
||||||
@ -112,20 +118,21 @@ namespace RSSBot {
|
|||||||
string chatName = args[2].Value;
|
string chatName = args[2].Value;
|
||||||
bool isId = long.TryParse(chatName, out chatId);
|
bool isId = long.TryParse(chatName, out chatId);
|
||||||
|
|
||||||
if (isId)
|
if (isId) {
|
||||||
try {
|
try {
|
||||||
chatInfo = await Bot.BotClient.GetChatAsync(chatId);
|
chatInfo = await Bot.BotClient.GetChatAsync(chatId);
|
||||||
} catch {
|
} catch {
|
||||||
await Bot.BotClient.SendTextMessageAsync(message.Chat, "❌ Dieser Kanal existiert nicht.");
|
await Bot.BotClient.SendTextMessageAsync(message.Chat, "❌ Dieser Kanal existiert nicht.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
} else {
|
||||||
try {
|
try {
|
||||||
chatInfo = await Bot.BotClient.GetChatAsync(chatName);
|
chatInfo = await Bot.BotClient.GetChatAsync(chatName);
|
||||||
} catch {
|
} catch {
|
||||||
await Bot.BotClient.SendTextMessageAsync(message.Chat, "❌ Dieser Kanal existiert nicht.");
|
await Bot.BotClient.SendTextMessageAsync(message.Chat, "❌ Dieser Kanal existiert nicht.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
chatId = chatInfo.Id;
|
chatId = chatInfo.Id;
|
||||||
|
|
||||||
@ -142,13 +149,16 @@ namespace RSSBot {
|
|||||||
}
|
}
|
||||||
|
|
||||||
feed.Cleanup(chatId);
|
feed.Cleanup(chatId);
|
||||||
if (feed.Subs.Count == 0) Bot.RssBotFeeds.Remove(feed);
|
if (feed.Subs.Count == 0) {
|
||||||
|
Bot.RssBotFeeds.Remove(feed);
|
||||||
|
}
|
||||||
|
|
||||||
await Bot.BotClient.SendTextMessageAsync(message.Chat, "✅ Feed deabonniert!");
|
await Bot.BotClient.SendTextMessageAsync(message.Chat, "✅ Feed deabonniert!");
|
||||||
Bot.Save();
|
Bot.Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async void Show(Message message, GroupCollection args) {
|
public static async void Show(Message message, GroupCollection args)
|
||||||
|
{
|
||||||
long chatId = message.Chat.Id;
|
long chatId = message.Chat.Id;
|
||||||
string chatTitle = message.Chat.Type.Equals(ChatType.Private) ? message.Chat.FirstName : message.Chat.Title;
|
string chatTitle = message.Chat.Type.Equals(ChatType.Private) ? message.Chat.FirstName : message.Chat.Title;
|
||||||
await Bot.BotClient.SendChatActionAsync(message.Chat, ChatAction.Typing);
|
await Bot.BotClient.SendChatActionAsync(message.Chat, ChatAction.Typing);
|
||||||
@ -158,20 +168,21 @@ namespace RSSBot {
|
|||||||
string chatName = args[1].Value;
|
string chatName = args[1].Value;
|
||||||
bool isId = long.TryParse(chatName, out chatId);
|
bool isId = long.TryParse(chatName, out chatId);
|
||||||
|
|
||||||
if (isId)
|
if (isId) {
|
||||||
try {
|
try {
|
||||||
chatInfo = await Bot.BotClient.GetChatAsync(chatId);
|
chatInfo = await Bot.BotClient.GetChatAsync(chatId);
|
||||||
} catch {
|
} catch {
|
||||||
await Bot.BotClient.SendTextMessageAsync(message.Chat, "❌ Dieser Kanal existiert nicht.");
|
await Bot.BotClient.SendTextMessageAsync(message.Chat, "❌ Dieser Kanal existiert nicht.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
} else {
|
||||||
try {
|
try {
|
||||||
chatInfo = await Bot.BotClient.GetChatAsync(chatName);
|
chatInfo = await Bot.BotClient.GetChatAsync(chatName);
|
||||||
} catch {
|
} catch {
|
||||||
await Bot.BotClient.SendTextMessageAsync(message.Chat, "❌ Dieser Kanal existiert nicht.");
|
await Bot.BotClient.SendTextMessageAsync(message.Chat, "❌ Dieser Kanal existiert nicht.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
chatId = chatInfo.Id;
|
chatId = chatInfo.Id;
|
||||||
chatTitle = chatInfo.Title;
|
chatTitle = chatInfo.Title;
|
||||||
@ -190,13 +201,16 @@ namespace RSSBot {
|
|||||||
text.Append("❌ Keine Feeds abonniert.");
|
text.Append("❌ Keine Feeds abonniert.");
|
||||||
} else {
|
} else {
|
||||||
text.Append($"<strong>{HttpUtility.HtmlEncode(chatTitle)}</strong> hat abonniert:\n");
|
text.Append($"<strong>{HttpUtility.HtmlEncode(chatTitle)}</strong> hat abonniert:\n");
|
||||||
for (int i = 0; i < feeds.Count; i++) text.Append($"<strong>{i + 1}</strong>) {feeds[i].Url}\n");
|
for (int i = 0; i < feeds.Count; i++) {
|
||||||
|
text.Append($"<strong>{i + 1}</strong>) {feeds[i].Url}\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await Bot.BotClient.SendTextMessageAsync(message.Chat, text.ToString(), ParseMode.Html, true);
|
await Bot.BotClient.SendTextMessageAsync(message.Chat, text.ToString(), ParseMode.Html, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async void Sync() {
|
public static async void Sync()
|
||||||
|
{
|
||||||
Logger.Info("================================");
|
Logger.Info("================================");
|
||||||
bool hadEntries = false;
|
bool hadEntries = false;
|
||||||
foreach (RssBotFeed feed in Bot.RssBotFeeds.ToList()) {
|
foreach (RssBotFeed feed in Bot.RssBotFeeds.ToList()) {
|
||||||
@ -220,7 +234,10 @@ namespace RSSBot {
|
|||||||
|
|
||||||
foreach (FeedItem entry in feed.NewEntries) {
|
foreach (FeedItem entry in feed.NewEntries) {
|
||||||
string postTitle = "Kein Titel";
|
string postTitle = "Kein Titel";
|
||||||
if (!string.IsNullOrWhiteSpace(entry.Title)) postTitle = Utils.StripHtml(entry.Title);
|
if (!string.IsNullOrWhiteSpace(entry.Title)) {
|
||||||
|
postTitle = Utils.StripHtml(entry.Title);
|
||||||
|
postTitle = Utils.EscapeHtml(postTitle);
|
||||||
|
}
|
||||||
|
|
||||||
string postLink = feed.MainLink;
|
string postLink = feed.MainLink;
|
||||||
string linkName = postLink;
|
string linkName = postLink;
|
||||||
@ -234,20 +251,22 @@ namespace RSSBot {
|
|||||||
|
|
||||||
// Remove "www."
|
// Remove "www."
|
||||||
int index = linkName.IndexOf("www.", StringComparison.Ordinal);
|
int index = linkName.IndexOf("www.", StringComparison.Ordinal);
|
||||||
if (index > -1) linkName = linkName.Remove(index, 4);
|
if (index > -1) {
|
||||||
|
linkName = linkName.Remove(index, 4);
|
||||||
|
}
|
||||||
|
|
||||||
string content = "";
|
string content = "";
|
||||||
if (!string.IsNullOrWhiteSpace(entry.Content))
|
if (!string.IsNullOrWhiteSpace(entry.Content)) {
|
||||||
content = Utils.ProcessContent(entry.Content);
|
content = Utils.ProcessContent(entry.Content);
|
||||||
else if (!string.IsNullOrWhiteSpace(entry.Description))
|
} else if (!string.IsNullOrWhiteSpace(entry.Description)) {
|
||||||
content = Utils.ProcessContent(entry.Description);
|
content = Utils.ProcessContent(entry.Description);
|
||||||
|
}
|
||||||
|
|
||||||
string text = $"<b>[#RSS] {postTitle}</b>\n{content}";
|
string text = $"<b>[#RSS] {postTitle}</b>\n{content}";
|
||||||
text += $"\n<a href=\"{postLink}\">Auf {linkName} ansehen.</a>";
|
text += $"\n<a href=\"{postLink}\">Auf {linkName} ansehen.</a>";
|
||||||
|
|
||||||
// Send
|
// Send
|
||||||
foreach (long chatId in feed.Subs.ToList())
|
foreach (long chatId in feed.Subs.ToList()) {
|
||||||
{
|
|
||||||
await SendFinishedMessage(chatId, text, feed);
|
await SendFinishedMessage(chatId, text, feed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -255,38 +274,39 @@ namespace RSSBot {
|
|||||||
|
|
||||||
/* Logger.Info("Nächster Check in 60 Sekunden"); */
|
/* Logger.Info("Nächster Check in 60 Sekunden"); */
|
||||||
|
|
||||||
if (hadEntries) Bot.Save();
|
if (hadEntries) {
|
||||||
|
Bot.Save();
|
||||||
|
}
|
||||||
|
|
||||||
Bot.JobQueue.Change(TimeSpan.FromMinutes(1), TimeSpan.FromMilliseconds(-1));
|
Bot.JobQueue.Change(TimeSpan.FromMinutes(1), TimeSpan.FromMilliseconds(-1));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task SendFinishedMessage(long chatId, string text, RssBotFeed feed, int waitTime = 10)
|
private static async Task SendFinishedMessage(long chatId, string text, RssBotFeed feed, int waitTime = 10)
|
||||||
{
|
{
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
await Bot.BotClient.SendTextMessageAsync(chatId, text, ParseMode.Html, true, true);
|
await Bot.BotClient.SendTextMessageAsync(chatId, text, ParseMode.Html, true, true);
|
||||||
Thread.Sleep(1000);
|
Thread.Sleep(1000);
|
||||||
} catch (ApiRequestException e)
|
} catch (ApiRequestException e) {
|
||||||
{
|
if (e.ErrorCode.Equals(403)) {
|
||||||
if (e.ErrorCode.Equals(403))
|
|
||||||
{
|
|
||||||
Logger.Warn(e.Message);
|
Logger.Warn(e.Message);
|
||||||
feed.Cleanup(chatId);
|
feed.Cleanup(chatId);
|
||||||
if (feed.Subs.Count == 0) // was last subscriber
|
if (feed.Subs.Count == 0) // was last subscriber
|
||||||
Bot.RssBotFeeds.Remove(feed);
|
|
||||||
} else
|
|
||||||
{
|
{
|
||||||
|
Bot.RssBotFeeds.Remove(feed);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
Logger.Error($"{e.ErrorCode}: {e.Message}");
|
Logger.Error($"{e.ErrorCode}: {e.Message}");
|
||||||
}
|
}
|
||||||
} catch (HttpRequestException e) // likely 429
|
} catch (HttpRequestException) // likely 429
|
||||||
{
|
{
|
||||||
Logger.Warn($"Got rate limited, waiting {waitTime} seconds...");
|
Logger.Warn($"Rate-Limit erreicht, warte {waitTime} Sekunden...");
|
||||||
Thread.Sleep(waitTime * 1000);
|
Thread.Sleep(waitTime * 1000);
|
||||||
await SendFinishedMessage(chatId, text, feed, (waitTime * 2));
|
await SendFinishedMessage(chatId, text, feed, waitTime * 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async void ShowAvailableFeeds(Message message, GroupCollection args) {
|
public static async void ShowAvailableFeeds(Message message, GroupCollection args)
|
||||||
|
{
|
||||||
string url = args[1].Value;
|
string url = args[1].Value;
|
||||||
IEnumerable<HtmlFeedLink> feeds;
|
IEnumerable<HtmlFeedLink> feeds;
|
||||||
try {
|
try {
|
||||||
|
@ -18,7 +18,8 @@ namespace RSSBot {
|
|||||||
public static List<int> Admins;
|
public static List<int> Admins;
|
||||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
public static void Parse() {
|
public static void Parse()
|
||||||
|
{
|
||||||
if (!File.Exists("NLog.config")) {
|
if (!File.Exists("NLog.config")) {
|
||||||
Console.WriteLine("NLog.config nicht gefunden, setze auf INFO...");
|
Console.WriteLine("NLog.config nicht gefunden, setze auf INFO...");
|
||||||
LoggingConfiguration config = new LoggingConfiguration();
|
LoggingConfiguration config = new LoggingConfiguration();
|
||||||
|
@ -7,15 +7,16 @@ namespace RSSBot {
|
|||||||
/// RegexHandler for Telegram Bots.
|
/// RegexHandler for Telegram Bots.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class RegexHandler {
|
public class RegexHandler {
|
||||||
private string Pattern;
|
private readonly Action<Message, GroupCollection> CallbackFunction;
|
||||||
private Action<Message, GroupCollection> CallbackFunction;
|
private readonly string Pattern;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructor for the RegexHandler.
|
/// Constructor for the RegexHandler.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="pattern">Regex pattern</param>
|
/// <param name="pattern">Regex pattern</param>
|
||||||
/// <param name="callback">Callback function to call when the update should be processed</param>
|
/// <param name="callback">Callback function to call when the update should be processed</param>
|
||||||
public RegexHandler(string pattern, Action<Message, GroupCollection> callback) {
|
public RegexHandler(string pattern, Action<Message, GroupCollection> callback)
|
||||||
|
{
|
||||||
Pattern = pattern;
|
Pattern = pattern;
|
||||||
CallbackFunction = callback;
|
CallbackFunction = callback;
|
||||||
}
|
}
|
||||||
@ -25,7 +26,8 @@ namespace RSSBot {
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="message">Telegram Message object</param>
|
/// <param name="message">Telegram Message object</param>
|
||||||
/// <returns>true if the update should be handled</returns>
|
/// <returns>true if the update should be handled</returns>
|
||||||
public bool HandleUpdate(Message message) {
|
public bool HandleUpdate(Message message)
|
||||||
|
{
|
||||||
return Regex.IsMatch(message.Text,
|
return Regex.IsMatch(message.Text,
|
||||||
Pattern,
|
Pattern,
|
||||||
RegexOptions.IgnoreCase);
|
RegexOptions.IgnoreCase);
|
||||||
@ -35,7 +37,8 @@ namespace RSSBot {
|
|||||||
/// Calls the assoicated callback function.
|
/// Calls the assoicated callback function.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="message">Telegram Message object</param>
|
/// <param name="message">Telegram Message object</param>
|
||||||
public void ProcessUpdate(Message message) {
|
public void ProcessUpdate(Message message)
|
||||||
|
{
|
||||||
GroupCollection matches = Regex.Match(message.Text,
|
GroupCollection matches = Regex.Match(message.Text,
|
||||||
Pattern,
|
Pattern,
|
||||||
RegexOptions.IgnoreCase
|
RegexOptions.IgnoreCase
|
||||||
|
@ -6,14 +6,12 @@ using CodeHollow.FeedReader;
|
|||||||
|
|
||||||
namespace RSSBot {
|
namespace RSSBot {
|
||||||
public class RssBotFeed {
|
public class RssBotFeed {
|
||||||
|
public readonly HashSet<long> Subs = new HashSet<long>();
|
||||||
public readonly string Url;
|
public readonly string Url;
|
||||||
public string LastEntry;
|
public string LastEntry;
|
||||||
public readonly HashSet<long> Subs = new HashSet<long>();
|
|
||||||
public string MainLink { get; private set; }
|
|
||||||
public string Title { get; private set; }
|
|
||||||
public List<FeedItem> NewEntries { get; private set; }
|
|
||||||
|
|
||||||
public RssBotFeed(string url, string lastEntry = null, HashSet<long> subs = null) {
|
public RssBotFeed(string url, string lastEntry = null, HashSet<long> subs = null)
|
||||||
|
{
|
||||||
Url = url;
|
Url = url;
|
||||||
if (!string.IsNullOrWhiteSpace(lastEntry)) {
|
if (!string.IsNullOrWhiteSpace(lastEntry)) {
|
||||||
LastEntry = lastEntry;
|
LastEntry = lastEntry;
|
||||||
@ -24,7 +22,12 @@ namespace RSSBot {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Check() {
|
public string MainLink { get; private set; }
|
||||||
|
public string Title { get; private set; }
|
||||||
|
public List<FeedItem> NewEntries { get; private set; }
|
||||||
|
|
||||||
|
public async Task Check()
|
||||||
|
{
|
||||||
Feed feed = await FeedReader.ReadAsync(Url);
|
Feed feed = await FeedReader.ReadAsync(Url);
|
||||||
if (string.IsNullOrWhiteSpace(feed.Link)) {
|
if (string.IsNullOrWhiteSpace(feed.Link)) {
|
||||||
throw new Exception("Kein gültiger RSS-Feed.");
|
throw new Exception("Kein gültiger RSS-Feed.");
|
||||||
@ -33,7 +36,10 @@ namespace RSSBot {
|
|||||||
MainLink = feed.Link;
|
MainLink = feed.Link;
|
||||||
Title = feed.Title;
|
Title = feed.Title;
|
||||||
|
|
||||||
if (feed.Items == null || feed.Items.Count <= 0) return;
|
if (feed.Items == null || feed.Items.Count <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
NewEntries = string.IsNullOrWhiteSpace(LastEntry)
|
NewEntries = string.IsNullOrWhiteSpace(LastEntry)
|
||||||
? feed.Items.ToList()
|
? feed.Items.ToList()
|
||||||
: GetNewEntries(feed.Items);
|
: GetNewEntries(feed.Items);
|
||||||
@ -43,7 +49,8 @@ namespace RSSBot {
|
|||||||
: feed.Items.First().Id;
|
: feed.Items.First().Id;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<FeedItem> GetNewEntries(IEnumerable<FeedItem> entries) {
|
private List<FeedItem> GetNewEntries(IEnumerable<FeedItem> entries)
|
||||||
|
{
|
||||||
List<FeedItem> newEntries = new List<FeedItem>();
|
List<FeedItem> newEntries = new List<FeedItem>();
|
||||||
foreach (FeedItem entry in entries) {
|
foreach (FeedItem entry in entries) {
|
||||||
if (!string.IsNullOrWhiteSpace(entry.Id)) {
|
if (!string.IsNullOrWhiteSpace(entry.Id)) {
|
||||||
@ -65,17 +72,22 @@ namespace RSSBot {
|
|||||||
return newEntries;
|
return newEntries;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString() {
|
public override string ToString()
|
||||||
|
{
|
||||||
return $"RSS-Feed: '{Url}'";
|
return $"RSS-Feed: '{Url}'";
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Cleanup(long chatId) {
|
public void Cleanup(long chatId)
|
||||||
|
{
|
||||||
Subs.Remove(chatId);
|
Subs.Remove(chatId);
|
||||||
string feedKey = $"{Configuration.RedisHash}:{Url}";
|
string feedKey = $"{Configuration.RedisHash}:{Url}";
|
||||||
Configuration.Database.SetRemove($"{feedKey}:subs", chatId);
|
Configuration.Database.SetRemove($"{feedKey}:subs", chatId);
|
||||||
|
|
||||||
// No subscribers, delete all references
|
// No subscribers, delete all references
|
||||||
if (Subs.Count != 0 || !Configuration.Database.KeyExists(feedKey)) return;
|
if (Subs.Count != 0 || !Configuration.Database.KeyExists(feedKey)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Configuration.Database.KeyDelete(feedKey);
|
Configuration.Database.KeyDelete(feedKey);
|
||||||
Configuration.Database.KeyDelete($"{feedKey}:subs");
|
Configuration.Database.KeyDelete($"{feedKey}:subs");
|
||||||
Configuration.Database.SetRemove($"{Configuration.RedisHash}:feeds", Url);
|
Configuration.Database.SetRemove($"{Configuration.RedisHash}:feeds", Url);
|
||||||
|
28
Utils.cs
28
Utils.cs
@ -9,11 +9,20 @@ namespace RSSBot {
|
|||||||
public static class Utils {
|
public static class Utils {
|
||||||
private static readonly Regex RegexHtml = new Regex("<.*?>");
|
private static readonly Regex RegexHtml = new Regex("<.*?>");
|
||||||
|
|
||||||
public static string StripHtml(string input) {
|
public static string StripHtml(string input)
|
||||||
|
{
|
||||||
return RegexHtml.Replace(input, string.Empty).Trim();
|
return RegexHtml.Replace(input, string.Empty).Trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string CleanRss(string input) {
|
public static string EscapeHtml(string input)
|
||||||
|
{
|
||||||
|
input = input.Replace("<", "<");
|
||||||
|
input = input.Replace(">", ">");
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string CleanRss(string input)
|
||||||
|
{
|
||||||
string[] replacements = {
|
string[] replacements = {
|
||||||
"[←]",
|
"[←]",
|
||||||
"[…]",
|
"[…]",
|
||||||
@ -69,22 +78,27 @@ namespace RSSBot {
|
|||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string ProcessContent(string input) {
|
public static string ProcessContent(string input)
|
||||||
var content = StripHtml(HttpUtility.HtmlDecode(input));
|
{
|
||||||
|
string content = StripHtml(HttpUtility.HtmlDecode(input));
|
||||||
content = CleanRss(content);
|
content = CleanRss(content);
|
||||||
if (content.Length > 250) content = content.Substring(0, 250) + "...";
|
if (content.Length > 250) {
|
||||||
|
content = content.Substring(0, 250) + "...";
|
||||||
|
}
|
||||||
|
|
||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GroupCollection ReturnMatches(string text, string pattern) {
|
public static GroupCollection ReturnMatches(string text, string pattern)
|
||||||
|
{
|
||||||
return Regex.Match(text,
|
return Regex.Match(text,
|
||||||
pattern,
|
pattern,
|
||||||
RegexOptions.IgnoreCase
|
RegexOptions.IgnoreCase
|
||||||
).Groups;
|
).Groups;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<bool> IsBotAdmin(long chatId) {
|
public static async Task<bool> IsBotAdmin(long chatId)
|
||||||
|
{
|
||||||
ChatMember chatMember = await Bot.BotClient.GetChatMemberAsync(chatId, Bot.BotClient.BotId);
|
ChatMember chatMember = await Bot.BotClient.GetChatMemberAsync(chatId, Bot.BotClient.BotId);
|
||||||
return chatMember.Status.Equals(ChatMemberStatus.Administrator);
|
return chatMember.Status.Equals(ChatMemberStatus.Administrator);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user