diff --git a/.gitignore b/.gitignore
index 97481fc..a9604bd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,10 +10,6 @@
sessions/
-# configurações dentro do programa
-
-state.json
-
# bytecode python
__pycache__/
diff --git a/README.MD b/README.MD
index af32124..9ab71e1 100644
--- a/README.MD
+++ b/README.MD
@@ -9,7 +9,7 @@ maturador de chips é um pequeno programa para "esquentar" contas do whatssap e
## Instalação
-Se você é usuário Windows, pode fazer download do instalador x64 ou siga as instruções abaixo para executar o código-fonte da versão de codigo aberto:
+Se você é usuário Windows, pode fazer download do instalador x64 ou siga as instruções abaixo para executar o código-fonte da versão de codigo aberto:
- Clone o repositório
@@ -48,6 +48,7 @@ python main.py
- Definir troca de conta após X mensagens
- Definir máximo de mensagens
- Parar em caso de bloqueio
+- Mensagens com ChatGpt
- sem limite de instâncias
- escolher nome instância
- remover instância
@@ -63,10 +64,27 @@ python main.py
Este é o comando pyinstaller para gerar o executavel do maturador:
```shell
-pyinstaller --noconfirm --onedir --windowed --icon "(pwd)/pages/assets/medias/icon.ico" --add-data "(pwd)/pages;pages/" --add-data "(pwd)/scripts;scripts/" --add-data "(pwd)/LICENSE;." --add-data "(pwd)/README.MD;." --add-data "(pwd)/user-agent;." --add-data "(pwd)/requirements.txt;." "(pwd)/main.py"
+pyinstaller --noconfirm --onedir --windowed --icon "$(pwd)/pages/assets/medias/icon.ico" --add-data "$(pwd)/pages;pages/" --add-data "$(pwd)/scripts;scripts/" --add-data "$(pwd)/LICENSE;." --add-data "$(pwd)/gpt.py;." --add-data "$(pwd)/README.MD;." --add-data "$(pwd)/user-agent;." --add-data "$(pwd)/requirements.txt;." "$(pwd)/main.py"
```
+### Encontrar o cookie de sessão para API não oficial?
+
+
+- 1 ° acesse o site bing e faça login usando uma conta miscrosoft. após login abra o *developer tools* presionando as teclas **CTRL + SHIFT + I** ou siga os passos na foto abaixo para realizar esta ação:
+
+![step1](https://i.ibb.co/TTSSXm1/passo-1.png)
+
+
+- 2 ° busque no submenu que fica ao lado de *network*, a opção **Application** e clique sobre ela:
+
+![step2](https://i.ibb.co/Q8JZpPZ/passo-2.png)
+
+- 3 ° por ultimo encontre o cookie nomeado de **_U** e copie seu valor:
+
+![step3](https://i.ibb.co/rdBFNt4/passo-3.png)
+
+
## Licença
diff --git a/accounts.py b/accounts.py
index fbf212a..e3d9586 100644
--- a/accounts.py
+++ b/accounts.py
@@ -12,9 +12,11 @@
from PyQt5.QtWebEngineWidgets import (QWebEngineView, QWebEngineProfile, QWebEnginePage)
from PyQt5.QtWebEngineCore import (QWebEngineUrlRequestInterceptor)
+from PyQt5.QtWebChannel import QWebChannel
from PyQt5.QtGui import (QIcon, QCursor)
from PyQt5.QtCore import (QUrl, Qt)
+from controller import Controller
import shutil
import json
import os
@@ -40,7 +42,6 @@ def javaScriptConsoleMessage(self, level, message, lineNumber, sourceID):
except:
pass
-
# interceptar as requisições que vem do WhatsApp web para filtrar
# as que são feitas para enviar dados ao maturador, isso é necessário
# pois o WhatsApp web bloqueia requisições feitas para domínios
@@ -68,10 +69,9 @@ def interceptRequest(self, info):
SIGNALS.account_blocked.emit(data)
info.block(True)
-
class MainWindow(QMainWindow):
def __init__(self):
- self.controller = None
+ self.controller:Controller = None
self._is_open = False
super().__init__()
self.webs_engine = []
@@ -234,11 +234,10 @@ def load_webviews(self):
except FileNotFoundError: # a pasta de sessões ainda não existe
return
for sessionname in sessions:
-
webview = QWebEngineView()
profile = QWebEngineProfile(f"storage{sessionname}", webview)
session_dir = os.getcwd() + f"/sessions/{sessionname}"
-
+
# apaga Service Worker porque está causando problema com a sessão
service_Worker_path = os.path.join(session_dir, "Service Worker")
@@ -261,7 +260,7 @@ def load_webviews(self):
self.webviews.append(webview)
webview.page().loadFinished.connect(lambda ok, session_name=sessionname : self.run_script(session_name))
- # injeta script login.js
+ # injeta script login.js e script do webchannel
def run_script(self, session_name:str):
for idx, key in enumerate(start=0, iterable=self.buttons.keys()):
diff --git a/controller.py b/controller.py
index 94f4b01..a850e45 100644
--- a/controller.py
+++ b/controller.py
@@ -170,4 +170,4 @@ def message_box(self, message, title) -> None:
self.dashboard_window,
title,
message
- )
\ No newline at end of file
+ )
\ No newline at end of file
diff --git a/gpt.py b/gpt.py
new file mode 100644
index 0000000..f6b35fe
--- /dev/null
+++ b/gpt.py
@@ -0,0 +1,197 @@
+from openai import OpenAI
+import random
+import g4f
+import sys
+
+sys.stdout = open("MaturadorLogs.txt", "a", encoding="utf-8")
+sys.stderr = open("MaturadorLogs.txt", "a", encoding="utf-8")
+
+TOPICS = [
+ "História mundial",
+ "Ciência",
+ "Cultura",
+ "Tecnologia",
+ "Política",
+ "Filosofia",
+ "Arte",
+ "Literatura",
+ "Geografia",
+ "Astronomia",
+ "Medicina",
+ "Música",
+ "Matemática",
+ "Biologia",
+ "Economia",
+ "Psicologia",
+ "Sociologia",
+ "Antropologia",
+ "Arqueologia",
+ "Educação",
+ "Religião",
+ "Esportes",
+ "Meio ambiente",
+ "Direito",
+ "Engenharia",
+ "Alimentação e nutrição",
+ "Moda",
+ "Cinema",
+ "Teatro",
+ "Fotografia",
+ "Dança",
+ "Agricultura",
+ "Energias renováveis",
+ "Jogos",
+ "Design",
+ "Saúde pública",
+ "Marketing",
+ "Administração",
+ "Linguística",
+ "Química",
+ "Física",
+ "Robótica",
+ "Inteligência artificial",
+ "Guerras mundiais",
+ "Revoluções",
+ "Movimentos sociais",
+ "Grandes descobrimentos",
+ "Colonização",
+ "Imperialismo",
+ "Revolução industrial",
+ "Revolução tecnológica",
+ "Guerra fria",
+ "Globalização",
+ "Mudanças climáticas",
+ "Exploração espacial",
+ "Avanços médicos",
+ "Invenções",
+ "Descobertas científicas",
+ "Grandes artistas",
+ "Grandes escritores",
+ "Grandes cientistas",
+ "Grandes filósofos",
+ "Grandes músicos",
+ "Grandes líderes políticos",
+ "Grandes inventores",
+ "Grandes exploradores",
+ "Grandes batalhas",
+ "Grandes catástrofes naturais",
+ "Grandes epidemias",
+ "Geopolítica",
+ "Inteligência emocional",
+ "Desenvolvimento sustentável",
+ "Economia comportamental",
+ "Criptomoedas",
+ "Inteligência de mercado",
+ "Tendências de consumo",
+ "Inovação tecnológica",
+ "Cibersegurança",
+ "Privacidade de dados",
+ "Bioética",
+ "Direitos humanos",
+ "Neurociência",
+ "Interação humano-computador",
+ "Robótica assistencial",
+ "Realidade virtual",
+ "Realidade aumentada",
+ "Nanotecnologia",
+ "Internet das coisas",
+ "Machine learning",
+ "Aprendizado profundo",
+ "Redes neurais",
+ "Computação quântica",
+ "Impressão 3D",
+ "Biotecnologia",
+ "Genética",
+ "Clonagem",
+ "Transplantes de órgãos",
+ "Neurotecnologia"
+
+]
+
+class GptGenerateMessage():
+ def __init__(self) -> None:
+ g4f.check_version = False
+ self._last_message = None
+ self._last_question = None
+ self.client:OpenAI = None
+
+
+ def generate_question_by_unnoficial(self) -> str:
+ response = g4f.ChatCompletion.create(
+ model=g4f.models.gpt_4_turbo,
+ provider=g4f.Provider.Bing,
+ messages=[{"role": "user", "content": random.choice(["conte uma curiosidade sobre " + random.choice(TOPICS) , "me faça uma pergunta sobre " + random.choice(TOPICS)]) }],
+ stream=False)
+ return response
+
+ def generate_response_by_unnoficial(self, question:str) -> str:
+ response = g4f.ChatCompletion.create(
+ model=g4f.models.gpt_4_turbo,
+ provider=g4f.Provider.Bing,
+ messages=[{"role": "user", "content": "uma pergunta para você: " + question}],
+ stream=False
+
+ )
+ return response
+
+ def by_unnoficial(self) -> str|tuple[bool, str]:
+ try:
+ if random.choice([True, True, False]) and self._last_message:
+ self._last_message = self.generate_response_by_unnoficial(question=self._last_message)
+ return self._last_message
+
+ self._last_message = self.generate_question_by_unnoficial()
+ return self.parser_message(self._last_message)
+
+ except Exception as response_by_unnoficial_error:
+ return (False, str(response_by_unnoficial_error))
+
+ def generate_question_by_official(self) -> str:
+ response = self.client.chat.completions.create(
+ messages=[{"role": "user", "content": random.choice(["conte uma curiosidade sobre " + random.choice(TOPICS) , "me faça uma pergunta sobre " + random.choice(TOPICS)]),}],
+ model="gpt-3.5-turbo",
+ )
+ return response
+
+ def generate_response_by_official(self, question:str) -> str:
+ response = self.client.chat.completions.create(
+ messages=[{"role": "user","content": "uma pergunta para você: " + question,}],
+ model="gpt-3.5-turbo",
+ )
+ return response.strip()
+
+ def by_official(self) -> str|tuple[bool, str]:
+ try:
+ if random.choice([True, True, False]) and self._last_message:
+ self._last_message = self.generate_response_by_official(question=self._last_message)
+ return self._last_message
+
+ self._last_message = self.generate_question_by_official()
+ return self.parser_message(self._last_message)
+
+ except Exception as response_by_official_error:
+ return (False, str(response_by_official_error))
+
+ def set_bing_cookie(self, cookie:str) -> None:
+ g4f.set_cookies(".bing.com", {"_U": cookie})
+
+
+ def ininialize_openai_client(self, token:str) -> None:
+ self.client = OpenAI(api_key=token)
+
+ @staticmethod
+ def parser_message(text:str):
+ parsed_message = ""
+ for _ in text.split():
+ parsed_message += " " + _.replace("**", "*")
+ return parsed_message \
+ .replace("**Pergunta aleatória:**", "") \
+ .replace("**Curiosidade Aleatória: ", "") \
+ .replace("Olá, este é o Copilot. Eu sou um assistente de inteligência artificial que pode conversar com você sobre vários tópicos e criar conteúdo interessante.", "") \
+ .replace( "Olá, este é o Copilot. Eu sou um assistente de inteligência artificial que pode conversar com você sobre vários tópicos e ajudá-lo com algumas tarefas.", "") \
+ .replace( "Olá, Eu sou o Copilot.", "") \
+ .replace("**Pergunta aleatória:**", "") \
+ .replace("**Pergunta aleatória:**", "") \
+ .replace("**Curiosidade Aleatória: ", "") \
+ .replace("**Curiosidade Aleatória:**", "") \
+ .replace( "Olá, este é o Copilot.", "")
\ No newline at end of file
diff --git a/main.py b/main.py
index a91b1a1..796e5d6 100644
--- a/main.py
+++ b/main.py
@@ -26,6 +26,7 @@ class SignalReceive(QtCore.QObject):
start_maturation = QtCore.pyqtSignal(dict, dict)
# exibir um Qmessagebox
message_box = QtCore.pyqtSignal(str, str)
+
# iniciar maturação
wapp:WhatsApp = None
@@ -37,7 +38,7 @@ def start_maturation(window, messages_file, phones,signals):
# iniciar a aplicação
-VERSION = "16.12.2023"
+VERSION = "24.02.2024"
if __name__ == "__main__":
@@ -49,10 +50,10 @@ def start_maturation(window, messages_file, phones,signals):
window = dashboard.MainWindow(accounts_page, signals, app, controller_instance)
accounts_page.controller = controller_instance
controller_instance.dashboard_window = window
-
+
# conectar os sinais de pyqtsignal
- signals.new_phone_number.connect(lambda account_data:( controller_instance.account_added(account_data) == window.webview.reload() if "/dashboard" in window.webview.url().toString() else None) if account_data else window.webview.reload())
+ signals.new_phone_number.connect(lambda account_data: [controller_instance.account_added(account_data), window.webview.reload()] if account_data else window.webview.reload())
signals.start_maturation.connect(lambda messages_file, phones: start_maturation(window=window, messages_file=messages_file, phones=phones,signals=signals))
signals.stop_maturation.connect(lambda: threading.Thread(target=wapp.stop() if wapp else None, daemon=True).start())
signals.account_blocked.connect(lambda account_data: ( controller_instance.account_blocked(account_data) == wapp.set_account_block(phone=account_data["phone"]) ))
diff --git a/pages/assets/css/dashboard.css b/pages/assets/css/dashboard.css
index a7716a7..2afc89e 100644
--- a/pages/assets/css/dashboard.css
+++ b/pages/assets/css/dashboard.css
@@ -176,13 +176,11 @@
align-items: center;
justify-content: center;
}
-.home-icon6 {
- width: 24px;
- height: 24px;
-}
+
.home-link {
transition: 0.3s;
text-decoration: none;
+ bottom: 30px !important;
}
.home-link:hover {
color: #000000;
@@ -190,6 +188,7 @@
.home-link1 {
transition: 0.3s;
text-decoration: none;
+ bottom: 30px !important;
}
.home-link1:hover {
color: #000000;
@@ -559,7 +558,7 @@
border-color: #ffffff;
border-style: hidden;
padding-bottom: 1px;
- background-color: #f9f9f9;
+ /* background-color: #f9f9f9; */
}
.home-container08 {
right: 0px;
@@ -569,14 +568,7 @@
position: absolute;
background-color: var(--dl-color-gray-500);
}
- .home-text31 {
- top: 7px;
- left: -178px;
- color: #000000;
- position: absolute;
- font-size: 14px;
- font-family: Arial;
- }
+
.home-icon6 {
fill: #D9D9D9;
}
@@ -659,4 +651,53 @@
a {
cursor: pointer;
+}
+
+#messagesmethod {
+ width: 100% ;
+ text-align: center;
+}
+
+#messagesmethod > option {
+ font-size: 14px !important;
+ font-family: Arial, Helvetica, sans-serif !important;
+}
+
+#GptKeyContext {
+ font-family: Impact, Haettenschweiler, 'Arial Narrow Bold', sans-serif;
+ margin-top: 40px !important;
+ text-align: center;
+ position: absolute;
+ color: #15441f;
+ width: 100%;
+}
+
+#GptKeyUnofficialContext {
+ font-family: Impact, Haettenschweiler, 'Arial Narrow Bold', sans-serif;
+ margin-top: 40px !important;
+ text-align: center;
+ position: absolute;
+ color: #1d383f;
+ width: 100%;
+}
+
+.home-text31 {
+ background-color: white;
+ margin-top: 40px !important;
+ position: absolute;
+ text-align: center;
+ color: #000000;
+ width: 100%;
+}
+
+.home-icon6 {
+ width: 24px;
+ height: 24px;
+ margin-top: 38px;
+ visibility: hidden;
+}
+
+#fileInputLabel{
+ width: 90%;
+ height: 22px;
}
\ No newline at end of file
diff --git a/pages/assets/js/dashboard.js b/pages/assets/js/dashboard.js
index 8289f6c..e436d49 100644
--- a/pages/assets/js/dashboard.js
+++ b/pages/assets/js/dashboard.js
@@ -4,11 +4,14 @@ const fileInputLabel = document.getElementById('fileInputLabel');
function update_user_config() {
const ContinueOnBlock = document.querySelector("#ContinueOnBlock").checked ;
+ const ChangeAccountEveryMessages = document.querySelector("#ChangeAccountEveryMessages").value;
+ const messageInputMethod = document.querySelector("#messagesmethod").selectedOptions[0].value
const ShutdownAfterCompletion = document.querySelector("#ShutdownAfterCompletion").checked ;
const MinimumMessageInterval = document.querySelector("#MinimumMessageInterval").value;
const MaximumMessageInterval = document.querySelector("#MaximumMessageInterval").value;
- const ChangeAccountEveryMessages = document.querySelector("#ChangeAccountEveryMessages").value;
const stopAfterMessages = document.querySelector("#stopAfterMessages").value;
+ const openAIToken = document.querySelector("#GptKeyContext").value
+ const AIUnofficialToken = document.querySelector("#GptKeyUnofficialContext").value
const notValidValues = ['', '0' , 0];
// antes de enviar validar as informações
@@ -23,6 +26,7 @@ function update_user_config() {
|| Number(ChangeAccountEveryMessages) < 0
|| Number(stopAfterMessages) < 0
|| Number(MaximumMessageInterval) <= Number(MinimumMessageInterval)
+ || notValidValues.includes(messageInputMethod)
) {
$.notify("verifique os dados informados", "error");
@@ -38,7 +42,11 @@ function update_user_config() {
"MaximumMessageInterval": MaximumMessageInterval,
"ChangeAccountEveryMessages": ChangeAccountEveryMessages,
"StopAfterMessages": stopAfterMessages,
- "ShutdownAfterCompletion": ShutdownAfterCompletion
+ "ShutdownAfterCompletion": ShutdownAfterCompletion,
+ "messageInputMethod": messageInputMethod,
+ "AIUnofficialToken": AIUnofficialToken,
+ "openAIToken": openAIToken
+
};
controller.update_user_configs(JSON.stringify(dadosAtualizados)).then(response => {
@@ -53,8 +61,9 @@ function update_user_config() {
document.querySelector("#MinimumMessageInterval").addEventListener("change", update_user_config);
document.querySelector("#MaximumMessageInterval").addEventListener("change", update_user_config);
document.querySelector("#ChangeAccountEveryMessages").addEventListener("change", update_user_config);
- document.querySelector("#stopAfterMessages").addEventListener("change", update_user_config);
-
+ document.querySelector("#stopAfterMessages").addEventListener("change", update_user_config);
+ document.querySelector("#GptKeyContext").addEventListener("change", update_user_config);
+ document.querySelector("#GptKeyUnofficialContext").addEventListener("change", update_user_config);
// abrir repositório do projeto
@@ -104,17 +113,41 @@ document.querySelector(".start-maturador").addEventListener("click", () =>{
controller.start_maturation();
})
+ // selecionar o método de entrada para mensagens
+
+ document.querySelector("#messagesmethod").addEventListener("change", (select) => {
+
+ if (select.target.selectedOptions[0].value === "byFile") {
+ document.querySelector("#GptKeyUnofficialContext").hidden = true;
+ document.querySelector(".home-icon6").style.visibility = "visible"
+ document.querySelector("#GptKeyContext").hidden = true;
+ fileInputLabel.hidden = false;
+
+ } else if (select.target.selectedOptions[0].value === "byOpenAI") {
+ document.querySelector("#GptKeyUnofficialContext").hidden = true;
+ document.querySelector(".home-icon6").style.visibility = "hidden"
+ document.querySelector("#GptKeyContext").hidden = false;
+ fileInputLabel.hidden = true;
+ }
+
+ else {
+ document.querySelector(".home-icon6").style.visibility = "hidden"
+ document.querySelector("#GptKeyUnofficialContext").hidden = false;
+ document.querySelector("#GptKeyContext").hidden = true;
+ fileInputLabel.hidden = true;
+ }
+
+ })
+
// selecionar o arquivo de mensagens
- document.querySelector("#files").addEventListener("click", () => {
- controller.select_file().then(response =>
- {
+ document.querySelector("#fileInputLabel").addEventListener("click", () => {
+
+ controller.select_file().then(response => {
response = JSON.parse(response)
$.notify(response.message, { className: response.ok ? "success" : "error"});
document.querySelector("#fileInputLabel").textContent = response["filename"]
} )
-
-
})
@@ -128,6 +161,10 @@ document.querySelector(".start-maturador").addEventListener("click", () =>{
document.querySelector("#stopAfterMessages").value = configs["StopAfterMessages"]
document.querySelector("#MinimumMessageInterval").value = configs["MinimumMessageInterval"]
document.querySelector("#MaximumMessageInterval").value = configs["MaximumMessageInterval"]
+ document.querySelector("#messagesmethod").selectedIndex = ["byFile", "byOpenAI", "byOpenAIUnofficial"].indexOf( configs["messageInputMethod"] )
+ document.querySelector("#GptKeyUnofficialContext").value = configs["AIUnofficialToken"]
+ document.querySelector("#GptKeyContext").value = configs["openAIToken"]
+ document.querySelector("#messagesmethod").dispatchEvent(new Event("change"));
fileInputLabel.textContent = configs["filename"]
const accounts_container = document.querySelector(".home-container02")
@@ -149,4 +186,11 @@ document.querySelector(".start-maturador").addEventListener("click", () =>{
})
-})
\ No newline at end of file
+})
+
+setTimeout(() => {
+
+ document.querySelector("#messagesmethod").addEventListener("change", update_user_config);
+
+
+}, 1000 * 1)
diff --git a/pages/dashboard.html b/pages/dashboard.html
index 3e243d7..00ea4bd 100644
--- a/pages/dashboard.html
+++ b/pages/dashboard.html
@@ -66,7 +66,7 @@