def init(): pathdir = Path(__file__).parent.absolute() profiledir = str(pathdir) + str("/firefox_cache") if not os.path.exists(profiledir): os.makedirs(profiledir) driver = WhatsAPIDriver(profile=profiledir, loadstyles=True) driver.driver.get(driver._URL) print("Waiting for QR") driver.wait_for_login() print("Saving session") driver.save_firefox_profile(remove_old=False) print("WhatsApp Ready") wabot_loop(driver)
def run(server_class=HTTPServer, handler_class=Server, port=8008): ##Save session on "/firefox_cache/localStorage.json". ##Create the directory "/firefox_cache", it's on .gitignore ##The "app" directory is internal to docker, it corresponds to the root of the project. ##The profile parameter requires a directory not a file. profiledir=os.path.join(".","firefox_cache") if not os.path.exists(profiledir): os.makedirs(profiledir) print("Initializing driver") driver = WhatsAPIDriver(profile=profiledir, client='remote', loadstyles=True, command_executor=os.environ["SELENIUM"]) print("Waiting for login") driver.wait_for_login() print("Saving session") driver.save_firefox_profile(remove_old=False) print("Bot started") handler_class.driver = driver server_address = ('', port) httpd = server_class(server_address, handler_class) print('Starting httpd on port %d...' % port) httpd.serve_forever()
def run(): print("Environment", os.environ) # try: # os.environ["SELENIUM"] # except KeyError: # print("Please set the environment variable SELENIUM to Selenium URL") # sys.exit(1) driver = WhatsAPIDriver( username='******', loadstyles=True, profile='/home/livelabs01/Development/WebWhatsapp-Wrapper/profile') print("Waiting for QR") driver.wait_for_login() driver.save_firefox_profile(remove_old=True) print("Bot started") # Answering to unread messages # unread_messages = driver.get_unread(include_notifications=True) # for chat_messages in unread_messages: # if not isinstance(chat_messages.chat, GroupChat): # last_message = chat_messages.messages[-1] # if last_message.type in ['chat']: # answers = requests.post( # 'http://sorrisus.localhost:8000/api/v1/answer', # json={'sentence': message.content}) # for answer in answers.json(): # driver.send_message_to_id( # last_message.sender.id, answer.get('sentence')) driver.subscribe_new_messages(NewMessageObserver(driver)) print("Waiting for new messages...") """ Locks the main thread while the subscription in running """ while True: time.sleep(60)
import os from webwhatsapi import WhatsAPIDriver profiledir = os.path.join('.', 'firefox_cache') if not os.path.exists(profiledir): os.makedirs(profiledir) driver = WhatsAPIDriver(profile=profiledir, headless=True) print('login') driver.wait_for_login() driver.save_firefox_profile(remove_old=False) print('start') chat = driver.get_chat_from_phone_number('491xxxxxxxxxx') driver.send_message_to_id(chat.id, 'This works')
def run(self, profile_path="/data/firefox_cache"): """ Faz a coleta dos metadados de grupos de Whatsapp de acordo com os parâmetros fornecidos na criação do objeto de coleta. Parâmetros ------------ profile_path : str Caminho para um profile alternativo do navegador utilizado na coleta. """ today = datetime.date.today().strftime('%Y-%m-%d') all_groups_filename = '/data/all_grupos_%s.json' % (today) with open(all_groups_filename, 'w') as json_file: print('Collecting metadata for groups at %s' % (today)) if not os.path.exists(profile_path): os.makedirs(profile_path) driver = WhatsAPIDriver(loadstyles=True, profile=profile_path, client="remote", command_executor=os.environ["SELENIUM"]) try: print("Waiting for WhatsApp Web Login") driver.wait_for_login() print("Saving session") driver.save_firefox_profile(remove_old=False) print("Bot started") pathlib.Path("/data/grupos").mkdir(parents=True, exist_ok=True) print('>>>>>>>>>>> Loading chat ids') chats = driver.get_all_chats() for chat in (chats): # Does not collect direct messages, only group chats if not chat._js_obj['isGroup']: continue gid = chat.id gid = gid.split('@')[0] s_name = self._process_string(chat.name) # Skip group if it is on blacklist (can be name or groupID) if (s_name in self.group_blacklist or gid in self.group_blacklist): continue group = dict() _id = chat.id creator = _id.split('-')[0] timestamp = _id.split('-')[-1].split('@')[0] date = convert_data_from_timestamp(float(timestamp)) str_date = date.strftime('%Y-%m-%d %H:%M:%S') name = chat.name.strip().replace('\t', ' ') kind = chat._js_obj["kind"] participants = list() for member in driver.group_get_participants(_id): user = dict() user['name'] = member.verified_name user['short_name'] = member.short_name user['nome_formatado'] = member.formatted_name user['number'] = member.id user['isBusiness'] = member.is_business user['profile_pic'] = member.profile_pic participants.append(user) group['group_id'] = _id group['creator'] = creator group['kind'] = kind group['creation'] = dict() group['creation']['creation_date'] = str_date group['creation']['creation_timestamp'] = timestamp group['title'] = name group['members'] = participants path = '/data/grupos/' filename = '%sgrupos_%s.json' % (path, _id.split('@')[0].strip()) print(group) with open(filename, 'w') as json_file: json.dump(group, json_file) print('', file=json_file) with open(all_groups_filename, 'a') as json_file: json.dump(group, json_file) print('', file=json_file) driver.close() except Exception as e: print(e) driver.close() raise Exception(e)
import os, sys, time, json, datetime from orator import DatabaseManager, Model from webwhatsapi import WhatsAPIDriver from time import sleep profiledir=os.path.join(".","firefox_cache") pic_path=os.path.join(".","marketing.jpeg") wppDriver = WhatsAPIDriver(username="******", profile=profiledir) print("Waiting for QR") wppDriver.wait_for_login() print("Bot started") wppDriver.save_firefox_profile() config = { 'postgres': { 'driver': 'postgres', 'host': '35.247.235.153', 'database': 'tbc_wpp', 'user': '******', 'password': '******', } } db = DatabaseManager(config) Model.set_connection_resolver(db)
##Save session on "/firefox_cache/localStorage.json". ##Create the directory "/firefox_cache", it's on .gitignore ##The "app" directory is internal to docker, it corresponds to the root of the project. ##The profile parameter requires a directory not a file. profiledir = os.path.join(".", "firefox_cache", mobile_number) if not os.path.exists(profiledir): os.makedirs(profiledir) driver = WhatsAPIDriver(profile=profiledir, client='remote', command_executor=os.environ["SELENIUM"]) try: logging.info("Waiting for QR") driver.wait_for_login(timeout=99999999999) logging.info("Saving session") driver.save_firefox_profile(remove_old=True) logging.info("Bot started") database_url = urlparse(os.environ["DATABASE_URL"]) username = database_url.username password = database_url.password database = database_url.path[1:] hostname = database_url.hostname port = database_url.port db_conn = psycopg2.connect(database=database, user=username, password=password, host=hostname, port=port) logging.info('Connected to database') insert_to_downloads = """INSERT INTO whatsapp.downloads(filename, datetime, status, description, message_id, size, mime, caption, media_key)
print("Environment", os.environ) try: os.environ["SELENIUM"] = "http://172.22.0.2:4444/wd/hub" except KeyError: print("Please set the environment variable SELENIUM to Selenium URL") sys.exit(1) profiledir = os.path.join(".", "firefox_cache_v2") if not os.path.exists(profiledir): os.makedirs(profiledir) print("Conectando a selenium ") driver = WhatsAPIDriver(profile=profiledir, client='remote', command_executor='172.18.0.2:4444/wd/hub') print("Conecto y saco screen shot") print("Espero login 30 seg") driver.screenshot('shot.png') try: driver.wait_for_login(30) except Exception as e: print(traceback.format_exc()) if driver.is_logged_in(): print("conectado a wsp") driver.screenshot('shot.png') else: print("Waiting for QR") driver.get_qr('lala.png') print("Waiting for QR") driver.wait_for_login() print("Bot started") driver.save_firefox_profile()
def run(self, profile_path="/data/firefox_cache"): """ Faz a coleta das mensagens de grupos de Whatsapp de acordo com os parâmetros fornecidos na criação do objeto de coleta. Parâmetros ------------ profile_path : str Caminho para um profile alternativo do navegador utilizado na coleta. """ if not os.path.exists(profile_path): os.makedirs(profile_path) driver = WhatsAPIDriver(loadstyles=True, profile=profile_path, client="remote", command_executor=os.environ["SELENIUM"]) pathlib.Path("/data/mensagens").mkdir(parents=True, exist_ok=True) pathlib.Path("/data/image").mkdir(parents=True, exist_ok=True) pathlib.Path("/data/audio").mkdir(parents=True, exist_ok=True) pathlib.Path("/data/video").mkdir(parents=True, exist_ok=True) pathlib.Path("/data/mensagens_grupo").mkdir(parents=True, exist_ok=True) pathlib.Path("/data/notificacoes").mkdir(parents=True, exist_ok=True) pathlib.Path("/data/mids").mkdir(parents=True, exist_ok=True) min_date = self.start_date max_date = self.end_date include_notf = self.collect_notifications looping = True if (self.collection_mode == 'period') and (min_date < '2020-01-01'): raise Exception("Can't start collection without a start and end" " date.") while looping: if self.collection_mode == 'continuous': looping = True else: looping = False try: print("Waiting for WhatsApp Web Login") driver.wait_for_login() print("Saving session") driver.save_firefox_profile(remove_old=False) print("Bot started") print('>>>>>>>>>>> Loading previous saved Messages') messagesID = self._get_load_messages() notificationsID = self._get_load_notifications() today_date = datetime.date.today().strftime("%Y-%m-%d") date_format = "%Y-%m-%d" file_name = "/data/mensagens/mensagens_" + today_date + ".json" start_date = min_date print('>>>>>>>>>>>>Getting Groups Messages...', end=' ') chats = driver.get_all_chats() count = 0 all_chats = list(chats) print(' DONE! %d chats loaded!' % (len(all_chats))) random.shuffle(all_chats) for chat in (all_chats): # Does not collect direct messages, only group chats if not chat._js_obj['isGroup']: continue gid = chat.id gid = gid.split('@')[0] s_name = self._process_string(chat.name) # Skip group if it is on blacklist (can be name or groupID) if (s_name in self.group_blacklist or gid in self.group_blacklist): continue # PRINT CHAT INFORMATION members = chat._js_obj['groupMetadata']['participants'] timestamp = gid.split('-')[-1] date = convert_data_from_timestamp(float(timestamp)) str_date = date.strftime('%Y-%m-%d %H:%M:%S') chat_print = "<Group chat - {name}: {id}, {participants} " \ "participants - at {time}!!>".format( name=s_name, id=gid, participants=len(members), time=str_date) print('>>>>>Loading messages from', chat_print) if gid not in messagesID: messagesID[gid] = dict() messagesID[gid]['messages'] = set() messagesID[gid]['date'] = '2000-01-01' # PROCESS PREVIOUS LOADED MESSAGES ID AND LAST DATE if self.collection_mode == 'continuous': if messagesID[gid]['date'] > max_date: continue if messagesID[gid]['date'] > min_date: start_date = messagesID[gid]['date'] till_date = datetime.datetime.strptime(start_date, date_format) else: start_date = min_date till_date = datetime.datetime.strptime(start_date, date_format) # LOAD MESSAGES FROM WHATSAPP SINCE MIN_DATE messages = chat.load_earlier_messages_till(till_date) messages = driver.get_all_message_ids_in_chat( chat, include_notifications=include_notf) elif self.collection_mode == 'period': till_date = datetime.datetime.strptime(start_date, date_format) # LOAD MESSAGES FROM WHATSAPP SINCE MIN_DATE messages = chat.load_earlier_messages_till(till_date) messages = driver.get_all_message_ids_in_chat( chat, include_notifications=include_notf) elif self.collection_mode == 'unread': # LOAD UNREAD MESSAGES FROM WHATSAPP messages = chat.get_unread_messages( include_me=False, include_notifications=include_notf) print('>>>>>Total messages %d' % (len(messages))) count += 1 for msg in messages: count += 1 gid = gid.split('@')[0] mid = msg if self._is_notification(mid): if gid not in notificationsID.keys(): notificationsID[gid] = set() if mid.strip() in notificationsID[gid]: continue j = driver.get_message_by_id(mid) self._save_notification_(j, gid) continue if mid.strip() in messagesID[gid]['messages']: print('Message: %d >>> %s from %s was CHECKED' % (count, mid, gid)) continue else: try: j = driver.get_message_by_id(mid) except Exception as e: print('Error getting a message >>', e) continue if not j: continue sender = j.sender.id sender = sender.replace(' ', '').strip() sender = sender.split('@')[0] if (sender in self.user_blacklist or '+' + sender in self.user_blacklist): continue try: date = self._get_date_from_message(j) except Exception: continue if (date > max_date) and (self.collection_mode == 'period'): break if (date < start_date): continue # Update day if today_date != date: today_date = date file_name = "/data/mensagens/mensagens_" + today_date + ".json" if self.collect_images: try: self._get_image_from_message(j) except Exception as ei: print('!!!!Error getting image!!!! ', ei) if self.collect_videos: try: self._get_video_from_message(j) except Exception as ev: print('!!!!Error getting video!!!! ', ev) if self.collect_audios: try: self._get_audio_from_message(j) except Exception as ea: print('!!!!Error getting audio!!!! ', ea) if self.collect_messages: self._save_message(j, s_name, gid, mid, file_name) driver.close() except Exception as e: print(e) driver.close() raise Exception(e) if looping: print('Waiting code to start again...') time.sleep(3600)
os.environ["SELENIUM"] except KeyError: print "Please set the environment variable SELENIUM to Selenium URL" sys.exit(1) ##Save session on "/firefox_cache/localStorage.json". ##Create the directory "/firefox_cache", it's on .gitignore ##The "app" directory is internal to docker, it corresponds to the root of the project. ##The profile parameter requires a directory not a file. profiledir=os.path.join(".","firefox_cache") if not os.path.exists(profiledir): os.makedirs(profiledir) driver = WhatsAPIDriver(profile=profiledir, client='remote', command_executor=os.environ["SELENIUM"]) print("Waiting for QR") driver.wait_for_login() print("Saving session") driver.save_firefox_profile(remove_old=False) print("Bot started") print("Bot started2") # while True: # time.sleep(3) # print 'Checking for more messages, status', driver.get_status() # for contact in driver.get_unread(): # for message in contact.messages: # print(json.dumps(message.get_js_obj(), indent = 4)) # print 'class', message.__class__.__name__ # print 'message', message # print 'id', message.id # print 'type', message.type # print 'timestamp', message.timestamp # print 'chat_id', message.chat_id
class WPChannelBot(): def __init__(self): self.model = WPChannelBotModel() self.data = self.model.get_all() self.convs = self.model.get_convs() self.convs_state = self.model.get_convs_state() self.simple_steps = True self.log_file = "log/chatbot.log" self.cmd_wait_from = None self.cmd_wait = False self.profile = "profile" self.driver = None def start(self): print("Iniciando bot...") self.driver = WhatsAPIDriver(profile=self.profile) time.sleep(3) if not self.driver.get_status() == "LoggedIn": print("Carregando QRCode") self.driver.get_qr("qrcode.png") print("Escaneie o QRCode no arquivo qrcode.png") self.driver.wait_for_login() print("Bot iniciado") self.driver.save_firefox_profile() while True: time.sleep(1) for contact in self.driver.get_unread(include_me=False, include_notifications=True, use_unread_count=True): if len(contact.messages) == 1: for message in contact.messages: if isinstance(message, Message): self.new_message(message.content, contact) self.driver.chat_send_seen(contact.chat.id) time.sleep(3) else: contact.chat.send_message( "Fico confuso com muitas mensagens :S Por favor, envie uma de cada vez e espere eu responder tá?" ) contact.chat.send_message(CHANNEL_ASK_KEYWORD) def new_message(self, message, contact): if not self._is_cmd(message): if self.cmd_wait and contact.chat.id == self.cmd_wait_from: self._cmd_envio(message, contact.chat) elif not contact.chat.id in self.convs: self._proc_etapa(contact.chat.id, message, contact.chat, 2) else: for conv in self.convs_state: if conv['id'] == contact.chat.id: e = self._proc_etapa(contact.chat.id, message, contact.chat, conv['etapa']) conv['etapa'] = e self.model.conv_update(contact.chat.id, e) else: print("ADMINISTRADOR") self._run_cmd(message, contact.chat) def shutdown(self): print("Desconectando...") self.driver.close() time.sleep(3) print("Desconectado") def _already_user(self, id, chat): if isinstance(self.model.get(id), dict): chat.send_message( "Olá, você já está cadastrado neste canal. Assim que tiver novidade você vai receber!" ) return True else: return False def _is_keyword(self, content, chat): if content.lower() == CHANNEL_KEYWORD: return True else: chat.send_message(CHANNEL_ASK_KEYWORD) return False def _proc_etapa(self, id, content, chat, etapa): if etapa == 2: if not self._already_user(id, chat) and self._is_keyword( content, chat): # Efetua registros self.convs.append(id) self.convs_state.append({"id": id, "etapa": 4}) self.model.conv_add(id, 4) # Introdução do canal - Solicita nome chat.send_message(CHANNEL_INTRO) chat.send_message(CHANNEL_MSGS[0]) self._to_log("Iniciando cadastro: %s" % id) elif etapa == 4: # Armazena nome - Solicita cidade if self.simple_steps: self.data.append({"id": id, "nome": content}) # Salva no banco de dados self.model.add(id, content) chat.send_message((CHANNEL_MSGS[3] % content)) self._remove_convs(id) self._to_log("Finalizado cadastro: %s - %s" % (id, content)) else: self.data.append({ "id": id, "nome": content, "cidade": "", "bairro": "" }) chat.send_message(CHANNEL_MSGS[1]) # Salva no banco de dados self.model.add(id, content) self._to_log("Registrado nome: %s - %s" % (id, content)) return 6 elif etapa == 6: # Implementar veficação de validade de cidade # Verifica cidade - volta ao 5 : armazena cidade - solicita bairro ou passo for obj in self.data: if obj["id"] == id: obj["cidade"] = content self.model.update(id=id, cidade=content) chat.send_message(CHANNEL_MSGS[2]) self._to_log("Registrado cidade: %s - %s" % (id, content)) return 7 elif etapa == 7: # Implementar veficação de validade de bairro if content == "passo": # Finaliza caso não seja informado bairro chat.send_message((CHANNEL_MSGS[3] % self._get_conv_nome(id))) self._remove_convs(id) self._to_log("Finalizado cadastro: %s - %s" % (id, content)) else: # Armazena bairro - Finaliza cadastro for obj in self.data: if obj["id"] == id: obj["bairro"] = content self.model.update(id=id, bairro=content) chat.send_message( (CHANNEL_MSGS[3] % self._get_conv_nome(id))) self._remove_convs(id) self._to_log("Finalizado cadastro: %s - %s" % (id, content)) def _to_log(self, log): file = open(self.log_file, "a") file.write("\n>> %s " % log) file.close() return def _get_conv_nome(self, id): for obj in self.data: if obj["id"] == id: return obj["nome"] def _remove_convs(self, id): self.convs.remove(id) for conv in self.convs_state: if conv["id"] == id: self.convs_state.remove(conv) self.model.conv_delete(id) def _is_cmd(self, content): if content[:4] == "/cmd": return True else: return False def _run_cmd(self, content, chat): cmd = content[5:] if not self.model.check_admin(chat.id) == False: if cmd == "usuarios": self._cmd_usuarios(chat) elif cmd == "envio": self.cmd_wait = True self.cmd_wait_from = chat.id chat.send_message( "*ENVIE A SEGUIR A MENSAGEM A SER ENVIADA PARA O CANAL*") else: chat.send_message("*COMANDO NÃO RECONHECIDO*") elif self.model.check_admin(id=None, all=True) == False and cmd[:5] == "admin": print("Cadastrando novo admin") self.model.add_admin(chat.id, content[11:]) chat.send_message("*ADMINISTRADOR CADASTRADO*") else: chat.send_message(CHANNEL_ASK_KEYWORD) def _cmd_usuarios(self, chat): response = "*USUÁRIOS CADASTRADOS*\n\n" i = 0 users = self.model.get_all() for user in users: i += 1 response += "\n%d) %s - %s" % (i, user['id'], user['nome']) chat.send_message(response) def _cmd_envio(self, content, chat): i = 0 users = self.model.get_all() for user in users: i += 1 self.driver.send_message_to_id(user['id'], content) self.cmd_wait_from = None self.cmd_wait = False chat.send_message("*MENSAGEM ENVIADA PARA %d USUÁRIOS DO CANAL*" % i)