Add Message implementation

This commit is contained in:
Henrik Hüttemann 2023-08-18 15:30:53 +02:00
parent 5e6f23aab4
commit 787c0c092f
No known key found for this signature in database
GPG Key ID: 9F7BD10E0A8A111E
2 changed files with 131 additions and 1 deletions

View File

@ -4,6 +4,7 @@ import lineByLine from 'n-readlines'
import 'reflect-metadata' import 'reflect-metadata'
import { handle as handleRoom } from './handlers/rooms' import { handle as handleRoom } from './handlers/rooms'
import { handle as handleUser } from './handlers/users' import { handle as handleUser } from './handlers/users'
import { handle as handleMessage } from './handlers/messages'
import log from './helpers/logger' import log from './helpers/logger'
import { initStorage } from './helpers/storage' import { initStorage } from './helpers/storage'
import { whoami } from './helpers/synapse' import { whoami } from './helpers/synapse'
@ -27,7 +28,7 @@ async function loadRcExport(entity: Entity) {
break break
case Entity.Messages: case Entity.Messages:
log.debug(`Message: ${item.name}`) await handleMessage(item)
break break
default: default:
@ -44,6 +45,8 @@ async function main() {
await loadRcExport(Entity.Users) await loadRcExport(Entity.Users)
log.info('Parsing rooms') log.info('Parsing rooms')
await loadRcExport(Entity.Rooms) await loadRcExport(Entity.Rooms)
log.info('Parsing messages')
await loadRcExport(Entity.Messages)
log.info('Done.') log.info('Done.')
} catch (error) { } catch (error) {
log.error(`Encountered an error while booting up: ${error}`, error) log.error(`Encountered an error while booting up: ${error}`, error)

127
src/handlers/messages.ts Normal file
View File

@ -0,0 +1,127 @@
import { Entity, entities } from '../Entities'
import { IdMapping } from '../entity/IdMapping'
import log from '../helpers/logger'
import { getMessageId, getRoomId, getUserId, save } from '../helpers/storage'
import { axios, formatUserSessionOptions } from '../helpers/synapse'
const applicationServiceToken = process.env.AS_TOKEN || ''
if (!applicationServiceToken) {
const message = 'No AS_TOKEN found in .env.'
log.error(message)
throw new Error(message)
}
export type RcMessage = {
_id: string
rid: string // The unique id for the room
msg: string // The content of the message.
tmid?: string
ts: {
$date: string
}
mentions?: string[]
u: {
_id: string
username?: string
name?: string
}
md?: any // The message's content in a markdown format.
pinned?: boolean
drid?: string // The direct room id (if belongs to a direct room).
attachments?: any[] // An array of attachment objects, available only when the message has at least one attachment.
reactions?: object // Object containing reaction information associated with the message.
}
export type MatrixMessage = {
body: string
msgtype: 'm.text'
type: 'm.room.message'
'm.relates_to'?: {
rel_type: 'm.thread'
event_id: string
is_falling_back: true
'm.in_reply_to': {
event_id: string
}
}
}
export function mapMessage(rcMessage: RcMessage): MatrixMessage {
return {
body: rcMessage.msg,
msgtype: 'm.text',
type: 'm.room.message',
}
}
export async function createMapping(
rcId: string,
matrixId: string
): Promise<void> {
const messageMapping = new IdMapping()
messageMapping.rcId = rcId
messageMapping.matrixId = matrixId
messageMapping.type = entities[Entity.Messages].mappingType
await save(messageMapping)
log.debug('Mapping added:', messageMapping)
}
export async function createMessage(
matrixMessage: MatrixMessage,
room_id: string,
user_id: string,
ts: number,
transactionId: string
): Promise<string> {
return (
await axios.put(
`/_matrix/client/v3/rooms/${room_id}/send/m.room.message/${transactionId}?user_id=${user_id}&ts=${ts}`,
matrixMessage,
formatUserSessionOptions(applicationServiceToken)
)
).data.event_id
}
export async function handle(rcMessage: RcMessage): Promise<void> {
const room_id = (await getRoomId(rcMessage.rid)) || ''
if (!room_id) {
log.info(
`Could not find room ${rcMessage.rid} for message ${rcMessage._id}, skipping.`
)
return
}
const user_id = (await getUserId(rcMessage.u._id)) || ''
if (!user_id) {
log.info(
`Could not find author ${rcMessage.u.username} for message ${rcMessage._id}, skipping.`
)
return
}
const matrixMessage = mapMessage(rcMessage)
const ts = new Date(rcMessage.ts.$date).valueOf()
if (rcMessage.tmid) {
const event_id = (await getMessageId(rcMessage.tmid)) || ''
matrixMessage['m.relates_to'] = {
rel_type: 'm.thread',
event_id,
is_falling_back: true,
'm.in_reply_to': {
event_id,
},
}
}
const event_id = await createMessage(
matrixMessage,
room_id,
user_id,
ts,
rcMessage._id
)
createMapping(rcMessage._id, event_id)
}