-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
28601ea
commit 5734e19
Showing
15 changed files
with
963 additions
and
0 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
using System.Collections.Generic; | ||
|
||
namespace ImageSearchBot.Config | ||
{ | ||
public class BotConfig | ||
{ | ||
public string Prefix { get; set; } | ||
|
||
public List<string> GreetingsMessages { get; set; } | ||
|
||
public List<string> Responses { get; set; } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
namespace ImageSearchBot.Config | ||
{ | ||
public class ImageSearchConfig | ||
{ | ||
public string Type { get; set; } | ||
|
||
public string Query { get; set; } | ||
|
||
public bool? IncludeNsfw { get; set; } | ||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
namespace ImageSearchBot.Config | ||
{ | ||
public class RootConfig | ||
{ | ||
public BotConfig BotConfig { get; set; } | ||
|
||
public ImageSearchConfig ImageSearchConfig { get; set; } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
using System; | ||
using System.Net; | ||
using ImageSearchBot.Config; | ||
using Microsoft.Azure.CognitiveServices.Search.ImageSearch; | ||
|
||
namespace ImageSearchBot.ImageSearch | ||
{ | ||
public class BingImageSearch : ImageSearch | ||
{ | ||
private readonly ImageSearchClient _client; | ||
|
||
public BingImageSearch(string botPrefix, ImageSearchConfig config) : base(botPrefix, config) | ||
{ | ||
var keyEnvVar = $"{BotPrefix}_BING_KEY"; | ||
var subscriptionKey = Environment.GetEnvironmentVariable(keyEnvVar); | ||
_client = new ImageSearchClient(new ApiKeyServiceClientCredentials(subscriptionKey)); | ||
} | ||
|
||
public override void Dispose() | ||
{ | ||
_client.Dispose(); | ||
} | ||
|
||
public override byte[] GetImage(int index, int count) | ||
{ | ||
var imageResults = _client.Images.SearchAsync( | ||
Config.Query, | ||
safeSearch: Config.IncludeNsfw ?? false ? "Off" : "Moderate", | ||
count: count).Result; //search query | ||
|
||
var clampedIndex = Math.Clamp(index, 0, imageResults.Value.Count-1); | ||
|
||
var imageUrl = imageResults.Value[clampedIndex].ContentUrl; | ||
using (var webClient = new WebClient()) | ||
{ | ||
return webClient.DownloadData(imageUrl); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
using System; | ||
using ImageSearchBot.Config; | ||
|
||
namespace ImageSearchBot.ImageSearch | ||
{ | ||
public interface IImageSearch : IDisposable | ||
{ | ||
string BotPrefix { get; } | ||
|
||
byte[] GetImage(int index, int count); | ||
} | ||
|
||
public abstract class ImageSearch : IImageSearch | ||
{ | ||
public string BotPrefix { get; } | ||
|
||
protected ImageSearchConfig Config { get; } | ||
|
||
protected ImageSearch(string botPrefix, ImageSearchConfig config) | ||
{ | ||
BotPrefix = botPrefix; | ||
Config = config; | ||
} | ||
|
||
public abstract void Dispose(); | ||
|
||
public abstract byte[] GetImage(int index, int count); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
using System; | ||
using System.IO; | ||
using ImageSearchBot.Config; | ||
using ImageSearchBot.ImageSearch; | ||
using Telegram.Bot; | ||
using Telegram.Bot.Args; | ||
using Telegram.Bot.Types; | ||
using Telegram.Bot.Types.Enums; | ||
|
||
namespace ImageSearchBot | ||
{ | ||
public class ImgBot | ||
{ | ||
private const int MaxImages = 500; | ||
|
||
private readonly TelegramBotClient _bot; | ||
private readonly User _me; | ||
private readonly BotConfig _config; | ||
private readonly IImageSearch _imageSearch; | ||
private readonly Random _random; | ||
|
||
public ImgBot(BotConfig config, IImageSearch imageSearch) | ||
{ | ||
_random = new Random(); | ||
|
||
_config = config; | ||
_imageSearch = imageSearch; | ||
_bot = new TelegramBotClient(Environment.GetEnvironmentVariable($"{_config.Prefix}_TELEGRAM_KEY")); | ||
|
||
_me = _bot.GetMeAsync().Result; | ||
|
||
_bot.OnMessage += BotOnMessageReceived; | ||
_bot.OnMessageEdited += BotOnMessageReceived; | ||
_bot.OnCallbackQuery += BotOnCallbackQueryReceived; | ||
_bot.OnInlineQuery += BotOnInlineQueryReceived; | ||
_bot.OnInlineResultChosen += BotOnChosenInlineResultReceived; | ||
_bot.OnReceiveError += BotOnReceiveError; | ||
} | ||
|
||
private void BotOnReceiveError(object sender, ReceiveErrorEventArgs e) | ||
{ | ||
|
||
} | ||
|
||
private void BotOnChosenInlineResultReceived(object sender, ChosenInlineResultEventArgs e) | ||
{ | ||
|
||
} | ||
|
||
private void BotOnInlineQueryReceived(object sender, InlineQueryEventArgs e) | ||
{ | ||
|
||
} | ||
|
||
private void BotOnCallbackQueryReceived(object sender, CallbackQueryEventArgs e) | ||
{ | ||
|
||
} | ||
|
||
private async void BotOnMessageReceived(object sender, MessageEventArgs e) | ||
{ | ||
var message = e.Message; | ||
|
||
var isPrivate = e.Message.Chat.Type == ChatType.Private; | ||
|
||
if (isPrivate || message.Text.Contains($"@{_me.Username}")) | ||
{ | ||
// TODO: configurable keywords | ||
if (message.Text.ToLower().Contains("photo")) | ||
{ | ||
var image = _imageSearch.GetImage(_random.Next(MaxImages), MaxImages); | ||
|
||
using (var memoryStream = new MemoryStream(image)) | ||
{ | ||
await _bot.SendPhotoAsync( | ||
message.Chat.Id, | ||
memoryStream, | ||
_config.Responses[_random.Next(_config.Responses.Count)]); | ||
} | ||
} | ||
else | ||
{ | ||
await _bot.SendTextMessageAsync(message.Chat.Id, | ||
_config.GreetingsMessages[_random.Next(_config.GreetingsMessages.Count)]); | ||
} | ||
} | ||
} | ||
|
||
public void Run() | ||
{ | ||
_bot.StartReceiving(Array.Empty<UpdateType>()); | ||
Console.WriteLine($"@{_me.Username}: started"); | ||
} | ||
|
||
public void Stop() | ||
{ | ||
Console.WriteLine($"@{_me.Username}: stopped"); | ||
_bot.StopReceiving(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Reflection; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using dotenv.net; | ||
using ImageSearchBot.Config; | ||
using ImageSearchBot.ImageSearch; | ||
using Newtonsoft.Json; | ||
using Newtonsoft.Json.Serialization; | ||
|
||
namespace ImageSearchBot | ||
{ | ||
public static class Program | ||
{ | ||
private static readonly List<ImgBot> Bots = new List<ImgBot>(); | ||
|
||
private static readonly ManualResetEvent ExitEvent = new ManualResetEvent(false); | ||
|
||
public static void Main(string[] args) | ||
{ | ||
DotEnv.Config(false); | ||
|
||
Console.CancelKeyPress += ConsoleOnCancelKeyPress; | ||
|
||
var dir = args.Length <= 0 ? Path.GetDirectoryName(Assembly.GetEntryAssembly()?.Location) : args[0]; | ||
|
||
// retrieve bots config inside the directory | ||
var configs = Directory.GetFiles(dir) | ||
.Where(file => Path.GetFileName(file).ToLower().EndsWith(".botconfig.json")).ToList(); | ||
if (configs.Count == 0) | ||
{ | ||
Console.Error.WriteLine("No bots configured. Add one like this mybot.botconfig.json"); | ||
Environment.Exit(1); | ||
return; | ||
} | ||
|
||
foreach (var config in configs) | ||
{ | ||
var contents = File.ReadAllText(config); | ||
var cfg = JsonConvert.DeserializeObject<RootConfig>(contents, | ||
new JsonSerializerSettings() | ||
{ | ||
ContractResolver = new CamelCasePropertyNamesContractResolver() | ||
}); | ||
var imageSearchType = Type.GetType(cfg.ImageSearchConfig.Type); | ||
var imageSearch = (IImageSearch)Activator.CreateInstance(imageSearchType, cfg.BotConfig.Prefix, cfg.ImageSearchConfig); | ||
var imgBot = new ImgBot(cfg.BotConfig, imageSearch); | ||
Bots.Add(imgBot); | ||
Task.Run(() => imgBot.Run()); | ||
} | ||
|
||
ExitEvent.WaitOne(); | ||
Console.CancelKeyPress -= ConsoleOnCancelKeyPress; | ||
Bots.ForEach(b => b.Stop()); | ||
} | ||
|
||
private static void ConsoleOnCancelKeyPress(object sender, ConsoleCancelEventArgs e) | ||
{ | ||
e.Cancel = true; | ||
ExitEvent.Set(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,11 @@ | ||
# image-search-bot | ||
Configurable apps for running Telegram Bots that responds to photo Image Queries | ||
|
||
## Bots using this framework | ||
|
||
* Mike's Mother - Bot That Looks for images of Cara Buono, Mike's mother in Stranger Things. | ||
|
||
## Deveopment | ||
|
||
* Register your bot(s) using @botfather. | ||
* ... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<OutputType>Exe</OutputType> | ||
<TargetFramework>netcoreapp2.2</TargetFramework> | ||
<RootNamespace>ImageSearchBot</RootNamespace> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="dotenv.net" Version="1.0.6" /> | ||
<PackageReference Include="Microsoft.Azure.CognitiveServices.Search.ImageSearch" Version="2.0.0" /> | ||
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" /> | ||
<PackageReference Include="Telegram.Bot" Version="14.12.0" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<None Update=".env"> | ||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
</None> | ||
<None Update="mikesmother.botconfig.json"> | ||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
</None> | ||
</ItemGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
|
||
Microsoft Visual Studio Solution File, Format Version 12.00 | ||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "image-search-bot", "image-search-bot.csproj", "{46E52E03-6EDD-45F2-838A-B9E994A13D8B}" | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|Any CPU = Debug|Any CPU | ||
Release|Any CPU = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
{46E52E03-6EDD-45F2-838A-B9E994A13D8B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{46E52E03-6EDD-45F2-838A-B9E994A13D8B}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{46E52E03-6EDD-45F2-838A-B9E994A13D8B}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{46E52E03-6EDD-45F2-838A-B9E994A13D8B}.Release|Any CPU.Build.0 = Release|Any CPU | ||
EndGlobalSection | ||
EndGlobal |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
{ | ||
"botConfig": { | ||
"prefix": "MMBOT", | ||
"greetingsMessages" : [ | ||
"Hello. I am Mike's Mother bot!", | ||
"Nice to meet you.", | ||
"Ask me something.", | ||
"Whats about a photo of Mike's Mother?" | ||
], | ||
"responses": [ | ||
"Here she is, gorgeous as always!", | ||
"Here you are.", | ||
"Here it is" | ||
], | ||
"keywords": [ | ||
"photo" | ||
] | ||
}, | ||
"imageSearchConfig": { | ||
"type": "ImageSearchBot.ImageSearch.BingImageSearch", | ||
"query": "cara buono", | ||
"includeNsfw": false | ||
} | ||
} |