2015-03-26 2 views
3

Справочная информация:yowsup - Интеграция отправки и получения

Я хотел бы интегрировать yowsup в мой проект автоматизации дома. Я видел простой пример того, как получать сообщения, и после некоторых незначительных изменений он работает нормально.

Выпуск:

Моя проблема начинается тогда, когда речь идет интегрировать функцию отправки сообщений. Те два файла, которые я использую:

run.py

from layer import EchoLayer 

from yowsup.layers.auth import YowAuthenticationProtocolLayer 
from yowsup.layers.protocol_messages import YowMessagesProtocolLayer 
from yowsup.layers.protocol_receipts import YowReceiptProtocolLayer 
from yowsup.layers.protocol_acks import YowAckProtocolLayer 
from yowsup.layers.protocol_presence import YowPresenceProtocolLayer 
from yowsup.layers.network import YowNetworkLayer 
from yowsup.layers.coder import YowCoderLayer 
from yowsup.common import YowConstants 
from yowsup.layers import YowLayerEvent 
from yowsup.stacks import YowStack, YOWSUP_CORE_LAYERS 
from yowsup import env 


CREDENTIALS = ("phone", "pwd") 

if __name__ == "__main__": 

    layers = (
     EchoLayer, 
     (YowAuthenticationProtocolLayer, YowMessagesProtocolLayer, YowReceiptProtocolLayer, YowAckProtocolLayer, YowPresenceProtocolLayer) 
    ) + YOWSUP_CORE_LAYERS 

    stack = YowStack(layers) 
    # Setting credentials 
    stack.setProp(YowAuthenticationProtocolLayer.PROP_CREDENTIALS, CREDENTIALS) 

    # WhatsApp server address 
    stack.setProp(YowNetworkLayer.PROP_ENDPOINT, YowConstants.ENDPOINTS[0]) 
    stack.setProp(YowCoderLayer.PROP_DOMAIN, YowConstants.DOMAIN)    
    stack.setProp(YowCoderLayer.PROP_RESOURCE, env.CURRENT_ENV.getResource()) 

    # Sending connecting signal 
    stack.broadcastEvent(YowLayerEvent(YowNetworkLayer.EVENT_STATE_CONNECT)) 

    # Program main loop 
    stack.loop() 

layer.py

from yowsup.layers.interface import YowInterfaceLayer, ProtocolEntityCallback 
from yowsup.layers.protocol_messages.protocolentities import TextMessageProtocolEntity 
from yowsup.layers.protocol_receipts.protocolentities import OutgoingReceiptProtocolEntity 
from yowsup.layers.protocol_acks.protocolentities import OutgoingAckProtocolEntity 
from yowsup.layers.protocol_presence.protocolentities import PresenceProtocolEntity 
import threading 
import logging 

logger = logging.getLogger(__name__) 

class EchoLayer(YowInterfaceLayer): 

    @ProtocolEntityCallback("message") 
    def onMessage(self, messageProtocolEntity): 
     #send receipt otherwise we keep receiving the same message over and over 
     print str(messageProtocolEntity.getFrom()) + ' - ' + str(messageProtocolEntity.getBody()) 
     receipt = OutgoingReceiptProtocolEntity(messageProtocolEntity.getId(), messageProtocolEntity.getFrom()) 
     self.toLower(receipt) 

    @ProtocolEntityCallback("send_message") 
    def sendMessage(self, destination, message, messageProtocolEntity): 
     outgoingMessageProtocolEntity = TextMessageProtocolEntity(
     message, 
     to = destination + "@s.whatsapp.net") 
     self.toLower(outgoingMessageProtocolEntity) 


    @ProtocolEntityCallback("receipt") 
    def onReceipt(self, entity): 
     ack = OutgoingAckProtocolEntity(entity.getId(), "receipt", "delivery") 
     self.toLower(ack) 

    # List of (jid, message) tuples 
    PROP_MESSAGES = "org.openwhatsapp.yowsup.prop.sendclient.queue" 

    def __init__(self): 
     super(EchoLayer, self).__init__() 
     self.ackQueue = [] 
     self.lock = threading.Condition() 

    @ProtocolEntityCallback("success") 
    def onSuccess(self, successProtocolEntity): 
     self.lock.acquire() 
     for target in self.getProp(self.__class__.PROP_MESSAGES, []): 
      phone, message = target 
      if '@' in phone: 
       messageEntity = TextMessageProtocolEntity(message, to = phone) 
      elif '-' in phone: 
       messageEntity = TextMessageProtocolEntity(message, to = "%[email protected]" % phone) 
      else: 
       messageEntity = TextMessageProtocolEntity(message, to = "%[email protected]" % phone) 
      self.ackQueue.append(messageEntity.getId()) 
      self.toLower(messageEntity) 
     self.lock.release() 

    @ProtocolEntityCallback("ack") 
    def onAck(self, entity): 
     self.lock.acquire() 

     if entity.getId() in self.ackQueue: 
      self.ackQueue.pop(self.ackQueue.index(entity.getId())) 

     if not len(self.ackQueue): 
      logger.info("Message sent") 
      #raise KeyboardInterrupt() 

     self.lock.release() 

Вопросы:

  • Где я Предполагается, что c весь метод send_message, поэтому я могу отправлять сообщения там, где мне это нужно?
  • Есть ли регулярное событие (срабатывающее каждую секунду или что-то еще), которое я мог бы использовать для отправки моих сообщений?

ответ

3
@ProtocolEntityCallback("send_message") 
    def sendMessage(self, destination, message, messageProtocolEntity): 
     outgoingMessageProtocolEntity = TextMessageProtocolEntity(
     message, 
     to = destination + "@s.whatsapp.net") 
     self.toLower(outgoingMessageProtocolEntity) 

В коде avove sendMessage, чтобы назвать, protocolEntity.getTag() == "send_message" должен быть True. Для отправки сообщения вам не нужно.

layer.py

from yowsup.layers.interface import YowInterfaceLayer, ProtocolEntityCallback 
from yowsup.layers.protocol_messages.protocolentities import TextMessageProtocolEntity 
from yowsup.layers.protocol_receipts.protocolentities import OutgoingReceiptProtocolEntity 
from yowsup.layers.protocol_acks.protocolentities import OutgoingAckProtocolEntity 
from yowsup.layers.protocol_presence.protocolentities import PresenceProtocolEntity 
import threading 
import logging 

logger = logging.getLogger(__name__) 
recv_msg = [] 

class EchoLayer(YowInterfaceLayer): 

    def __init__(self): 
     super(EchoLayer, self).__init__() 
     self.ackQueue = [] 
     self.lock = threading.Condition() 

@ProtocolEntityCallback("message") 
def onMessage(self, messageProtocolEntity): 
    if messageProtocolEntity.getType() == 'text': 
     recv_msg.append((messageProtocolEntity.getFrom(),messageProtocolEntity.getBody())) 

    #send receipt otherwise we keep receiving the same message over and over 
    receipt = OutgoingReceiptProtocolEntity(messageProtocolEntity.getId(), messageProtocolEntity.getFrom()) 
    self.toLower(receipt) 

    @ProtocolEntityCallback("receipt") 
    def onReceipt(self, entity): 
     ack = OutgoingAckProtocolEntity(entity.getId(), "receipt", "delivery") 
     self.toLower(ack) 

    # List of (jid, message) tuples 
    PROP_MESSAGES = "org.openwhatsapp.yowsup.prop.sendclient.queue" 

    @ProtocolEntityCallback("success") 
    def onSuccess(self, successProtocolEntity): 
     self.lock.acquire() 
     for target in self.getProp(self.__class__.PROP_MESSAGES, []): 
      phone, message = target 
      if '@' in phone: 
       messageEntity = TextMessageProtocolEntity(message, to = phone) 
      elif '-' in phone: 
       messageEntity = TextMessageProtocolEntity(message, to = "%[email protected]" % phone) 
      else: 
       messageEntity = TextMessageProtocolEntity(message, to = "%[email protected]" % phone) 
      self.ackQueue.append(messageEntity.getId()) 
      self.toLower(messageEntity) 
     self.lock.release() 

    @ProtocolEntityCallback("ack") 
    def onAck(self, entity): 
     self.lock.acquire() 

     if entity.getId() in self.ackQueue: 
      self.ackQueue.pop(self.ackQueue.index(entity.getId())) 

     if not len(self.ackQueue): 
      self.lock.release() 
      logger.info("Message sent") 
      raise KeyboardInterrupt() 

     self.lock.release() 

Чтобы отправить сообщение определить функцию send_message в стеке run.py. Вы также можете импортировать run.py и использовать его функцию из другого скрипта.

from layer import EchoLayer, recv_msg 
CREDENTIALS = ("phone", "pwd") 
def send_message(destination, message): 

    ''' 
    destination is <phone number> without '+' 
    and with country code of type string, 
    message is string 
    e.g send_message('11133434343','hello') 
    ''' 
    messages = [(destination, message)] 
    layers = (EchoLayer, 
       (YowAuthenticationProtocolLayer, 
       YowMessagesProtocolLayer, 
       YowReceiptProtocolLayer, 
       YowAckProtocolLayer, 
       YowPresenceProtocolLayer) 
      ) + YOWSUP_CORE_LAYERS 
    stack = YowStack(layers) 
    stack.setProp(EchoLayer.PROP_MESSAGES, messages) 
    stack.setProp(YowAuthenticationProtocolLayer.PROP_PASSIVE, True) 
    # Setting credentials 
    stack.setProp(YowAuthenticationProtocolLayer.PROP_CREDENTIALS, CREDENTIALS) 

    # WhatsApp server address 
    stack.setProp(YowNetworkLayer.PROP_ENDPOINT, YowConstants.ENDPOINTS[0]) 
    stack.setProp(YowCoderLayer.PROP_DOMAIN, YowConstants.DOMAIN)    
    stack.setProp(YowCoderLayer.PROP_RESOURCE, env.CURRENT_ENV.getResource()) 

    # Sending connecting signal 
    stack.broadcastEvent(YowLayerEvent(YowNetworkLayer.EVENT_STATE_CONNECT)) 
    try: 
     # Program main loop 
     stack.loop() 
    except AuthError as e: 
     print('Authentication error %s' % e.message) 
     sys.exit(1) 

def recv_message(): 
    layers = ( EchoLayer, 
       (YowAuthenticationProtocolLayer, YowMessagesProtocolLayer, 
       YowReceiptProtocolLayer, YowAckProtocolLayer, 
       YowPresenceProtocolLayer) 
      ) + YOWSUP_CORE_LAYERS 

    stack = YowStack(layers) 
    # Setting credentials 
    stack.setProp(YowAuthenticationProtocolLayer.PROP_CREDENTIALS, CREDENTIALS) 

    # WhatsApp server address 
    stack.setProp(YowNetworkLayer.PROP_ENDPOINT, YowConstants.ENDPOINTS[0]) 
    stack.setProp(YowCoderLayer.PROP_DOMAIN, YowConstants.DOMAIN) 
    stack.setProp(YowCoderLayer.PROP_RESOURCE, env.CURRENT_ENV.getResource()) 

    # Sending connecting signal 
    stack.broadcastEvent(YowLayerEvent(YowNetworkLayer.EVENT_STATE_CONNECT)) 
    try: 
     # Program main loop 
     stack.loop() 
    except AuthError as e: 
     print('Authentication error %s' % e.message) 
     sys.exit(1) 

if __name__ == '__main__': 
    if len(sys.argv) == 1: 
     print('%s send number message\nrecv\n' % sys.argv[0]) 
     sys.exit(1) 
    if sys.argv[1] == 'send': 
     try: 
      send_message(sys.argv[2],sys.argv[3]) 
     except KeyboardInterrupt: 
      print('closing') 
      sys.exit(0) 
    if sys.argv[1] == 'recv': 
     try: 
      recv_message() 
     except KeyboardInterrupt: 
      print('closing') 
      sys.exit(0) 
     for m in recv_msg: 
      print('From %s:\n%s\n' % m) 

Теперь вы можете отправить сообщение по телефону send_message('1234567890','Howdy') и получать сообщение, позвонив recv_message().

+0

Спасибо. Прежде всего, можете ли вы проверить правильность отступов run.py? Когда вы говорите, что мне нужно вызвать send_message, все, что мне нужно сделать, это запустить run.py, а с другого скрипта вызывать что-то вроде: layer.send_message ('number', 'message')? –

+0

'send_message' находится в run.py. вы можете запустить 'python run.py number message'. Или импортируйте run.py, вы получите доступ к функции 'send_message'. –

+0

Привет. Я протестировал, как вы сказали. Кажется, что код остается в бесконечном цикле. Это единственное сообщение, которое я получаю: никаких обработчиков не найдено для журнала «yowsup.stacks.yowstack» –

Смежные вопросы