From e559b3e13497012581ee8093afba73b208b9dae4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Monezi?= Date: Wed, 29 Jan 2025 09:00:34 -0300 Subject: [PATCH] Subindo Arquivos --- Dimensao.csv | 57 +++++++ README.md | 0 busca_pdv.py | 21 +++ consultoras.py | 49 ++++++ consultoras.xlsx | Bin 0 -> 39261 bytes data_handler.py | 58 +++++++ datas.py | 28 ++++ gerentes_erp.py | 429 +++++++++++++++++++++++++++++++++++++++++++++++ login.py | 259 ++++++++++++++++++++++++++++ main.py | 59 +++++++ 10 files changed, 960 insertions(+) create mode 100644 Dimensao.csv delete mode 100644 README.md create mode 100644 busca_pdv.py create mode 100644 consultoras.py create mode 100644 consultoras.xlsx create mode 100644 data_handler.py create mode 100644 datas.py create mode 100644 gerentes_erp.py create mode 100644 login.py create mode 100644 main.py diff --git a/Dimensao.csv b/Dimensao.csv new file mode 100644 index 0000000..1067448 --- /dev/null +++ b/Dimensao.csv @@ -0,0 +1,57 @@ +codigo,descricao,cpf_gr,gerencia,cpf_sup,sup,gerencia_loja,estado +3546,SAM'S CLUB FAROL,64774937487,Raquel Tenório,910362408,Maxwell Vieira,Carla Lima,ALAGOAS +4560,MCZ SH. TERREO,64774937487,Raquel Tenório,1009194488,Efigênia Herculano,Rosilane Pagamonha,ALAGOAS +5699,MOREIRA LIMA,64774937487,Raquel Tenório,910362408,Maxwell Vieira,Solange Bezerra,ALAGOAS +12522,MCZ SH. EXP.,64774937487,Raquel Tenório,1009194488,Efigênia Herculano,Betina Melo,ALAGOAS +12817,SH. PATIO,64774937487,Raquel Tenório,910362408,Maxwell Vieira,Pamella Barbosa,ALAGOAS +12818,GB. SERRARIA,64774937487,Raquel Tenório,910362408,Maxwell Vieira,Laura Ruiz,ALAGOAS +12820,ATACADÃO,64774937487,Raquel Tenório,910362408,Maxwell Vieira,Pamella Barbosa,ALAGOAS +12823,PONTA VERDE,64774937487,Raquel Tenório,1009194488,Efigênia Herculano,Felipe Barros,ALAGOAS +12824,GB. TABULEIRO,64774937487,Raquel Tenório,910362408,Maxwell Vieira,Laura Ruiz,ALAGOAS +12826,ASSAÍ MANGABEIRAS,64774937487,Raquel Tenório,1009194488,Efigênia Herculano,Grasiele Oliveira,ALAGOAS +12828,GB. STELLA MARIS,64774937487,Raquel Tenório,1009194488,Efigênia Herculano,Grasiele Oliveira,ALAGOAS +12829,JACINTINHO,64774937487,Raquel Tenório,1009194488,Efigênia Herculano,Manoela Araújo,ALAGOAS +12830,LIVRAMENTO,64774937487,Raquel Tenório,910362408,Maxwell Vieira,Solange Bezerra,ALAGOAS +12838,RIO LARGO,64774937487,Raquel Tenório,910362408,Maxwell Vieira,Maria Jucelia,ALAGOAS +13427,SHOPPING CIDADE,64774937487,Raquel Tenório,910362408,Maxwell Vieira,Thiana Melo,ALAGOAS +14617,PARQUE SHOPPING,64774937487,Raquel Tenório,1009194488,Efigênia Herculano,Synara Morais,ALAGOAS +19103,UNICOMPRA,64774937487,Raquel Tenório,1009194488,Efigênia Herculano,Felipe Barros,ALAGOAS +20858,SUPER GIRO,64774937487,Raquel Tenório,910362408,Maxwell Vieira,Rayzha Moreira,ALAGOAS +20969,MAR. DEODORO,64774937487,Raquel Tenório,1009194488,Efigênia Herculano,Maria Gabriela,ALAGOAS +20991,CAMPO ALEGRE,64774937487,Raquel Tenório,1009194488,Efigênia Herculano,Daliane Santos,ALAGOAS +21647,CARAJAS,64774937487,Raquel Tenório,1009194488,Efigênia Herculano,Betina Melo,ALAGOAS +21624,MIX MATEUS,64774937487,Raquel Tenório,910362408,Maxwell Vieira,Rayzha Moreira,ALAGOAS +910173,QDB PARQUE,64774937487,Raquel Tenório,1009194488,Efigênia Herculano,Débora Araújo,ALAGOAS +910291,QDB MACEIO,64774937487,Raquel Tenório,1009194488,Efigênia Herculano,Débora Araújo,ALAGOAS +21007,TÔ QUE TÔ,64774937487,Raquel Tenório,910362408,Maxwell Vieira,Thiana Melo,ALAGOAS +20998,CD TABULEIRO,64774937487,Raquel Tenório,2522564412,Anna Schelly,----,ALAGOAS +20005,CANDEIAS CIMA,1819238580,Arianne Sodré,88708365504,Fernanda Vieira,Juliana Cerqueira,BAHIA +20006,SÃO SEBASTIÃO,1819238580,Arianne Sodré,88708365504,Fernanda Vieira,Laiane Martins,BAHIA +20009,CANDEIAS BAIXO,1819238580,Arianne Sodré,88708365504,Fernanda Vieira,Juliana Cerqueira,BAHIA +20056,SIMÕES FILHO,1819238580,Arianne Sodré,88708365504,Fernanda Vieira,Laiane Martins,BAHIA +20057,CONC. DO COITE,1819238580,Arianne Sodré,81834993504,Juliana Vasconcelos,VR Vanuzia,BAHIA +20986,OLINDINA,1819238580,Arianne Sodré,79215424504,Cláudia Fontes,Aniele Souza,BAHIA +20988,QUEIMADAS,1819238580,Arianne Sodré,81834993504,Juliana Vasconcelos,VR Genivia,BAHIA +20989,ENTRE RIOS,1819238580,Arianne Sodré,79215424504,Cláudia Fontes,Ione de Souza,BAHIA +20999,ESPLANADA,1819238580,Arianne Sodré,79215424504,Cláudia Fontes,Ione de Souza,BAHIA +21000,SANTALUZ,1819238580,Arianne Sodré,81834993504,Juliana Vasconcelos,VR Jessica,BAHIA +21001,RIO REAL,1819238580,Arianne Sodré,79215424504,Cláudia Fontes,Aniele Souza,BAHIA +21068,ATAKAREJO,1819238580,Arianne Sodré,88708365504,Fernanda Vieira,Laiane Martins,BAHIA +21375,IPIRA,1819238580,Arianne Sodré,79215424504,Cláudia Fontes,----,BAHIA +21381,CAPIM GROSSO,1819238580,Arianne Sodré,81834993504,Juliana Vasconcelos,VR Mirlane,BAHIA +20441,LAGARTO,1472167538,Luciana Amaral,3961945594,Taciana,Damila Matos,SERGIPE +20968,ITABAIANINHA,1472167538,Luciana Amaral,3961945594,Taciana,Verônica Abril,SERGIPE +21277,GB. SOCORRO,1472167538,Luciana Amaral,736514511,Carla Melo,Patrícia Maria,SERGIPE +21296,SH. PRM. SOCORRO,1472167538,Luciana Amaral,736514511,Carla Melo,Patrícia Maria,SERGIPE +21495,B. COQUEIROS,1472167538,Luciana Amaral,736514511,Carla Melo,Patrícia Maria,SERGIPE +23475,MIX TABULEIRO,64774937487,Raquel Tenório,910362408,Maxwell Vieira,Laura Ruiz,ALAGOAS +23702,PANVICON,1819238580,Arianne Sodré,1819238580,Arianne Sodré,Lucimara Ferreira,VDC +23701,9 DE NOVEMBRO,1819238580,Arianne Sodré,1819238580,Arianne Sodré,Camilla Oliveira,VDC +23665,SHOPPING BOULEVARD,1819238580,Arianne Sodré,1819238580,Arianne Sodré,Camilla Oliveira,VDC +23709,SHOPPING CONQUISTA SUL,1819238580,Arianne Sodré,1819238580,Arianne Sodré,Lucimara Ferreira,VDC +23712,CANDIDO SALES,1819238580,Arianne Sodré,1819238580,Arianne Sodré,Camilla Oliveira,VDC +23713,ZEFERINO CORREIA,1819238580,Arianne Sodré,1819238580,Arianne Sodré,Camilla Oliveira,VDC +23707,BAIRRO BRASIL,1819238580,Arianne Sodré,1819238580,Arianne Sodré,Camilla Oliveira,VDC +23705,SHOPPING CONQUISTA,1819238580,Arianne Sodré,1819238580,Arianne Sodré,Lucimara Ferreira,VDC +23708,BARRA DO CHOÇA,1819238580,Arianne Sodré,1819238580,Arianne Sodré,Camilla Oliveira,VDC +23706,ASSAI VITÓRIA DA CONQUISTA,1819238580,Arianne Sodré,1819238580,Arianne Sodré,Lucimara Ferreira,VDC diff --git a/README.md b/README.md deleted file mode 100644 index e69de29..0000000 diff --git a/busca_pdv.py b/busca_pdv.py new file mode 100644 index 0000000..5ef59b0 --- /dev/null +++ b/busca_pdv.py @@ -0,0 +1,21 @@ +import pandas as pd + +def extract_data(file): + consultoras = pd.read_excel(f"{file}", sheet_name="PDV") + consultoras.drop(index=1, inplace=True) + consultoras.columns = consultoras.iloc[0] + consultoras.drop(index=0, inplace=True) + consultoras= consultoras.iloc[:,[0,2,3,8,9]] + consultoras.columns = ['PDV','GMV ATUAL', 'VAR GMV', 'BOLETO MEDIO', 'VAR BOL'] + return consultoras + +def busca_realizado(codigo_pesquisar): + dimensao = pd.read_csv('Dimensao.csv',encoding='utf-8') + df = dimensao + codigos_correspondentes = df[(df['cpf_gr'] == codigo_pesquisar) | (df['cpf_sup'] == codigo_pesquisar)]['codigo'].tolist() + dados = extract_data("consultoras.xlsx") + pdv_filtrados = dados[dados['PDV'].isin(codigos_correspondentes)] + receita_gmv = pdv_filtrados["GMV ATUAL"].sum() + return int(receita_gmv) + + diff --git a/consultoras.py b/consultoras.py new file mode 100644 index 0000000..41c19cb --- /dev/null +++ b/consultoras.py @@ -0,0 +1,49 @@ +import requests + +def consultoras (access_token, data_inicial, data_final): + # Defina o endpoint e os headers + url = "https://backend-dashboards.prd.franqueado.grupoboticario.digital/store-indicators" + headers = { + "authorization": f"Bearer {access_token}", # Substitua pelo token real + "dash-view-name": "store-view/general", + "x-api-key": "8V5pUI1u1y3dFASezqZYY6iZvkUXDHZO6Ol66ja5", + "revenue-type": "gmv-revenue", + "cp-code": "10269", + "Accept": "application/json, text/plain, */*", + # Outros cabeçalhos podem ser adicionados aqui + } + + # Parâmetros da URL + params = { + "orderBy": "revenueCurrentPeriodValue", + "aggregation": "consultant", + "order": "DESC", + "years": "2025", + "pillars": "Todos", + "startCurrentDate": {data_inicial}, + "endCurrentDate": {data_final}, + "startPreviousDate": "2024-01-03", + "endPreviousDate": "2024-01-21", + "calendarType": "calendar", + "previousPeriodCycleType": "retail-year", + "previousPeriodCalendarType": "retail-year", + "hour": "00:00 - 23:00", + "separationType": "businessDays", + "download": "true", + "channels": "LOJ", + } + + # Envie a requisição GET + response = requests.get(url, headers=headers, params=params) + + # Verifique a resposta + if response.status_code == 200: + print("Requisição bem-sucedida!") + response_json = response.json() + file_url = response_json.get("data", "") + + else: + print(f"Erro: {response.status_code}") + print(response.text) + return file_url + diff --git a/consultoras.xlsx b/consultoras.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..6763637406ba6cee6d6f728ffd3723f23709a4b2 GIT binary patch literal 39261 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 literal 0 HcmV?d00001 diff --git a/data_handler.py b/data_handler.py new file mode 100644 index 0000000..b76bdbe --- /dev/null +++ b/data_handler.py @@ -0,0 +1,58 @@ +from datetime import datetime +import gerentes_erp as gerp +import pandas as pd +import login as GI +dimensao = pd.read_csv('Dimensao.csv') +# Dicionário para armazenar o estado dos usuários +user_states = {} + +def extract_message_data(data): + """ + Função que extrai o número, nome e mensagem do JSON recebido. + """ + try: + # Extrair número, nome e mensagem + number = data['data']['key']['remoteJid'].split('@')[0] # Extrai o número antes de @ + name = data['data']['pushName'] # Extrai o nome do remetente + message = data['data']['message']['conversation'] # Extrai a mensagem enviada + + # Verificar o estado do usuário + if message.lower() == "iniciar": + # Configurar o estado do usuário como "aguardando nome" + user_states[number] = "aguardando_nome" + resposta = f"Olá, {name}! Você iniciou o Consultme. Por favor, digite o seu cpf para obter o menu." + print("Bot aguardando nome da consultora.") + + elif number in user_states and user_states[number] == "aguardando_nome": + # Usuário enviou o nome da consultora, processar a consulta + cpf = message.strip() + cpf = int(cpf) + hoje = datetime.today() + primeiro_dia_mes = hoje.replace(day=1) + hoje_formatado = hoje.strftime('%Y-%m-%d') + primeiro_dia_formatado = primeiro_dia_mes.strftime('%Y-%m-%d') + gerp.log_pdv(cpf) + + if cpf in dimensao['cpf_gr'].values or cpf in dimensao['cpf_sup'].values: + # Executa a consulta no sistema ERP + dados = GI.main() + mensagem = gerp.exec(cpf, primeiro_dia_formatado, hoje_formatado) + resposta = f"Olá, {name} " + mensagem + else: + mensagem = "Seu cpf não está cadastrado." + resposta = mensagem + + # Limpar o estado do usuário após responder + del user_states[number] + print(f"Consulta realizada com sucesso para {cpf}.") + + else: + # Caso o usuário envie outra mensagem sem iniciar + resposta = "Por favor, digite 'iniciar' para começar o Consultme." + print("Bot pediu ao usuário para iniciar.") + + # Retorna as informações extraídas + return number, name, message, resposta + + except KeyError as e: + raise ValueError(f"Erro ao extrair dados: {e}") diff --git a/datas.py b/datas.py new file mode 100644 index 0000000..46b49eb --- /dev/null +++ b/datas.py @@ -0,0 +1,28 @@ +#teste +from datetime import datetime +#Fazer as funções de calendário varejo + +def acumulado_mes_atual(): + hoje = datetime.today() + primeiro_dia_mes = hoje.replace(day=1) + hoje_formatado = hoje.strftime('%Y-%m-%d') + primeiro_dia_formatado = primeiro_dia_mes.strftime('%Y-%m-%d') + return primeiro_dia_formatado, hoje_formatado + +def acumulado_ano_atual(): + hoje = datetime.today() + primeiro_dia_mes = hoje.replace(day=1, month=1) + hoje_formatado = hoje.strftime('%Y-%m-%d') + primeiro_dia_formatado = primeiro_dia_mes.strftime('%Y-%m-%d') + return primeiro_dia_formatado, hoje_formatado + +def acumulado_do_dia_atual(): + hoje = datetime.today() + hoje_formatado = hoje.strftime('%Y-%m-%d') + return hoje_formatado, hoje_formatado + +def data_hora_atual(): + data_hora_atual = datetime.now() + data_hora_formatada = data_hora_atual.strftime("%Y-%m-%d_%H-%M-%S") + return data_hora_formatada + diff --git a/gerentes_erp.py b/gerentes_erp.py new file mode 100644 index 0000000..e759606 --- /dev/null +++ b/gerentes_erp.py @@ -0,0 +1,429 @@ +import csv +import http.client +import time +from io import StringIO +import requests +import xml.etree.ElementTree as ET +from datetime import date +import pandas as pd +from datetime import date +import datetime +import os +from datetime import datetime + +dimensao = pd.read_csv('Dimensao.csv') +def busca_pdv(codigo_pesquisar): + dimensao = pd.read_csv('Dimensao.csv',encoding='utf-8') + df = dimensao + codigos_correspondentes = df[(df['cpf_gr'] == codigo_pesquisar) | (df['cpf_sup'] == codigo_pesquisar)]['codigo'].tolist() + + unidades_dict = {'3546': 'aef41e8b-2a07-49eb-90ff-13b4a5ce6b65', + '4494': '804cb2f5-be0e-46ea-81cf-5faa1bfb59f2', + '4560': '2fb956b7-14ca-4320-b748-d7f3a9ea8e08', + '5699': 'b215bb37-3d30-4684-8d63-006a543bf9b4', + '11111': '01c5e9d5-fda9-4a7b-a57a-cf4ace4a0571', + '12522': '64ea8dd9-ffde-495b-9f86-3108fab1a203', + '12817': '56a47735-92e7-4317-9a86-0fcc35676a80', + '12818': '32af600c-4823-487b-b254-981666086329', + '12819': 'f20e7ffe-9d87-4fbc-b0ec-c49da6f43f33', + '12820': '54ba626b-eee9-4e4b-8a99-cbc15c9e3490', + '12823': '0c59fa2c-54d4-4f00-8952-38c9e9cda3d0', + '12824': 'ff5b50cb-3268-4653-968e-293f5155b938', + '12826': 'a15b0b35-bf09-4afa-8243-0469447d0ecd', + '12828': '0ec5b446-bbd8-438b-ba7c-d89eb1867c9d', + '12829': 'f3635215-5641-425f-80fa-44bc3041815e', + '12830': '00c76705-008e-41ab-b731-f7db638b81cc', + '12838': '35de9486-db2c-4449-8640-9e6e6e717c15', + '13427': 'decb5cb6-1e33-4c28-a2a9-945ff520b733', + '14617': '8b264cc0-cf93-4d8c-96d4-4dfb43fa5a4e', + '14668': '9439d248-6ca7-49b0-8bec-365741bd1518', + '19103': 'ea75000b-2d75-4eaa-af5f-37592b31c510', + '20005': 'ba3c5825-bd75-471d-81be-e59dc9bdb765', + '20006': 'f0169aed-0a07-4050-8952-114b1adafb50', + '20007': '1a28d239-8a39-4205-ae71-305dd47a3f67', + '20009': '4cd5cf69-82fd-472c-ade9-8cd924682dca', + '20056': '9188a0fe-5672-4e94-abb1-7cd5564566ff', + '20057': '8b2dae02-0d67-48d3-8a39-552769786b41', + '20441': 'ac31866e-1106-4c41-85dd-61ab3f782a1f', + '20858': '2189b870-51ab-4b5f-bf8d-2ed20324bfa2', + '20968': '6462b005-be0a-4065-968c-8308ff97389d', + '20969': '4c6eb12f-f16d-452f-808a-daa3d44c3cd0', + '20970': '550d82e1-ab5c-496e-88dd-0a4d4174b039', + '20986': 'd4c1f35b-0458-415c-ba02-e5a4a0e545e1', + '20988': '72921848-e9a3-4837-9941-9fccf9ca1beb', + '20989': '5b13795e-3062-4208-97de-27ed4642d097', + '20991': '9939bb4a-3d8b-43c6-857d-7c2efd6541cc', + '20992': '12148415-fb86-431e-89cd-7b17b27a345b', + '20993': '4aeac823-6b09-4582-acb4-22f0e72735d8', + '20994': '7860f680-bcc9-4d21-bf11-9dde76e2b1f1', + '20995': 'a3e122bc-2060-4f80-94f5-f43be99fb7a2', + '20996': '8676f6f8-a5b0-44cf-8220-06d41289fc34', + '20997': '680f71f3-1d4a-4263-a91f-6fb2a08b2dda', + '20998': '03cf8f3a-950c-43da-8b57-c498395fae5c', + '20999': '58691507-093a-4197-a696-81367eff33ff', + '21000': 'abcd6221-a26d-47bb-95e1-488602f76d51', + '21001': 'eadb3fa2-36ec-4936-b840-fb9597cadbac', + '21068': 'bdb2958d-7895-4c08-8dc6-7c724c1ae9c6', + '21277': '6a448c7d-fe7c-41e4-b8eb-5433ac52693b', + '21278': 'aedf2a6d-d982-4111-b3a4-117e46f5e9d5', + '21279': 'af5f4861-581a-4d45-aeb9-c90e44f30a50', + '21296': 'bbc66aa3-5d74-4405-8f58-d1b739c6a1ba', + '21375': '57ff2d4a-3945-48ca-a227-533c402e3060', + '21381': '2b030fe9-9285-45ef-97fb-b896337c739f', + '21382': 'f0f4884b-c190-4868-85c3-8cb64872ca84', + '21383': '0d9f481a-de26-47e6-8171-14f09643df57', + '21495': 'f7b321d8-b043-48f2-8555-3496630e9e83', + '21624': '22607a28-33a2-4cb4-a456-71054bda3755', + '21647': 'd4bb9aba-30e8-44f3-a83e-d44e6f87ce37', + '22448': 'e2778279-5fc4-4257-add4-3f196535e989', + '22541': 'e6a71600-0e5e-4806-8d6f-8dbe013da6e5', + '23156': "ace15a69-2af4-4f8d-8101-92c9e5201c84", + '23156': 'ace15a69-2af4-4f8d-8101-92c9e5201c84', + '23475': '4b149b33-33c0-4b95-9a7f-716dbd557b4a', + '23665': '5495e224-9b18-4b28-9d92-2f335e238dee', + '23701': '4e501dc2-c417-4bb4-bc97-3ba167360578', + '23702': 'ca93d092-b461-4446-bc78-7b9c717bb553', + '23703': '4d132cdc-0763-4e1f-8b4b-6a38a1280f81', + '23704': '9c4ec32d-38e2-46c7-9450-624f8f083ded', + '23705': '71badcb2-1043-431a-99b1-0bd11a9754a5', + '23706': 'c06de6a6-7b03-47ea-80a7-68d4a1f3dd04', + '23707': '9db686c8-5119-4eb1-9dd5-363d91db2513', + '23708': '3887a770-2b44-45d0-ab08-6cf03ec0e3d8', + '23709': 'a0e9e003-144e-4543-ac50-e4bf6894e6a2', + '23710': '3e4fc9f9-2716-4c03-b814-4fea06392757', + '23711': 'ab746a88-dbf2-4fb1-80f0-4e20a9c945f6', + '23712': '5b995c5e-563e-4dee-b408-78243fff8ec0', + '23713': 'fe02eab3-620c-402d-ae1d-ad564876b9af' + } + + concatenated_string = "" + json_data = unidades_dict + for codigo in codigos_correspondentes: + if str(codigo) in json_data: # Verificar se o código existe no JSON + concatenated_string += json_data[str(codigo)] # Concatenar o valor com um espaço + print(codigo) + # Remover o espaço extra no final (opcional) + concatenated_string = concatenated_string.strip() + return concatenated_string + +def log_pdv(codigo_pesquisar): + dimensao = pd.read_csv('Dimensao.csv',encoding='utf-8') + df = dimensao + codigos_correspondentes = df[(df['cpf_gr'] == codigo_pesquisar) | (df['cpf_sup'] == codigo_pesquisar)]['codigo'].tolist() + + unidades_dict = {'3546': 'aef41e8b-2a07-49eb-90ff-13b4a5ce6b65', + '4494': '804cb2f5-be0e-46ea-81cf-5faa1bfb59f2', + '4560': '2fb956b7-14ca-4320-b748-d7f3a9ea8e08', + '5699': 'b215bb37-3d30-4684-8d63-006a543bf9b4', + '11111': '01c5e9d5-fda9-4a7b-a57a-cf4ace4a0571', + '12522': '64ea8dd9-ffde-495b-9f86-3108fab1a203', + '12817': '56a47735-92e7-4317-9a86-0fcc35676a80', + '12818': '32af600c-4823-487b-b254-981666086329', + '12819': 'f20e7ffe-9d87-4fbc-b0ec-c49da6f43f33', + '12820': '54ba626b-eee9-4e4b-8a99-cbc15c9e3490', + '12823': '0c59fa2c-54d4-4f00-8952-38c9e9cda3d0', + '12824': 'ff5b50cb-3268-4653-968e-293f5155b938', + '12826': 'a15b0b35-bf09-4afa-8243-0469447d0ecd', + '12828': '0ec5b446-bbd8-438b-ba7c-d89eb1867c9d', + '12829': 'f3635215-5641-425f-80fa-44bc3041815e', + '12830': '00c76705-008e-41ab-b731-f7db638b81cc', + '12838': '35de9486-db2c-4449-8640-9e6e6e717c15', + '13427': 'decb5cb6-1e33-4c28-a2a9-945ff520b733', + '14617': '8b264cc0-cf93-4d8c-96d4-4dfb43fa5a4e', + '14668': '9439d248-6ca7-49b0-8bec-365741bd1518', + '19103': 'ea75000b-2d75-4eaa-af5f-37592b31c510', + '20005': 'ba3c5825-bd75-471d-81be-e59dc9bdb765', + '20006': 'f0169aed-0a07-4050-8952-114b1adafb50', + '20007': '1a28d239-8a39-4205-ae71-305dd47a3f67', + '20009': '4cd5cf69-82fd-472c-ade9-8cd924682dca', + '20056': '9188a0fe-5672-4e94-abb1-7cd5564566ff', + '20057': '8b2dae02-0d67-48d3-8a39-552769786b41', + '20441': 'ac31866e-1106-4c41-85dd-61ab3f782a1f', + '20858': '2189b870-51ab-4b5f-bf8d-2ed20324bfa2', + '20968': '6462b005-be0a-4065-968c-8308ff97389d', + '20969': '4c6eb12f-f16d-452f-808a-daa3d44c3cd0', + '20970': '550d82e1-ab5c-496e-88dd-0a4d4174b039', + '20986': 'd4c1f35b-0458-415c-ba02-e5a4a0e545e1', + '20988': '72921848-e9a3-4837-9941-9fccf9ca1beb', + '20989': '5b13795e-3062-4208-97de-27ed4642d097', + '20991': '9939bb4a-3d8b-43c6-857d-7c2efd6541cc', + '20992': '12148415-fb86-431e-89cd-7b17b27a345b', + '20993': '4aeac823-6b09-4582-acb4-22f0e72735d8', + '20994': '7860f680-bcc9-4d21-bf11-9dde76e2b1f1', + '20995': 'a3e122bc-2060-4f80-94f5-f43be99fb7a2', + '20996': '8676f6f8-a5b0-44cf-8220-06d41289fc34', + '20997': '680f71f3-1d4a-4263-a91f-6fb2a08b2dda', + '20998': '03cf8f3a-950c-43da-8b57-c498395fae5c', + '20999': '58691507-093a-4197-a696-81367eff33ff', + '21000': 'abcd6221-a26d-47bb-95e1-488602f76d51', + '21001': 'eadb3fa2-36ec-4936-b840-fb9597cadbac', + '21068': 'bdb2958d-7895-4c08-8dc6-7c724c1ae9c6', + '21277': '6a448c7d-fe7c-41e4-b8eb-5433ac52693b', + '21278': 'aedf2a6d-d982-4111-b3a4-117e46f5e9d5', + '21279': 'af5f4861-581a-4d45-aeb9-c90e44f30a50', + '21296': 'bbc66aa3-5d74-4405-8f58-d1b739c6a1ba', + '21375': '57ff2d4a-3945-48ca-a227-533c402e3060', + '21381': '2b030fe9-9285-45ef-97fb-b896337c739f', + '21382': 'f0f4884b-c190-4868-85c3-8cb64872ca84', + '21383': '0d9f481a-de26-47e6-8171-14f09643df57', + '21495': 'f7b321d8-b043-48f2-8555-3496630e9e83', + '21624': '22607a28-33a2-4cb4-a456-71054bda3755', + '21647': 'd4bb9aba-30e8-44f3-a83e-d44e6f87ce37', + '22448': 'e2778279-5fc4-4257-add4-3f196535e989', + '22541': 'e6a71600-0e5e-4806-8d6f-8dbe013da6e5', + '23156': "ace15a69-2af4-4f8d-8101-92c9e5201c84", + '23156': 'ace15a69-2af4-4f8d-8101-92c9e5201c84', + '23475': '4b149b33-33c0-4b95-9a7f-716dbd557b4a', + '23665': '5495e224-9b18-4b28-9d92-2f335e238dee', + '23701': '4e501dc2-c417-4bb4-bc97-3ba167360578', + '23702': 'ca93d092-b461-4446-bc78-7b9c717bb553', + '23703': '4d132cdc-0763-4e1f-8b4b-6a38a1280f81', + '23704': '9c4ec32d-38e2-46c7-9450-624f8f083ded', + '23705': '71badcb2-1043-431a-99b1-0bd11a9754a5', + '23706': 'c06de6a6-7b03-47ea-80a7-68d4a1f3dd04', + '23707': '9db686c8-5119-4eb1-9dd5-363d91db2513', + '23708': '3887a770-2b44-45d0-ab08-6cf03ec0e3d8', + '23709': 'a0e9e003-144e-4543-ac50-e4bf6894e6a2', + '23710': '3e4fc9f9-2716-4c03-b814-4fea06392757', + '23711': 'ab746a88-dbf2-4fb1-80f0-4e20a9c945f6', + '23712': '5b995c5e-563e-4dee-b408-78243fff8ec0', + '23713': 'fe02eab3-620c-402d-ae1d-ad564876b9af' + } + + concatenated_string = "" + json_data = unidades_dict + for codigo in codigos_correspondentes: + if str(codigo) in json_data: # Verificar se o código existe no JSON + concatenated_string += json_data[str(codigo)] # Concatenar o valor com um espaço + print(codigo) + + +def encode_url(texto): + return ''.join('%{:02X}'.format(ord(char)) if char not in 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.-' else char for char in texto) + +def gerar_session_id(marca, relatorio): + # URL do endpoint + url = '', '' + if marca == 'BOT': + url = 'https://livers.e-boticario.com.br/ReportServer/ReportExecution2005.asmx' + + payload = f''' + + + {relatorio} + + + ''' + + headers = { + "Content-Type": "text/xml; charset=utf-8", + "SOAPAction": "http://schemas.microsoft.com/sqlserver/2005/06/30/reporting/reportingservices/LoadReport", + "Authorization": "Basic ZG16XExpdmVSZXBvcnQ6MUVrd1BPRC9VMURrL0YxS2YrVVM=" + } + + response = requests.request("POST", url, data=payload, headers=headers) + + if response.status_code == 200: + response_xml = response.text + # Analisar o XML + root = ET.fromstring(response_xml) + + # Encontrar o elemento ExecutionID + execution_id_element = root.find( + './/{http://schemas.microsoft.com/sqlserver/2005/06/30/reporting/reportingservices}ExecutionID') + + # Obter o valor do elemento ExecutionID + execution_id = execution_id_element.text + + # print("ExecutionID:", execution_id) + print(f'gerar sessão: {response.status_code} - {execution_id}') + # print(response.text) + return execution_id + else: + return + + + +def carregar_relatorio(marca, execution_id, cpf, data_inicial, data_final): + pdvs = busca_pdv(cpf) + url, host = '', '' + if marca == 'QDB': + # url = 'http://rs.quemdisseberenice.com.br/ReportServer/ReportExecution2005.asmx' + url = 'rs.quemdisseberenice.com.br' + owner_id = 'ea16f59c-ddec-4e6e-aea1-a220cbf0eaba' + elif marca == 'BOT': + # url = 'http://livers.e-boticario.com.br/ReportServer/ReportExecution2005.asmx' + url = 'livers.e-boticario.com.br' + owner_id = '3861c9c1-600b-4f7a-86b1-9bf685a6d041' + + endpoint = '/ReportServer/ReportExecution2005.asmx' + payload = f''' +

+ + {execution_id} + +
+ + + + + tipo + 3 + + + situacao + -1 + + + interesse + 2 + + + titulorelatorio + Resumo de Vendas + + + filtrorelatorio + de 15/01/2025 até 15/01/2025; Lojas: 4494-COMERCIO-PONTA VERDE-MACEIO, 4560-COMERCIO-MACEIO SHOP TERREO-AL, 5699-COMERCIO -MOREIRA LIMA; Produtos: Todos; Vendedor: Todos; Tipo Relatório: Por Vendedor; Situação: Todos; Interesse: Todos; Classificadores: Todos; + + + lojarelatorio + CENTRAL 9004494 + + + unidadesnegocio + {pdvs} + + + datainicial + {data_inicial} 00:00:00 + + + datafinal + {data_final} 23:59:59 + + + ownerid + 3861c9c1-600b-4f7a-86b1-9bf685a6d041 + + + pt-BR + + + + ''' + + headers = { + "Content-Type": "text/xml; charset=utf-8", + "SOAPAction": 'http://schemas.microsoft.com/sqlserver/2005/06/30/reporting/reportingservices/SetExecutionParameters', + "Authorization": "Basic ZG16XExpdmVSZXBvcnQ6MUVrd1BPRC9VMURrL0YxS2YrVVM=", + } + + # Enable debugging for http.client + # http.client.HTTPSConnection.debuglevel = 1 + + # connection = http.client.HTTPSConnection(url) + connection = http.client.HTTPSConnection(url) + connection.request("POST", endpoint, body=payload, headers=headers) + response = connection.getresponse() + + # Enable debugging for http.client + # http.client.HTTPSConnection.debuglevel = 0 + + print(f'setar parametros: {response.status}') + + + +def gerar_csv(marca, execution_id, relatorio, cpf): + url, host = '', '' + if marca == 'QDB': + url = 'http://rs.quemdisseberenice.com.br/ReportServer?' + host = 'rs.quemdisseberenice.com.br' + elif marca == 'BOT': + url = 'https://livers.e-boticario.com.br/ReportServer?' + host = 'livers.e-boticario.com.br' + + querystring = f'{encode_url(relatorio)}&rs:SessionID={execution_id}&rs:command=Render&rs:Format=CSV&rc:Toolbar=false&rs:ErrorResponseAsXml=true&rs:AllowNewSessions=false%20HTTP/1.1' + + headers = { + 'Accept-Language': 'pt-BR', + 'Authorization': 'Basic ZG16XExpdmVSZXBvcnQ6MUVrd1BPRC9VMURrL0YxS2YrVVM=', + 'Host': f'{host}' + } + + response = requests.request("GET", f'{url}{querystring}', headers=headers) + + # print(url, querystring, sep='') + # print(f'gerar csv: {response.status_code}') + response_data = response.text + # print(response_data[:100]) + + # Separar mês e ano da string de data + # inicio = data_inicial.find('-') + 1 + # fim = data_inicial.find('-', inicio) + #ano = datetime.today().date().strftime('%Y') + #numero_mes = datetime.today().date().strftime('%m') + + csv_file = StringIO(response_data) + reader = csv.reader(csv_file) + # output_file = fr'../csv_base/brindes/{numero_mes}.{numero_ano}_{cod_unidade}_brindes_{marca}.csv' + # output_file = fr'../csv_base/posicao_de_estoque_na_data/posicao estoque_{data}_{cod_unidade}.csv' + output_file = fr'temp\{cpf}.csv' + + # output_file = fr'../csv_base/brindes/{numero_mes}.csv' + # Escrever os dados no arquivo CSV + with open(output_file, mode='w', newline='', encoding='utf-8') as file: + writer = csv.writer(file) + + # Escrever o cabeçalho + writer.writerow(next(reader)) + + # Escrever as linhas de dados + for row in reader: + writer.writerow(row) + + print(f'Dados foram gravados em "{output_file}"') + + + +def exec (cpf, data_inicial, data_final): + relatorio = '/Vendas/vendas14ResumoVendas' + exec_id = gerar_session_id('BOT', relatorio) + MAX_RETRIES = 10 + retry_count = 0 + while True: # Loop para tentar novamente em caso de falha + try: + carregar_relatorio('BOT', exec_id, cpf, data_inicial, data_final) + gerar_csv('BOT', exec_id, relatorio, cpf) + # print(cod_unidade, unidade, sep='\t') + break # Se chegou até aqui sem lançar exceções, pode sair do loop + except requests.exceptions.ConnectionError as e: + if retry_count == MAX_RETRIES: + raise e + else: + print(f"Erro de conexão: {e}") + time.sleep(5) + retry_count += 1 + except ConnectionResetError as e: + if retry_count == MAX_RETRIES: + raise e + else: + print(f"Erro de conexão: {e}") + time.sleep(5) + retry_count += 1 + + consulta = pd.read_csv(fr'temp\{cpf}.csv', encoding='ISO-8859-1') + realizado_formatado = consulta['textbox56'] + boleto_medio = consulta['textbox86'] + realizado = (float(realizado_formatado.iloc[0].replace('.', '').replace(',', '.'))) + boleto_formato = (float(boleto_medio.iloc[0].replace('.', '').replace(',', '.'))) + mensagem = f"Aqui está o seu realizado deste mês: R$ {realizado} e o boleto médio foi R$ {boleto_formato}" + return mensagem +''' +hoje = datetime.today() +primeiro_dia_mes = hoje.replace(day=1) +hoje_formatado = hoje.strftime('%Y-%m-%d') +primeiro_dia_formatado = primeiro_dia_mes.strftime('%Y-%m-%d') +realizado = exec(736514511, primeiro_dia_formatado, hoje_formatado) +print(hoje) +''' \ No newline at end of file diff --git a/login.py b/login.py new file mode 100644 index 0000000..f7b9c66 --- /dev/null +++ b/login.py @@ -0,0 +1,259 @@ +import os +import hashlib +import base64 +import requests +import re +import json +import consultoras as c +import datas as d +import pandas as pd + +def generate_code_verifier(): + """Gera um code_verifier aleatório.""" + return base64.urlsafe_b64encode(os.urandom(32)).decode('utf-8').rstrip("=") + +def generate_code_challenge(code_verifier): + """Gera o code_challenge usando SHA-256.""" + sha256_hash = hashlib.sha256(code_verifier.encode('utf-8')).digest() + return base64.urlsafe_b64encode(sha256_hash).decode('utf-8').rstrip("=") + +def send_authorization_request(session, code_challenge): + """Envia uma requisição GET para a página de login usando a sessão.""" + url = "https://login.extranet.grupoboticario.com.br/1e6392bd-5377-48f0-9a8e-467f5b381b18/oauth2/v2.0/authorize" + params = { + "p": "B2C_1A_JIT_SIGNUPORSIGNIN_FEDCORP_APIGEE_PRD", + "client_id": "b3001e60-a8e0-4da8-82ba-c3a701405f08", + "redirect_uri": "https://extranet.grupoboticario.com.br/auth/callback", + "response_type": "code", + "scope": "openid email https://gboticariob2c.onmicrosoft.com/a6cd4fe6-3d71-455a-b99d-f458a07cc0d1/extranet.api offline_access", + "state": "15d9d7f95f8648d1941426f4665aa383", + "code_challenge": code_challenge, + "code_challenge_method": "S256", + "response_mode": "query" + } + + response = session.get(url, params=params) + if response.status_code == 200: + print("Página de login carregada com sucesso.") + return response.text # Retorna o HTML + else: + print(f"Erro ao acessar a página de login: {response.status_code}") + print("Resposta de erro:", response.text) + return None + +def extract_tokens(html_content): + """Extrai o CSRF Token e StateProperties do conteúdo HTML.""" + csrf_token = None + state_properties = None + + if html_content: + csrf_match = re.search(r'"csrf":"(.*?)"', html_content) + csrf_token = csrf_match.group(1) if csrf_match else None + + state_properties_match = re.search(r'"transId":"StateProperties=(.*?)"', html_content) + state_properties = state_properties_match.group(1) if state_properties_match else None + + return csrf_token, state_properties + +def send_login_request(session, csrf_token, state_properties, username, password): + """Envia uma requisição POST para realizar o login usando a sessão.""" + url = "https://login.extranet.grupoboticario.com.br/1e6392bd-5377-48f0-9a8e-467f5b381b18/B2C_1A_JIT_SignUpOrSignin_FedCorp_APIGEE_PRD/SelfAsserted" + + params = { + "tx": f"StateProperties={state_properties}", + "p": "B2C_1A_JIT_SignUpOrSignin_FEDCorp_APIGEE_PRD" + } + + headers = { + "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", + "X-CSRF-TOKEN": csrf_token, + "X-Requested-With": "XMLHttpRequest", + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36 Edg/132.0.0.0", + "Accept": "application/json, text/javascript, */*; q=0.01", + "Origin": "https://login.extranet.grupoboticario.com.br", + "Referer": "https://login.extranet.grupoboticario.com.br/1e6392bd-5377-48f0-9a8e-467f5b381b18/oauth2/v2.0/authorize" + } + + data = { + "request_type": "RESPONSE", + "signInName": username, + "password": password + } + + response = session.post(url, params=params, headers=headers, data=data) + if response.status_code == 200: + print("Login realizado com sucesso!") + return response.text + else: + print(f"Erro ao realizar login: {response.status_code}") + return None + +def send_final_request(session, csrf_token, state_properties): + """ + Envia a última requisição GET para obter a página HTML. + """ + url = "https://login.extranet.grupoboticario.com.br/1e6392bd-5377-48f0-9a8e-467f5b381b18/B2C_1A_JIT_SignUpOrSignin_FedCorp_APIGEE_PRD/api/CombinedSigninAndSignup/confirmed" + + params = { + "rememberMe": "false", + "csrf_token": csrf_token, + "tx": f"StateProperties={state_properties}", + "p": "B2C_1A_JIT_SignUpOrSignin_FedCorp_APIGEE_PRD" + } + + headers = { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36 Edg/132.0.0.0", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", + "Referer": "https://login.extranet.grupoboticario.com.br/1e6392bd-5377-48f0-9a8e-467f5b381b18/oauth2/v2.0/authorize" + } + + response = session.get(url, headers=headers, params=params, allow_redirects=False) + if response.status_code == 200: + print("Requisição final bem-sucedida!") + return response.text # Retorna o HTML + else: + print(f"Erro na requisição final: {response.status_code}") + return response.text + +def extract_code_from_html(html_content): + """ + Extrai o valor do parâmetro `code` da URL no HTML fornecido. + + :param html_content: O conteúdo HTML como string. + :return: O valor do código ou None, se não encontrado. + """ + # Regex para encontrar o parâmetro `code` na URL do atributo `href` + match = re.search(r'href="[^"]*?code=([^&"]+)', html_content) + if match: + return match.group(1) # Captura o valor do parâmetro `code` + return match + +def send_token_request(code, code_verifier): + """ + Envia uma requisição POST para obter o token usando o código e o code_verifier. + + :param code: O código extraído da etapa anterior. + :param code_verifier: O code_verifier usado no início do fluxo. + :return: A resposta do servidor. + """ + url = "https://login.extranet.grupoboticario.com.br/1e6392bd-5377-48f0-9a8e-467f5b381b18/oauth2/v2.0/token" + params = { + "p": "B2C_1A_JIT_SIGNUPORSIGNIN_FEDCORP_APIGEE_PRD" + } + + headers = { + "Host": "login.extranet.grupoboticario.com.br", + "Connection": "keep-alive", + "Content-Type": "application/x-www-form-urlencoded", + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36 Edg/132.0.0.0", + "Accept": "*/*", + "Origin": "https://extranet.grupoboticario.com.br", + "Sec-Fetch-Site": "same-site", + "Sec-Fetch-Mode": "cors", + "Sec-Fetch-Dest": "empty", + "Referer": "https://extranet.grupoboticario.com.br/", + "Accept-Encoding": "gzip, deflate, br", + "Accept-Language": "pt-BR,pt;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6", + } + + data = { + "client_id": "b3001e60-a8e0-4da8-82ba-c3a701405f08", + "code": code, + "redirect_uri": "https://extranet.grupoboticario.com.br/auth/callback", + "code_verifier": code_verifier, + "grant_type": "authorization_code" + } + + response = requests.post(url, params=params, headers=headers, data=data) + return response.text + + +def extract_tokens_2(response_1): + response = json.loads(response_1) + try: + access_token = response.get("access_token") + id_token = response.get("id_token") + refresh_token = response.get("refresh_token") + + return { + "access_token": access_token, + "id_token": id_token, + "refresh_token": refresh_token + } + except Exception as e: + print(f"Erro ao extrair tokens: {e}") + return None + +def extract_data(file): + consultoras = pd.read_excel(f"{file}", sheet_name="PDV") + consultoras.drop(index=1, inplace=True) + consultoras.columns = consultoras.iloc[0] + consultoras.drop(index=0, inplace=True) + consultoras= consultoras.iloc[:,[0,2,3,8,9]] + consultoras.columns = ['PDV','GMV ATUAL', 'VAR GMV', 'BOLETO MEDIO', 'VAR BOL'] + return consultoras + +def busca_realizado(codigo_pesquisar, file): + dimensao = pd.read_csv('Dimensao.csv',encoding='utf-8') + df = dimensao + codigos_correspondentes = df[(df['cpf_gr'] == codigo_pesquisar) | (df['cpf_sup'] == codigo_pesquisar)]['codigo'].tolist() + dados = extract_data(f"{file}") + pdv_filtrados = dados[dados['PDV'].isin(codigos_correspondentes)] + receita_gmv = pdv_filtrados["GMV ATUAL"].sum() + return int(receita_gmv) + +# Processo principal +def main(): + session = requests.Session() # Iniciar uma sessão persistente + + code_verifier = generate_code_verifier() + code_challenge = generate_code_challenge(code_verifier) + print(f"Code Verifier: {code_verifier}") + print(f"Code Challenge: {code_challenge}") + + # Enviar requisição GET para obter tokens + html_content = send_authorization_request(session, code_challenge) + csrf_token, state_properties = extract_tokens(html_content) + + if not csrf_token or not state_properties: + print("Falha ao extrair CSRF Token ou StateProperties.") + else: + print("CSRF Token:", csrf_token) + print("StateProperties:", state_properties) + + # Dados de login + username = "andressa.santos4" + password = "Admufal@202" + + # Enviar requisição POST para login + login_response = send_login_request(session, csrf_token, state_properties, username, password) + + if login_response: + print("Resposta do servidor:", login_response) + + # Enviar requisição final + final_page_html = send_final_request(session, csrf_token, state_properties) + code = extract_code_from_html(final_page_html) + token = send_token_request(code, code_verifier) + +# Carregar o JSON do arquivo texto + tokens = extract_tokens_2(token) + if tokens: + Access = tokens["access_token"] + #print("ID Token:", tokens["id_token"]) + #print("Refresh Token:", tokens["refresh_token"]) + else: + print("Falha ao carregar ou processar o JSON.") + + url = c.consultoras(Access, d.acumulado_do_dia_atual()[0], d.acumulado_do_dia_atual()[1]) + baixar = requests.get(url) + file_name = f"consultoras{d.data_hora_atual()}.xlsx" + if baixar.status_code == 200: + # Salvar o conteúdo do arquivo + with open(file_name, "wb") as file: + file.write(baixar.content) + dados = extract_data(file_name) + print(f"Arquivo salvo com sucesso como {file_name}.") + else: + print(f"Erro ao acessar o arquivo. Código de status: {baixar.status_code}") + return dados \ No newline at end of file diff --git a/main.py b/main.py new file mode 100644 index 0000000..fee49d9 --- /dev/null +++ b/main.py @@ -0,0 +1,59 @@ +from flask import Flask, request, jsonify +from data_handler import extract_message_data +import requests +import gerentes_erp as gerp +import login as lg + +# URL do endpoint +url = "http://localhost:8081/message/sendText/Consultme" + +# Cabeçalhos com token de autenticação +headers = { + 'apikey': "429683C4C977415CAAFCCE10F7D57E11", # Substitua SEU_TOKEN_AQUI pelo token correto + "Content-Type": "application/json" +} + + +app = Flask(__name__) + +@app.route('/webhook', methods=['POST']) +def receive_message(): + try: + # Recebe os dados da requisição como JSON + data = request.json + + # Verificar se a mensagem foi enviada pelo próprio bot (fromMe == True) + if data['data']['key'].get('fromMe', False): + print("Mensagem enviada pelo bot, ignorando.") + return jsonify({"status": "ignored"}), 200 + + # Extrair as informações usando a função importada + number, name, message, resposta = extract_message_data(data) + + # Log das informações extraídas + print(f"Número: {number}, Nome: {name}, Mensagem: {message}") + # Responder apenas se a mensagem foi enviada pelo usuário + if number.startswith("5582") and len(number) == 12: + number = number[:4] + "9" + number[4:] + + # JSON de resposta a ser enviado para a Evolution API + response_data = { + "number": str(number), + "text": resposta + } + response = requests.post(url, json=response_data, headers=headers) + print("Status Code:", response.status_code) + print("Response Body:", response.text) + + # Retorna a resposta confirmando o recebimento + return jsonify({"status": "received", "number": number, "name": name, "message": message, "resposta": resposta}), 200 + + except ValueError as e: + print("Erro ao processar a mensagem:", e) + return jsonify({"status": "error", "message": str(e)}), 400 + except Exception as e: + print("Erro inesperado:", e) + return jsonify({"status": "error", "message": "Erro inesperado"}), 500 + +if __name__ == '__main__': + app.run(port=5000, debug=True)