Browse Source

initial version

it supports bi-direcitonal text, after manually filling the database :)
master
lub 3 years ago
commit
5ae481ccf2
  1. 3
      .gitignore
  2. 117
      index.js
  3. 13
      package.json
  4. 1311
      yarn.lock

3
.gitignore vendored

@ -0,0 +1,3 @@
node_modules
matritch-registration.yaml
*.db

117
index.js

@ -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();
}

13
package.json

@ -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"
}
}

1311
yarn.lock

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save