tgalal / yowsup

The WhatsApp lib
GNU General Public License v3.0
7.06k stars 2.23k forks source link

Yowsup for Home Automation #647

Closed PierfrancescoElia closed 5 years ago

PierfrancescoElia commented 9 years ago

Hi, we will create a private secretary with YowSup.

Version 1.2

You need three files. http://pastebin.com/KbjPc7Tx <- run.py http://pastebin.com/aXza2W2B <- layer.py http://pastebin.com/KNhv8Kea <- whatsapp.sh

You need also a WhatsApp account! :smile:

Premise: my scripts are in /home/pi/domo/

Ok now You just create a directory where you put in run.py and layer.py.

You must edit run.py with your credentials and you must edit layer.py for allowed senders and the commands (question - answer).

whatsapp.sh care to keep the app always active.

Make start whatsapp.sh on startup.

Ok, now You are active!


Changelog:

V1.2: Script more flexible

V1.0: First stable and functional version.

Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

ghost commented 9 years ago

Hi, heres an example. I dont know how to poste code here

http://pastebin.com/XWicY72z If you created both files you can start this script with: python /path/to/file/run.py

Greetings, eXayte

PierfrancescoElia commented 9 years ago

Hi, tanks for your help. Your scripts don't work :( When I run the run.py script I receive:

root@raspberrypi:/home/pi/domo# python run.py Traceback (most recent call last): File "run.py", line 14, in EchoLayer, NameError: name 'EchoLayer' is not defined

I think you haven't include the layer.py but I'm not shure..... How can I fix? Thanks:)

PierfrancescoElia commented 9 years ago

Ok. I've corrected the scripts.

http://pastebin.com/02vEGkt7

Now it works fine. I would like to add more conditions (ex. Message= hi -> yowsup = hei!; message = how are you -> yowsup = Fine, thanks! ) and I would like to filter the number who send the message...

ghost commented 9 years ago

It's pretty easy.

http://pastebin.com/5Yvi1rKN

PierfrancescoElia commented 9 years ago

Hi, I've make my script with more response (ex. Message= hi -> yowsup = hei!; message = how are you -> yowsup = Fine, thanks! ).

Now, my problem is this: I would like to filter the message's sender. But senders allowed to interact with yowsup are more of one! I tryed this command:

if '391234567' or '3913243432' or '123123412242' in messageProtocolEntity.getFrom(): ... else: answer('You are not authorized.')

the script does not check whether the number actually is among those who have entered, the script allows everyone to interact with yowsup.

What should I do?

PS: sorry for my english but I'm italian :)

ghost commented 9 years ago

Hi. allowedPersons = ['491234567892', '431234567890', '1123456789'] ap = set(allowedPersons) if messageProtocolEntity.getFrom(False) in ap: print 'Authorized'

blackjack4494 commented 9 years ago

Hi, I came across an error but don't know how to fix it. I used the latest pastebin link from EliaComputers. But I am getting this:

No handlers could be found for logger "yowsup.stacks.yowstack" ^CTraceback (most recent call last): File "run.py", line 36, in stack.loop() File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.2.78-py2.7.egg/yowsup/stacks/yowstack.py", line 170, in loop asyncore.loop(_args, *_kwargs) File "/usr/lib/python2.7/asyncore.py", line 216, in loop poll_fun(timeout, map) File "/usr/lib/python2.7/asyncore.py", line 145, in poll r, w, e = select.select(r, w, e, timeout) KeyboardInterrupt

I also tried to add from yowsup.layers.logger import YowLoggerLayer and layers = ( ... YowLoggerLayer )

But it threw me another error back: ImportError: No module named layer.logger

ghost commented 9 years ago

I'm also getting this "error". Dont know how to fix this, but the app is just working, also with this error.

PierfrancescoElia commented 9 years ago

Hi, I'm also get the errors, but it works. Now I've got the last problem. :smile: This is an app that must run forever... For run the app at boot, I write the script whatsapp.sh:

!/bin/bash

sudo python /home/pi/domo/run.py

The script works but the app is stopped after a few minutes.... How can I fix??

Thanks and sorry for my english :laughing:

gautamMalu commented 9 years ago

@EliaComputers it will disconnect after some time, you can just put it into infinite loop in your bash script.

while true: do sudo python run.py done

fore more info checkout https://github.com/tgalal/yowsup/issues/648#

PierfrancescoElia commented 9 years ago

Thank you, it works!

Ok, now I post the scripts:

run.py: http://pastebin.com/KbjPc7Tx layer.py: http://pastebin.com/kSXNEehK whatsapp.sh: http://pastebin.com/sJ8nEJJ0

I will edit the first post, to make a 'guide' :) thanks to all!

PierfrancescoElia commented 9 years ago

Ok, now the scripts work fine, but I would like to control the 'online' and 'last access at xx.xx'.

Now while I message with the machine, it is online, but a few minutes later the last access isn't of a few second ago, but the last access is when i have launch the yowsup-cli and I've wrote /presence set available...

Sorry for my english, I'm italian :)

How can I fix?:)

ngalongc commented 9 years ago

Wow, thank you very much for your great secretary project. I am trying to use it to do my home-automation as well. And might turn into business as well. But I found I ran into a little problem when I do run.py in Version 1.2(First post) There is a del risposta in layer.py Also, I am thinking using a variable to store messageProtocolEntity.getBody() might be a easier solution, say message_body = messageProtocolEntity.getBody(), as we can then turn that variable to lower case by message_body.lower() then we can save a few lines in the script.

ngalongc commented 9 years ago

http://pastebin.com/48UP8UEd (layer.py) I have explore yowsup a little bit. After adding AvailablePresenceProtocolEntity, and UnavailablePresenceProtocolEntity and send to the lower layer, now antwort is pretending to be human, echo back message after 5 seconds of receival, and be online within 5 seconds, then echo back the message and send an unavailable presence to server.

One point to add is,

from yowsup.layers.protocol_presence import YowPresenceProtocolLayer

this line should be added to run.py in order to utilize presence function of whatsapp.

Kevke commented 9 years ago

Hi,

The Script above works great for me. But the Disconnect problem is still there. After a few minutes, the "yowsup" script receives no longer Messages from WhatsApp. Ive got the Bash "infinity" code, the run and layer, exactly same as yours @EliaComputers . Is there a way to solve my problem?

sr2ds commented 9 years ago

Hello, I am trying to record the numbers of users in a file but I can not, can you help me?

f = open ("user.txt", 'w') f.write ('User Number in Here \ n') f.close ()

You know in which variable is the user number?

edugargon commented 9 years ago

@srdavidsilva try this:

f = open("user.txt", 'a') #append mode f.writelines('User Number in Here'+'\n') f.close ()

gojigeje commented 9 years ago

same problem with @Kevke , using latest script provided on first post. initially worked fine (able to respond messages) but suddenly stopped working after few minutes, and the disconnect problem still exist. I tried to add these line to layer.py to output debug message

import logging
logging.basicConfig(level=logging.DEBUG)

and script outputs these line:

DEBUG:yowsup.stacks.yowstack:Initializing stack
DEBUG:yowsup.stacks.yowstack:Constructed Network Layer
DEBUG:yowsup.stacks.yowstack:Constructed Stanza Regulator Layer
DEBUG:yowsup.stacks.yowstack:Constructed Crypt Layer
DEBUG:yowsup.stacks.yowstack:Constructed Coder Layer
WARNING:yowsup.stacks.yowstack:Implicit declaration of parallel layers in a tuple is deprecated, pass a YowParallelLayer instead
DEBUG:yowsup.stacks.yowstack:Constructed Authentication Layer - Messages Layer - Receipt Layer - Ack Layer
DEBUG:yowsup.stacks.yowstack:Constructed Interface Layer
***script just paused here for 1 minute or so***
***then it disconnected***
DEBUG:yowsup.layers.network.layer:Disconnected, reason: Connection Closed
DEBUG:yowsup.layers.network.layer:Disconnected, reason: Connection Closed

Idk why, sometimes the script is just working fine, but a moment later its not working :confused:

PierfrancescoElia commented 9 years ago

Hi, I'm very very happy forma your attenction for my scripts :) OK, at the moment I'have also your problemi: the scripts stop working after a few minutes... I create a script wich upload the sender, a number (if sender is my number n=1 else n=0), the text, and the time to a MySQL table. I will upload this script tomorrow :).

Now I'm going to try @ngalongc 's script and I will edit the first post to the correct scripts.. @ngalongc 's scripts are useful but I can't wait 5 or 10 sec forma a response, because I would like to get an instantly reply..

OK now I do some experiments and I will update this post, stay tuned ;)

rafaelpstein commented 9 years ago

HI, i use your example and change for my system.

  1. I change to any image received i send to email and save in folder.

    def onMediaMessage(self, messageProtocolEntity): <------><------> <--><------>if messageProtocolEntity.getMediaType() == "image": <--><------> receipt = OutgoingReceiptProtocolEntity(messageProtocolEntity.getId(), messageProtocolEntity.getFrom()) outImage = ImageDownloadableMediaMessageProtocolEntity( <--><------><------>messageProtocolEntity.getMimeType(), messageProtocolEntity.fileHash, messageProtocolEntity.url, messageProtocolEntity.ip, <--><------><------>messageProtocolEntity.size, messageProtocolEntity.fileName, messageProtocolEntity.encoding, messageProtocolEntity.width,. <--><------><------>messageProtocolEntity.height, <--><------><------>messageProtocolEntity.getCaption(), <--><------><------>to = messageProtocolEntity.getFrom(), preview = messageProtocolEntity.getPreview()) <------><------> variavel="%s" % (messageProtocolEntity.url) <------><------> varrand=randint(0,13) <------><------> v1 = variavel.split("/",4) <------><------> v2 = v1[4].split(".") <------><------> now = datetime.now() <------><------> arquivo="%s"%(messageProtocolEntity.getFrom(False))+"-"+str(now.year)+str(now.month)+str(now.day)+str(now.hour)+str(now.minute)+ <------><------> str(now.second)+str(varrand)+"."+v2[1] <------><------> print arquivo <------><------> urllib.urlretrieve ("%s" % (messageProtocolEntity.url), "/home/"+arquivo)

<------><------>.... <------><------> msg = MIMEMultipart() <------><------> msg['Subject'] = 'Whatsapp - Sent by %s'% messageProtocolEntity.getFrom(False) <------><------> msg['From'] = 'xxx@xxx.com.br' <------><------> msg['To'] = 'xxx@xxx.com.br' <------><------>..... <------><------> # That is what u see if dont have an email reader: <------><------> msg.preamble = 'Multipart massage.\n' <------><------>...... <------><------> # This is the textual part: <------><------> part = MIMEText("Foto enviada pelo numero %s" % messageProtocolEntity.getFrom(False) ) <------><------> msg.attach(part) <------><------>....... <------><------> # This is the binary part(The Attachment): <------><------> part = MIMEApplication(open("/home/"+arquivo,"rb").read()) <------><------> part.add_header('Content-Disposition', 'attachment', filename=arquivo) <------><------> msg.attach(part) <------><------>........ <------><------> # Create an instance in SMTP server <------><------> smtp = SMTP("xxxxxx") <------><------> # Start the server: <------><------> # Send the email

work fine!!!

In other example i use postgres to permit number send message to system but not work. How i use array in python??

con = psycopg2.connect("dbname='whatsapp' user='xxxx' password='xxxx'") cur = con.cursor() cur.execute("SELECT celular FROM celular_liberados") row = cur.fetchall() allowedPersons=(row) ap = set(allowedPersons)

Rafiudo commented 9 years ago

Hello, I have a error:

pi@raspberrypi ~/domo $ python run.py DEBUG:yowsup.stacks.yowstack:Initializing stack DEBUG:yowsup.stacks.yowstack:Constructed Network Layer DEBUG:yowsup.stacks.yowstack:Constructed Stanza Regulator Layer DEBUG:yowsup.stacks.yowstack:Constructed Crypt Layer DEBUG:yowsup.stacks.yowstack:Constructed Coder Layer WARNING:yowsup.stacks.yowstack:Implicit declaration of parallel layers in a tuple is deprecated, pass a YowParallelLayer instead DEBUG:yowsup.stacks.yowstack:Constructed Authentication Layer - Messages Layer - Receipt Layer - Ack Layer DEBUG:yowsup.stacks.yowstack:Constructed Interface Layer Traceback (most recent call last): File "run.py", line 41, in stack.loop() File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.2.78-py2.7.egg/yowsup/stacks/yowstack.py", line 174, in loop asyncore.loop(_args, *_kwargs) File "/usr/lib/python2.7/asyncore.py", line 216, in loop poll_fun(timeout, map) File "/usr/lib/python2.7/asyncore.py", line 156, in poll read(obj) File "/usr/lib/python2.7/asyncore.py", line 87, in read obj.handle_error() File "/usr/lib/python2.7/asyncore.py", line 83, in read obj.handle_read_event() File "/usr/lib/python2.7/asyncore.py", line 449, in handle_read_event self.handle_read() File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.2.78-py2.7.egg/yowsup/layers/network/layer.py", line 73, in handle_read self.receive(data) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.2.78-py2.7.egg/yowsup/layers/network/layer.py", line 80, in receive self.toUpper(data) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.2.78-py2.7.egg/yowsup/layers/init.py", line 55, in toUpper self.upper.receive(data) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.2.78-py2.7.egg/yowsup/layers/stanzaregulator/layer.py", line 28, in receive self.processReceived() File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.2.78-py2.7.egg/yowsup/layers/stanzaregulator/layer.py", line 48, in processReceived self.toUpper(oneMessageData) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.2.78-py2.7.egg/yowsup/layers/__init.py", line 55, in toUpper self.upper.receive(data) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.2.78-py2.7.egg/yowsup/layers/auth/layer_crypt.py", line 63, in receive self.toUpper(payload) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.2.78-py2.7.egg/yowsup/layers/__init.py", line 55, in toUpper self.upper.receive(data) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.2.78-py2.7.egg/yowsup/layers/coder/layer.py", line 35, in receive self.toUpper(node) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.2.78-py2.7.egg/yowsup/layers/__init.py", line 55, in toUpper self.upper.receive(data) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.2.78-py2.7.egg/yowsup/layers/__init.py", line 160, in receive s.receive(data) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.2.78-py2.7.egg/yowsup/layers/init.py", line 101, in receive recv(node) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.2.78-py2.7.egg/yowsup/layers/protocol_receipts/layer.py", line 17, in recvReceiptNode self.toUpper(IncomingReceiptProtocolEntity.fromProtocolTreeNode(node)) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.2.78-py2.7.egg/yowsup/layers/init.py", line 55, in toUpper self.upper.receive(data) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.2.78-py2.7.egg/yowsup/layers/interface/interface.py", line 71, in receive self.callbacksentityType File "/home/pi/domo/layer.py", line 22, in onReceipt ack = OutgoingAckProtocolEntity(entity.getId(), "receipt", "delivery") TypeError: __init() takes exactly 5 arguments (4 given)

¿Why?

Thaks!!!!!!!!

tgalal commented 9 years ago

@Rafiudo see #770, and please don't post your problems under random issues

Systm21 commented 9 years ago

Hi Everyone, i have some Problems withe the Syript above:

sudo python /home/pi/domo/run.py

Traceback (most recent call last): File "/home/pi/domo/run.py", line 9, in from layer import EchoLayer File "/home/pi/domo/layer.py", line 59 antwort = 'You aren't a valid sender.' ^ SyntaxError: invalid syntax

Are there someone who have the same problem or can help me? :(

abhiramnarla commented 9 years ago

change antwort = 'You aren't a valid sender.' to "You aren't a valid sender."

hostman89 commented 9 years ago

I have a problem with app layer.py and run.py. this is my problem after 60 seconds :

DEBUG:yowsup.layers.logger.layer:rx:

DEBUG:yowsup.layers.network.layer:Disconnected, reason: Connection Closed DEBUG:yowsup.layers.network.layer:Disconnected, reason: Connection Closed anyone know any solution? I have tried many solutions and not work. Thank you very much and sorry for my English
abhiramnarla commented 9 years ago

Open the terminal, go to your project directory and enter this: bash whatsapp.sh

LeoSdls commented 8 years ago

Hi friend, I have this problem, how I can solve?

Traceback (most recent call last): File "build\bdist.win-amd64\egg\yowsup\stacks\yowstack.py", line 195, in loop asyncore.loop(_args, *_kwargs) File "C:\Python27\lib\asyncore.py", line 216, in loop poll_fun(timeout, map) File "C:\Python27\lib\asyncore.py", line 156, in poll read(obj) File "C:\Python27\lib\asyncore.py", line 87, in read obj.handle_error() File "C:\Python27\lib\asyncore.py", line 83, in read obj.handle_read_event() File "C:\Python27\lib\asyncore.py", line 444, in handle_read_event self.handle_read() File "build\bdist.win-amd64\egg\yowsup\layers\network\layer.py", line 86, in handle_read self.receive(data) File "build\bdist.win-amd64\egg\yowsup\layers\network\layer.py", line 94, in receive self.toUpper(data) File "build\bdist.win-amd64\egg\yowsup\layersinit.py", line 59, in toUpper self.upper.receive(data) File "build\bdist.win-amd64\egg\yowsup\layers\stanzaregulator\layer.py", line 28, in receive self.processReceived() File "build\bdist.win-amd64\egg\yowsup\layers\stanzaregulator\layer.py", line 51, in processReceived self.processReceived() File "build\bdist.win-amd64\egg\yowsup\layers\stanzaregulator\layer.py", line 48, in processReceived self.toUpper(oneMessageData) File "build\bdist.win-amd64\egg\yowsup\layers__init.py", line 59, in toUpper self.upper.receive(data) File "build\bdist.win-amd64\egg\yowsup\layers\auth\layer_crypt.py", line 63, in receive self.toUpper(payload) File "build\bdist.win-amd64\egg\yowsup\layers__init.py", line 59, in toUpper self.upper.receive(data) File "build\bdist.win-amd64\egg\yowsup\layers\coder\layer.py", line 35, in receive self.toUpper(node) File "build\bdist.win-amd64\egg\yowsup\layers__init.py", line 59, in toUpper self.upper.receive(data) File "build\bdist.win-amd64\egg\yowsup\layers__init.py", line 169, in receive s.receive(data) File "build\bdist.win-amd64\egg\yowsup\layersinit.py", line 105, in receive recv(node) File "build\bdist.win-amd64\egg\yowsup\layers\protocol_messages\layer.py", line 20, in recvMessageStanza entity = TextMessageProtocolEntity.fromProtocolTreeNode(node) File "build\bdist.win-amd64\egg\yowsup\layers\protocol_messages\protocolentities\message_text.py", line 38, in fromProtocolTreeNode entity.setBody(node.getChild("body").getData()) AttributeError: 'NoneType' object has no attribute 'getData'

utkarshamishra commented 8 years ago

hello, I'm new to python and have been trying to run run.py but keep receiving this error, can anyone help?

pi@raspberrypi:~/yowsup $ python run.py Traceback (most recent call last): File "run.py", line 9, in from layer import EchoLayer File "/home/pi/yowsup/layer.py", line 14, in class EchoLayer(YowInterfaceLayer):
File "/home/pi/yowsup/layer.py", line 29, in EchoLayer if messageProtocolEntity.getFrom(False) in ap: NameError: name 'messageProtocolEntity' is not defined

langioletto commented 8 years ago

I clean and perfected the .py

The scripts allow this

Connecting to WhatsApp WhatsApp listening Receive a message (case sensitive disable - THANKS @sowerkoku)) Check that the number of the sender is enabled, if it is not enabled sends bad message If the number is enabled it performs what is asked You can add functions, now I added a basic:

Hi Temperature Restart On GPIO14 Off GPIO14

I included all the features. (PRESENCE, THANKS @sowerkoku)

Set received (double v)

Set online

Set read (double v blue)

Set is writing

Set no is writing

Send the answer

Set offline

I tried to insert comments to understand what you are doing

Follow this thread

SKZ05 commented 8 years ago

i'm using these scripts for home automation project and everything worked fine, thanks for that! the only thing that i could't get to work is that i want pi to send me a certain message on whatsapp whenever this run.py is executed. P.S. i'm just a beginner so please go easy with the stuff for me. Cheers!

sowerkoku commented 8 years ago

try this:

#!/bin/bash

#This script performs a control check on the execution of Yowsup.

cd /path/yowsup/
nameprogram="python run.py"

#controls the execution
if [ "$(pidof $nameprogram)" ]; then
   echo "PID: $(pidof $nameprogram)"
   echo "$nameprogram in execution"
   kill -9 $(pidof $nameprogram)
   python yowsup-cli demos -c config.config -s PHONE "message send"
else
   echo "$nameprogram... down"
fi

exit 0
wnew commented 7 years ago

Hi guys this is great work, thank you.

I have managed to get these example running but an unable to send a message with out receiving one first. Can someone provide an example of how to send a message on an event not generated in yowsup?

Thanks

sowerkoku commented 7 years ago

@wnew

that already it is shown here with "subprocess"

or something like that with "commands"?

if messageProtocolEntity.getBody().lower() == 'ls':
    answer = commands.getoutput('ls')

add to head: import commands

wnew commented 7 years ago

Thanks @sowerkoku.

What I am trying to do is to monitor a raspberry pi gpio pin and if it goes high send a whatsapp message.

I am able to run a command when I receive a whatsapp message, as the examples you cited show. But not sure how to send a message on an event generated by yowsup something other than yowsup.

sowerkoku commented 7 years ago

@wnew Explain to me. Give me an example of what you want

sowerkoku commented 7 years ago

@wnew

I think the easiest way to do is create a script for that event monitoring. if the captured item is equal to what your looking for, you will have to send a message: yowsup-cli.

run.py focuses on interacting directly with whatsapp. question answer.

to automate sending this message yowsup-cli

ghost commented 7 years ago

@PierfrancescoElia AttributeError: module 'yowsup.env' has no attribute 'CURRENT_ENV' This is the error I am getting. I am using Pycharm by the way.