Skip to content
This repository has been archived by the owner on Jun 27, 2022. It is now read-only.

Commit

Permalink
Merge pull request #3 from stv0g/yowsup-2
Browse files Browse the repository at this point in the history
update my fork
  • Loading branch information
dazzzl committed Dec 6, 2015
2 parents f269bf5 + 7302c4f commit cd44b01
Show file tree
Hide file tree
Showing 22 changed files with 1,170 additions and 1,232 deletions.
674 changes: 0 additions & 674 deletions COPYING.gpl3

This file was deleted.

596 changes: 596 additions & 0 deletions COPYING.md

Large diffs are not rendered by default.

80 changes: 80 additions & 0 deletions INSTALL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Installation and configuration guide

I assume that you have a basic understanding of XMPP and the the concept of a XMPP component / transport. If not, please get a book about Jabber or read the standards.

transWhat is a XMPP transport. By this means it extends the functionallity of an existing XMPP server. It acts as a gateway between the XMPP and WhatsApp networks. It receives WhatsApp messages and forwards them to your XMPP client (and vice-versa).

The implementation of transWhat is based on the [Spectrum 2](http://www.spectrum.im) framework and the [Yowsup 2](https://github.com/tgalal/yowsup) library to interface with WhatsApp.

The following chart summarizes the involved components and the protocols they use to communicate.

## Prosody

### Installation

I will not cover the installation of Prosody in this guide. Please look for some other tutorials on how to do that.

### Configuration

The only important thing for us is the configuration of a XMPP component (Spectrum 2 in our case).
See http://prosody.im/doc/components.

Append the following at the end of `/etc/prosody/prosody.cfg.lua`

Component "whatsapp.0l.de"
component_secret = "whatsappsucks"
component_ports = { 5221 }
component_interface = "127.0.0.1"

## Spectrum 2

#### Installation

Manual compile latest version from [Github](https://github.com/hanzz/libtransport).
You can use the following guide: http://spectrum.im/documentation/installation/from_source_code.html.

#### Configuration

Create a new file `/etc/spectrum2/transports/whatsapp.cfg` with the following content:

[service]
user = spectrum
group = spectrum

jid = whatsapp.0l.de

server = localhost
password = whatsappsucks
port = 5221

backend_host = localhost
backend = /location/to/transwhat/transwhat.py

users_per_backend = 10
more_resources = 1

admin_jid = your@jid.example

[identity]
name = transWhat
type = xmpp
category = gateway

[logging]
config = /etc/spectrum2/logging.cfg
backend_config = /etc/spectrum2/backend-logging.cfg

## transWhat

### Installation

Checkout the latest version of transWhat from GitHub:

$ git clone git@github.com:stv0g/transwhat.git

Install required dependencies:

$ pip install --pre e4u protobuf python-dateutil yowsup

- **e4u**: is a simple emoji4unicode python bindings
- [**yowsup**](https://github.com/tgalal/yowsup): is a python library that enables you build application which use WhatsApp service.
35 changes: 19 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,35 @@

transWhat is a WhatsApp XMPP Gateway based on [Spectrum 2](http://www.spectrum.im) and [Yowsup 2](https://github.com/tgalal/yowsup).

## Dependencies
## [Installation](INSTALL.md)
## [Usage](USAGE.md)

#### Python packages
## Features

pip install e4u protobuf mysql dateutil

- **e4u**: is a simple emoji4unicode python bindings
- [**yowsup**](https://github.com/tgalal/yowsup): is a python library that enables you build application which use WhatsApp service.
- **mysqldb**: MySQL client python bindings

#### Spectrum 2
is a XMPP transport

Manual compile latest version from https://github.com/hanzz/libtransport.
* Typing notifications
* Receive images, audio & video
* Set/get online status
* Set status message
* Groupchats

## Contributors

Pull requests, bug reports etc. are welcome. Help us to provide a open implementation of the WhatsApp protocol.

The following persons have contributed major parts of this code:

- **Steffen Vogel** (@stv0g): Idea and initial implementation based on Yowsup 1
- **Mohammed Yaseen Mowzer** (@moyamo): Port to Yowsup 2
- @stv0g (Steffen Vogel): Idea and initial implementation based on Yowsup 1
- @moyamo (Mohammed Yaseen Mowzer): Port to Yowsup 2
- @DaZZZl: Improvements to group chats, media & message receipts

## [License](COPYING.md)

transWhat is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

Foobar is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

## Documentation
## Links

A project wiki is available [here](https://dev.0l.de/wiki/projects/transwhat/).
An *outdated* project wiki is available [here](https://dev.0l.de/wiki/projects/transwhat/).

An *outdated* writeup of this project is also availabe at my [blog](http://www.steffenvogel.de/2013/06/29/transwhat/).
40 changes: 26 additions & 14 deletions Spectrum2/backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class SpectrumBackend:
@param host: Host where Spectrum2 NetworkPluginServer runs.
@param port: Port.
"""

def __init__(self):
self.m_pingReceived = False
self.m_data = ""
Expand All @@ -38,14 +39,14 @@ def handleMessage(self, user, legacyName, msg, nickname = "", xhtml = "", timest
self.send(message)

def handleMessageAck(self, user, legacyName, ID):
m = protocol_pb2.ConversationMessage()
m.userName = user
m.buddyName = legacyName
m.message = ""
m.id = ID
m = protocol_pb2.ConversationMessage()
m.userName = user
m.buddyName = legacyName
m.message = ""
m.id = ID

message = WRAP(m.SerializeToString(), protocol_pb2.WrapperMessage.TYPE_CONV_MESSAGE_ACK)
self.send(message)
message = WRAP(m.SerializeToString(), protocol_pb2.WrapperMessage.TYPE_CONV_MESSAGE_ACK)
self.send(message)


def handleAttention(self, user, buddyName, msg):
Expand Down Expand Up @@ -344,6 +345,14 @@ def handleBuddyRemovedPayload(self, data):
groups = [g for g in payload.group]
self.handleBuddyRemovedRequest(payload.userName, payload.buddyName, groups);

def handleBuddiesPayload(self, data):
payload = protocol_pb2.Buddies()
if (payload.ParseFromString(data) == False):
#TODO: ERROR
return

self.handleBuddies(payload);

def handleChatStatePayload(self, data, msgType):
payload = protocol_pb2.Buddy()
if (payload.ParseFromString(data) == False):
Expand All @@ -364,10 +373,10 @@ def handleDataRead(self, data):
if (len(self.m_data) >= 4):
expected_size = struct.unpack('!I', self.m_data[0:4])[0]
if (len(self.m_data) - 4 < expected_size):
self.logger.error("Expected Data Size Error")
self.logger.debug("Data packet incomplete")
return
else:
self.logger.error("Data too small")
self.logger.debug("Data packet incomplete")
return

packet = self.m_data[4:4+expected_size]
Expand All @@ -376,17 +385,15 @@ def handleDataRead(self, data):
parseFromString = wrapper.ParseFromString(packet)
except:
self.m_data = self.m_data[expected_size+4:]
self.logger.error("Parse from String exception")
self.logger.error("Parse from String exception. Skipping packet.")
return

if parseFromString == False:
self.m_data = self.m_data[expected_size+4:]
self.logger.error("Parse from String failed")
self.logger.error("Parse from String failed. Skipping packet.")
return

self.m_data = self.m_data[4+expected_size:]
#self.logger.error("Data Type: %s",wrapper.type)


if wrapper.type == protocol_pb2.WrapperMessage.TYPE_LOGIN:
self.handleLoginPayload(wrapper.payload)
Expand Down Expand Up @@ -430,6 +437,8 @@ def handleDataRead(self, data):
self.handleConvMessageAckPayload(wrapper.payload)
elif wrapper.type == protocol_pb2.WrapperMessage.TYPE_RAW_XML:
self.handleRawXmlRequest(wrapper.payload)
elif wrapper.type == protocol_pb2.WrapperMessage.TYPE_BUDDIES:
self.handleBuddiesPayload(wrapper.payload)

def send(self, data):
header = struct.pack('!I',len(data))
Expand Down Expand Up @@ -490,6 +499,9 @@ def handleLoginRequest(self, user, legacyName, password, extra):

raise NotImplementedError, "Implement me"

def handleBuddies(self, buddies):
pass

def handleLogoutRequest(self, user, legacyName):
"""
Called when XMPP user wants to disconnect legacy network.
Expand All @@ -507,7 +519,7 @@ def handleMessageSendRequest(self, user, legacyName, message, xhtml = "", ID = 0
@param legacyName: Legacy network name of buddy or room.
@param message: Plain text message.
@param xhtml: XHTML message.
@param ID: message ID
@param ID: message ID
"""

raise NotImplementedError, "Implement me"
Expand Down
5 changes: 5 additions & 0 deletions Spectrum2/protocol.proto
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ message Buddy {
optional bool blocked = 8;
}

message Buddies {
repeated Buddy buddy = 1;
}

message ConversationMessage {
required string userName = 1;
required string buddyName = 2;
Expand Down Expand Up @@ -182,6 +186,7 @@ message WrapperMessage {
TYPE_ROOM_LIST = 32;
TYPE_CONV_MESSAGE_ACK = 33;
TYPE_RAW_XML = 34;
TYPE_BUDDIES = 35;
}
required Type type = 1;
optional bytes payload = 2;
Expand Down
Loading

0 comments on commit cd44b01

Please sign in to comment.