-
-
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) |
Hello I'm new to programming, I'm emulating anbox with whatsapp on ubuntu and I would like to run your application, but I have no idea how to do it, I access the normal adb shell, and this is the only device on my machine that emulates android, and now what do i need to do? I tried to run it on my host machine:
python -c rwas.py
But nothing happens
Sorry but it is saying
/system/bin/sh: sqlite3: not found
Help me...
Does it require the device to be rooted??
I have the same issue. Please help.
Wonderful, this is more than I expected.
Is there any way to send an image using this method?
Does it require the device to be rooted??
you can use Genymotion. and install GAPPS, if you want to use a phisical device you need to rooted and install busybox
Sorry but it is saying
/system/bin/sh: sqlite3: not found
Help me...
busybox can help you with that
I have the same issue. Please help.
hi you can install busybox
Erick logró que funcionara, ahora el problema es, ¿cómo veo los mensajes? Seguí tu ejemplo de Python, pero como no sé mucho sobre Python, ¿puedes hacer algunos ejemplos de leer el mensaje por usuario o por mensajes nuevos?
Hi, cool class, but it works for me only if i try to send the message to user, who sent any message to me before.
If a chat list on device is empty, script only inserts in database, then it starts app, but do not send the message))
Do you have any idea how to fix it?)
Can you tell us how to use it?
Hi, cool class, but it works for me only if i try to send the message to user, who sent any message to me before.
If a chat list on device is empty, script only inserts in database, then it starts app, but do not send the message))
Do you have any idea how to fix it?)
Hi, thanks. before nothing, sorry for my bad english. That's maybe a error in the insert of list
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)
let me fix this weekend and update the class
how ever i have an library in pip, you can install and use it.
Can you tell us how to use it?
Hi, first you need genymotion with Whatsapp installed, once you have installed it. use the file like ihe example in above
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
Can you tell us how to use it?
Hi, first you need genymotion with Whatsapp installed, once you have installed it. use the file like ihe example in above
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
thank you very much for answering me. i wonder how can manually send command from adb? can u help me
example, i got error always:
└──╼ $adb shell 'sqlite3 /data/data/com.whatsapp/databases/msgstore.db "select * from messages;"'
sqlite3: Error: too many options: "acct"
Use -help for a list of options.
/system/bin/sh: ": not found
edit: i solve like this
import os
os.system('adb shell "su -c 'sqlite3 /data/data/com.whatsapp/databases/msgstore.db \"select * from messages\"'"')
but i can't modify insert string, i can't handle exception("\") in string. can u help me for insert method
l1 = int(round(time.time() * 1000))
l2 = int(l1 / 1000)
k = "-1150867590"
jid = "[email protected]"
message = "test"
os.system('adb shell "su -c 'sqlite3 /data/data/com.whatsapp/databases/msgstore.db \"INSERT INTO messages (key_remot........... "'"')
edit2:
i test insert witout timestamp but i got error :
Error: near "@s": syntax error
└──╼ $adb shell "su -c '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 ('[email protected]', 1,'1599942971--1150867590', 0,0, 'Hello world from mexico',1599942971860,'','', 0, 0,'', 0.0,0.0,'','',1599942971860, -1, -1, -1,0 ,'',0,0,0)"'"
Error: near "@s": syntax error
after insert in chat_list it is not visible, i think it is a problem, do you have a good query for inserting?)
if i run script several times, then writing message via wa.me, it sends all messages from script, which i send before from script)
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]
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.
if you want to use the Class you only need call it of this way.
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