tgalal / yowsup

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

Send presence #1648

Closed langioletto closed 5 years ago

langioletto commented 8 years ago

Hello tagal, can I ask you a few examples to send the presence before the answer

taking as example /yowsup/demos/echoclient

receive the message (it's already present) active presence responds (it's already present) deactivates the presence

Thanks for your project, I donated.

from yowsup.layers.interface                           import YowInterfaceLayer, ProtocolEntityCallback

class EchoLayer(YowInterfaceLayer):

    @ProtocolEntityCallback("message")
    def onMessage(self, messageProtocolEntity):

        if messageProtocolEntity.getType() == 'text':
            self.onTextMessage(messageProtocolEntity)
        elif messageProtocolEntity.getType() == 'media':
            self.onMediaMessage(messageProtocolEntity)

        self.toLower(messageProtocolEntity.forward(messageProtocolEntity.getFrom()))
        self.toLower(messageProtocolEntity.ack())
        self.toLower(messageProtocolEntity.ack(True))

    @ProtocolEntityCallback("receipt")
    def onReceipt(self, entity):
        self.toLower(entity.ack())

    def onTextMessage(self,messageProtocolEntity):
        # just print info
        print("Echoing %s to %s" % (messageProtocolEntity.getBody(), messageProtocolEntity.getFrom(False)))

    def onMediaMessage(self, messageProtocolEntity):
        # just print info
        if messageProtocolEntity.getMediaType() == "image":
            print("Echoing image %s to %s" % (messageProtocolEntity.url, messageProtocolEntity.getFrom(False)))

        elif messageProtocolEntity.getMediaType() == "location":
            print("Echoing location (%s, %s) to %s" % (messageProtocolEntity.getLatitude(), messageProtocolEntity.getLongitude(), messageProtocolEntity.getFrom(False)))

        elif messageProtocolEntity.getMediaType() == "vcard":
            print("Echoing vcard (%s, %s) to %s" % (messageProtocolEntity.getName(), messageProtocolEntity.getCardData(), messageProtocolEntity.getFrom(False)))

run.py

from yowsup.stacks                             import YowStackBuilder
from yowsup.layers.protocol_messages           import YowMessagesProtocolLayer
from yowsup.layers.stanzaregulator             import YowStanzaRegulator
from yowsup.layers.protocol_receipts           import YowReceiptProtocolLayer
from yowsup.layers.protocol_acks               import YowAckProtocolLayer
from yowsup.stacks                             import YowStack
from yowsup.common                             import YowConstants
from yowsup.layers                             import YowLayerEvent
from yowsup                                    import env
from layer                                     import EchoLayer
from yowsup.layers.auth                        import YowCryptLayer, YowAuthenticationProtocolLayer, AuthError
from yowsup.layers.coder                       import YowCoderLayer
from yowsup.layers.network                     import YowNetworkLayer
from yowsup.layers.protocol_messages           import YowMessagesProtocolLayer
from yowsup.layers.stanzaregulator             import YowStanzaRegulator
from yowsup.layers.protocol_presence           import YowPresenceProtocolLayer
from yowsup.env                                import YowsupEnv

#Deccomentare per log
#import logging
#logging.basicConfig(level=logging.DEBUG)

CREDENTIALS = ("**************************", "**************************") #replace with your phone and password

if __name__==  "__main__":
    stackBuilder = YowStackBuilder()

    stack = stackBuilder\
        .pushDefaultLayers(True)\
        .push(EchoLayer)\
        .build()

    stack.setProp(YowAuthenticationProtocolLayer.PROP_CREDENTIALS, CREDENTIALS)       #setting credentials
    stack.broadcastEvent(YowLayerEvent(YowNetworkLayer.EVENT_STATE_CONNECT))          #sending the connect signal
    stack.setProp(YowNetworkLayer.PROP_ENDPOINT, YowConstants.ENDPOINTS[0])           #whatsapp server address
    stack.setProp(YowCoderLayer.PROP_DOMAIN, YowConstants.DOMAIN)
    stack.setProp(YowCoderLayer.PROP_RESOURCE, YowsupEnv.getCurrent().getResource())  #info about us as WhatsApp client

    stack.loop( timeout = 0.5, discrete = 0.5 )                                       #this is the program mainloop
sowerkoku commented 8 years ago

@langioletto very easy: self.toLower(AvailablePresenceProtocolEntity())

example:

self.toLower(messageProtocolEntity.ack())
self.toLower(AvailablePresenceProtocolEntity())
self.toLower(messageProtocolEntity.ack(True))
self.toLower(OutgoingChatstateProtocolEntity(OutgoingChatstateProtocolEntity.STATE_TYPING, Jid.normalize(messageProtocolEntity.getFrom(False)) ))
self.toLower(OutgoingChatstateProtocolEntity(OutgoingChatstateProtocolEntity.STATE_PAUSED, Jid.normalize(messageProtocolEntity.getFrom(False)) ))
self.toLower(messageProtocolEntity.forward(messageProtocolEntity.getFrom()))
self.toLower(UnavailablePresenceProtocolEntity())
langioletto commented 8 years ago

Very thanks, perfect!!

You're very kind..

Another question, how can I do to disable the case sensitive in the body of an incoming message?

Example: lower

sowerkoku commented 8 years ago

@langioletto I do not quite understand the question. my English is not good.

langioletto commented 8 years ago

Italiano

Molte grazie, perfetto!! Tu sei molto gentile

Un'altra domanda, come posso fare per disattivare il case sensitive nel body di un messaggio che mando io e che riceve yowsup?

Esempio: lower

Generalmente uso questo comando: msg.text:lower, ma in py é diverso.

Deutsch:

Viel Dank, perfekt !! Sie sind sehr freundlich .. Eine andere Frage, wie kann ich tun, um die Groß- und Kleinschreibung in den Körper einer Nachricht zu deaktivieren, die ich das Senden und Empfangen yowsup?

Beispiel: Unter

Normalerweise verwenden Sie diesen Befehl: msg.text:lower, aber py ist anders.

sowerkoku commented 8 years ago

sorry, I speak Spanish. I understand all that. but the question can not understand.

how can I do to disable the case sensitive in the body of an incoming message?

writing this, I begin to understand. you have problems with case sensitive?

hola != Hola != HOLA !=hOLA

tell me what you need to do and help

sowerkoku commented 8 years ago

cadena = "Hola Mundo" print cadena.lower() hola mundo

cadena = "Hola Mundo" print cadena.upper() HOLA MUNDO

according to your example:

msg = messageProtocolEntity.getBody().lower()
                if messageProtocolEntity.getFrom(False) in ap:
                        if  'hi' in msg:  #you can type: "hi, how are you?"
                                antwort = 'Hello!'
                        elif 'temperature' == msg:  #only allows "temperature" and not "which is the temperature?"
                                 t=float(subprocess.check_output(["/opt/vc/bin/vcgencmd measure_temp | cut -c6-9"], shell=True)[:-1])
                                 ts=str(t)
                                 antwort = 'My temperature is  '+ts+' °C.'
---

or

msg = messageProtocolEntity.getBody()
                if messageProtocolEntity.getFrom(False) in ap:
                        if msg in ["Hi","hi","hI","HI"]:
                                antwort = 'Hello!'
                        elif msg in ["Temperature","temperature","TEMPERATURE","tEMPERATURE"]:
                                 t=float(subprocess.check_output(["/opt/vc/bin/vcgencmd measure_temp | cut -c6-9"], shell=True)[:-1])
                                 ts=str(t)
                                 antwort = 'My temperature is  '+ts+' °C.'
---
langioletto commented 8 years ago

Yes

line of the layer.py

namemitt = messageProtocolEntity.getNotify() message = messageProtocolEntity.getBody() recipient = messageProtocolEntity.getFrom() textmsg = TextMessageProtocolEntity

        if message == 'Hola':
            answer = "Hola"+namemitt+" " 
            self.toLower(textmsg(answer, to = recipient ))

        else:
            answer = "Sorry"+namemitt+", I do not understand" 
            self.toLower(textmsg(answer, to = recipient))
            print answer

If I write Hola he answers Hola

If I write hola he answers Sorry......

I thought about it, but it does not work

        if message.lower() == 'Hola':
            answer = "Hola"+namemitt+" " 
            self.toLower(textmsg(answer, to = recipient ))
sowerkoku commented 8 years ago

this works perfect:

# -*- coding: iso-8859-15
import sys

msg1 = sys.argv[1].upper()
msg2 = sys.argv[1].lower()

print msg1
print msg2

your mistake here is the string:

hola != Hola

        if message.lower() == 'hola':
            answer = "Hola"+namemitt+" " 
            self.toLower(textmsg(answer, to = recipient ))
langioletto commented 8 years ago

Perfect!!!

This work very well

Send HOLA hola Hola, always it works

message = messageProtocolEntity.getBody().lower()

   if message == 'hola':
        answer = "Hola"+namemitt+" " 
        self.toLower(textmsg(answer, to = recipient ))

Very very thanks!!

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 name presence

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

v01 Frist release v02 Corrected Unavailable Presence in the event of a reboot command v03 Add Name presence (THANKS @sowerkoku) v04 Added log unauthorized phone number Is logged: Sender, Number sender, Message text received v05 Add correction if you receive an audio file and yowsup crashes (THANKS @jlguardi) Add to send pictures (THANKS @sowerkoku) Add the management of received images (THANKS @sowerkoku) Add the image save (beta) (THANKS @sowerkoku) v06 Add to send geolocation v07 Little bug fix v08 Ok the image save (enc) "Now works" (THANKS @sowerkoku) v09 Add automatic reconnection (THANKS @shekar3110a) Add the ability to send messages directly from the browser via the address bar, read the readme inside the zip file (THANKS @shekar3110a) v10 Code optimization Add the ability to send image directly from the browser via the address bar, read the readme inside the zip file (THANKS @langioletto) Add the ability to run scripts directly from the browser via the address bar, read the readme inside the zip file (THANKS @langioletto)

#Download HERE v04#

#Download HERE v05#

#Download HERE v06#

#Download HERE v07#

#Download HERE v08#

#Download HERE v09#

#Download HERE v10#

langioletto commented 8 years ago

Since you're very good :+1: :100:

if when I send the answer you wanted to send a sound file instead of a text

example

  if message == 'hola':
        answer = "Hola"+namemitt+" " 
        self.toLower(textmsg(answer, to = recipient ))
        /audio         send           <number> <path>               Send audio file

I'd also like to know how to send the presence of the name :)

self.toLower(AvailablePresenceProtocolEntity())
/presence      name           <name>                        Set presence name
sowerkoku commented 8 years ago

@langioletto

the presence is simple, but to send sound files is somewhat more complex. I do not have a PC near , even within 2hrs .

from yowsup.layers.protocol_presence.protocolentities import PresenceProtocolEntity

/presence      name           <name>

name = "string"
self.toLower(PresenceProtocolEntity(name = name))
or 
self.toLower(PresenceProtocolEntity(name = "string"))
langioletto commented 8 years ago

Thanks, do not worry!!

I added the string

¿Cómo se define el nombre? :)

pasar un buen descanso :+1:

File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/interface/interface.py", line 80, in receive self.entity_callbacks[entityType](entity) File "/root/.yowsup/layer.py", line 43, in onMessage self.toLower(PresenceProtocolEntity(name = name)) NameError: global name 'name' is not defined

sowerkoku commented 8 years ago

send an audio file I can not even.

1656

langioletto commented 8 years ago

Ok, @sowerkoku I am reading "layer.py" in /usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/demos/cli/

And I begin to understand, thank you.

You think I should I send other things in a message?

Set received (double v)

Set name presence

Set available presence

Set read (double v blue)

Set is writing

Set no is writing

Send the answer

Set unavailable presence

ib "CleanIqProtocolEntity" ??

Unsubscribe Presence or Subscribe Presence?? This is to hide the presence from contacts "privacy?

Very thanks

sowerkoku commented 8 years ago

set Name presence -> I occupied only once to name

Available #set presence -> I use it after every #set received (double v)

I do not understand the question, but I will answer.

ib "CleanIqProtocolEntity" ??

this should clear the conversation: (I'm not entirely sure) self.toLower(CleanIqProtocolEntity("groups", YowConstants.DOMAIN))

"Presence Unsubscribe" or "Presence Subscribe" ?? ok: Unsubscribe Presence: I "available presence" above. I am for all numbers online. then active "Presence Unsubscribe (number)". then only this number see me offline.

Subscribe Presence: this makes contact only see me online

langioletto commented 8 years ago

Ok, perfect!! :+1:

langioletto commented 8 years ago

@sowerkoku

Do you think that you can send a message from cmd sending also presence of the name?

Changing the py off yowsup but I do not know what to change

python yowsup-cli demos -c /root/.yowsup/config -s 441234567890 "Hola"

It must be added the presence name that now is not sent

Very thanks!!

langioletto commented 8 years ago

Done, I have changed the "layer.py" in /usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/demos/sendclient

I add:

from yowsup.layers.protocol_presence.protocolentities import PresenceProtocolEntity #Name presence

name = "MyName"

and modified this by so

@ProtocolEntityCallback("success")
def onSuccess(self, successProtocolEntity):
    self.lock.acquire()
    for target in self.getProp(self.__class__.PROP_MESSAGES, []):
        #getProp() is trying to retreive the list of (jid, message) tuples, if none exist, use the default []
        phone, message = target
        messageEntity = TextMessageProtocolEntity(message, to = Jid.normalize(phone))
        #append the id of message to ackQueue list
        #which the id of message will be deleted when ack is received.
        self.ackQueue.append(messageEntity.getId())
        self.toLower(messageEntity)
    self.lock.release()

To

@ProtocolEntityCallback("success")
def onSuccess(self, successProtocolEntity):
    self.lock.acquire()
    for target in self.getProp(self.__class__.PROP_MESSAGES, []):
        #getProp() is trying to retreive the list of (jid, message) tuples, if none exist, use the default []
        phone, message = target
        messageEntity = TextMessageProtocolEntity(message, to = Jid.normalize(phone))
        self.toLower(PresenceProtocolEntity(name = name))
        #append the id of message to ackQueue list
        #which the id of message will be deleted when ack is received.
        self.ackQueue.append(messageEntity.getId())
        self.toLower(messageEntity)
    self.lock.release()

self.toLower(PresenceProtocolEntity(name = name))

But it would be nice to change yowsup-cli to send the name via command line ex:

python yowsup-cli demos -c /root/.yowsup/config -s 441234567890 "Hola" -n "MyName"

sowerkoku commented 8 years ago

@langioletto ok, having a time'll see some modification to cli. ;)

jlguardi commented 8 years ago

I think that send client is ok with current implementation. Nick name is just a "configuration" of the account and shouldn't be modified on each message. Do you agree?

langioletto commented 8 years ago

@sowerkoku @jlguardi

My change is too rough, the Nickname is how the subject at first glance when you receive a message

python yowsup-cli demos -c /root/.yowsup/config -s 441234567890 "Hola" -n "My Love"

python yowsup-cli demos -c /root/.yowsup/config -s 441234567890 "Hola" -n "My friend"

python yowsup-cli demos -c /root/.yowsup/config -s 441234567890 "Hola" -n "Happy birthday"

ecc ecc..

It 'very convenient if you use the command line, so the change is much more flexible

But the parameter would not put obligatory

python yowsup-cli demos -c /root/.yowsup/config -s 441234567890 "Hola" or python yowsup-cli demos -c /root/.yowsup/config -s 441234567890 "Hola" -n "My Love"

os and you prefer you can add fixed in the config file

cc=44 #if not specified it will be autodetected name=MyName #if not specified It is not sent phone=xxxxxxxxxxxxxxxxxxxxxxx password=xxxxxxxxxxxxxxxxxxxxxxx

Really thank you for your interest :+1: :100:

sowerkoku commented 8 years ago

@jlguardi is true, but what makes @langioletto is a personal script. It does not seek to modify the master of "yowsup".

I think it would be more useful an amendment to cli to send audio or video image. what has already been done in a particular way by a few. but it is not really important. there are many out here who have created bots, and more than one similar to that of "@langioletto" for its simplicity.

@jlguardi without going too far, I myself have my own modifications to cli or yowsup code. well as you brought your own branch. yowsup helps many people, and that makes me happy ;)

the work of @langioletto directly benefits those who are not able to create their own bot.

jlguardi commented 8 years ago

@sowerkoku I'm so sorry if didn't explained well. I wanted to say that I think that it isn't a good feature for send cli in master. Obviously every on can propose improvements/features or fork the project. I was just sa my opinion and also showin th risk of change the nickname too many times. Anyway, I think this kind of issues helps to users and developers to improve the project.

langioletto commented 8 years ago

Another question for you experts

I added a filter to number

allowedPersons=['xxxxxxxxxxxxx','xxxxxxxxxxxxx'] #Filter the senders numbers ap = set(allowedPersons)

    if messageProtocolEntity.getFrom(False) in ap:

    else:
        answer = "Salve "+namemitt+", mi dispiace, non vorrei essere scortese, ma adesso non posso chattare con te."

If I instead want to do the opposite,

denyPersons=['xxxxxxxxxxxxx','xxxxxxxxxxxxx'] #Filter the senders numbers denyp = set(denyPersons)

    if messageProtocolEntity.getFrom(False) in denyp:

How do I change the if messageProtocolEntity.getFrom(False) in denyp: , so why not work

Very thanks!!

sowerkoku commented 8 years ago

That should work fine, except for the "," at the end of the list or trupa

@langioletto, one more thing. I'm no expert. I'm here to help if I can.

langioletto commented 8 years ago

He apologizes, copy and paste error.

This works with numbers inside allowedPersons

But I want the opposite

Denying the numbers in that list "denyPersons"

if messageProtocolEntity.getFrom(False) in denyp:

This should be changed, so it is not sufficient to deny

sowerkoku commented 8 years ago

you can not deny that a number send a message . but can a message or other action

if num in denyp:
 send "unautorized"
else:
 all

or

if num not in denyp:
    all
else:
    send "unautorized"

or

if num not in denyp:
    all
else:
    self.toLower(messageProtocolEntity.ack())
    self.toLower(messageProtocolEntity.ack(True))
Kaoala commented 8 years ago

Hello,

I tried to use your code with a group chat. But it crash the programm.

But the answer wich the programm wants to send is written in the terminal. After that message it crashed.

Traceback (most recent call last): File "run.py", line 30, in stack.loop( timeout = 0.5, discrete = 0.5 ) #this is the program mainloop File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/stacks/yowstack.py", line 188, 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.5.0-py2.7.egg/yowsup/layers/network/layer.py", line 102, in handle_read self.receive(data) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/network/layer.py", line 110, in receive self.toUpper(data) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/init.py", line 76, in toUpper self.upper.receive(data) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/stanzaregulator/layer.py", line 29, in receive self.processReceived() File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/stanzaregulator/layer.py", line 49, in processReceived self.toUpper(oneMessageData) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/__init.py", line 76, in toUpper self.upper.receive(data) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/auth/layer_crypt.py", line 65, in receive self.toUpper(payload) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/__init.py", line 76, in toUpper self.upper.receive(data) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-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.5.0-py2.7.egg/yowsup/layers/__init.py", line 76, in toUpper self.upper.receive(data) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/logger/layer.py", line 14, in receive self.toUpper(data) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/__init.py", line 76, in toUpper self.upper.receive(data) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/axolotl/layer_control.py", line 44, in receive self.toUpper(protocolTreeNode) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/__init.py", line 76, in toUpper self.upper.receive(data) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/__init.py", line 189, in receive s.receive(data) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/axolotl/layer_send.py", line 64, in receive if not self.processIqRegistry(protocolTreeNode): File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/init.py", line 156, in processIqRegistry successClbk(protocolTreeNode, originalIq) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/axolotl/layer_send.py", line 215, in sendToGroup jids.remove(ownJid) ValueError: list.remove(x): x not in list

It worked fine when I used the demo client to send a message to the group. Did i have to add something?

sowerkoku commented 8 years ago

Hello @Kaoala.

ValueError: list.remove(x): x not in list --> the participant of group fails

if messageProtocolEntity.getFrom(False) in ap: --> this does not work for groups

modifies the line with this:

---
sender = messageProtocolEntity.getFrom(False) if not messageProtocolEntity.isGroupMessage() else messageProtocolEntity.getParticipant(False)
if sender in ap:
---

and add: from yowsup.layers.auth import YowAuthenticationProtocolLayer

Kaoala commented 8 years ago

Hello @sowerkoku Thank you for your answer. Is here a formating error? I modified the code: if messageProtocolEntity.getFrom(False) in ap: to the following: sender = messageProtocolEntity.getFrom(False) if not messageProtocolEntity.isGroupMessage() else messageProtocolEntity.getParticipant(False) (Everything in one row?) if sender in ap:

But I gote the same error:

Traceback (most recent call last): File "run.py", line 30, in stack.loop( timeout = 0.5, discrete = 0.5 ) #this is the program mainloop File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/stacks/yowstack.py", line 188, 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.5.0-py2.7.egg/yowsup/layers/network/layer.py", line 102, in handle_read self.receive(data) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/network/layer.py", line 110, in receive self.toUpper(data) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/init.py", line 76, in toUpper self.upper.receive(data) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/stanzaregulator/layer.py", line 29, in receive self.processReceived() File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/stanzaregulator/layer.py", line 49, in processReceived self.toUpper(oneMessageData) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/__init.py", line 76, in toUpper self.upper.receive(data) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/auth/layer_crypt.py", line 65, in receive self.toUpper(payload) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/__init.py", line 76, in toUpper self.upper.receive(data) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-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.5.0-py2.7.egg/yowsup/layers/__init.py", line 76, in toUpper self.upper.receive(data) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/logger/layer.py", line 14, in receive self.toUpper(data) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/__init.py", line 76, in toUpper self.upper.receive(data) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/axolotl/layer_control.py", line 44, in receive self.toUpper(protocolTreeNode) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/__init.py", line 76, in toUpper self.upper.receive(data) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/__init.py", line 189, in receive s.receive(data) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/axolotl/layer_send.py", line 64, in receive if not self.processIqRegistry(protocolTreeNode): File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/init.py", line 156, in processIqRegistry successClbk(protocolTreeNode, originalIq) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/axolotl/layer_send.py", line 215, in sendToGroup jids.remove(ownJid) ValueError: list.remove(x): x not in list

sowerkoku commented 8 years ago

hello @Kaoala

yes, all in a line. so I see another change is needed in the delivery.

add to layer.py: from yowsup.layers.auth import YowAuthenticationProtocolLayer

Kaoala commented 8 years ago

Hello @sowerkoku thank you for your answer! I added

from yowsup.layers.auth import YowAuthenticationProtocolLayer

here:

from yowsup.common.tools import Jid #is writing, writing pause from yowsup.layers.auth import YowAuthenticationProtocolLayer

Log, but only creates the file and writes only if you kill by hand from the console (CTRL + C)

I updated all:

sudo apt-get install python-dateutil sudo apt-get install python-argparse sudo apt-get install python-setuptools sudo apt-get install python-dev sudo apt-get install libevent-dev sudo apt-get install ncurses-dev sudo apt-get install libglib2.0.0 sudo apt-get install libglib2.0-dev sudo apt-get install libxml2 sudo apt-get install python-pip sudo pip install protobuf sudo pip install python-axolotl

but still there is the error :(

Traceback (most recent call last): File "run.py", line 30, in stack.loop( timeout = 0.5, discrete = 0.5 ) #this is the program mainloop File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/stacks/yowstack.py", line 188, 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.5.0-py2.7.egg/yowsup/layers/network/layer.py", line 102, in handle_read self.receive(data) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/network/layer.py", line 110, in receive self.toUpper(data) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/init.py", line 76, in toUpper self.upper.receive(data) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/stanzaregulator/layer.py", line 29, in receive self.processReceived() File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/stanzaregulator/layer.py", line 52, in processReceived self.processReceived() File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/stanzaregulator/layer.py", line 52, in processReceived self.processReceived() File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/stanzaregulator/layer.py", line 52, in processReceived self.processReceived() File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/stanzaregulator/layer.py", line 49, in processReceived self.toUpper(oneMessageData) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/__init.py", line 76, in toUpper self.upper.receive(data) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/auth/layer_crypt.py", line 65, in receive self.toUpper(payload) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/__init.py", line 76, in toUpper self.upper.receive(data) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-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.5.0-py2.7.egg/yowsup/layers/__init.py", line 76, in toUpper self.upper.receive(data) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/logger/layer.py", line 14, in receive self.toUpper(data) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/__init.py", line 76, in toUpper self.upper.receive(data) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/axolotl/layer_control.py", line 44, in receive self.toUpper(protocolTreeNode) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/__init.py", line 76, in toUpper self.upper.receive(data) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/__init.py", line 189, in receive s.receive(data) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/axolotl/layer_send.py", line 64, in receive if not self.processIqRegistry(protocolTreeNode): File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/init.py", line 156, in processIqRegistry successClbk(protocolTreeNode, originalIq) File "/usr/local/lib/python2.7/dist-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/axolotl/layer_send.py", line 215, in sendToGroup jids.remove(ownJid) ValueError: list.remove(x): x not in list

Messiefee commented 8 years ago

Men try to move your proyect to /yowsup/demos/echoclient/ in this folder are only two files, layer.py and stack.py, the layer.py change the name momently, and run the code. the stack.py keep and don t move and don t change.

sowerkoku commented 8 years ago

@Kaoala

true. I use myself that way. as @Messiefee says. if you move the layer.py to the folder yowsup/demos/echoclient you should run your project like this: ./yosup-cli demos -c config.config -e

that's the easiest solution. but if you still want to run it with the run.py, do the following:

you must modify the file "yowsup/layers/auth/layer_authentication.py"

    def getUsername(self, full = False):
        if self._credentials:
            return self._credentials[0] if not full else ("%s@%s" % (self._credentials[0], YowConstants.WHATSAPP_SERVER))
        else:
            #prop = self.getProp(YowAuthenticationProtocolLayer.PROP_CREDENTIALS)  #Original line
            prop = self.getProp(YowAuthenticationProtocolLayer.PROP_CREDENTIALS)[0] if not full else ("%s@%s" % (
                    self.getProp(YowAuthenticationProtocolLayer.PROP_CREDENTIALS)[0], YowConstants.WHATSAPP_SERVER))
            #return prop[0] if prop else None  #Original line
            return prop if prop else None
Brammmm commented 8 years ago

This can also be fixed by modifying your run.py. You currently have: stack.setProp(YowAuthenticationProtocolLayer.PROP_CREDENTIALS, CREDENTIALS) #setting credentials

Change this into: stack.setCredentials(CREDENTIALS) #setting credentials

when this is done there is no need to patch layer_authentication.py.

Kaoala commented 8 years ago

Thank you guys, i will check everything in the next few days.

controller-t commented 8 years ago

Hi, Thank you for this script. It is working fine and is able to reply with text message. However, could someone be able to add ability to respond with an image/video file?

sowerkoku commented 8 years ago

possible, with a little work and a couple of extra lines.

controller-t commented 8 years ago

Thank you!!! Eagerly waiting.

sowerkoku commented 8 years ago

ok, the promised.

add to head:

from yowsup.layers.protocol_media.protocolentities       import *
from yowsup.layers.protocol_media.mediauploader          import MediaUploader
import sys, logging
logger = logging.getLogger(__name__)

add to tail:

    def image_send(self, number, path, caption = None):
    jid = number
    mediaType = "image"
        entity = RequestUploadIqProtocolEntity(mediaType, filePath = path)
        successFn = lambda successEntity, originalEntity: self.onRequestUploadResult(jid, mediaType, path, successEntity, originalEntity, caption)
        errorFn = lambda errorEntity, originalEntity: self.onRequestUploadError(jid, path, errorEntity, originalEntity)
        self._sendIq(entity, successFn, errorFn)

    def doSendMedia(self, mediaType, filePath, url, to, ip = None, caption = None):
        entity = ImageDownloadableMediaMessageProtocolEntity.fromFilePath(filePath, url, ip, to, caption = caption)
        self.toLower(entity)

    def onRequestUploadResult(self, jid, mediaType, filePath, resultRequestUploadIqProtocolEntity, requestUploadIqProtocolEntity, caption = None):
        if resultRequestUploadIqProtocolEntity.isDuplicate():
            self.doSendMedia(mediaType, filePath, resultRequestUploadIqProtocolEntity.getUrl(), jid,
                             resultRequestUploadIqProtocolEntity.getIp(), caption)
        else:
            successFn = lambda filePath, jid, url: self.doSendMedia(mediaType, filePath, url, jid, resultRequestUploadIqProtocolEntity.getIp(), caption)
            mediaUploader = MediaUploader(jid, self.getOwnJid(), filePath,
                                      resultRequestUploadIqProtocolEntity.getUrl(),
                                      resultRequestUploadIqProtocolEntity.getResumeOffset(),
                                      successFn, self.onUploadError, self.onUploadProgress, async=False)
            mediaUploader.start()

    def onRequestUploadError(self, jid, path, errorRequestUploadIqProtocolEntity, requestUploadIqProtocolEntity):
        logger.error("Request upload for file %s for %s failed" % (path, jid))

    def onUploadError(self, filePath, jid, url):
        logger.error("Upload file %s to %s for %s failed!" % (filePath, url, jid))

    def onUploadProgress(self, filePath, jid, url, progress):
        sys.stdout.write("%s => %s, %d%% \r" % (os.path.basename(filePath), jid, progress))
        sys.stdout.flush()

to call:

            if message == 'hi':
                answer = "Hi "+namemitt+" " 
                self.toLower(textmsg(answer, to = recipient ))
                print answer

            elif message == 'image1':
                path = "image path"
                self.image_send(recipient, path)
controller-t commented 8 years ago

This is brilliant!!! Thank you Sowerkoku!! Now I am able to receive captured picture if asked via whatsapp. Is there an easy way to trigger a message based on an event? eg I have a python script monitoring push button. Right now it simply flips a GPIO. How can I send a message if button is pressed without losing echo functionality. I tried sending message via command line where it was able to send but I have to kill and restart run.py with every push.

Button Script import RPi.GPIO as GPIO import time GPIO.setmode(GPIO.BCM) GPIO.setup(27, GPIO.IN, pull_up_down=GPIO.PUD_UP) GPIO.setup(17, GPIO.OUT) GPIO.setup(22, GPIO.OUT) ledState = 1 def toggleState(channel): global ledState print("Rising edge detected. Toggling state") <SEND WHATSAPP TEXT as Button Pressed"> if (ledState%2 == 1): GPIO.output(17,False) GPIO.output(22,True) elif (ledState%2 == 0): GPIO.output(17,True) GPIO.output(22,False) ledState = ledState+1 GPIO.add_event_detect(27, GPIO.RISING, callback=toggleState, bouncetime=300) try: while True: time.sleep(60) except KeyboardInterrupt: GPIO.cleanup()

sowerkoku commented 8 years ago

you've tried to integrate the button ?

you can read here.

controller-t commented 8 years ago

Hi Sowerkoku,

My apologies, looks like I didn't communicate in clear way. I am trying to use same setup to send adhoc messages to whatsapp number. Right now I get echo back. But I have to send a message first.

sowerkoku commented 8 years ago

I'm understanding. but the purpose of the echo is responding previous message. Might I happen to generate a new layer.py with: -def startEcho (self): and -def startSendClient (self):

or do something like this.

controller-t commented 8 years ago

Thanks for quick response. I tired in a way where it kills current instance, execute cli and send required message and then start run.py again. Looks like I'll wait for your new layer.py :)

sowerkoku commented 8 years ago

How is this? execute cli and send required message

say you run: ./yowsup-cli demos -c config -s PHONE "message"

controller-t commented 8 years ago

It does send the message but already running echo (run.py) stops listening/responding. I have to restart after each message send via cli

sowerkoku commented 8 years ago

do something simple first. a script to stop the echoclient, send the message and run the echoclient

controller-t commented 8 years ago

Yepp that's my current solution as i am idiot in programming language. This is working but it is crude and there must be something we can directly do in layer.py

!/bin/bash

msg=$1 sudo service whatsapp stop sleep 1 sudo python whatsapp_photo.py $msg sleep 1 sudo service whatsapp start

run.py is installed as service and whatsapp_photo.py is simple cli call