-
-
Save kimseler14/1e0e2d4a6928264d86fb20296a264977 to your computer and use it in GitHub Desktop.
Class to read and write messages to Whatsapp through of the ADB. You need a android Device with Sqlite3 installed and ADB service.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment