fix: primeira versao

This commit is contained in:
Ricardo Carneiro 2024-11-28 21:45:34 -03:00
parent dede34a105
commit 4d430e9a18
10 changed files with 363 additions and 0 deletions

View File

@ -0,0 +1,146 @@
using Microsoft.AspNetCore.Mvc;
using OpenRHCall.Models;
using PuppeteerSharp;
namespace OpenRHCall.Controllers
{
[ApiController]
[Route("[controller]")]
public class CallRHController : ControllerBase
{
private readonly ILogger<CallRHController> _logger;
public CallRHController(ILogger<CallRHController> logger)
{
_logger = logger;
}
[HttpPost(Name = "Create")]
public async Task<IActionResult> Create(CallRequest request)
{
if (request == null) return BadRequest();
if (string.IsNullOrEmpty(request.Nome)) return BadRequest();
if (string.IsNullOrEmpty(request.Email)) return BadRequest();
if (string.IsNullOrEmpty(request.TipoSolicitacao)) return BadRequest();
if (string.IsNullOrEmpty(request.Descricao)) return BadRequest();
if (string.IsNullOrEmpty(request.WhatsApp)) return BadRequest();
// Download and launch browser
await new BrowserFetcher().DownloadAsync();
#if DEBUG
var browser = await Puppeteer.LaunchAsync(new LaunchOptions
{
Headless = false
});
#else
var browser = await Puppeteer.LaunchAsync(GetLaunchOptions());
#endif
var page = await browser.NewPageAsync();
try
{
// Navigate to the form page - replace with your actual URL
await page.GoToAsync("https://app.pipefy.com/portals/efdbbe89-b25e-40e3-8026-8120b05c137c");
await page.WaitForSelectorAsync("a[data-title^='Solicita']");
await page.ClickAsync("a[data-title^='Solicita']");
var elementFrame = await page.WaitForSelectorAsync("#iFrameResizer0");
var frame = await elementFrame.ContentFrameAsync();
await frame.WaitForSelectorAsync("#publicForm-ShortText-nome_do_solicitante");
// Fill Nome Completo
await frame.TypeAsync("#publicForm-ShortText-nome_do_solicitante", request.Nome);
// Fill Email
await frame.TypeAsync("#publicForm-Email-email_do_solicitante", request.Email);
// Fill Celular
await frame.TypeAsync("#publicForm-ShortText-celular_com_whatsapp", request.WhatsApp);
// Select Tipo da solicitação
await frame.WaitForSelectorAsync(".sc-ayeQl.ituYoD");
await frame.ClickAsync("[data-testid='select-field']");
await frame.WaitForSelectorAsync($"div[data-testid='list-item-content']:has(div[title='{request.TipoSolicitacao}'])",
new WaitForSelectorOptions { Visible = true });
await PressionarSetaAteOpcao(frame, page, request.TipoSolicitacao);
// Fill Descrição
await frame.TypeAsync("#publicForm-LongText-informa_es_adicionais", request.Descricao);
//// Submit form
// Wait for submission to complete - adjust selector based on success indicator
await frame.ClickAsync("#submit-form-button");
await frame.WaitForNavigationAsync();
return Ok(new { message = "Solicitação criada com sucesso!" });
}
catch (Exception ex)
{
return BadRequest(new { error = ex.Message });
}
finally
{
await browser.CloseAsync();
}
}
async Task PressionarSetaAteOpcao(IFrame frame, IPage page, string opcaoDesejada)
{
bool opcaoEncontrada = false;
int maxTentativas = 30; // Limite de segurança para não ficar em loop infinito
int tentativa = 0;
while (!opcaoEncontrada && tentativa < maxTentativas)
{
// Pega o elemento selecionado atual
var elementoSelecionado = await frame.EvaluateExpressionAsync<string>(
"document.querySelector('div[data-focused=\"true\"] div[data-lib=\"lumen\"]')?.getAttribute('title')");
if (elementoSelecionado == opcaoDesejada)
{
opcaoEncontrada = true;
await page.Keyboard.PressAsync("Enter");
break;
}
await page.Keyboard.PressAsync("ArrowDown");
await Task.Delay(200);
tentativa++;
}
if (!opcaoEncontrada)
{
throw new Exception($"Opção {opcaoDesejada} não encontrada após {maxTentativas} tentativas");
}
}
private static LaunchOptions GetLaunchOptions()
{
return new LaunchOptions
{
Headless = true,
ExecutablePath = "/usr/bin/google-chrome-stable",
Args = new[]
{
"--no-sandbox",
"--disable-setuid-sandbox",
"--disable-dev-shm-usage",
"--disable-gpu"
},
DefaultViewport = new ViewPortOptions
{
Width = 1920,
Height = 1080
}
};
}
}
}

76
Dockerfile Normal file
View File

@ -0,0 +1,76 @@
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY ["OpenRHCall.csproj", "./"]
RUN dotnet restore
COPY . .
RUN dotnet publish -c Release -o /app/publish
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS final
WORKDIR /app
# Install dependencies for Chrome
RUN apt-get update && apt-get install -y \
wget \
gnupg2 \
apt-transport-https \
ca-certificates \
libglib2.0-0 \
libnss3 \
libatk1.0-0 \
libatk-bridge2.0-0 \
libcups2 \
libdrm2 \
libxkbcommon0 \
libxcomposite1 \
libxdamage1 \
libxfixes3 \
libxrandr2 \
libgbm1 \
libpango-1.0-0 \
libcairo2 \
libasound2 \
libxcb1 \
libxcb-dri3-0 \
libxcursor1 \
libxtst6 \
fonts-ipafont-gothic \
fonts-wqy-zenhei \
fonts-thai-tlwg \
fonts-kacst \
fonts-symbola \
fonts-noto \
fonts-freefont-ttf \
--no-install-recommends \
&& rm -rf /var/lib/apt/lists/*
# Install Chrome
RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \
&& sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list' \
&& apt-get update \
&& apt-get install -y google-chrome-stable --no-install-recommends \
&& rm -rf /var/lib/apt/lists/*
# Create chrome-user and configure permissions
RUN groupadd -r chrome-user \
&& useradd -r -g chrome-user -G audio,video chrome-user \
&& mkdir -p /home/chrome-user/Downloads \
&& mkdir -p /app/.local/share \
&& chown -R chrome-user:chrome-user /home/chrome-user \
&& chown -R chrome-user:chrome-user /app
# Copy published app
COPY --from=build /app/publish .
RUN chown -R chrome-user:chrome-user /app
# Set environment variables for Chrome
ENV PUPPETEER_EXECUTABLE_PATH "/usr/bin/google-chrome-stable"
ENV CHROME_EXECUTABLE_PATH "/usr/bin/google-chrome-stable"
# Switch to chrome-user
USER chrome-user
EXPOSE 8080
EXPOSE 80
ENTRYPOINT ["dotnet", "OpenRHCall.dll"]

11
Models/CallRequest.cs Normal file
View File

@ -0,0 +1,11 @@
namespace OpenRHCall.Models
{
public class CallRequest
{
public string Nome { get; set; }
public string Email { get; set; }
public string WhatsApp { get; set; }
public string TipoSolicitacao { get; set; }
public string Descricao { get; set; }
}
}

14
OpenRHCall.csproj Normal file
View File

@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="PuppeteerSharp" Version="20.0.5" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2" />
</ItemGroup>
</Project>

6
OpenRHCall.http Normal file
View File

@ -0,0 +1,6 @@
@OpenRHCall_HostAddress = http://localhost:5025
GET {{OpenRHCall_HostAddress}}/weatherforecast/
Accept: application/json
###

25
OpenRHCall.sln Normal file
View File

@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.11.35327.3
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenRHCall", "OpenRHCall.csproj", "{C8B6CDA5-A799-4A0A-B614-2C6FC91B0C60}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{C8B6CDA5-A799-4A0A-B614-2C6FC91B0C60}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C8B6CDA5-A799-4A0A-B614-2C6FC91B0C60}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C8B6CDA5-A799-4A0A-B614-2C6FC91B0C60}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C8B6CDA5-A799-4A0A-B614-2C6FC91B0C60}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {3B443C84-6E02-48FA-BB66-7B9E0872B883}
EndGlobalSection
EndGlobal

27
Program.cs Normal file
View File

@ -0,0 +1,27 @@
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
//if (app.Environment.IsDevelopment())
//{
// app.UseSwagger();
// app.UseSwaggerUI();
//}
app.UseSwagger();
app.UseSwaggerUI();
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();

View File

@ -0,0 +1,41 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:18589",
"sslPort": 0
}
},
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "http://localhost:5025",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:7070;http://localhost:5025",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}

9
appsettings.json Normal file
View File

@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}