-
-
Save erickdsama/8b312635ca34770f69d08f58d65f69d1 to your computer and use it in GitHub Desktop.
| # coding=utf-8 | |
| import json | |
| import time | |
| from subprocess import check_output, CalledProcessError | |
| class WHO: | |
| FROM_ME = "key_from_me == 1" | |
| OTHERS = "key_from_me != 1" | |
| ALL = "" | |
| class TYPE: | |
| GPS = 1 | |
| IMAGE = 2 | |
| TEXT = 3 | |
| class COLUMN: | |
| _id = id = 0 | |
| key_remote_jid = 1 | |
| key_from_me = 2 | |
| key_id = 3 | |
| status = 4 | |
| needs_push = 5 | |
| data = message = 6 | |
| timestamp = 7 | |
| media_url = 8 | |
| media_mime_type = 9 | |
| media_wa_type = 10 | |
| media_size = 11 | |
| media_name = 12 | |
| media_caption = 13 | |
| media_hash = 14 | |
| media_duration = 15 | |
| origin = 16 | |
| latitude = 17 | |
| longitude = 18 | |
| thumb_image = 19 | |
| remote_resource = 20 | |
| received_timestamp = 21 | |
| send_timestamp = 22 | |
| receipt_server_timestamp = 23 | |
| receipt_device_timestamp = 24 | |
| read_device_timestamp = 25 | |
| played_device_timestamp = 26 | |
| raw_data = 27 | |
| recipient_count = 28 | |
| participant_hash = 29 | |
| starred = 30 | |
| quoted_row_id = 31 | |
| mentioned_jids = 32 | |
| multicast_id = 33 | |
| edit_version = 34 | |
| media_enc_hash = 35 | |
| payment_transaction_id = 36 | |
| class RWAS: | |
| """Rest WhatsApp Application Service | |
| Class to read and write messgaes directly to an android device [Sqlite3 is needed] | |
| Args: | |
| emulator (str): ID from your Android device, can be an Android phone or a Emulator with Sqlite3 installed. | |
| Note: | |
| if you only use one Device is not necesary pass the 'emulator' arg, It will be detected automatically | |
| """ | |
| def __init__(self, emulator=None): | |
| self.emulator = emulator | |
| def rwas_check_output(self, last_id=None, who=None): | |
| if last_id is None: | |
| query_str = " WHERE {}".format(who) if (who != WHO.ALL) else "" | |
| else: | |
| query_str = " AND {}".format(who) if (who != WHO.ALL) else "" | |
| query_str = "WHERE _id>{} {}".format(last_id, query_str) | |
| if self.emulator is None: | |
| return check_output( | |
| "adb shell 'sqlite3 /data/data/com.whatsapp/databases/msgstore.db \"select * from messages {};\"'".format(query_str), shell=True) | |
| else: | |
| return check_output( | |
| "adb -s {} shell 'sqlite3 /data/data/com.whatsapp/databases/msgstore.db \"select * from messages {};\"'".format(self.emulator, query_str), shell=True) | |
| def read(self, last_id=None, who=WHO.OTHERS): | |
| """ Method to read the messages from the database of whatsapp | |
| Args: | |
| last_id (int): The last _id that do u want | |
| who (WHO): Whos the message emitter | |
| Note: | |
| if you don't pass tha last_id param, returns all messages | |
| Returns: | |
| DATA if successful, None otherwise. | |
| """ | |
| try: | |
| return self.DATA(self.rwas_check_output(last_id=last_id, who=who)) | |
| except CalledProcessError as e: | |
| return None | |
| def send(self, message=None, location=None, remote_jid=None): | |
| build_message = self.BuildMessage(message=message, location=None, remote_jid=remote_jid) | |
| print build_message.chat_string | |
| try: | |
| print check_output("adb shell pkill com.whatsapp", shell=True) | |
| print check_output("adb shell chmod 777 /data/data/com.whatsapp/databases/msgstore.db", shell=True) | |
| print check_output(build_message.chat_string, shell=True) | |
| print check_output(build_message.list_string, shell=True) | |
| print check_output(build_message.update_string, shell=True) | |
| print check_output("adb shell am start -n com.whatsapp/.Main", shell=True) | |
| except CalledProcessError as e: | |
| print e | |
| class DATA: | |
| def __init__(self, dumped=None): | |
| self.dumped = dumped | |
| def parse_to_array(self): | |
| fields = [] | |
| rows = self.dumped.split("|\r\n") | |
| del rows[-1] | |
| for row in rows: | |
| elements = row.split("|") | |
| fields.append(elements) | |
| return fields | |
| def parse_to_dict(self): | |
| array = self.parse_to_array() | |
| messages = [] | |
| for row in array: | |
| data = { | |
| "_id": row[COLUMN.id], | |
| "message": row[COLUMN.message], | |
| "latitude": row[COLUMN.latitude], | |
| "longitude": row[COLUMN.longitude], | |
| "med_du": row[COLUMN.media_duration], | |
| "key_remote_jid": row[COLUMN.key_remote_jid], | |
| } | |
| messages.append(data) | |
| data = { | |
| "messages": messages | |
| } | |
| return data | |
| def parse_to_json(self): | |
| """ Convert the data to JSON object | |
| Returns: | |
| A Json object of the data fetched | |
| """ | |
| return json.dumps(self.parse_to_dict(), ensure_ascii=False) | |
| class BuildMessage: | |
| def __init__(self, message=None, location=None, remote_jid=None): | |
| self.location = location | |
| self.message = message | |
| self.remote_jid = remote_jid | |
| @property | |
| def chat_string(self): | |
| """str: Chat string query to insert """ | |
| l1 = int(round(time.time() * 1000)) | |
| l2 = int(l1 / 1000) | |
| k = "-1150867590" | |
| return """adb shell "sqlite3 /data/data/com.whatsapp/databases/msgstore.db \\"INSERT INTO messages (key_remote_jid, key_from_me, key_id, status, needs_push, data, timestamp, MEDIA_URL, media_mime_type, media_wa_type, MEDIA_SIZE, media_name , latitude, longitude, thumb_image, remote_resource, received_timestamp, send_timestamp, receipt_server_timestamp, receipt_device_timestamp, raw_data, media_hash, recipient_count, media_duration, origin) VALUES ('{}', 1,'{}-{}', 0,0, '{}',{},'','', 0, 0,'', 0.0,0.0,'','',{}, -1, -1, -1,0 ,'',0,0,0);\\"" | |
| """.format(self.remote_jid, l2, k, self.message, l1, l1) | |
| @property | |
| def list_string(self): | |
| """str: List chat query to insert """ | |
| return """ adb shell "sqlite3 /data/data/com.whatsapp/databases/msgstore.db \\"insert into chat_list (key_remote_jid) select '{0}' where not exists (select 1 from chat_list where key_remote_jid='{0}');\\"" """.format( | |
| self.remote_jid) | |
| @property | |
| def update_string(self): | |
| """str: List chat query to update based on list insert """ | |
| return """ adb shell "sqlite3 /data/data/com.whatsapp/databases/msgstore.db \\"update chat_list set message_table_id = (select max(messages._id) from messages) where chat_list.key_remote_jid='{}';\\"" """.format( | |
| self.remote_jid) |
I have modified this script, currently its working fine with python3.
contact me on skype: suraj.prasad1990
should I modify WhatsApp message using this script. if you any idea then please help me +919034132449
Hi Erick
Thank you for your script. Awesome!
Saidly I get the following error when I run rwas.py with the following lines inside rwas.py.
rwas_service = RWAS(emulator=None) # class call
rwas_service.read(last_id=None).parse_to_json() # to read all on and parse to json
rwas_service.send(message="Hello world from mexico", remote_jid="[email protected]") # to send change the remote_jid
Any idea why it doesnt work?
ERROR
thomas$ python3 rwas.py
Traceback (most recent call last):
File "/Users/thomas/rwas.py", line 190, in
rwas_service.read(last_id=None).parse_to_json() # to read all on and parse to json
File "/Users/thomas/rwas.py", line 157, in parse_to_json
return json.dumps(self.parse_to_dict(), ensure_ascii=False)
File "/Users/thomas/rwas.py", line 135, in parse_to_dict
array = self.parse_to_array()
File "/Users/thomas/rwas.py", line 127, in parse_to_array
rows = self.dumped.split("|\r\n")
TypeError: a bytes-like object is required, not 'str'
Hi Erick
Could it be that your script doesnt work anymore with the a new version of whatsapp? Which version have you used, when your script still worked. Do you remember?
Brigado!
This happens when I call the send.message function.
b''
b''
b'Error: no such table: messages\r\n'
b'Error: no such table: chat_list\r\n'
b'Error: no such table: chat_list\r\n'
b'Starting: Intent { cmp=com.whatsapp/.Main }\r\n'
seems like the database of whatsapp has changed.
for sending messages you can use api.whatsapp.com
f'am start -a android.intent.action.VIEW -d "https://api.whatsapp.com/send?phone={number}&text={text}"'