Skip to content

Commit

Permalink
Merge pull request #3 from decimo3/restricted-mode
Browse files Browse the repository at this point in the history
Restricted mode
  • Loading branch information
decimo3 authored Oct 11, 2023
2 parents 125b6b7 + c87448f commit 255f6c8
Show file tree
Hide file tree
Showing 14 changed files with 196 additions and 59 deletions.
4 changes: 2 additions & 2 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
// Use IntelliSense to find out which attributes exist for C# debugging
// Use hover for the description of the existing attributes
// For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
"name": ".NET Core Launch (console)",
"name": ".NET Core Launch",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/bin/Debug/net7.0/telbot.dll",
"args": ["--em-desenvolvimento", "--sem-faturas"],
"args": ["--em-desenvolvimento"],
"cwd": "${workspaceFolder}",
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
"console": "internalConsole",
Expand Down
26 changes: 8 additions & 18 deletions HOWTODO.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,5 @@
# Instruções de operação do chatbot

O chatbot após o `build`, criará uma pasta chamada `MestreRuan` onde estará os arquivos necessários para seu funcionamento:

```
%USERPROFILE%/Mestre Ruan/
|
├── tmp/
├── telbot.exe
├── sap.exe
├── img.exe
├── fileDialog.vbs
├── database.db
├── sni.dll
├── SQLite.Interop.dll
└── telbot.pdb
```

O arquivo `telbot.exe` pode ser executado diretamente pelo explorer, com dois cliques, usando as configurações padrões. Para alterar o comportamento do programa conforme a necessidade é necessário executar o programa **via linha de comando**.

Para executar via linha de comando, use o atalho `Inicio + R` e digite `cmd` na janela Executar.
Expand Down Expand Up @@ -54,9 +38,15 @@ Esse argumento fará o chatbot ignorar todas as solicitações recebidas, envian
#### --sem-faturas

Esse argumento fará o chatbot ignorar todas as solicitações de faturas, enviando uma mensagem notificando que o sistema SAP não está gerando faturas.
Esse argumento fará o chatbot trocar as solicitações de FATURA por INFORMACAO, e envia uma mensagem notificando que o sistema SAP não está gerando faturas.

> Usado quando houver problema para o sistema da Light gerar faturas, para que as equipes estejam cientes, e as informações para que peguem no LIA.
#### --sap-espera

Esse argumento é utilizado para definir o tempo de espera de uma solicitação realizada para o SAP, e deve ser usada no formato de atribuição (--sap-espera=tempo_de_espera_em_segundos).

> Usado quando houver problema para o sistema da Light gerar faturas, para que as equipes estejam cientes.
> O tempo padrão de espera para uma solicitação é de 60 segundos. Esse parâmetro deve ser usado quando houver lentidão no sistema SAP e as solicitações estiverem demorando um pouco mais que o normal.
## Solução de problemas

Expand Down
20 changes: 18 additions & 2 deletions Handles/HandleCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ public class HandleCommand
private HandleMessage bot;
private Request request;
private UsersModel user;
public HandleCommand(HandleMessage bot, UsersModel user, Request request)
private Configuration cfg;
public HandleCommand(HandleMessage bot, UsersModel user, Request request, Configuration cfg)
{
this.bot = bot;
this.user = user;
this.request = request;
this.cfg = cfg;
}
async public Task routerCommand()
{
Expand All @@ -23,18 +25,32 @@ async public Task routerCommand()
await bot.sendTextMesssageWraper(user.id, "Digite o tipo de informação que deseja e depois o número da nota ou instalação.");
await bot.sendTextMesssageWraper(user.id, "*TELEFONE* ou *CONTATO* para receber todos os telefones no cadastro do cliente;");
await bot.sendTextMesssageWraper(user.id, "*COORDENADA* para receber um link da localização no cadastro do cliente;");
await bot.sendTextMesssageWraper(user.id, "*LEITURISTA* ou *ROTEIRO* para receber a lista de instalações ordenada por horário;");
await bot.sendTextMesssageWraper(user.id, "*ROTEIRO* para receber a lista de instalações ordenada por horário;");
await bot.sendTextMesssageWraper(user.id, "*LEITURISTA* para receber a lista de instalações ordenada por sequencia;");
await bot.sendTextMesssageWraper(user.id, "*PENDENTE* para receber a lista de débitos para aquela instalação do cliente;");
await bot.sendTextMesssageWraper(user.id, "*FATURA* ou *DEBITO* _(sem acentuação)_ para receber as faturas vencidas em PDF (limite de 5 faturas)");
await bot.sendTextMesssageWraper(user.id, "*HISTORICO* _(sem acentuação)_ para receber a lista com os 5 últimos serviços para a instalação;");
await bot.sendTextMesssageWraper(user.id, "*MEDIDOR* para receber as informações referentes ao medidor;");
await bot.sendTextMesssageWraper(user.id, "*AGRUPAMENTO* para receber as informações referentes ao PC;");
await bot.sendTextMesssageWraper(user.id, "*INFORMACAO* para receber informações código e CPF do cliente;");
await bot.sendTextMesssageWraper(user.id, "Todas as solicitações não possuem acentuação e são no sigular (não tem o 's' no final).");
await bot.sendTextMesssageWraper(user.id, "Estou trabalhando para trazer mais funções em breve");
break;
case "/ping":
await bot.sendTextMesssageWraper(user.id, "Estou de prontidão aguardando as solicitações! (^.^)");
break;
case "/status":
if(user.id == (Int64)1469480868)
{
await using Stream stream = System.IO.File.OpenRead(@$"{cfg.CURRENT_PATH}\database.db");
await bot.SendDocumentAsyncWraper(user.id, stream, $"{DateTime.Now.ToLocalTime().ToString("yyyyMMdd_HHmmss")}.db");
stream.Dispose();
}
else
{
await bot.sendTextMesssageWraper(user.id, "Você não tem permissão para usar esse comando!");
}
break;
default:
await bot.sendTextMesssageWraper(user.id, "Comando solicitado não foi programado! Verifique e tente um válido");
break;
Expand Down
26 changes: 20 additions & 6 deletions Handles/HandleInformation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,31 @@ public HandleInformation(HandleMessage bot, Configuration cfg, UsersModel user,
}
async private Task<bool> has_impediment()
{
if((request.tipo == TypeRequest.pdfInfo) && (cfg.GERAR_FATURAS == false))
{
await bot.sendTextMesssageWraper(user.id, "O sistema SAP não está gerando faturas no momento!");
Database.inserirRelatorio(new logsModel(user.id, request.aplicacao, request.informacao, false, request.received_at));
return true;
}
if(request.aplicacao == "passivo" && (DateTime.Today.DayOfWeek == DayOfWeek.Friday || DateTime.Today.DayOfWeek == DayOfWeek.Saturday))
{
await bot.sendTextMesssageWraper(user.id, "Essa aplicação não deve ser usada na sexta e no sábado!");
await bot.sendTextMesssageWraper(user.id, "Notas de recorte devem ter todas as faturas cobradas!");
Database.inserirRelatorio(new logsModel(user.id, request.aplicacao, request.informacao, false, request.received_at));
return true;
}
// Knockout system to mitigate the queue
if((request.tipo == TypeRequest.pdfInfo) && (cfg.GERAR_FATURAS == true))
{
var knockout = DateTime.Now.AddMinutes(-3);
if(System.DateTime.Compare(knockout, request.received_at) > 0)
{
await bot.sendTextMesssageWraper(user.id, "Devido a fila de solicitações, estaremos te enviando as informações do cliente!");
request.aplicacao = "informacao";
return false;
}
return false;
}
if((request.tipo == TypeRequest.pdfInfo) && (cfg.GERAR_FATURAS == false))
{
await bot.sendTextMesssageWraper(user.id, "O sistema SAP não está gerando faturas no momento!\nEstaremos te enviando as informações do cliente!");
request.aplicacao = "informacao";
return false;
}
if((request.tipo == TypeRequest.xlsInfo) && (user.has_privilege == false))
{
await bot.sendTextMesssageWraper(user.id, "Você não tem permissão para gerar relatórios!");
Expand Down Expand Up @@ -73,6 +86,7 @@ async public Task routeInformation()
case "medidor":await SendManuscripts(); break;
case "passivo":await SendDocument(); break;
case "suspenso":await SendManuscripts(); break;
case "informacao":await SendManuscripts(); break;
}
return;
}
Expand Down
24 changes: 17 additions & 7 deletions Helpers/Configuration.cs
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
namespace telbot;
public class Configuration
{
public readonly string BOT_TOKEN;
public readonly string? BOT_TOKEN;
public readonly long ID_ADM_BOT;
public readonly bool IS_DEVELOPMENT;
public readonly string CURRENT_PATH;
public readonly string SAP_SCRIPT;
public readonly string IMG_SCRIPT;
public readonly string? CURRENT_PATH;
public readonly string? SAP_SCRIPT;
public readonly string? IMG_SCRIPT;
public readonly int DIAS_EXPIRACAO;
public readonly bool GERAR_FATURAS;
public readonly bool SAP_OFFLINE;
public readonly int INSTANCIA;
public readonly string CURRENT_PC;
public readonly string LICENCE;
public readonly DateTime EXPIRATION;
public readonly string? CURRENT_PC;
public readonly string? LICENCE;
public readonly bool SAP_RESTRITO;
public readonly int ESPERA;
public Configuration(string[] args)
{
LICENCE = System.Environment.GetEnvironmentVariable("BOT_LICENCE");
Expand Down Expand Up @@ -54,7 +55,9 @@ public Configuration(string[] args)
if(!Validador.isValidToken(BOT_TOKEN)) throw new InvalidOperationException("Environment variable BOT_TOKEN is not valid!");

ID_ADM_BOT = AUTHORIZATION.adm_id_bot;
SAP_RESTRITO = AUTHORIZATION.sap_access;
DIAS_EXPIRACAO = 30;
ESPERA = 60_000;
INSTANCIA = 0; // valor padrão caso não encontre o argumento no loop
GERAR_FATURAS = true; // valor padrão caso não encontre o argumento no loop
SAP_OFFLINE = false; // valor padrão caso não encontre o argumento no loop
Expand All @@ -69,11 +72,18 @@ public Configuration(string[] args)
else throw new InvalidOperationException("Argumento 'instancia' não está no formato correto! Use the format: '--sap-instancia=<numInstancia>'");
continue;
}
if(arg.StartsWith("--sap-espera"))
{
if(Int32.TryParse(arg.Split("=")[1], out int espera)) ESPERA = espera * 1000;
else throw new InvalidOperationException("Argumento 'espera' não está no formato correto! Use the format: '--sap-espera=<segundos_espera>'");
continue;
}
switch (arg)
{
case "--sem-faturas": GERAR_FATURAS = false; break;
case "--sap-offline": SAP_OFFLINE = true; break;
case "--em-desenvolvimento": IS_DEVELOPMENT = true; break;
case "--sap-restrito": SAP_RESTRITO = true; break;
default: throw new InvalidOperationException($"O argumento {arg} é inválido!");
}
}
Expand Down
54 changes: 39 additions & 15 deletions Helpers/Temporary.cs
Original file line number Diff line number Diff line change
@@ -1,27 +1,51 @@
using System.Diagnostics;
namespace telbot;
public static class Temporary
{
public static List<string> executar(Configuration cfg, string aplicacao, string informacao)
{
string[] args = System.Environment.GetCommandLineArgs();
using(var proc = new System.Diagnostics.Process{
StartInfo = new System.Diagnostics.ProcessStartInfo
{
FileName = cfg.SAP_SCRIPT,
Arguments = $"{aplicacao} {informacao} {cfg.INSTANCIA}",
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true
}})
var argumentos = $"{aplicacao} {informacao} {cfg.INSTANCIA}";
if(cfg.SAP_RESTRITO) argumentos += " --sap-restrito";
var proc = new System.Diagnostics.Process();
var startInfo = new System.Diagnostics.ProcessStartInfo
{
var linha = new List<string>();
proc.Start();
while (!proc.StandardOutput.EndOfStream)
FileName = cfg.SAP_SCRIPT,
Arguments = argumentos,
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true
};
proc.StartInfo = startInfo;
var linha = new List<string>();
proc.Start();
var tempo = new System.Threading.Timer(state => {
if(!proc.HasExited)
{
var mos = Temporary.GetChildProcesses(proc);
foreach (var mo in mos)
{
linha.Add(proc.StandardOutput.ReadLine()!);
mo.Kill();
}
return linha;
}
}, null, cfg.ESPERA, Timeout.Infinite);
while (!proc.StandardOutput.EndOfStream)
{
linha.Add(proc.StandardOutput.ReadLine()!);
}
tempo.Dispose();
proc.Dispose();
return linha;
}
private static IEnumerable<Process> GetChildProcesses(this Process process)
{
var children = new List<Process>();
var queryProcess = $"Select * From Win32_Process Where ParentProcessID={process.Id}";
var mos = new System.Management.ManagementObjectSearcher(queryProcess);
foreach (var mo in mos.Get())
{
children.Add(Process.GetProcessById(Convert.ToInt32(mo["ProcessID"])));
}
return children;
}
public static List<string> executar(Configuration cfg, List<string> listaValoresSeparadosPorTabulacao)
{
Expand Down
1 change: 1 addition & 0 deletions Helpers/Validator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public static bool isValidInformacao (string informacao)
if(aplicacao == "relatorio") return TypeRequest.xlsInfo;
if(aplicacao == "manobra") return TypeRequest.xlsInfo;
if(aplicacao == "medidor") return TypeRequest.txtInfo;
if(aplicacao == "informacao") return TypeRequest.txtInfo;
return null;
}
public static bool? orderOperandos (string info1, string info2)
Expand Down
42 changes: 42 additions & 0 deletions Helpers/WakeUpSAP.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
namespace telbot;
public class WakeUpSAP
{
private readonly Configuration cfg;
public WakeUpSAP(Configuration cfg)
{
this.cfg = cfg;
}
public void Start()
{
Console.WriteLine($"< {DateTime.Now} Manager: Iniciado sistema de despertador do SapAutomation!");
while(true)
{
var horario = System.IO.File.GetLastWriteTime("database.db");
var prazo = DateTime.Now.AddMinutes(-5);
var diferenca = horario - prazo;
Console.WriteLine($"< {DateTime.Now} Manager: Última solicitação registrada às {horario}.");
if(diferenca.TotalMinutes < 0)
{
Console.WriteLine($"< {DateTime.Now} Manager: Realizando consulta para manter o SAP acordado...");
var resposta = Temporary.executar(cfg, "desperta", "1380763967");
if(resposta.Count == 0) resposta.Add("ERRO: O SAP demorou muito tempo na solicitação e foi encerrado!");
if(resposta[0].StartsWith("ERRO"))
{
Console.Beep();
Console.BackgroundColor = ConsoleColor.Red;
Console.WriteLine($"< {DateTime.Now} Manager: A solicitação não pode ser concluída!");
Console.ResetColor();
Console.WriteLine($"< {DateTime.Now} Manager: Tentando novamente em daqui a 5 minutos...");
Database.inserirRelatorio(new logsModel(0,"desperta", "0", false, DateTime.Now));
}
else
{
Console.WriteLine($"< {DateTime.Now} Manager: Consulta fantasma realizada com sucesso!");
Database.inserirRelatorio(new logsModel(0,"desperta", "0", true, DateTime.Now));
}
}
Console.WriteLine($"< {DateTime.Now} Manager: Última verificação foi realizada agora mesmo.");
System.Threading.Thread.Sleep(cfg.ESPERA);
}
}
}
3 changes: 2 additions & 1 deletion Models/TokenModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ namespace telbot.models;
public class TokenModel
{
public long adm_id_bot { get; set; }
public string allowed_pc { get; set; }
public string? allowed_pc { get; set; }
public long exp { get; set; }
public bool sap_access { get; set; }
}
4 changes: 2 additions & 2 deletions Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public Program(Configuration cfg)
// StartReceiving does not block the caller thread. Receiving is done on the ThreadPool, so we use cancellation token
bot.StartReceiving(updateHandler: HandleUpdate, pollingErrorHandler: HandleError, cancellationToken: cts.Token);
// Tell the user the bot is online
Console.WriteLine("Start listening for updates. Press enter to stop");
Console.WriteLine($"< {DateTime.Now} Manager: Start listening for updates. Press enter to stop.");
Console.ReadLine();
// Send cancellation request to stop the bot
cts.Cancel();
Expand Down Expand Up @@ -103,7 +103,7 @@ async Task HandleMessage(Message message)
// When we get a command, we react accordingly
if (request.tipo == TypeRequest.comando)
{
await new HandleCommand(msg, user, request).routerCommand();
await new HandleCommand(msg, user, request, cfg).routerCommand();
return;
}
if(request.tipo == TypeRequest.gestao)
Expand Down
Loading

0 comments on commit 255f6c8

Please sign in to comment.