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

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
jfrederickson committed Oct 4, 2015
0 parents commit dd8aa34
Show file tree
Hide file tree
Showing 9 changed files with 218 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
@@ -0,0 +1,3 @@
*.pyc
*swp
registration.yaml
10 changes: 10 additions & 0 deletions .kdev4/matrix-xmpp-bridge.kdev4
@@ -0,0 +1,10 @@
[Buildset]
BuildItems=@Variant(\x00\x00\x00\t\x00\x00\x00\x00\x01\x00\x00\x00\x0b\x00\x00\x00\x00\x01\x00\x00\x00$\x00m\x00a\x00t\x00r\x00i\x00x\x00-\x00x\x00m\x00p\x00p\x00-\x00b\x00r\x00i\x00d\x00g\x00e)

[Defines And Includes][Compiler]
Name=GCC
Path=gcc
Type=GCC

[Project]
VersionControlSupport=kdevgit
2 changes: 2 additions & 0 deletions README.md
@@ -0,0 +1,2 @@
#Matrix-XMPP Bridge
This project creates a bridge between a Matrix room and an XMPP MUC. It is currently very early in development and only relays messages one way (from XMPP to Matrix). Use it if you wish, but don't blame me if it blows up in your face.
87 changes: 87 additions & 0 deletions appservice.py
@@ -0,0 +1,87 @@
# app_service.py:

import json, requests
from flask import Flask, jsonify, request
import xmpp_component as xmpp
import ConfigParser
app = Flask(__name__)

# Application service access token - protect this with your life!
#TOKEN = 'wfghWEGh3wgWHEf3478sHFWE'
# API URL for your Matrix homeserver
#APIURL = 'http://localhost:8008/_matrix/client/api/v1'

config = ConfigParser.ConfigParser()
config.read('/etc/mxbridge.conf')
TOKEN = config.get("Matrix", "token")
APIURL = config.get("Matrix", "api_url")

# Observe all the things forever
# TODO: Send these to XMPP
@app.route("/transactions/<transaction>", methods=["PUT"])
def on_receive_events(transaction):
events = request.get_json()["events"]
#if(event['type'] == 'm.room.message'):
#xmpp.sendMessage(event['user_id'] + ': ' + event['content']['body'])
for event in events:
print "User: %s Room: %s" % (event["user_id"], event["room_id"])
print "Event Type: %s" % event["type"]
print "Content: %s" % event["content"]
return jsonify({})

# Create this room if it doesn't exist
@app.route("/rooms/<alias>")
def query_alias(alias):
alias_localpart = alias.split(":")[0][1:]
createRoom(TOKEN, alias_localpart)
print('Room alias: ' + alias)
return jsonify({})

def createRoom(as_token, alias_localpart):
roomCreateURL = APIURL + "/createRoom?access_token=" + as_token
data = json.dumps({
"room_alias_name": alias_localpart
})
resp = requests.post(roomCreateURL, data=data, headers={"Content-Type": "application/json"})
print('Room creation URL: ' + roomCreateURL)
print('Data: ' + data)
print(resp.text)

@app.route("/mxbridge/send", methods=["POST"])
def sendMessage():
print(request.data)
req = request.get_json()

sender = req["from"]
#sender = request.args.get('from')
xmppRecipient = req["to"]
#xmppRecipient = request.args.get('to')
message = req["body"]
#message = request.args.get('body')
print('Sending to room: ' + str(xmppRecipient))

#recipient = xmppMap(xmppRecipient)

joinRoom(token=TOKEN, roomid=xmppRecipient)
sendMessageURL = APIURL + "/rooms/" + xmppRecipient + '/send/m.room.message?access_token=' + TOKEN
body = json.dumps({
"msgtype": "m.text",
"body": message
})
requests.post(sendMessageURL, data=body, headers={"Content-Type": "application/json"})

return jsonify({})


def joinRoom(token, roomid):
if(token != None and roomid != None):
requests.post(APIURL + '/' + roomid + '/join?access_token=' + token)
elif(token == None):
print("Must include access token!")
elif(roomid == None):
print("Must include roomid!")


if __name__ == "__main__":
app.config['TRAP_BAD_REQUEST_ERRORS'] = True
app.run(debug=True)
3 changes: 3 additions & 0 deletions matrix-xmpp-bridge.kdev4
@@ -0,0 +1,3 @@
[Project]
Manager=KDevGenericManager
Name=matrix-xmpp-bridge
11 changes: 11 additions & 0 deletions mxbridge.conf.example
@@ -0,0 +1,11 @@
[Matrix]
token=supersekrettoken
api_url=http://localhost:8008/_matrix/client/api/v1
room_id=!CvcvRuDYDzTOzfKKgh:localhost
as_api_url=http://localhost:5000

[XMPP]
muc_room=test@conference.example.com
nick=mxbridge
username=test@example.com
#password=supersekret
21 changes: 21 additions & 0 deletions registration.yaml.example
@@ -0,0 +1,21 @@
# registration.yaml

# this is the base URL of the application service
url: "http://localhost:5000"

# This is the token that the AS should use as its access_token when using the Client-Server API
# This can be anything you want.
as_token: supersekret

# This is the token that the HS will use when sending requests to the AS.
# This can be anything you want.
hs_token: supersekret

# this is the local part of the desired user ID for this AS (in this case @logging:localhost)
sender_localpart: mxbridge
namespaces:
users: []
rooms: []
aliases:
- exclusive: false
regex: "#xmpp.*"
16 changes: 16 additions & 0 deletions schema.sql
@@ -0,0 +1,16 @@
drop table if exists virtual_users;
create table usermap (
id integer primary key autoincrement,
xmpp_user text not null,
matrix_user text not null
);
create table roommap (
id integer primary key autoincrement,
xmpp_room text not null,
matrix_room text not null
);
create table room_membership (
id integer primary key autoincrement,
room text not null,
room integer not null
)
65 changes: 65 additions & 0 deletions xmpp_component.py
@@ -0,0 +1,65 @@
#!/usr/bin/env python

import sys
import logging
import getpass
from optparse import OptionParser
import requests
import json
import ConfigParser

import sleekxmpp

config = ConfigParser.ConfigParser()
config.read('/etc/mxbridge.conf')
MXAPI = config.get("Matrix", "as_api_url")
MXROOM = config.get("Matrix", "room_id")

class BridgeBot(sleekxmpp.ClientXMPP):
def __init__(self, jid, password, room, nick):
sleekxmpp.ClientXMPP.__init__(self, jid, password)
self.room = room
self.nick = nick

self.add_event_handler("session_start", self.start)
self.add_event_handler("groupchat_message", self.muc_message)

def start(self, event):
self.get_roster()
self.send_presence()
self.plugin['xep_0045'].joinMUC(self.room,
self.nick,
wait=True)

def muc_message(self, msg):
if(msg['mucnick'] != self.nick):
data = {"from": "test", "to": MXROOM, "body": msg['mucnick'] + ": " + msg['body']}
requests.post(MXAPI + "/mxbridge/send", data=json.dumps(data), headers={"Content-Type": "application/json"})

#if sys.version_info < (3, 0):
#reload(sys)
#sys.setdefaultencoding('utf8')



if(__name__ == '__main__'):
jid = config.get("XMPP", "username")
room = config.get("XMPP", "muc_room")
nick = config.get("XMPP", "nick")

try:
password = config.get("XMPP", "password")
except ConfigParser.NoOptionError:
password = getpass.getpass("Password: ")

xmpp = BridgeBot(jid, password, room, nick)
xmpp.register_plugin('xep_0045')

if xmpp.connect():
try:
xmpp.process(block=True)
except TypeError:
xmpp.process(threaded=False) # Used for older versions of SleekXMPP
print("Done")
else:
print("Unable to connect.")

0 comments on commit dd8aa34

Please sign in to comment.