-
-
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) |
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}"'
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.
now it can send messages, but very slowly, 40-60 seconds per 1 msg)
erickdsama, can you send to me your contacts or telegram please?)
if you have a time to conversations, sometimes
my mail is [email protected]