Exemplo n.º 1
0
def webCrawler():
    #os.system('export PATH=$PATH:/path/t-/geckodriver')
    
    driver_executable_path="./geckodriver"
    driver = WhatsAPIDriver( driver_executable_path="./geckodriver")

    #driver.firstrun()
    print("Waiting for QR")
    driver.wait_for_login()

    print("Bot started")


    files = {}
    caminho = "./"
    path = './'
    
    today_date = ""    
    file_name = ""
    while True:
        time.sleep(3)
        file_name = "AllMessages_" + today_date[-2:] + ".txt" 
        file_t = open(caminho + file_name, 'a', 0)
        time.sleep(3)
        #try:
        msg_list = driver.get_unread(include_me=False, include_notifications=False, use_unread_count=False)
        if len(msg_list) == 0: continue
        
        for i in msg_list:
            if len(i.messages)>0:
                print >> file_t, i.chat
                for j in i.messages:
                    date = get_date_from_message(j)
                    if today_date != date:  #update day
                            today_date = date
                            file_t.close()
                            file_name = "AllMessages_" + today_date[-2:] + ".txt" 
                            file_t = open(caminho + file_name, 'a', 0)
                  
                    get_text_from_message(j, file_t)
                    get_image_from_message(j)
                    get_video_from_message(j)
                    get_audio_from_message(j)


        #except Exception, err:
         #   sys.stderr.write('ERROR: %sn' % str(err))
          #  if 'Message: Tried to run command without establishing a connection' in str(err):
           #     webCrawler()
                 
    file_t.close()
Exemplo n.º 2
0
class WhatsAppAgent(object):
    def __init__(self):
        self.driver = WhatsAPIDriver(client=WhatsAppAgentConstants.BROWSER)
        logger.info("Waiting for successful QR Code scan...")
        self.driver.wait_for_login()
        logger.info("Logged in!")

    def get_all_chats(self):
        return self.driver.get_all_chats()

    def get_all_msgs_in_chat(self, chat=None):
        if chat is None:
            return []
        return self.driver.get_all_messages_in_chat(chat)

    def get_msg_text(self, message=None):
        if message is None:
            return ""
        return message.safe_content

    def get_unread_msgs(self):
        for contact in self.driver.get_unread():
            for message in contact.messages:
                if isinstance(message, Message):
                    whatsAppMsg = WhatsAppAgentMessage(
                        chatId=contact.chat.id,
                        chatName=contact.chat.name,
                        senderId="",
                        senderName=message.sender.get_safe_name(),
                        msgType="",
                        msgData=message.safe_content,
                        msgTime=message.timestamp)

                    logger.debug("New message: %s",
                                 whatsAppMsg.readable_format())

    def run(self):
        while True:
            time.sleep(WhatsAppAgentConstants.NEW_MSG_POLL)
            self.get_unread_msgs()
Exemplo n.º 3
0
print("Bot started")

allowed_chats = [
    '*****@*****.**',
    '*****@*****.**',
    '*****@*****.**',  #superb
    '*****@*****.**',  #отбитые
    '*****@*****.**',
    '*****@*****.**',  #йети чат
    '*****@*****.**'
]

while True:
    rand_delay(1, 2)
    try:
        for contact in driver.get_unread():
            #print ("DEBUG:", dir(contact))
            for message in contact.messages:

                #try:
                chat_id = message.chat_id['_serialized']
                print("DEBUG: got message!")
                print("DEBUG: chat_id {}!".format(chat_id))
                #if chat_id.endswith('c.us') or ( chat_id.endswith('g.us') and chat_id in allowed_chats ):
                rand_delay(1, 2)
                process_message(driver, contact, message, chat_id)
                process_cron_jobs(driver, chat_id)
                #else:
                #    print ("DEBUG: not allowed chat!")
                #    process_message(driver, contact, message, chat_id, False, False)
    except Exception as e:
Exemplo n.º 4
0
start_time = datetime.now()
output_folder = 'output/' + start_time.strftime('%Y-%m-%d') + match_name
sleep_time = 60
match_threshold = 80

submission_log = {}
player_options = get_player_list()
player_tallies = {player: 0 for player in player_options}

# Main loop
driver = WhatsAPIDriver(loadstyles=True)
driver.wait_for_login()

try:
    while True:
        messages_by_sender = driver.get_unread()
        print('{} berichten ontvangen. Verwerken...'.format(
            len(messages_by_sender)))
        for contact in messages_by_sender:
            for message in contact.messages:
                try:
                    best_player_match, match_value = process.extractOne(
                        message.content, player_options)
                    print(
                        'Message received from: {}. Match value: {}. Text: {}'.
                        format(message.sender.id["user"], match_value,
                               message.content))
                except AttributeError:
                    best_player_match = "Player match failed: AtrributeError"
                    match_value = 0
                    print(
Exemplo n.º 5
0
def runReminder():
    from webwhatsapi import WhatsAPIDriver

    print("Environment", os.environ)
    try:
        os.environ["SELENIUM"]
    except KeyError:
        print("Please set the environment variable SELENIUM to Selenium URL")
        sys.exit(1)

    from PIL import Image

    from resizeimage import resizeimage

    ##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.

    from pyzbar.pyzbar import decode
    dir_path = os.path.dirname(os.path.realpath(__file__))

    print(")(AFYN)(ANY*FU(A*UKFA(E*FU*****************************)))")
    print(")(AFYN)(ANY*FU(A*UKFA(E*FU*****************************)))")
    print(")(AFYN)(ANY*FU(A*UKFA(E*FU*****************************)))")
    print(")(AFYN)(ANY*FU(A*UKFA(E*FU*****************************))),",
          dir_path)
    returned_value = os.system('export PATH="' + dir_path +
                               ':$PATH"')  # returns the exit code in unix

    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"])

    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"])

    import timg

    obj = timg.Renderer()

    print("Waiting for QR")
    driver.wait_for_login()
    print("Saving session")

    # from qrtools import qrtools
    # from PIL import Image
    # import zbarlight
    # qr = qrtools.QR()

    #
    # from PIL import Image

    # import os
    # import numpy as np
    # import pyboof as pb

    # # pb.init_memmap() #Optional
    #
    # class QR_Extractor:
    #     # Src: github.com/lessthanoptimal/PyBoof/blob/master/examples/qrcode_detect.py
    #     def __init__(self):
    #         self.detector = pb.FactoryFiducial(np.uint8).qrcode()
    #
    #     def extract(self, img_path):
    #         if not os.path.isfile(img_path):
    #             print('File not found:', img_path)
    #             return None
    #         image = pb.load_single_band(img_path, np.uint8)
    #         self.detector.detect(image)
    #         qr_codes = []
    #         for qr in self.detector.detections:
    #             qr_codes.append({
    #                 'text': qr.message,
    #                 'points': qr.bounds.convert_tuple()
    #             })
    #         return qr_codes

    # qr_scanner = QR_Extractor()

    print("AAA")
    c = 0
    s = 60
    status = "NotLoggedIn"
    while status is not "LoggedIn":
        c += 1
        print("status", status)

        # print("Checking qr, status", driver.get_status())

        print("AAAAAAAAAAAAA")
        # img = driver.get_qr("static/img/newQR.png")
        im_path = os.path.join("newQR.png")
        pathlib.Path().absolute()
        os.system("cp newQR.png sample/static/img/newQR.png")

        img = driver.get_qr("newQR.png")
        # from PIL import Image
        print("BBBBBBBBBBBBBBB")
        decoded = decode(Image.open(im_path))
        # print(decoded, "#######################")
        # print(decoded, "#######################")
        # print(decoded, "#######################")
        # print(decoded, "#######################")
        # print(decoded, "#######################")
        # print(decoded, "#######################")
        # print(decoded, "#######################")

        for barcode in decoded:
            print("@@@@@@@@@@@@@@@@@@@")
            # the barcode data is a bytes object so if we want to draw it
            # on our output image we need to convert it to a string first
            barcodeData = barcode.data.decode("utf-8")
            barcodeType = barcode.type
            # draw the barcode data and barcode type on the image
            text = "{} ({})".format(barcodeData, barcodeType)
            print(text)
            print("@@@@@@@@@@@@@@@@@@@")
            printQR(barcodeData)
            print("@@@@@@@@@@@@@@@@@@@X")

        status = driver.get_status()
        # output = qr_scanner.extract(img)
        # print(output,"!!!!!!!!!!!!!!!!WDIOUSICNOIUCJ)(Z*UCINJ)(ZP*DFJYUF)((P*SUD)(UASIDMUJ))")
        # print(qr.decode(img))
        # print(qr.data)

        # print("BBBB2")
        # with open(img, 'r+b') as f:
        #     with Image.open(f) as image:
        #         cover = resizeimage.resize_cover(image, [57, 57])
        #         cover.save(img, image.format)
        # #
        # qr.decode(img)
        # print (qr.data)
        # print(retval,"!!!!!!!!!!!!!!!!!!!")
        #
        # print("CCC",img)
        # obj.load_image_from_file(img)

        # obj.resize(s,s)
        # s-=1
        # print(obj)
        # obj.render(timg.Ansi24HblockMethod)
        # print("DDD",s,s,s,s)
        # time.sleep(10)
        # driver.save_firefox_profile(remove_old=False)
        # time.sleep(3)
        # try:
        #     driver.reload_qr()
        # except:
        #     print("refresh finised")
    print("Bot started")

    while True:
        time.sleep(.71)
        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))
                sender = message.get_js_obj(
                )["chat"]["contact"]["formattedName"]

                for contact in driver.get_contacts():
                    # print("CCCC",contact.get_safe_name() )
                    if sender in contact.get_safe_name():
                        chat = contact.get_chat()
                        chat.send_message("Hi " + sender + " !!!*" + message +
                                          "*")

                print()
                print()
                print(sender)
                print()
                print()
                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)
                print("sender", message.sender)
                print("sender.id", message.sender.id)
                print("sender.safe_name", message.sender.get_safe_name())
                if message.type == "chat":
                    print("-- Chat")
                    print("safe_content", message.safe_content)
                    print("content", message.content)
                    # contact.chat.send_message(message.safe_content)
                elif message.type == "image" or message.type == "video":
                    print("-- Image or Video")
                    print("filename", message.filename)
                    print("size", message.size)
                    print("mime", message.mime)
                    print("caption", message.caption)
                    print("client_url", message.client_url)
                    message.save_media("./")
                else:
                    print("-- Other")
Exemplo n.º 6
0
	epoch = 1

	print('Making initial update')
	new_clues = get_clues_from_file(NEW_CHATFILE_NAME)
	old_clues = get_clues_from_file(OLD_CHATFILE_NAME)
	older_clues = get_clues_from_file(OLDER_CHATFILE_NAME)
	all_clues = make_unique(older_clues + old_clues + new_clues)
	push_clues_to_sheet(all_clues)
	print('Done')

	while True:
		time.sleep(TIME_BETWEEN_UPDATES)
		flag = False
		print("Beep " + str(epoch))
		unread = driver.get_unread()
		for message_group in unread:
			if message_group.chat.id == GROUP_ID:
				flag = True
				with open(NEW_CHATFILE_NAME, 'a+') as chat_file:
					for m in message_group.messages:
						# Checking and updating sheet
						print(m)
						fmt_ts = format_timestamp(str(m.timestamp))
						chat_file.write(fmt_ts)
						chat_file.write(" - ")
						chat_file.write(str(m.sender.get_safe_name()))
						chat_file.write(": ")
						chat_file.write(str(m.content))
						chat_file.write("\n")
Exemplo n.º 7
0
             VALUES(%s, %s, %s, %s, %s, NOW(), %s ) RETURNING id;"""

    check_if_processed = """SELECT MAX(a.datetime) latest_process_time FROM (SELECT d.status, d.datetime FROM whatsapp.messages m, whatsapp.downloads d WHERE m.id=d.message_id AND m.origin_id=%s) a GROUP BY a.status HAVING status!='skipped' ORDER BY latest_process_time DESC LIMIT 1;"""

    reloaded_contacts = """SELECT id, sender_msisdn FROM whatsapp.load_earlier_messages WHERE receiver_msisdn=%s AND earlier_messages=True;"""
    activate_reload = """UPDATE whatsapp.load_earlier_messages SET reload_start=NOW() WHERE id=%s;"""
    deactivate_reload = """UPDATE whatsapp.load_earlier_messages SET earlier_messages=False, reload_end=NOW(), note=%s WHERE id=%s;"""

    while True:
        time.sleep(3)
        logging.info('Checking for more messages, status, ' +
                     driver.get_status())

        # Read unread messages
        logging.debug("Getting unread messages")
        for contact in driver.get_unread(use_unread_count=True,
                                         fetch_all_as_unread=True):
            logging.info(contact.chat)
            sender_msisdn = str(contact.chat.id).split('@')[0]
            dirName = create_directory(sender_msisdn)
            logging.info("Messages will be processed for " + sender_msisdn)
            process_messages(contact.messages, dirName)
            contact.chat.send_seen()
            logging.info("Sent seen request")

        # Define reloaded contacts and process them
        logging.debug("Getting reload contacts")
        with db_conn.cursor() as cur:
            cur.execute(reloaded_contacts, (str(mobile_number), ))
            reloaded_contacts_set = cur.fetchall()
            sender_msisdn_list = [i[1] for i in reloaded_contacts_set]
Exemplo n.º 8
0
 time.sleep(3)  # Checks for new messages every 3 secs.
 pinger = pinger + 1
 if (pinger % 600) == 0:  # Notification every 30 min. (600 * 3 sec = 1800 sec)
     pinger = 0
     send_message_to_master(
         "Resetting counter to {pingcount}. Driver status is '{status}'".format(
             pingcount=pinger, status=driver.get_status()
         )
     )
 print(
     "Checking for more messages, status. Pinger={pingcount}".format(
         pingcount=pinger
     ),
     driver.get_status(),
 )
 for contact in driver.get_unread(include_me=True, include_notifications=True):
     for message in contact.messages:
         print(json.dumps(message.get_js_obj(), indent=4))
         # Log full JSON to general log
         f = open("generallog.log", "a+", encoding="utf-8")
         f.write(
             "\n\n==========================================================================\nMessage received at {timestamp}\n".format(
                 timestamp=str(datetime.datetime.now())
             )
         )
         try:
             f.write(json.dumps(message.get_js_obj(), indent=4))
         except:
             f.write("ERROR!! Unprintable JSON!")
             send_message_to_master("Unprintable JSON! Please check!")
         f.write("\n")
Exemplo n.º 9
0
class Master(object):
	shares = []
	db = {
		"masters":["972512170493", "972547932000"],
		"users":{"id":{"services":{"groupID":None}}},
		"services":{"Reminders":{"dbID":None,"incomingTarget":None},"Proxy":{"dbID":None,"incomingTarget":None},"Danilator":{"dbID":None,"incomingTarget":None}},
		"groups": {"id":"service"},
		"id":"*****@*****.**"}
	services = {}

	''' start master driver and log in '''
	def __init__(self, profileDir = "/app/session/rprofile2"):
		Master.shares.append(self)
		self.db = Master.db
		# self.services = ServiceLoader.LoadServices(self)

		self.status = "INIT"
		self.lastQR = 0
		self.driver = None
		self.masterService = None

		asyncInit = Thread(target = self.initAsync,args = [profileDir])
		asyncInit.start()

	def initAsync(self, profileDir = "/app/session/rprofile2"):

		''' init driver variables '''
		if len(Master.shares) > 1:
			profileDir += "-"+str(len(Master.shares))
		chrome_options = webdriver.ChromeOptions()
		chrome_options.binary_location = os.environ.get("GOOGLE_CHROME_BIN")
		chrome_options.add_argument("--headless")
		chrome_options.add_argument("--disable-dev-shm-usage")
		chrome_options.add_argument("--no-sandbox")
		chrome_options.add_argument("user-agent=Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36")
		chrome_options.add_argument("user-data-dir="+profileDir);
		chrome_options.add_argument('--profile-directory='+profileDir)

		if not runLocal:
			self.driver = WhatsAPIDriver(profile = profileDir, client='chrome', chrome_options=chrome_options,username="******")
		else:
			self.driver = WhatsAPIDriver(username="******",profile=None)
		driver = self.driver

		''' RUNNING MASTER SERVICE '''
		self.masterService = MasterService(runLocal, self.db, self.services, self.driver, self)


		print(''' ::: waiting for login ::: ''')
		driver.wait_for_login()
		try:
			self.status = status = driver.get_status()
		except Exception as e:
			print(" ::: ERROR - Status Init ::: ","\n",e,e.args,"\n")

		''' preping for qr '''
		if status is not "LoggedIn":
			img = None
			triesCount = 0
			maxtries = 40

			while status is not "LoggedIn" and triesCount < maxtries:
				triesCount+=1

				print("-------------------------------")
				print("status:",status,"tries:",triesCount,"/",maxtries)
				print("-------------------------------")

				self.lastQR += 1
				try:
					img = driver.get_qr("static/img/QR"+str(self.lastQR)+".png")
					print("QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ")
					print("QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ")
					print("QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ")
					print("QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ")
					print("QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ")
					print("QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ")
					print("QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ",str(img)[17:130])

				except Exception as e:
					print(" ::: ERROR - QR Fetching ::: ","\n",e,e.args,"\n")

				# im_path = os.path.join("static/img/newQR.png")

				print(''' ::: rechecking status ::: ''')
				try:
					self.status = status = driver.get_status()
				except Exception as e :
					self.status = status = "XXXXXXXX"
					print(" ::: ERROR - Status Fetching ::: ","\n",e,e.args,"\n")

		if status is "LoggedIn":
			print(''' :::::::::::::::::::::::::::::::::::: ''')
			print(''' :::::::::::::::::::::::::::::::::::: ''')
			print(''' ::::                           ::::: ''')
			print(''' ::::   MASTER IS LOGGED IN!    ::::: ''')
			print(''' ::::                           ::::: ''')
			print(''' :::::::::::::::::::::::::::::::::::: ''')
			print(''' :::::::::::::::::::::::::::::::::::: ''')
			# if runLocal:
			# 	self.driver.save_firefox_profile(remove_old=False)

			''' load DB '''
			## overwrite to init db
			initOverwrite = True
			if initOverwrite:
				self.backup(now = True)
			# driver.updateDB(self.db,number=self.db["id"])
			lastDB = self.loadDB()
			self.db = lastDB
			self.db["init"] = time.time()
			self.db["backupInterval"] = 10*60
			if runLocal:
				self.db["backupInterval"] = 0

			self.db["backupDelay"] = 10
			if runLocal:
				self.db["backupDelay"] = 3

			self.db["lastBackup"] = 0
			self.db["lastBackupServices"] = 0
			self.backup()
			print(''' :::::::::::::::::::::::::::::::::::: ''')
			print(''' :::::::::::::::::::::::::::::::::::: ''')
			print(''' ::::                           ::::: ''')
			print(''' ::::     DATABASE LOADED       ::::: ''')
			print(''' ::::                           ::::: ''')
			print(''' :::::::::::::::::::::::::::::::::::: ''')
			print(''' :::::::::::::::::::::::::::::::::::: ''')
			print(self.db)
			print()

			self.services = ServiceLoader.LoadServices(self.send, self.backupService)
			self.initServicesDB()
			print(''' :::::::::::::::::::::::::::::::::::: ''')
			print(''' :::::::::::::::::::::::::::::::::::: ''')
			print(''' ::::                           ::::: ''')
			print(''' ::::     SERVICES LOADED       ::::: ''')
			print(''' ::::                           ::::: ''')
			print(''' :::::::::::::::::::::::::::::::::::: ''')
			print(''' :::::::::::::::::::::::::::::::::::: ''')
			print(self.services)
			print()
			#
			# ''' Load Services '''
			# # print("SSSSSSSSSSSSSSSSSSSSs")
			# self.LoadServices()
			# # print("SSSSSSSSSSSSSSSSSSSSs")

			''' process incoming '''
			process = Thread(target = self.ProcessIncoming, args=[None])
			process.start()
		else:
			print(" ::: ERROR - COULD NOT LOG IN  ::: ","\n")

	def send(self, api, service, target, content):
		print("!!!!!!!!!!!!")
		if service in self.services:
			if self.services[service]["api"] is api:
				if target in self.db["groups"] and service.lower() == self.db["groups"][target].lower():
					return self.driver.sendMessage(target,content)


	def Process(self,contact):
		for message in contact.messages:
			print("MMMMMMMMMM",message)

			if runLocal:
				chatID = message.chat_id["_serialized"]
			else:
				chatID = message.chat_id

			try:
				chat = self.driver.get_chat_from_id(chatID)
			except Exception as e:
				print(" ::: ERROR - _serialized chatID ::: "+chatID+" ::: ","\n",e,e.args,"\n")

			''' incoming from: '''
			''' Personal Chat  '''
			senderName = message.get_js_obj()["chat"]["contact"]["formattedName"]
			senderID = message.sender.id
			fromGroup = False
			if "c" in chatID:

				''' SEND TO MASTER SERVICE '''
				self.masterService.Process(message)

				#
				# print(
				# '''
				# ===================================
				#    Incoming Messages from '''+senderID+" "+senderName+'''
				# ===================================
				# '''
				# )
				# if message.type == "chat":
				# 	text = message.content
				#
				# 	print("TTTTTXXXXXXXXXTTTTTTT",text)
				# 	''' subscribe to service '''
				#
				# 	''' SENT FROM GROUP CHAT '''
				#
				# 	if "%%%!%%%" in text:
				# 		target = text.split(u"%%%!%%%")[1]
				# 		self.driver.sendMessage(chatID,"Adding Service to DB: "+target)
				# 		self.db["services"][target] = {"dbID":None,"incomingTarget":None}
				# 		self.LoadServices()
				# 		# self.serviceFuncs["services"][target] = None
				#
				# 		self.backup(now = True)
				# 	else:
				# 		print("XXXXXXXXXXXXXXXXXXX")
				# 		print("XXXXXXXXXXXXXXXXXXX")
				# 		print("XXXXXXXXXXXXXXXXXXX")
				#
				# 	if text[0] is "=":
				# 		''' person registering service with ='''
				# 		target = text[1:]
				# 		dbChanged = False
				# 		now = False
				#
				# 		''' check target service in db '''
				# 		serviceFound = False
				# 		for service in self.services:
				# 			print("______________ ----------"+service)
				# 			print("")
				# 			if not serviceFound and target.lower() == service.lower():
				# 				target = service
				# 				''' service found '''
				# 				serviceFound = True
				#
				# 				if chatID not in self.db["users"]:
				# 					self.db["users"][chatID] = {}
				# 					dbChanged = True
				# 					''' first time user '''
				# 					# self.db["users"][senderID] = {'services': {'Reminders': {'groupID': None}}}
				# 				else:
				# 					pass
				# 					''' known user '''
				#
				#
				# 				foundChat = None
				# 				if service in self.db["users"][chatID]:
				#
				# 					serviceChat = self.db["users"][chatID][service]
				#
				# 					# self.driver.sendMessage(senderID,"You are already subscirbed to: "+target+" \nYou can unsubscribe with -"+target.lower())
				# 					if serviceChat is not None:
				# 						try:
				# 							foundChat = self.driver.get_chat_from_id(serviceChat)
				# 						except:
				# 							print('chat could not be found')
				#
				#
				# 				chatName = target
				# 				welcome = "Thank you for Subscribing to "+target
				# 				try:
				# 					chatName = self.services[service]["obj"].name
				# 					welcome = "Thank you for Subscribing to "+chatName
				# 					welcome = self.services[service]["obj"].welcome
				# 				except:
				# 					pass
				#
				# 				if foundChat is not None:
				# 					check_participents = False
				# 					if check_participents:
				# 						if senderID in foundChat.get_participants_ids() or True:
				# 							'''##### check that user is participant '''
				# 							self.driver.sendMessage(senderID,"You are already subscirbed to: "+chatName+" \nYou can unsubscribe with -"+target.lower())
				# 							self.driver.sendMessage(serviceChat,"subscirbed to: "+chatName)
				# 						else:
				# 							foundChat = None
				# 					else:
				# 						self.driver.sendMessage(senderID,"You are already subscirbed to:\n"+chatName+" \n<Link>\nYou can unsubscribe with -"+target.lower())
				# 						self.driver.sendMessage(serviceChat,"subscirbed to: "+chatName)
				#
				#
				# 				''' create new group '''
				# 				if foundChat is None:
				# 					groupName = service
				# 					if service in self.services and "obj" in self.services[service] and self.services[service]["obj"] is not None:
				# 						groupName = self.services[service]["obj"].name
				#
				# 					newGroup = self.driver.newGroup(newGroupName = groupName, number = "+"+senderID.split("@")[0], local = runLocal)
				# 					newGroupID = newGroup.id
				# 					self.newG = newGroupID
				#
				# 					self.db["users"][chatID][service] = newGroupID
				# 					self.db["groups"][newGroupID] = target
				# 					dbChanged = True
				# 					now = True
				# 					print(
				# 					'''
				# 					===============================================
				# 					 ''' + senderID +" is NOW SUBSCRIBED TO "+ target +" :D "+'''
				# 					===============================================
				# 					'''
				# 					)
				#
				# 					self.driver.sendMessage(senderID,"Thank you! you are now subscribed to: "+chatName+" \n<Link>\nPlease check your new group :)")
				# 					self.driver.sendMessage(newGroupID,welcome)
				# 					# self.driver.sendMessage(serviceChat,"subscirbed to: "+target)
				#
				# 		if not serviceFound:
				# 			self.driver.sendMessage(chatID,target+" : is not recognized as a service "+target)
				# 			print(
				# 			'''
				# 			===============================================
				# 			  SERVICE '''+ target +" IS NOT AVAILABLE"+'''
				# 			===============================================
				# 			'''
				# 			)
				# 		if dbChanged:
				# 			self.backup(now=now)


			# ''' Group Chat '''
			elif "g" in chatID:
				fromGroup = True
				print(
				'''
				===============================================
				   Incoming Messages in Group \"'''+senderName+" from "+senderID+'''
				===============================================
				'''
				)
				if message.type == "chat":
					text = message.content

					''' GOT REGISTRATION COMMAND '''
					if text[0] is "=":
						foundService = None
						target = text[1:]

						''' register group to service '''
						for service in self.services:
							if target.lower() == service.lower():
								foundService = service

								foundChat = False
								if chatID in self.db["groups"]:
									targetService = self.db["groups"][chatID]
									print("TTTTTTTTTTTTTTTTTTTT")
									print(targetService, service)
									if targetService is not None:
										if targetService.lower() == service.lower():
											foundChat = True
											self.driver.sendMessage(chatID,"You are already subscirbed to: "+target+" \nYou can unsubscribe with -"+target.lower())

								if not foundChat:
									print("SSSSSSSSSSSSSSSSSSSSSSsxxxxx")
									print("SSSSSSSSSSSSSSSSSSSSSSsxxxxx")
									print("SSSSSSSSSSSSSSSSSSSSSSsxxxxx")
									self.driver.sendMessage(chatID,"Subscribing to service: "+service)
									self.db["groups"][chatID] = service
									self.backup()

						if foundService is None:
							self.driver.sendMessage(chatID,"service: "+target+" Not Found")

					''' Chat is not registered first time'''
					if chatID not in self.db["groups"]:
						# print("SSSSSSSSSSSSSSSSSSSSSS")
						self.driver.sendMessage(chatID,"This chat is not registered with any service yet\nYou can register it by sending =service_name")
						# print("JJJJJJJJJJJJJJ")
						self.db["groups"][chatID] = None
						# print("SSSSSSSSSSSSSSSSSSSSSS")
						self.backup()

					if self.db["groups"][chatID] is not None:
						''' Chat is known '''
						target = self.db["groups"][chatID]
						print("MMMMMMMMMMMMMMMM",target)
						''' adding new user to service from group'''

						foundService = None
						for service in self.services:
							if target.lower() == service.lower():
								foundService = service

								''' CHAT IS REGISTERED TO SERVICE! '''
								''' PROCESS INCOMNG MESSAGE in SERVICE '''
								if foundService is not None and text[0] is not "=":

									''' this is where the magic happens - send to service'''

									if "obj" in self.services[foundService]:
										obj = self.services[foundService]["obj"]
										if obj is not None:
											#Get Nicknames

											self.ProcessServiceAsync(obj,{"origin":chatID, "user":senderID, "content":text})
											# obj.process({"origin":chatID, "user":senderID, "content":text})

									# self.ProcessServiceAsync(service,chatID,text)


						if foundService is None:
							self.driver.sendMessage(chatID,target+" : is not recognized as a service "+target)



	def ProcessIncoming(self, data):
		print(
		'''
		===================================
			Processing Incoming Messages
		===================================
		'''
		)
		lastm = None
		loopc = 0
		delay = 0.5
		while True:
			# try:
			if True:
				if loopc % 20 == 0:
					''' ::: rechecking status ::: '''
					try:
						self.status = status = self.driver.get_status()
						print(" ::: status is",status,"::: ")
					except Exception as e:
						self.status = status = "XXXXXXXX"
						print(" ::: ERROR - Status Fetching ::: ","\n",e,e.args,"\n")


				''' all unread messages '''
				for contact in self.driver.get_unread():

					self.Process(contact)


					'''
					lastm = message
					print(json.dumps(message.get_js_obj(), indent=4))
					for contact in self.driver.get_contacts():
						# print("CCCC",contact.get_safe_name() )
						if  sender in contact.get_safe_name():
							chat = contact.get_chat()
							# chat.send_message("Hi "+sender+" !!!*"+message.content+"*")
					print()
					print()
					print(sender)
					print()
					print()
					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)
					print("sender", message.sender)
					print("sender.id", message.sender.id)
					print("sender.safe_name", message.sender.get_safe_name())
					if message.type == "chat":
						print("-- Chat")
						print("safe_content", message.safe_content)
						print("content", message.content)
						# Manager.process(message.sender.id,message.content)
						# contact.chat.send_message(message.safe_content)
					elif message.type == "image" or message.type == "video":
						print("-- Image or Video")
						print("filename", message.filename)
						print("size", message.size)
						print("mime", message.mime)
						print("caption", message.caption)
						print("client_url", message.client_url)
						message.save_media("./")
					else:
						print("-- Other type:",str(message.type))
					print("PROCESSING MESSAGE:",message)
					'''

			else:
				pass
			# except Exception as e:
			# 	print(" ::: ERROR - CHECKING MESSAGES ::: ","\n",e,e.args,"\n")

			loopc += 1; loopc = loopc % 120
			time.sleep(delay)






# class Master0(object):
	# print(
	# '''
	# :::::::::::::::::::::::::::::::::
	# :::::::::::::::::::::::::::::::::
	# ::::                         ::::
	# ::::     MASTER DRIVER       ::::
	# ::::                         ::::
	# :::::::::::::::::::::::::::::::::
	# :::::::::::::::::::::::::::::::::
	# '''
	# )

	def initServicesDB(self):
		for service in self.services:
			# try:
			if True:
				if "servicesDB" not in self.db:
					self.db["servicesDB"] = {}

				if service not in self.db["servicesDB"]:
					self.db["servicesDB"][service] = {}

				if "dbID" not in self.db["servicesDB"][service]:
					self.db["servicesDB"][service]["dbID"] = None

				dbID = self.db["servicesDB"][service]["dbID"]
				''' create new db group '''
				db = {}
				if dbID is None:
					print("-------------------------------")
					print("     CREATING NEW DB GROUP   "+service)
					print("-------------------------------")
					groupName = service

					newGroup = self.driver.newGroup(newGroupName = service+"_DB", number = "+"+self.db["masters"][1], local = runLocal)
					newGroupID = newGroup.id
					self.db["servicesDB"][service]["dbID"] = newGroupID
					db = {"init":True}
					self.driver.sendMessage(newGroupID, json.dumps(db))
					self.backup()
				else:
					db = self.loadDB(dbID)

				print("-------------------------------")
				print("service: ",service,"  dbID: ",dbID)
				print("-------------------------------")
				print(db)
				# while()
				self.services[service]["obj"].updateDB(db)

			# except Exception as e:
			else:
				print(" ::: ERROR - LOAD SERVICES ::: ","\n",e,e.args,"\n")




	def LoadServices0(self):
		# load list of services
		for service in self.db["services"]:


			if "reminders".lower() == service.lower():
				print("FFFFFFFFFFFFFFFFFFFFFFFFFFF")
				print("FFFFFFFFFFFFFFFFFFFFFFFFFFF")
				print("FFFFFFFFFFFFFFFFFFFFFFFFFFF")
				print("FFFFFFFFFFFFFFFFFFFFFFFFFFF")
				print("FFFFFFFFFFFFFFFFFFFFFFFFFFF")
				print("FFFFFFFFFFFFFFFFFFFFFFFFFFF")
				ReminderService.go(sendDelegate=self.driver.sendMessage,backupDelegate=self.backupService)
				self.serviceFuncs["services"][service]=ReminderService.process
				groupName = "🔔 Reminders 🔔"
				self.serviceGroupNames[service] = groupName
				self.db["services"][service]["welcome"] = ReminderService.welcome
				self.db["services"][service]["groupName"] = groupName
				# self.serviceGroupNames[service] = "Reminders"


			if "danilator".lower() == service.lower():
				print("FFFFFFFFFFFFFFFFFFFFFFFFFFF")
				print("FFFFFFFFFFFFFFFFFFFFFFFFFFF")
				print("FFFFFFFFFFFFFFFFFFFFFFFFFFF")
				print("FFFFFFFFFFFFFFFFFFFFFFFFFFF")
				print("FFFFFFFFFFFFFFFFFFFFFFFFFFF")
				print("FFFFFFFFFFFFFFFFFFFFFFFFFFF")
				DanilatorService.go(sendDelegate=self.driver.sendMessage,backupDelegate=self.backupService)
				self.serviceFuncs["services"][service]=DanilatorService.process
				groupName = "💚 Danilator 💚"
				self.serviceGroupNames[service] = groupName
				self.db["services"][service]["welcome"] = DanilatorService.welcome
				self.db["services"][service]["groupName"] = groupName


				# self.serviceGroupNames[service] = "Danilator"

			try:
				if "dbID" not in self.db["services"][service]:
					self.db["services"][service]["dbID"] = None

				dbID = self.db["services"][service]["dbID"]
				''' create new db group '''
				if dbID is None:
					print("-------------------------------")
					print("     CREATING NEW DB GROUP   "+service)
					print("-------------------------------")
					groupName = service

					newGroup = self.driver.newGroup(newGroupName = service+"_DB", number = "+"+self.db["masters"][1], local = runLocal)
					newGroupID = newGroup.id
					self.db["services"][service]["dbID"] = newGroupID
					self.driver.sendMessage(newGroupID, json.dumps({"init":True}))
					self.backup()
				else:
					print("-------------------------------")
					print("service: ",service,"  dbID: ",dbID)
					print("-------------------------------")

			except Exception as e:
				print(" ::: ERROR - LOAD SERVICES ::: ","\n",e,e.args,"\n")

	def initAsync0(self, profileDir = "/app/session/rprofile2"):

		''' init driver variables '''
		if len(Master.shares) > 1:
			profileDir += "-"+str(len(Master.shares))
		chrome_options = webdriver.ChromeOptions()
		chrome_options.binary_location = os.environ.get("GOOGLE_CHROME_BIN")
		chrome_options.add_argument("--headless")
		chrome_options.add_argument("--disable-dev-shm-usage")
		chrome_options.add_argument("--no-sandbox")
		chrome_options.add_argument("user-agent=Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36")
		chrome_options.add_argument("user-data-dir="+profileDir);
		chrome_options.add_argument('--profile-directory='+profileDir)

		if not runLocal:
			self.driver = WhatsAPIDriver(profile = profileDir, client='chrome', chrome_options=chrome_options,username="******")
		else:
			self.driver = WhatsAPIDriver(username="******",profile=None)
		driver = self.driver

		self.masterService = MasterService(runLocal, self.db, self.services, self.driver, self)

		print(''' ::: waiting for login ::: ''')
		driver.wait_for_login()
		try:
			self.status = status = driver.get_status()
		except Exception as e:
			print(" ::: ERROR - Status Init ::: ","\n",e,e.args,"\n")

		''' preping for qr '''
		if status is not "LoggedIn":
			img = None
			triesCount = 0
			maxtries = 40

			while status is not "LoggedIn" and triesCount < maxtries:
				triesCount+=1

				print("-------------------------------")
				print("status:",status,"tries:",triesCount,"/",maxtries)
				print("-------------------------------")

				self.lastQR += 1
				try:
					img = driver.get_qr("static/img/QR"+str(self.lastQR)+".png")
					print("QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ")
					print("QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ")
					print("QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ")
					print("QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ")
					print("QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ")
					print("QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ")
					print("QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ",str(img)[17:130])

				except Exception as e:
					print(" ::: ERROR - QR Fetching ::: ","\n",e,e.args,"\n")

				# im_path = os.path.join("static/img/newQR.png")

				print(''' ::: rechecking status ::: ''')
				try:
					self.status = status = driver.get_status()
				except Exception as e :
					self.status = status = "XXXXXXXX"
					print(" ::: ERROR - Status Fetching ::: ","\n",e,e.args,"\n")

		if status is "LoggedIn":
			print(''' :::::::::::::::::::::::::::::::::::: ''')
			print(''' :::::::::::::::::::::::::::::::::::: ''')
			print(''' ::::                           ::::: ''')
			print(''' ::::   MASTER IS LOGGED IN!    ::::: ''')
			print(''' ::::                           ::::: ''')
			print(''' :::::::::::::::::::::::::::::::::::: ''')
			print(''' :::::::::::::::::::::::::::::::::::: ''')
			# if runLocal:
			# 	self.driver.save_firefox_profile(remove_old=False)

			''' load DB '''
			## overwrite to init db
			initOverwrite = False
			if initOverwrite:
				self.backup(now = True)
			# driver.updateDB(self.db,number=self.db["id"])
			lastDB = self.loadDB()
			self.db = lastDB
			self.db["init"] = time.time()
			self.db["backupInterval"] = 10*60
			if runLocal:
				self.db["backupInterval"] = 0

			self.db["backupDelay"] = 10
			if runLocal:
				self.db["backupDelay"] = 3

			self.db["lastBackup"] = 0
			self.db["lastBackupServices"] = 0
			self.backup()
			print(''' :::::::::::::::::::::::::::::::::::: ''')
			print(''' :::::::::::::::::::::::::::::::::::: ''')
			print(''' ::::                           ::::: ''')
			print(''' ::::     DATABASE LOADED       ::::: ''')
			print(''' ::::                           ::::: ''')
			print(''' :::::::::::::::::::::::::::::::::::: ''')
			print(''' :::::::::::::::::::::::::::::::::::: ''')
			print(self.db)
			print()
			#
			''' Load Services '''
			# print("SSSSSSSSSSSSSSSSSSSSs")
			self.LoadServices()
			# print("SSSSSSSSSSSSSSSSSSSSs")

			''' process incoming '''
			process = Thread(target = self.ProcessIncoming, args=[None])
			process.start()
		else:
			print(" ::: ERROR - COULD NOT LOG IN  ::: ","\n")


	def loadDB(self, number = None):
		if number is None:
			number = self.db["id"]
		return self.driver.loadDB(number = number)


	def backupService(self, db = None, service = None, api = None):
		data = [db,service]
		# self.backupServiceAsync(data)
		if service in self.services:
			if self.services[service]["api"] is api:
				bT = Thread(target = self.backupServiceAsync,args = [data])
				bT.start()

	def backupServiceAsync(self,data):
		time.sleep(self.db["backupDelay"])
		db, service = data
		print("SSSSSSSSS",service,db)
		if time.time() - self.db["lastBackupServices"] < self.db["backupInterval"]:
			return False

		if service is None or len(service) == 0:
			return None

		backupChat = None
		if service in self.db["servicesDB"]:
			chatID = self.db["servicesDB"][service]["dbID"]
			if chatID is not None:
				bchat = None
				try:
					bchat = self.driver.getChat(chatID)
				except Exception as e:
					print(" ::: ERROR - COULD NOT GET BACKUPCHAT",e," ::: ","\n")
				if bchat is not None:
					print("FFFFFFFFFFFFFFFUCKKK")
					# self.driver.sendMessage(chatID,"FFFFFFFFFFFFFFFUCKKK")

					backupChat = chatID
			else:
				print(" ::: ERROR - SERVICE HAS NO BACKUPCHAT"+" ::: ","\n")


		if backupChat is not None:
			if db is not None:
				return self.driver.updateDB(db,number=backupChat)
			else:
				return self.loadDB(backupChat)
		else:
			print(" ::: ERROR - BackupChat NOT FOUND for :"+service+": service ::: \n")
		self.db["lastBackupServices"] = time.time()



	def backup(self, now = None):
		bT = Thread(target = self.backupAsync,args = [now])
		bT.start()

	def backupAsync(self,data):
		now = data
		if now is None:
			time.sleep(self.db["backupDelay"])
			if time.time() - self.db["lastBackup"] < self.db["backupInterval"]:
				return False
		self.db["lastBackup"] = time.time()
		return self.driver.updateDB(self.db,number=self.db["id"])

	def ProcessServiceAsync(self, obj, info):
		serviceT = Thread(target = self.ProcessService, args = [[obj,info]])
		serviceT.start()

	def ProcessService(self, data):
		# try:
		# service, chatID, text = data
		obj, info = data
		obj.process(info)
		# self.serviceFuncs["services"][service](chatID, text)

		# except Exception as e:
		# 	print(" ::: ERROR - Processing Service ::: ",serice,":::",chatID,":::",text,":::","\n",e,e.args,"\n")


	def ProcessIncoming0(self, data):
		print(
		'''
		===================================
			Processing Incoming Messages
		===================================
		'''
		)
		lastm = None
		loopc = 0
		delay = 0.5
		while True:
			# try:
			if True:
				if loopc % 20 == 0:
					''' ::: rechecking status ::: '''
					try:
						self.status = status = self.driver.get_status()
						print(" ::: status is",status,"::: ")
					except Exception as e:
						self.status = status = "XXXXXXXX"
						print(" ::: ERROR - Status Fetching ::: ","\n",e,e.args,"\n")


				''' all unread messages '''
				for contact in self.driver.get_unread():
					# print("MMMMMMMMMMXXX",contact)
					# print("MMMMMMMMMMXXX",contact)
					# print("MMMMMMMMMMXXX",contact)
					# print("MMMMMMMMMMXXX",contact)
					# print("MMMMMMMMMMXXX",contact)
					for message in contact.messages:
						print("MMMMMMMMMM",message)

						# print("IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII")
						# pprint(vars(contact))
						# print("IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII")
						# pprint(vars(message))
						# print("IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII")
						# print("IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII")
						# print("IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII")
						if runLocal:
							chatID = message.chat_id["_serialized"]
						else:
							chatID = message.chat_id
						try:
							chat = self.driver.get_chat_from_id(chatID)
						except Exception as e:
							print(" ::: ERROR - _serialized chatID ::: "+chatID+" ::: ","\n",e,e.args,"\n")

						''' incoming from: '''
						''' Personal Chat  '''
						senderName = message.get_js_obj()["chat"]["contact"]["formattedName"]
						senderID = message.sender.id
						fromGroup = False
						if "c" in chatID:
							print(
							'''
							===================================
							   Incoming Messages from '''+senderID+" "+senderName+'''
							===================================
							'''
							)
						# ''' Group Chat '''
						elif "g" in chatID:
							fromGroup = True
							print(
							'''
							===============================================
							   Incoming Messages from \"'''+senderID+" in "+senderName+'''\" GROUP
							===============================================
							'''
							)

						if message.type == "chat":
							text = message.content

							print("TTTTTXXXXXXXXXTTTTTTT",text)
							''' subscribe to service '''

							''' SENT FROM GROUP CHAT '''

							if "%%%!%%%" in text:

								print("YYYYYYYYYYYYYYYYYYYY")
								print("YYYYYYYYYYYYYYYYYYYY")
								print("YYYYYYYYYYYYYYYYYYYY")
								target = text.split(u"%%%!%%%")[1]
								self.driver.sendMessage(chatID,"Adding Service to DB: "+target)
								self.db["services"][target] = {"dbID":None,"incomingTarget":None}
								self.LoadServices()
								# self.serviceFuncs["services"][target] = None

								self.backup(now = True)
							else:
								print("XXXXXXXXXXXXXXXXXXX")
								print("XXXXXXXXXXXXXXXXXXX")
								print("XXXXXXXXXXXXXXXXXXX")



							if fromGroup is True:
								''' GOT REGISTRATION COMMAND '''
								if text[0] is "=":
									foundService = None
									target = text[1:]

									''' register group to service '''
									for service in self.db["services"]:
										if target.lower() == service.lower():
											foundService = service

											foundChat = False
											if chatID in self.db["groups"]:
												targetService = self.db["groups"][chatID]
												print("TTTTTTTTTTTTTTTTTTTT")
												print(targetService, service)
												if targetService is not None:
													if targetService.lower() == service.lower():
														foundChat = True
														self.driver.sendMessage(chatID,"You are already subscirbed to: "+target+" \nYou can unsubscribe with -"+target.lower())

											if not foundChat:
												print("SSSSSSSSSSSSSSSSSSSSSSsxxxxx")
												print("SSSSSSSSSSSSSSSSSSSSSSsxxxxx")
												print("SSSSSSSSSSSSSSSSSSSSSSsxxxxx")
												self.driver.sendMessage(chatID,"Subscribing to service: "+service)
												self.db["groups"][chatID] = service
												self.backup()

									if foundService is None:
										self.driver.sendMessage(chatID,"service: "+target+" Not Found")

								''' Chat is not registered first time'''
								if chatID not in self.db["groups"]:
									# print("SSSSSSSSSSSSSSSSSSSSSS")
									self.driver.sendMessage(chatID,"This chat is not registered with any service yet\nYou can register it by sending =service_name")
									# print("JJJJJJJJJJJJJJ")
									self.db["groups"][chatID] = None
									# print("SSSSSSSSSSSSSSSSSSSSSS")
									self.backup()
								elif self.db["groups"][chatID] is not None:
									''' Chat is known '''
									target = self.db["groups"][chatID]
									print("MMMMMMMMMMMMMMMM",target)
									''' adding new user to service from group'''

									foundService = None
									for service in self.db["services"]:
										if target.lower() == service.lower():
											foundService = service


											''' CHAT IS REGISTERED TO SERVICE! '''
											''' PROCESS INCOMNG MESSAGE in SERVICE '''
											if foundService is not None and text[0] is not "=":
												# self.driver.sendMessage(chatID,text+" ::: GONNA BE PROCESSED BY "+target)

												''' this is where the magic happens - send to service'''
												self.ProcessServiceAsync(service,chatID,text)



									if foundService is None:
										self.driver.sendMessage(chatID,target+" : is not recognized as a service "+target)


								else:
									''' service is None '''
									self.driver.sendMessage(chatID,"You can register this chat by sending =service_name")



							elif text[0] is "=":
								''' person registering service with ='''
								target = text[1:]
								dbChanged = False
								now = False

								''' check target service in db '''
								serviceFound = False
								for service in self.db["services"]:
									print("______________ ----------"+service)
									print("")
									if not serviceFound and target.lower() == service.lower():
										''' service found '''
										serviceFound = True

										if chatID not in self.db["users"]:
											self.db["users"][chatID] = {'services': {}}
											dbChanged = True
											''' first time user '''
											# self.db["users"][senderID] = {'services': {'Reminders': {'groupID': None}}}
										else:
											''' known user '''


										foundChat = None
										if service in self.db["users"][chatID]["services"]:

											serviceChat = self.db["users"][chatID]["services"][service]

											# self.driver.sendMessage(senderID,"You are already subscirbed to: "+target+" \nYou can unsubscribe with -"+target.lower())
											try:
												foundChat = self.driver.get_chat_from_id(serviceChat)

											except:
												print('chat could not be found')


										chatName = target
										welcome = "Thank you for Subscribing to "+target
										try:
											chatName = 	self.db["services"][service]["groupName"]
											welcome = "Thank you for Subscribing to "+chatName
											welcome = self.db["services"][service]["welcome"]
										except:
											pass
										if foundChat is not None:


											check_participents = False
											if check_participents:
												if senderID in foundChat.get_participants_ids() or True:
													'''##### check that user is participant '''
													self.driver.sendMessage(senderID,"You are already subscirbed to: "+chatName+" \nYou can unsubscribe with -"+target.lower())
													self.driver.sendMessage(serviceChat,"subscirbed to: "+chatName)
												else:
													foundChat = None
											else:
												self.driver.sendMessage(senderID,"You are already subscirbed to:\n"+chatName+" \nYou can unsubscribe with -"+target.lower())
												self.driver.sendMessage(serviceChat,"subscirbed to: "+chatName)

										''' create new group '''
										if foundChat is None:
											groupName = service
											if service in self.serviceGroupNames:
												groupName = self.serviceGroupNames[service]

											newGroup = self.driver.newGroup(newGroupName = groupName, number = "+"+senderID.split("@")[0], local = runLocal)
											newGroupID = newGroup.id
											self.newG = newGroupID

											self.db["users"][chatID]['services'][service] = newGroupID
											self.db["groups"][newGroupID] = target
											dbChanged = True
											now = True
											print(
											'''
											===============================================
											 ''' + senderID +" is NOW SUBSCRIBED TO "+ target +" :D "+'''
											===============================================
											'''
											)

											self.driver.sendMessage(senderID,"Thank you! you are now subscribed to: "+chatName+" \nPlease check your new group :)")
											self.driver.sendMessage(newGroupID,welcome)
											# self.driver.sendMessage(serviceChat,"subscirbed to: "+target)

								if not serviceFound:
									self.driver.sendMessage(chatID,target+" : is not recognized as a service "+target)
									print(
									'''
									===============================================
									  SERVICE '''+ target +" IS NOT AVAILABLE"+'''
									===============================================
									'''
									)
								if dbChanged:
									self.backup(now=now)



						'''
						lastm = message
						print(json.dumps(message.get_js_obj(), indent=4))
						for contact in self.driver.get_contacts():
							# print("CCCC",contact.get_safe_name() )
							if  sender in contact.get_safe_name():
								chat = contact.get_chat()
								# chat.send_message("Hi "+sender+" !!!*"+message.content+"*")
						print()
						print()
						print(sender)
						print()
						print()
						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)
						print("sender", message.sender)
						print("sender.id", message.sender.id)
						print("sender.safe_name", message.sender.get_safe_name())
						if message.type == "chat":
							print("-- Chat")
							print("safe_content", message.safe_content)
							print("content", message.content)
							# Manager.process(message.sender.id,message.content)
							# contact.chat.send_message(message.safe_content)
						elif message.type == "image" or message.type == "video":
							print("-- Image or Video")
							print("filename", message.filename)
							print("size", message.size)
							print("mime", message.mime)
							print("caption", message.caption)
							print("client_url", message.client_url)
							message.save_media("./")
						else:
							print("-- Other type:",str(message.type))
						print("PROCESSING MESSAGE:",message)
						'''

			else:
				pass
			# except Exception as e:
			# 	print(" ::: ERROR - CHECKING MESSAGES ::: ","\n",e,e.args,"\n")

			loopc += 1; loopc = loopc % 120
			time.sleep(delay)

	def quit(self):
		self.driver.quit()

	def Nothing(data):
		print(":::Nothign::: DATA=",data)
Exemplo n.º 10
0
from webwhatsapi import WhatsAPIDriver

driver = WhatsAPIDriver(username="******")
print('get_unread: ',
      driver.get_unread(include_me=True, include_notifications=True))
print('get_contacts: ', driver.get_contacts())
# print('save_firefox_profile: ', driver.save_firefox_profile())
getChatFrom = driver.get_chat_from_phone_number(628999871008)
print('get_chat_from_phone_number: ', getChatFrom)
# print('get_all_messages_in_chat: ', driver.get_all_messages_in_chat(getChatFrom.id, include_me=True, include_notifications=True))
print(driver.get_qr())
print('get_all_chats: ', driver.get_all_chats())
print(driver.wait_for_login())
# print('get_safe_name', driver.get_safe_name())
print('get_unread: ', driver.get_unread())
# print('view_unread: ', driver.view_unread())
Exemplo n.º 11
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.º 12
0
class Whatsapp(threading.Thread):
    def __init__(self, identifier):
        self.driver = WhatsAPIDriver(loadstyles=True)
        self.identifier = identifier
        self.messagesSent = 0
        self.messageQueue = []
        self.status = {}
        
        print("Waiting for QR")
        try:
            self.driver.wait_for_login()
            super(Whatsapp, self).__init__()
            self.setDaemon(True)
        except Exception as ex:
            print("Error", ex)

        print("New Browser Opened")
        
    def get_chat(self, phone):
        try:
            chat = self.driver.get_chat_from_phone_number(phone)
        except ChatNotFoundError:
            url = self.driver._URL+"/send?phone="+phone
            self.driver.driver.get(url)
            t.sleep(5)
            chat = self.driver.get_chat_from_phone_number(phone)
        return chat

    # Give timeout_after_sent to avoid being suspected as a spammer.
    # Assign high value after multithreading is implemented.
    def send_whatsapp_message(self, phone, message, chat_id=None):
        try:
            if chat_id is None:
                chat = self.get_chat(phone)
                self.driver.chat_send_message(chat.id, message)
            else:
                self.driver.send_message_to_id(chat_id, message)

            self.messagesSent += 1
        except ChatNotFoundError:
            # This means the given number is invalid.
            Logger.warning("Invalid phone number: " + str(phone) + " will be deleted")
            c = Contact.objects.get(phone=phone)
            c.delete()
            raise ChatNotFoundError
        except Exception as e:
            # This means browser is still not available even after 5 seconds.
            # But the number is not invalid.(= valid)
            Logger.error(repr(e))
            raise e

    def send_message_and_save_log(self):
        messages = Message.objects.all().filter(use=True).filter(broadcast=True)
        for m in messages:
            logs = Log.objects.all().filter(message_id=m.id).filter(sent=True)
            contacts_already_sent = []
            for l in logs:
                contacts_already_sent.append(l.contact_id)
            contacts_to_send = Contact.objects.all().exclude(id__in=contacts_already_sent)

            if len(contacts_to_send) > 0:
                # Save the log first so that the same contact cannot be used in another browsers.
                for contact in contacts_to_send:
                    newLogs = Log.objects.filter(message_id=m.id).filter(contact_id=contact.id).get_or_create(message_id=m.id, contact_id=contact.id, sent=False, sender_id=self.identifier, broadcasted=True)
                    if len(newLogs) > 0:
                        l = newLogs[0]
                    
                    try:
                        print("Try to send message: [phone(", contact.id, ": ", contact.phone, "), text(", m.id, ": ", m.text, ")", sep="")
                        # If no exception, update 'sent', 'sent_at'
                        self.send_whatsapp_message(contact.phone, m.text)
                        l.sent = True
                        l.sent_at = now()
                        l.save(update_fields=['sent', 'sent_at'])
                        # The reason returning here is: once the message is sent to anyone of contacts,
                        # then server should bring available contacts again, not iterating over the given list.
                        # Otherwise, there is no way to control server immediately after insert new messages, contacts to DB.
                        return
                    except Exception as e:
                        Logger.warning(repr(e))
                        # Wait when error occurred so that browser can be opened again.
                        t.sleep(5)

    def poll_unread(self):
        try:
            if self.driver.is_logged_in():
                # Spam only works when this server is used as a spammer.
                if apps.WhatsappConfig.spammer == 'true':
                    try:
                        self.send_message_and_save_log()
                    except Exception as e:
                        Logger.error(repr(e))
                # Otherwise, this server will fetch unread messages and send webhook.
                else:
                    data = []
                    
                    try:
                        Logger.debug("(" + self.identifier + "): get_unread()")
                        for messageGroup in self.driver.get_unread():
                            unread_messages = []
                            for m in messageGroup.messages:
                                unread_messages.append({
                                    "content": m.content,
                                    "timestamp": "{timestamp}".format(timestamp=m.timestamp)
                                })
                            data.append({ "chatId": messageGroup.chat.id, "unreadMessages": unread_messages })
                    except Exception as e:
                        Logger.error(repr(e))

                    # Doesn't have to make a request when there is no unread message.
                    if len(data) > 0:
                        payload = {'data': data}
                        webhook_url = apps.WhatsappConfig.api_endpoint + '/no_auth/whatsapp/webhook'
                        try:
                            print("Request:", webhook_url)
                            r = requests.post(webhook_url, json=payload, timeout=3)
                            print("Response:", r.text)
                        except Exception as e:
                            print("Tokotalk API(" + webhook_url + ") doesn't respond in 3 second", sep='')

        except Exception as e:
            Logger.error(repr(e))

    def run(self):
        while True:
            try:
                self.poll_unread()
            except Exception as e:
                Logger.debug(repr(e) + ": POLL FAILED")
            
            # in case the interval is not set in .env
            interval = 5
            if apps.WhatsappConfig.message_interval is not None:
                interval = int(apps.WhatsappConfig.message_interval)
            t.sleep(interval)
Exemplo n.º 13
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.º 14
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)