Skip to content

Commit

Permalink
App architecture was improved
Browse files Browse the repository at this point in the history
  • Loading branch information
Eptagone committed Jan 15, 2022
1 parent ad44dd8 commit 9647b9c
Show file tree
Hide file tree
Showing 134 changed files with 4,916 additions and 3,604 deletions.
19 changes: 15 additions & 4 deletions README.es.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,38 @@ SauceNAO bot es un bot de Telegram escrito en CSharp.NET. Este bot te permite bu

Pruebalo! [@SauceNAObot](https://t.me/SauceNAObot)

Este bot fue creado por un tercero para usar SauceNAO en Telegram. El proyecto no tiene ninguna afiliación con Xamayon (el creador de SauceNAO).

# Funciones

- Busca inversamente imagenes con saucenao tan solo con enviar una imagen a [@SauceNAObot](https://t.me/SauceNAObot). Tambien puedes responder a una imagen con: /sauce, /source/, /saucenao, /sourcenow, /search, Sauce, sauce o con una mencion \([@SauceNAObot](https://t.me/SauceNAObot)\).
- Busca inversamente imagenes con saucenao tan solo con enviar una imagen a [@SauceNAObot](https://t.me/SauceNAObot). Tambien puedes responder a una imagen con: /sauce, /source, /saucenao, /snao, /sourcenow, /search, Sauce, sauce o con una mencion \([@SauceNAObot](https://t.me/SauceNAObot)\).

- Ofrece opciones de busqueda alternativas cuando el sauce no es encontrado o cuando se usa el comando /temp.

- Historial de búsqueda personal mediante inline. Reenvía la multimedia que has buscado junto con el sauce a tus grupos o canales.

- Anti-Trampas. Si en tu grupo hay bots de "adivina el persona" o similares, puedes usar la función AntiCheats de SauceNAO. Esto evitara que [@SauceNAObot](https://t.me/SauceNAObot) realice busquedas inversas de la multimedia enviada por los bots que especifiques. Responde a un bot con **/anticheats add** para añadirlo al control o con **/anticheats remove** para removerlo.
- Anti-Trampas. Si en tu grupo hay bots de "adivina el persona" o similares, puedes usar la función AntiCheats de SauceNAO. Esto evitara que [@SauceNAObot](https://t.me/SauceNAObot) realice busquedas inversas de la multimedia enviada por los bots que especifiques.

# Lista de comandos

| Nombre | Descripción | Como usar |
| :--------- | :---------------------------------- | :---------------------------------- |
| anticheats | Usa la característica Anti-Trampas | **/anticheats** _args_ |
| apikey | Usa tu propia clave de api | **/apikey** _args_ |
| help | Ayuda | **/help** _args_ |
| history | Mira tu historial de salsas | **/history** |
| history | Administra tu historial de salsas | **/history** _args_ |
| sauce | Busca la salsa de la imagen | Responde a la imagen con **/sauce** |
| stats | Estadisticas globales de uso | **/stats** |
| temp | Crea un enlace temporal a la imagen | Responde a la imagen con **/temp** |

# Apoyame

Si lo deseas, [comprame una galleta](https://www.buymeacoffee.com/eptagone)
Tus contribuciones son usadas para pagar el hospedaje del bot y la cuenta compartida usada para buscar tus salsas.

Puedes apoyar a este proyecto a traves de las siguientes opciones:

- [Comprame una galleta!](https://www.buymeacoffee.com/eptagone)
- **Bitcoin:** [bc1q0w43tprjn80zn248k7xlztu7lvhkzgy6dak8mt](bitcoin:BC1Q0W43TPRJN80ZN248K7XLZTU7LVHKZGY6DAK8MT?label=MyCoffe&message=Invite%20me%20for%20a%20coffee)
- **Toncoin:** [EQC3SWZxs_4ive2aD-njns1KnB4S2RUgaxDKJ7X44VA52SsY](ton://transfer/EQC3SWZxs_4ive2aD-njns1KnB4S2RUgaxDKJ7X44VA52SsY)

Nota: Por favor, asegurece de confirmar la cantidad que va a donar. No hacemos devoluciones.
19 changes: 15 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,38 @@ SauceNAO bot is a telegram bot written with CSharp.NET. This bot allows you to r

Try it! [@SauceNAObot](https://t.me/SauceNAObot)

This bot was created by a third party to use SauceNAO on Telegram. The project has not any affiliation with Xamayon (the creator of SauceNAO).

# Features

- Send an image to [@SauceNAObot](https://t.me/SauceNAObot) for saucenao search. You can also reply to a image with: /sauce, /source/, /saucenao, /sourcenow, /search, Sauce, sauce or a mention \([@SauceNAObot](https://t.me/SauceNAObot)\).
- Send an image to [@SauceNAObot](https://t.me/SauceNAObot) for saucenao search. You can also reply to a image with: /sauce, /source/, /snao ,/saucenao, /sourcenow, /search, Sauce, sauce or a mention \([@SauceNAObot](https://t.me/SauceNAObot)\).

- Offers alternative search options when sauce is not found or when you use the /temp command.

- Personal search history using inline. Forward the multimedia you've searched along with the sauce to your groups or channels.

- Anti-Cheats. If your group has "guess the character" bots or similar bots, you can use SauceNAO's AntiCheats feature. This will prevent [@SauceNAObot](https://t.me/SauceNAObot) from performing reverse media searches sent by specific bots you specified. Reply to a bot with **/anticheats add** to add it to the AntiCheat List or reply **/anticheats remove** to remove it.
- Anti-Cheats. If your group has "guess the character" bots or similar bots, you can use SauceNAO's AntiCheats feature. This will prevent [@SauceNAObot](https://t.me/SauceNAObot) from performing reverse media searches sent by specific bots you specified.

# Command List

| Name | Description | How to Use |
| :--------- | :---------------------------------- | :------------------------------- |
| anticheats | Use the AntiCheats feature | **/anticheats** _args_ |
| apikey | Use your own apikey | **/apikey** _args_ |
| help | Help | **/help** _args_ |
| history | See your Sauce history | **/history** |
| history | Manage your sauces | **/history** _args_ |
| sauce | Look for the image source | Reply to a image with **/sauce** |
| stats | Global usage statistics | **/stats** |
| temp | Create a temporary link to an image | Reply to a image with **/temp** |

# Support me

If you want, [Buy me a cookie](https://www.buymeacoffee.com/eptagone)
Your contributions are used to pay for the bot's hosting and the shared account that we use to search for your sauces.

You can support this project through the following options:

- [Buy me a cookie](https://www.buymeacoffee.com/eptagone)
- **Bitcoin:** [bc1q0w43tprjn80zn248k7xlztu7lvhkzgy6dak8mt](bitcoin:BC1Q0W43TPRJN80ZN248K7XLZTU7LVHKZGY6DAK8MT?label=MyCoffe&message=Invite%20me%20for%20a%20coffee)
- **Toncoin:** [EQC3SWZxs_4ive2aD-njns1KnB4S2RUgaxDKJ7X44VA52SsY](ton://transfer/EQC3SWZxs_4ive2aD-njns1KnB4S2RUgaxDKJ7X44VA52SsY)

Note: Please be sure to confirm the amount you will donate. We don't make refunds.
Binary file added docs/1_5104843900044968425.xlsx
Binary file not shown.
Binary file added docs/SauceNAObot - messages.xlsx
Binary file not shown.
Binary file modified docs/SauceNao.xlsx
Binary file not shown.
50 changes: 24 additions & 26 deletions src/README.es.md
Original file line number Diff line number Diff line change
@@ -1,33 +1,31 @@
# SauceNAObot
# Configuración

El bot funciona usando un webhook.
Este bot funciona utilizando un Webhook. Usted puede ejecutar el Webhook localmente usando [NGROK](https://ngrok.com/).

Si quiere probar este bot localmente, recomiendo utilizar una herramienta como [NGROK](https://ngrok.com/).
Esta solución esta compuesta por **5** proyectos:

# Configurar
| Nombre | Descripción |
| :---------------------- | :------------------------------------------------------------------------ |
| SauceNAO.Core | Contiene la funcionalidad principal del bot |
| SauceNAO.Infrastructure | Implementa clases para el acceso a datos |
| SauceNAO.Webhook | La aplicación Webhook |
| SauceNAO.LocalWebhook | La aplicación Webhook (como `SauceNAO.Webhook` pero para ejecución local) |
| SauceNAO.Tests | Pruebas unitarias |

Antes de probar el proyecto e implementarlo en tu propio bot, deberás editar el archivo appsettings.json or tu archivo secrets.json de usuario paraa hacer que el bot funcione.
Para ejecutar cualquiera de los proyectos de Webhook, usted necesita establecer la siguiente configuración de la aplicación meidiante un **archivo json** (`secrets.json`, `application.json`) o usando **variables de entorno**.

Abre appsettings.json o secrets.json y especifica la siguiente información:
| Nombre de la propiedad JSON | Variable de entorno | Aplica a | Descripción |
| :-------------------------- | :---------------------------- | :-------------------- | :------------------------------------------------------ |
| AccessToken | AccessToken | Ambos proyectos | El token secreto del webhook especificado por usted. |
| FFmpegExec | FFmpegExec | Ambos proyectos | La ruta al ejecutable de **ffmpeg**. |
| SauceNAO:ApiKey | SauceNAO\_\_ApiKey | Ambos proyectos | La clave de api para usar la SauceNAO API. |
| Telegram:BotToken | Telegram\_\_BotToken | Ambos proyectos | El token del bot. |
| Telegram:SupportChatLink | Telegram\_\_SupportChatLink | Ambos proyectos | Link al chat de ayuda. (https://t.me/+8NJMCbRmiTk2Yjkx) |
| ConnectionStrings:SauceNAO | ConnectionStrings\_\_SauceNAO | Ambos proyectos | La cadena de conexión a la base de datos. |
| AplicationUrl | AplicationUrl | SauceNAO.Webhook | La dirección base del webhook. (https://example.com) |
| Ngrok:Port | Ngrok\_\_Port | SauceNAO.LocalWebhook | Puerto donde se ejecuta la aplicación. (7161) |
| Ngrok:TunnelName | Ngrok\_\_TunnelName | SauceNAO.LocalWebhook | Opcional. Nombre del tunnel. (SnaoTunnel) |

- LiteDB es tu cadena de conexión a la base de datos de sqlite. Por favor especifica un nombre de archivo valido.
- ApiKey es la clave de api de tu cuenta de Saucenao, puedes dejarla vacia o incluir tu clave para incrementar el numero de busquedas.
- BotToken es el token del bot, proporcionado por BotFather.
- SecretToken es tu ruta secreta, tu token del webhook. Se recomienda usar caracteres aleatorios y no proporcionar la clave a nadie.
- WebhookUrl es la la direccion web de tu Webhook. ejemplo: https://saucenao.com/
> Antes de ejecutar el proyecto **SauceNAO.LocalWebhook**, usted necesita iniciar **ngrok** en segundo plano. De lo contrario, la aplicación no podrá iniciar. Puede usar el siguiente comando: `ngrok start --none `.
## appsettings.json, secrets.json

```json
{
"ConnectionStrings": {
"LiteDB": "Filename=saucenaobot-SECRET-GUID.db"
},
"SauceNao": {
"ApiKey": "<SAUCENAO-API-KEY>",
"BotToken": "<BOT-TOKEN>",
"SecretToken": "<SECRET-TOKEN>",
"WebhookUrl": "https://example.com/"
}
}
```
> Actualmente, el bot usa **SQLite** para el almacenamiento de datos y también para almacenar información en caché. Si desea cambiarlo a otro proveedor, elimine la carpeta `Migrations` de `SauceNAO.Infraestructura`, modifique el archivo `Program.cs` de los proyectos de Webhooks para usar otro proveedor compatible con **Entity Framework**, y finalmente crear nuevas migraciones. Si no desea utilizar **Entity Framework**, debe implementar una clase basada en la interfaz `IBotDb` y registrar la clase en `Program.cs` desde sus proyectos Webhook. Puede tomar la clase `Data/BotDb.cs` ubicada en el proyecto `SauceNAO.Infrastructure` como ejemplo.
50 changes: 24 additions & 26 deletions src/README.md
Original file line number Diff line number Diff line change
@@ -1,33 +1,31 @@
# SauceNAObot

The bot works using a webhook.
# Setup

If you want to try this bot locally, I recommend using a tool like [NGROK](https://ngrok.com/).
This bot works using a webhook. You can run the webhook locally using [NGROK](https://ngrok.com/).

# Setup
This solution is composed by **5** projects:

Before you test this project and deploy it to your own bot, you'll need to edit appsettings.json file or your user secrets.json file to make it work.
| Name | Description |
| :---------------------- | :---------------------------------------------------------------------- |
| SauceNAO.Core | Contains the main functionality of the bot |
| SauceNAO.Infrastructure | Implements clases for data access |
| SauceNAO.Webhook | The webhook application |
| SauceNAO.LocalWebhook | The webhook application (like `SauceNAO.Webhook` but for local running) |
| SauceNAO.Tests | Unit Tests |

Open appsettings.json or your secrets.json and specify the follow informatión:
In order to run anyone of webhook projects, you need to set the following application settings via **json file** (`secrets.json`, `application.json`) or using **enviroment variables**. See the table below that shows the available settings.

- LiteDB is your connection string to your sqlite database. Please specify a valid filename.
- ApiKey is the api key of your Saucenao account, you can keep it empty or include your key to increase reverse searches.
- BotToken is the bot token, provided by BotFathe.
- SecretToken is a secret path, your webhook's token. We recommend that you use random characters and not provide this key to anyone.
- WebhookUrl is the Webhook's URL. Example: https://saucenao.com/
| JSON property name | Enviroment variable | Apply to | Description |
| :------------------------- | :---------------------------- | :-------------------- | :-------------------------------------------------- |
| AccessToken | AccessToken | Both | Your webhook secret token specified by you. |
| FFmpegExec | FFmpegExec | Both | The ffmpeg path executable. |
| SauceNAO:ApiKey | SauceNAO\_\_ApiKey | Both | You apikey for SauceNAO API. |
| Telegram:BotToken | Telegram\_\_BotToken | Both | You bot token. |
| Telegram:SupportChatLink | Telegram\_\_SupportChatLink | Both | Support chat link. (https://t.me/+8NJMCbRmiTk2Yjkx) |
| ConnectionStrings:SauceNAO | ConnectionStrings\_\_SauceNAO | Both | The connection string to database. |
| AplicationUrl | AplicationUrl | SauceNAO.Webhook | Your webhook base url. (https://example.com) |
| Ngrok:Port | Ngrok\_\_Port | SauceNAO.LocalWebhook | Port where your app is running. (7161) |
| Ngrok:TunnelName | Ngrok\_\_TunnelName | SauceNAO.LocalWebhook | Optional. The tunnel name. (SnaoTunnel) |

## appsettings.json, secrets.json
> Before running the **SauceNAO.LocalWebhook** project, you have to start **ngrok** in the background. Otherwise, your application will not be able to start. You can use the following command: `ngrok start --none `.
```json
{
"ConnectionStrings": {
"LiteDB": "Filename=saucenaobot-SECRET-GUID.db"
},
"SauceNao": {
"ApiKey": "<SAUCENAO-API-KEY>",
"BotToken": "<BOT-TOKEN>",
"SecretToken": "<SECRET-TOKEN>",
"WebhookUrl": "https://example.com/"
}
}
```
> Currently the bot uses **SQLite** for data storage and also for caching information. If you want to change it to another provider, delete the `Migrations` folder from `SauceNAO.Infrastructure`, modify the `Program.cs` file from the Webhooks projects to use another provider compatible with **Entity Framework**, and finally create new migrations. If you don't want to use **Entity Framework**, you must implement a class based on the `IBotDb` interface and register the class in `Program.cs` from your Webhook projects. You can take the `Data/BotDb.cs` class located in the `SauceNAO.Infrastructure` project as an example.
53 changes: 53 additions & 0 deletions src/SauceNAO.LocalWebhook/Controllers/BotController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Copyright (c) 2022 Quetzal Rivera.
// Licensed under the GNU General Public License v3.0, See LICENCE in the project root for license information.

using Microsoft.AspNetCore.Mvc;
using SauceNAO.Core;
using Telegram.BotAPI.GettingUpdates;

namespace SauceNAO.Webhook.Controllers
{
[Route("[controller]")]
[ApiController]
public sealed class BotController : ControllerBase
{
private readonly IConfiguration _configuration;
private readonly ILogger<BotController> _logger;
private readonly SauceNaoBot _bot;

public BotController(ILogger<BotController> logger, IConfiguration configuration, SauceNaoBot bot)
{
_configuration = configuration;
_logger = logger;
_bot = bot;
}

[HttpGet("{accessToken}")]
public IActionResult Get(string accessToken)
{
if (_configuration["AccessToken"] != accessToken)
{
_logger.LogWarning("Failed access!");
return Unauthorized();
}
return Ok();
}

[HttpPost("{accessToken}")]
public async Task<IActionResult> PostAsync(string accessToken, [FromBody] Update update, CancellationToken cancellationToken)
{
if (_configuration["AccessToken"] != accessToken)
{
_logger.LogWarning("Failed access");
return Unauthorized();
}
if (update == default)
{
_logger.LogWarning("Invalid update detected");
return BadRequest();
}
await _bot.OnUpdateAsync(update, cancellationToken).ConfigureAwait(false);
return Ok();
}
}
}
44 changes: 44 additions & 0 deletions src/SauceNAO.LocalWebhook/Controllers/TempController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright (c) 2022 Quetzal Rivera.
// Licensed under the GNU General Public License v3.0, See LICENCE in the project root for license information.

using Microsoft.AspNetCore.Mvc;
using SauceNAO.Core;

namespace SauceNAO.Webhook.Controllers
{
[Route("[controller]")]
[ApiController]
public sealed class TempController : ControllerBase
{
private readonly ILogger<TempController> _logger;
private readonly IBotCache _cache;

public TempController(ILogger<TempController> logger, IBotCache cache)
{
_logger = logger;
_cache = cache;
}

// GET: api/temp/5
///<Summary>If file exists, return file.</Summary>
[HttpGet("{id}")]
public async Task<IActionResult> GetTemporalFile(string id, CancellationToken cancellationToken)
{
var fileUniqueId = id;
var tempFile = await _cache.Files.GetFileAsync(fileUniqueId, cancellationToken).ConfigureAwait(false);
if (tempFile == default)
{
return NotFound();
}
try
{
return File(tempFile.RawData, tempFile.ContentType ?? "application/octet-stream", tempFile.Filename);
}
catch (Exception e)
{
_logger.LogError("Can't return temporal file [{0}]. Error message: {1}", fileUniqueId, e.InnerException?.Message ?? e.Message);
return BadRequest();
}
}
}
}
Loading

0 comments on commit 9647b9c

Please sign in to comment.