-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Matrix bridge #46
Matrix bridge #46
Changes from 16 commits
df1e8d0
ca9a53c
4f971cb
bf2d142
37becfc
3d537ef
5488466
85e094e
0cff1f8
3bf7ac6
8d6dc72
acda0cd
2ce6947
12febf3
aff713c
5c71723
faad273
b7eab78
b67ea7c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,3 +2,4 @@ | |
/config | ||
/config.ts | ||
/docker-compose.yml | ||
db | ||
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
|
@@ -16,11 +16,11 @@ export async function onEvent(this: MatrixPlugin, request: Request<WeakEvent>) { | |||||||
this.emit('debug', `Failed to join room ${event.room_id}: ${e}`); | ||||||||
} | ||||||||
} | ||||||||
if (event.type === 'm.room.message' && !event['m.new_content']) { | ||||||||
this.emit('messageCreate', await messageToCore(event, intent)); | ||||||||
if (event.type === 'm.room.message' && !event.content['m.new_content']) { | ||||||||
this.emit('messageCreate', await messageToCore(event, intent, this.config.homeserverUrl)); | ||||||||
austinhuang0131 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||
} | ||||||||
if (event.type === 'm.room.message' && event['m.new_content']) { | ||||||||
this.emit('messageUpdate', await messageToCore(event, intent)); | ||||||||
if (event.type === 'm.room.message' && event.content['m.new_content']) { | ||||||||
this.emit('messageUpdate', await messageToCore(event, intent, this.config.homeserverUrl)); | ||||||||
austinhuang0131 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||
} | ||||||||
if (event.type === 'm.room.redaction') { | ||||||||
this.emit('messageDelete', { | ||||||||
|
@@ -34,20 +34,23 @@ export async function onEvent(this: MatrixPlugin, request: Request<WeakEvent>) { | |||||||
|
||||||||
export async function messageToCore( | ||||||||
event: WeakEvent, | ||||||||
intent: Intent | ||||||||
intent: Intent, | ||||||||
homeserverUrl: String | ||||||||
austinhuang0131 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||
): Promise<BoltMessage<WeakEvent>> { | ||||||||
const sender = await intent.getProfileInfo(event.sender); | ||||||||
return { | ||||||||
author: { | ||||||||
username: sender.displayname || event.sender, | ||||||||
rawname: event.sender, | ||||||||
id: event.sender, | ||||||||
profile: sender.avatar_url | ||||||||
profile: `${sender.avatar_url.replace("mxc://", `${homeserverUrl}/_matrix/media/v3/thumbnail/`)}?width=96&height=96&method=scale` | ||||||||
austinhuang0131 marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
}, | ||||||||
channel: event.room_id, | ||||||||
id: event.event_id, | ||||||||
id: event.content['m.relates_to']?.rel_type == "m.replace" | ||||||||
? event.content['m.relates_to'].event_id | ||||||||
: event.event_id, | ||||||||
timestamp: event.origin_server_ts, | ||||||||
content: event.content.body as string, | ||||||||
content: (event.content['m.new_content']?.body || event.content.body) as string, | ||||||||
reply: async (msg: BoltMessage<unknown>) => { | ||||||||
await intent.sendMessage(event.room_id, coreToMessage(msg)); | ||||||||
}, | ||||||||
|
@@ -57,11 +60,9 @@ export async function messageToCore( | |||||||
|
||||||||
export function coreToMessage(msg: BoltMessage<unknown>) { | ||||||||
return { | ||||||||
content: { | ||||||||
body: msg.content | ||||||||
? msg.content | ||||||||
: "*this bridge doesn't support anything except text at the moment*", | ||||||||
msgtype: 'm.text' | ||||||||
} | ||||||||
body: msg.content | ||||||||
? msg.content | ||||||||
: "*this bridge doesn't support anything except text at the moment*", | ||||||||
msgtype: 'm.text' | ||||||||
}; | ||||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,13 +5,15 @@ import { | |
BoltMessage, | ||
BoltPlugin, | ||
Bridge, | ||
Buffer, | ||
ClientEncryptionSession, | ||
MatrixUser, | ||
existsSync | ||
} from './deps.ts'; | ||
import { coreToMessage, onEvent } from './events.ts'; | ||
|
||
type MatrixConfig = { | ||
accessToken: string; | ||
appserviceUrl: string; | ||
williamhorning marked this conversation as resolved.
Show resolved
Hide resolved
|
||
homeserverUrl: string; | ||
domain: string; | ||
port?: number; | ||
|
@@ -21,7 +23,7 @@ type MatrixConfig = { | |
export default class MatrixPlugin extends BoltPlugin { | ||
bot: Bridge; | ||
config: MatrixConfig; | ||
name = 'bolt-revolt'; | ||
name = 'bolt-matrix'; | ||
version = '0.5.4'; | ||
bolt?: Bolt; | ||
constructor(config: MatrixConfig) { | ||
|
@@ -31,23 +33,6 @@ export default class MatrixPlugin extends BoltPlugin { | |
homeserverUrl: this.config.homeserverUrl, | ||
domain: this.config.domain, | ||
registration: this.config.reg_path, | ||
bridgeEncryption: { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there any reason to remove all the encryption code? I'd prefer it if bolt-matrix supported encrypted rooms but if there's a reason I guess that's fine There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. because it doesn't launch on my end with it, i might revisit it in the future, but almost all matrix-appservice-${platform} don't have encryption There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ah okay, i guess we could go back to that in the future then |
||
homeserverUrl: config.homeserverUrl, | ||
store: { | ||
getStoredSession: async (userId: string) => { | ||
return JSON.parse( | ||
(await this.bolt?.redis?.get(`mtx-session-${userId}`)) || 'null' | ||
); | ||
}, | ||
setStoredSession: async (session: ClientEncryptionSession) => { | ||
await this.bolt?.redis?.set( | ||
`mtx-session-${session.userId}`, | ||
JSON.stringify(session) | ||
); | ||
}, | ||
async updateSyncToken() {} | ||
} | ||
}, | ||
controller: { | ||
onEvent: onEvent.bind(this) | ||
}, | ||
|
@@ -59,16 +44,14 @@ export default class MatrixPlugin extends BoltPlugin { | |
async start(bolt: Bolt) { | ||
this.bolt = bolt; | ||
if (!existsSync(this.config.reg_path)) { | ||
const reg = new AppServiceRegistration(this.config.homeserverUrl); | ||
const reg = new AppServiceRegistration(this.config.appserviceUrl); | ||
reg.setAppServiceToken(AppServiceRegistration.generateToken()); | ||
reg.setHomeserverToken(AppServiceRegistration.generateToken()); | ||
reg.setId( | ||
'b4d15f02f7e406db25563c1a74ac78863dc4fbcc5595db8d835f6ee6ffef1448' | ||
); | ||
reg.setId(AppServiceRegistration.generateToken()); | ||
austinhuang0131 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
reg.setProtocols(['bolt']); | ||
reg.setRateLimited(false); | ||
reg.setSenderLocalpart('boltbot'); | ||
reg.addRegexPattern('users', '@bolt_*', true); | ||
reg.setSenderLocalpart('bot.bolt'); | ||
reg.addRegexPattern('users', `@bolt-.+_.+:${this.config.domain}`, true); | ||
reg.outputAsYaml(this.config.reg_path); | ||
} | ||
await this.bot.run(this.config.port || 8081); | ||
|
@@ -79,15 +62,30 @@ export default class MatrixPlugin extends BoltPlugin { | |
return channelId; | ||
} | ||
async bridgeMessage(data: BoltBridgeMessageArgs) { | ||
const intent = this.bot.getIntent( | ||
`${data.data.platform.name}_${ | ||
'author' in data.data ? data.data.author.id : 'deletion' | ||
}` | ||
); | ||
const room = data.data.bridgePlatform.senddata as string; | ||
switch (data.type) { | ||
case 'create': | ||
case 'update': { | ||
const name = `@${data.data.platform.name}_${data.data.author.id}:${this.config.domain}`; | ||
const intent = this.bot.getIntent(name); | ||
// check for profile | ||
await intent.ensureProfile(data.data.author.username); | ||
const store = this.bot.getUserStore(); | ||
let storeUser = await store?.getMatrixUser(name); | ||
if (!storeUser) { | ||
storeUser = new MatrixUser(name); | ||
} | ||
if (storeUser?.get("avatar") != data.data.author.profile) { | ||
storeUser?.set("avatar", data.data.author.profile); | ||
let b = await (await fetch(data.data.author.profile)).blob(); | ||
const newMxc = await intent.uploadContent( | ||
Buffer.from(await b.arrayBuffer()), | ||
{ type: b.type } | ||
); | ||
await intent.ensureProfile(data.data.author.username, newMxc); | ||
await store?.setMatrixUser(storeUser); | ||
} | ||
// now to our message | ||
const message = coreToMessage( | ||
data.data as unknown as BoltMessage<unknown> | ||
); | ||
|
@@ -113,15 +111,13 @@ export default class MatrixPlugin extends BoltPlugin { | |
}; | ||
} | ||
case 'delete': { | ||
await intent.sendEvent(room, 'm.room.redaction', { | ||
content: { | ||
reason: 'bridge message deletion' | ||
}, | ||
redacts: data.data.id | ||
}); | ||
const intent = this.bot.getIntent(); | ||
await intent.botSdkIntent.underlyingClient.redactEvent( | ||
room, data.data.id, 'bridge message deletion' | ||
); | ||
return { | ||
channel: room, | ||
id: data.data.id, | ||
id: data.data.id, | ||
plugin: 'bolt-matrix', | ||
senddata: room | ||
}; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.