Exemplo n.º 1
0
def run():
    print("Environment", os.environ)

    driver = WhatsAPIDriver(username="******")
    print("Waiting for QR")
    driver.wait_for_login()
    print("Bot started")

    driver.subscribe_new_messages(NewMessageObserver())
    print("Waiting for new messages...")

    """ Locks the main thread while the subscription in running """
    while True:
        time.sleep(60)
Exemplo n.º 2
0
# encoding=utf8
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)

Exemplo n.º 3
0
    img_w, img_h = img.size
    offset = ((bg_w - img_w) // 2, (bg_h - img_h) // 2)
    background.paste(img, offset, img)
    background.save('goodqr.png', "PNG")
    imgur = pyimgur.Imgur(CLIENT_ID)
    uploaded_image = imgur.upload_image(PATH, title="WhatsApp QR Code")
    print("QR code has been uploaded to:\n" + str(uploaded_image.link) +
          "\nPlease scan the QR code to login.")
else:
    pass
z = 0
a = 0
try:
    while z == 0:
        try:
            driver.wait_for_login(timeout=5)
        except CannotSendRequest:
            z = 0
            continue
        else:
            z = 1
except TimeoutException:
    try:
        while a == 0:
            try:
                print("Awaiting login... YOU HAVE 90 SECONDS TO DO SO.")
                driver.wait_for_login(timeout=90)
            except CannotSendRequest:
                a = 0
                continue
    except TimeoutException:
Exemplo n.º 4
0
import time
from webwhatsapi import WhatsAPIDriver
from webwhatsapi.objects.message import Message

driver = WhatsAPIDriver(username='******', client='C:\\Users\\raosa\\Desktop\\PROJECTS\\chromedriver.exe')
print("Waiting for QR")
driver.wait_for_login()

print("Bot started")

while True:
    time.sleep(3)
    print('Checking for more messages')
    for contact in driver.get_unread():
        for message in contact.messages:
            if isinstance(message, Message): # Currently works for text messages only.
                contact.chat.send_message(message.safe_content)
Exemplo n.º 5
0
def checknumber(phoneNumberStr):
    # if (driver.check_number_status(phoneNumberStr + '@c.us').status == 200):
    if (driver.check_number_status(phoneNumberStr).status == 200):
        return True
    else:
        return False


def createListOfNumbers(number):
    rs = number + " " + str(checknumber(number)) + "\n"
    file.write(rs)


driver = WhatsAPIDriver()
print("Waiting for QR")
driver.wait_for_login()

print("Bot started")

number_array = []
for i in range(5410010, 5410020):
    number_array.append("97252" + str(i) + '@c.us')
print(number_array)

threads = []

counter = 0
while counter < len(number_array):
    if threading.active_count() > MAX_THREAD:
        time.sleep(0.1)
    else:
Exemplo n.º 6
0
class WhatsappBot:
    def __init__(self, auto_run=False, auto_long_run=False, headless=False):
        self._chromedriver = os.environ.get(
            'CHROMEDRIVE_PATH',
            os.path.join(os.path.dirname(__file__), "chromedriver"))
        self._profile_path = os.path.join(os.path.dirname(__file__),
                                          "chromeprofile")

        self._headless = headless
        self._driver = WhatsAPIDriver(
            username="******",
            client="chrome",
            profile=self._profile_path,
            executable_path=self._chromedriver,
            headless=self._headless,
            chrome_options=[
                "user-agent=Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36",
            ],
            heroku=self._headless)
        self._bot_actions = BotActions(self._driver)

        self._thread_pool = ThreadPoolExecutor(max_workers=2)
        self._threaded_users = []

        if auto_long_run:
            self.keep_running()
        elif auto_run:
            self.run()

    def run(self) -> None:
        """
        • Check if there's some user with status == 6 (if yes, generate sticker pack)
        • Listen to new messages
            Here we can either keep listening to new messages (long_run == True) or check just once.
        """

        # Check for new messages
        self.check_for_unread_messages()

        # Check for users waiting the pack
        user_in_last_stage = User.find_users_in_last_stage()
        for user in user_in_last_stage:
            if user[0] not in self._threaded_users:
                self._thread_pool.submit(self.create_sticker_pack, user)
                self._threaded_users.append(user[0])
                logging.info(f"{user[0]} added to queue.")
            else:
                logging.info(f"{user[0]} already in queue.")

    def keep_running(self) -> None:
        """
        Keeps running with self.run()
        :return:
        """

        while True:
            if not self._driver.is_logged_in():
                self._driver.screenshot('scrsht.png')
                self._driver.wait_for_login()
            try:
                self.run()
                sleep(2)
            except TypeError as err:
                logging.critical(err)
                logging.critical("---RESTARTING---")

    def create_sticker_pack(self, user_info: tuple) -> bool:
        """Create a sticker pack using StickerSet class."""
        wa_chat_id = user_info[0]
        package_title = user_info[1]
        tg_chat_id = user_info[2]

        logging.info(f"Running for {wa_chat_id}")

        # Get stickers messages
        stickers = self.list_user_unread_stickers(wa_chat_id)

        # Create sticker set
        sticker_set = StickerSet(tg_chat_id)
        name = sticker_set.create_new_sticker_set(
            package_title, stickers[0].save_media_buffer(True))

        if not name:
            logging.error(f"Can't create {wa_chat_id} pack: name = {name}")
            return False

        # Populate sticker set
        for sticker in stickers[1:]:
            stts = sticker_set.add_sticker_to_set(
                tg_chat_id, name, sticker.save_media_buffer(True))
            logging.info(f"Added a sticker to {name}: {stts}")

        # Send confirmation
        self._bot_actions.confirmation(wa_chat_id, name)

        logging.info(f"Finished {wa_chat_id}")

        # Remove user from threading
        if wa_chat_id in self._threaded_users:
            self._threaded_users.remove(wa_chat_id)

        return True

    def check_for_unread_messages(self) -> None:
        """
        Check for unread messages and call actions
        :return:
        """
        unread = self._driver.get_unread()
        for msg_group in unread:
            print(f'Message from <{msg_group.chat.id}>.')
            for message in msg_group.messages:
                self.process_incoming_message(message)

    def process_incoming_message(self, message: Message) -> None:
        # Message properties: https://gist.github.com/hellmrf/6e06fc374bb43de0868fbb57c223aecd
        if message.type == 'chat':
            print(
                f"[{message.chat_id} {message.timestamp}]: {message.content}")
            user_is_threaded = message.chat_id in self._threaded_users
            self.treat_message(message.chat_id,
                               message.content,
                               queued=user_is_threaded)
        elif User.get_stage(message.chat_id) == 0:
            self.treat_message(message.chat_id, "Hello")

    def list_user_unread_stickers(self, chat_id: str) -> List[Message]:
        messages: List[Message] = self._driver.get_all_messages_in_chat(
            chat_id)
        stickers = [
            message for message in messages if message.type == 'sticker'
        ]
        return stickers

    @staticmethod
    def upload_sticker_from_message(tg_user_id: int,
                                    sticker_message: Message) -> str:
        sticker = sticker_message.save_media_buffer(True)
        return StickerSet.upload_sticker(tg_user_id, sticker)

    def treat_message(self, chat_id: str, message: str, queued=False) -> bool:
        return self._bot_actions.answer(chat_id, message, queued=queued)

    @staticmethod
    def convert_sticker_to_png_base64(sticker: BytesIO) -> str:
        """
        Converts a sticker file (webp) to base64 string (png)
        :param sticker: the sticker to be converted
        :return: the base64 string
        """
        file = BytesIO()
        img = Image.open(sticker)
        img.save(file, 'png')

        base64_content = base64.b64encode(file.getvalue()).decode()
        base64_string = 'data:image/png;base64,' + base64_content
        return base64_string

    # TODO: remove that
    @staticmethod
    def temp_save_to_txt(base64_string: str, suffix="") -> None:
        with open(
                f"/home/helitonmrf/Projects/WhatsGram_Stickers/test/sticker{suffix}.html",
                'w') as fl:
            fl.write(f"<img src='{base64_string}' />")
Exemplo n.º 7
0
from orator import DatabaseManager, Model
from webwhatsapi import WhatsAPIDriver

wppDriver = WhatsAPIDriver(username="******")

print("Waiting for QR")
wppDriver.wait_for_login()

print("Bot started")
config = {
    'postgres': {
        'driver': 'postgres',
        'host': '35.247.235.153',
        'database': 'tbc_wpp',
        'user': '******',
        'password': '******',
    }
}

db = DatabaseManager(config)
Model.set_connection_resolver(db)


class Driver(Model):
    __table__ = 'drivers'
    pass


drivers = Driver.all()

print("Buscando motoristas...")
Exemplo n.º 8
0
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)
Exemplo n.º 9
0
    def run(self, profile_path="/data/firefox_cache"):

        profile_path = self.profile
        """
        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(self.data_path):
            os.makedirs(self.data_path)

        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(self.data_path + "mensagens").mkdir(parents=True,
                                                         exist_ok=True)
        pathlib.Path(self.data_path + "image").mkdir(parents=True,
                                                     exist_ok=True)
        pathlib.Path(self.data_path + "audio").mkdir(parents=True,
                                                     exist_ok=True)
        pathlib.Path(self.data_path + "video").mkdir(parents=True,
                                                     exist_ok=True)
        pathlib.Path(self.data_path + "mensagens_grupo").mkdir(parents=True,
                                                               exist_ok=True)
        pathlib.Path(self.data_path + "notificacoes").mkdir(parents=True,
                                                            exist_ok=True)
        pathlib.Path(self.data_path + "all_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.")

        check_group_w = False
        check_group_b = False
        if len(self.group_whitelist) > 0: check_group_w = True
        if len(self.group_blacklist) > 0: check_group_b = True

        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 = self.data_path + "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)

                    if check_group_w and (gid not in self.group_whitelist):
                        if check_group_w and (s_name
                                              not in self.group_whitelist):
                            continue
                    if check_group_b and (gid in self.group_blacklist
                                          or s_name in self.group_blacklist):
                        print(
                            'Group', gid, str(s_name),
                            'in blacklist and will not be collected! Next group'
                        )
                        continue

                    # 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

                        if not self.check_user(j): 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 = self.data_path + "mensagens/mensagens_" + today_date + ".json"

                        if self.collect_images:
                            try:
                                self._get_image_from_message(
                                    j, self.data_path + "image")
                            except Exception as ei:
                                print('!!!!Error getting image!!!! ', ei)

                        if self.collect_videos:
                            try:
                                self._get_video_from_message(
                                    j, self.data_path + "video")
                            except Exception as ev:
                                print('!!!!Error getting video!!!! ', ev)

                        if self.collect_audios:
                            try:
                                self._get_audio_from_message(
                                    j, self.data_path + "audio")
                            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)