initial version
it supports bi-direcitonal text, after manually filling the database :)master
						commit
						5ae481ccf2
					
				@ -0,0 +1,3 @@
 | 
			
		||||
node_modules
 | 
			
		||||
matritch-registration.yaml
 | 
			
		||||
*.db
 | 
			
		||||
@ -0,0 +1,117 @@
 | 
			
		||||
const mx = require('matrix-appservice-bridge');
 | 
			
		||||
const tmi = require('tmi.js');
 | 
			
		||||
 | 
			
		||||
// has to be defined here because of scope
 | 
			
		||||
let bridge;
 | 
			
		||||
let tmiListener;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Matrix part
 | 
			
		||||
async function matrixEventHandler(request, context) {
 | 
			
		||||
    const event = request.getData();
 | 
			
		||||
 | 
			
		||||
    if(event.type === 'm.room.message') {
 | 
			
		||||
        const message = event.content.body;
 | 
			
		||||
        const remoteUsers = await bridge.getUserStore().getRemoteUsersFromMatrixId(event.sender);
 | 
			
		||||
        // use the first user, multipe user mappings are unsupported
 | 
			
		||||
        const remoteUser = remoteUsers[0];
 | 
			
		||||
        const tmiUsername = remoteUser.id;
 | 
			
		||||
        const tmiPassword = remoteUser.data.password;
 | 
			
		||||
 | 
			
		||||
        const remoteRooms = await bridge.getRoomStore().getLinkedRemoteRooms(event.room_id);
 | 
			
		||||
        remoteRooms.forEach(remoteRoom => {
 | 
			
		||||
            const tmiClient = new tmi.Client({
 | 
			
		||||
                connection: {
 | 
			
		||||
                    secure: true,
 | 
			
		||||
                },
 | 
			
		||||
                identity: {
 | 
			
		||||
                    username: tmiUsername,
 | 
			
		||||
                    password: tmiPassword
 | 
			
		||||
                },
 | 
			
		||||
                channels: [
 | 
			
		||||
                    remoteRoom.roomId
 | 
			
		||||
                ]
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // connect to tmi, send message and disconnect
 | 
			
		||||
            tmiClient.connect();
 | 
			
		||||
            tmiClient.on('connected', () => {
 | 
			
		||||
                tmiClient.say(remoteRoom.roomId, message);
 | 
			
		||||
                tmiClient.disconnect();
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
new mx.Cli({
 | 
			
		||||
    registrationPath: 'matritch-registration.yaml',
 | 
			
		||||
    generateRegistration: (reg, callback) => {
 | 
			
		||||
        reg.setId(mx.AppServiceRegistration.generateToken());
 | 
			
		||||
        reg.setHomeserverToken(mx.AppServiceRegistration.generateToken());
 | 
			
		||||
        reg.setAppServiceToken(mx.AppServiceRegistration.generateToken());
 | 
			
		||||
        reg.setSenderLocalpart('_matritch');
 | 
			
		||||
        reg.addRegexPattern('users', '@_matritch_.*', true);
 | 
			
		||||
        callback(reg);
 | 
			
		||||
    },
 | 
			
		||||
    run: async (port, config) => {
 | 
			
		||||
        bridge = new mx.Bridge({
 | 
			
		||||
            homeserverUrl: process.env.HOMESEVER || 'http://localhost:8008',
 | 
			
		||||
            domain: process.env.DOMAIN || 'localhost',
 | 
			
		||||
            registration: 'matritch-registration.yaml',
 | 
			
		||||
            controller: {
 | 
			
		||||
                onUserQuery: queriedUser => {
 | 
			
		||||
                    // auto-provision users with no additonal data
 | 
			
		||||
                    console.log(JSON.stringify(queriedUser))
 | 
			
		||||
                    return {};
 | 
			
		||||
                },
 | 
			
		||||
                onEvent: matrixEventHandler
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        console.log('Matrix-side listening on port %s', port);
 | 
			
		||||
 | 
			
		||||
        await bridge.run(port, config);
 | 
			
		||||
        connectTmiListener();
 | 
			
		||||
    }
 | 
			
		||||
}).run();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Twitch part
 | 
			
		||||
const localpartPrefix = bridge.opts.registration.namespaces.users[0].regex.slice(0, -2);
 | 
			
		||||
const domain = bridge.opts.domain;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async function tmiEventHandler(target, context, message, self) {
 | 
			
		||||
    const remoteUsers = await bridge.getUserStore().getRemoteUser(context.username)
 | 
			
		||||
    if(remoteUsers) {
 | 
			
		||||
        // ignore messages from briged users
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const matrixRooms = await bridge.getRoomStore().getLinkedMatrixRooms(target);
 | 
			
		||||
    matrixRooms.forEach(matrixRoom => {
 | 
			
		||||
        const intent = bridge.getIntent(localpartPrefix+context.username+':'+domain);
 | 
			
		||||
        intent.sendText(matrixRoom.roomId, message);
 | 
			
		||||
    });
 | 
			
		||||
};
 | 
			
		||||
async function connectTmiListener() {
 | 
			
		||||
    const remoteRooms = await bridge.getRoomStore().select({
 | 
			
		||||
        matrix_id: {$exists: true},
 | 
			
		||||
        remote_id: {$exists: true}
 | 
			
		||||
    });
 | 
			
		||||
    const channels = remoteRooms.map(remoteRoom => {
 | 
			
		||||
        return remoteRoom.remote_id;
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    const tmiAnonymousOptions = {
 | 
			
		||||
        connection: {
 | 
			
		||||
            secure: true,
 | 
			
		||||
            reconnect: true
 | 
			
		||||
        },
 | 
			
		||||
        channels: channels
 | 
			
		||||
    };
 | 
			
		||||
    tmiListener = new tmi.Client(tmiAnonymousOptions);
 | 
			
		||||
    tmiListener.on('message', tmiEventHandler);
 | 
			
		||||
    tmiListener.connect();
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,13 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "matritch",
 | 
			
		||||
  "version": "0.0",
 | 
			
		||||
  "description": "a matrix-twitch bridge",
 | 
			
		||||
  "main": "index.js",
 | 
			
		||||
  "repository": "https://gitea.lubiland.de/lub/matritch",
 | 
			
		||||
  "author": "lub <git@lubiland.de>",
 | 
			
		||||
  "license": "GPL-3.0-or-later",
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "matrix-appservice-bridge": "^1.11.1",
 | 
			
		||||
    "tmi.js": "^1.5.0"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
					Loading…
					
					
				
		Reference in New Issue