Skip to content
This repository has been archived by the owner on Feb 11, 2019. It is now read-only.

Commit

Permalink
Merge pull request #3 from praekelt/feature/issue-3-define-setup_tran…
Browse files Browse the repository at this point in the history
…sport

Define setup_transport method and working teardown method
  • Loading branch information
Hannarst authored and Hannarst committed Jun 24, 2015
2 parents 08e587a + b7572de commit a93c30f
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 10 deletions.
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
install_requires=[
'vumi',
'Twisted>=13.1.0',
'yowsup2',
],
classifiers=[
'Development Status :: 4 - Beta',
Expand Down
112 changes: 102 additions & 10 deletions vxyowsup/whatsapp.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,40 @@
# -*- test-case-name: vumi.transports.whatsapp.tests.test_whatsapp -*-
from twisted.internet import defer
from twisted.internet.threads import deferToThread

from vumi.transports.base import Transport
from vumi.config import ConfigText
from vumi import log

from yowsup.layers.network import YowNetworkLayer

from yowsup.common import YowConstants
from yowsup.layers import YowLayerEvent
from yowsup.stacks import YowStack, YowStackBuilder
from yowsup import env

import sys, argparse, yowsup, logging

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


class WhatsAppTransportConfig(Transport.CONFIG_CLASS):
cc = ConfigText('Country code of host phone number', default='27',
static=True)
cc = ConfigText(
'Country code of host phone number',
default='27', static=True)
phone = ConfigText(
'Phone number, excluding "+", including country code',
'Phone number, excluding "+", including country code',
static=True)
password = ConfigText(
'Password received from WhatsApp on yowsup registration',
static=True)
'Password received from WhatsApp on yowsup registration',
static=True)


class WhatsAppClientDone(Exception):
""" Signal that the Yowsup client is done. """


class WhatsAppTransport(Transport):
Expand All @@ -26,16 +46,88 @@ def setup_transport(self):
config = self.get_static_config()
log.info('Transport starting with: %s' % (config,))
CREDENTIALS = (config.phone, config.password)

return defer.succeed(1)

client = self.client = Client(CREDENTIALS)

self.client_d = deferToThread(client.client_start)
self.client_d.addErrback(self.catch_exit)
self.client_d.addErrback(self.print_error)

@defer.inlineCallbacks
def teardown_transport(self):
return defer.succeed(1)
print "Stopping client ..."
self.client.client_stop()
print "Stop sent."
print "Waiting for asyncore loop to exit ..."
yield self.client_d
print "Loop done."

def handle_outbound_message(self, message):
# message is a vumi.message.TransportUserMessage
log.info('Sending %r' % (message.to_json(),))
if message['content'] == 'fail!':
return self.publish_nack(message['message_id'], 'failed')
return self.publish_ack(message['message_id'],
'remote-message-id')
return self.publish_ack(
message['message_id'], 'remote-message-id')

def catch_exit(self, f):
f.trap(WhatsAppClientDone)
print "Yowsup client killed."

def print_error(self, f):
print f
return f


class Client(object):
def __init__(self, credentials):
self.CREDENTIALS = credentials

def client_start(self):
self.stack = YowStackBuilder.getDefaultStack(
layer=EchoLayer, media=False)
self.stack.setCredentials(self.CREDENTIALS)
self.network_layer = self.stack.getLayer(0)

self.stack.broadcastEvent(YowLayerEvent(
YowNetworkLayer.EVENT_STATE_CONNECT))
self.stack.loop(discrete=0, count=1, timeout=1)

def client_stop(self):
print "Stopping client ..."

def _stop():
print "Sending disconnect ..."
self.stack.broadcastEvent(YowLayerEvent(
YowNetworkLayer.EVENT_STATE_DISCONNECT))

def _kill():
raise WhatsAppClientDone("We are exiting NOW!")

self.stack.execDetached(_stop)
self.stack.execDetached(_kill)


class EchoLayer(YowInterfaceLayer):

@ProtocolEntityCallback("message")
def onMessage(self, messageProtocolEntity):
receipt = OutgoingReceiptProtocolEntity(
messageProtocolEntity.getId(),
messageProtocolEntity.getFrom(), 'read',
messageProtocolEntity.getParticipant())

outgoingMessageProtocolEntity = TextMessageProtocolEntity(
messageProtocolEntity.getBody(),
to=messageProtocolEntity.getFrom())

self.toLower(receipt)

self.toLower(outgoingMessageProtocolEntity)
print(messageProtocolEntity.getBody())

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

0 comments on commit a93c30f

Please sign in to comment.