Skip to content

Commit

Permalink
feat: add file upload
Browse files Browse the repository at this point in the history
  • Loading branch information
pierreozoux committed Apr 9, 2024
1 parent 42f4529 commit a437a75
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 3 deletions.
1 change: 1 addition & 0 deletions src/handlers/messages.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const rcMessage: RcMessage = {
ts: {
$date: '1970-01-02T06:51:51.0Z', // UNIX-TS: 111111000
},
type: 'm.text'
}

const matrixMessage: MatrixMessage = {
Expand Down
104 changes: 101 additions & 3 deletions src/handlers/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@ import {
getMessageId,
getRoomId,
getUserId,
getAccessToken,
getUserMappingByName,
save,
} from '../helpers/storage'
import { axios, formatUserSessionOptions } from '../helpers/synapse'
import reactionKeys from '../reactions.json'
import { executeAndHandleMissingMember } from './rooms'
import { AxiosError } from 'axios'
import * as fs from 'fs'

const applicationServiceToken = process.env.AS_TOKEN || ''
if (!applicationServiceToken) {
Expand All @@ -22,6 +24,16 @@ if (!applicationServiceToken) {
throw new Error(message)
}

type attachment = {
type?: string
description?: string
message_link?: string
image_url?: string
image_type?: string
title: string
title_link?: string
}

/**
* Type of Rocket.Chat messages
*/
Expand All @@ -30,6 +42,14 @@ export type RcMessage = {
t?: string // Event type
rid: string // The unique id for the room
msg: string // The content of the message.
attachments?: attachment[]
file?: {
_id: string
name: string
type: string
url: string
}
type: string
tmid?: string
ts: {
$date: string
Expand Down Expand Up @@ -60,7 +80,7 @@ export type RcMessage = {
*/
export type MatrixMessage = {
body: string
msgtype: 'm.text'
msgtype: string
type: 'm.room.message'
'm.relates_to'?: {
rel_type: 'm.thread'
Expand All @@ -70,6 +90,7 @@ export type MatrixMessage = {
event_id: string
}
}
url?: string
}

/**
Expand All @@ -87,7 +108,7 @@ export type ReactionKeys = {
export function mapMessage(rcMessage: RcMessage): MatrixMessage {
return {
body: rcMessage.msg,
msgtype: 'm.text',
msgtype: rcMessage.type,
type: 'm.room.message',
}
}
Expand Down Expand Up @@ -135,6 +156,43 @@ export async function createMessage(
).data.event_id
}

/**
* Send a File to Synapse
* @param user_id The user the media will be posted by
* @param ts The timestamp to which the file will be dated
* @param filePath the path on the local filesystem
* @param fileName the filename
* @param content_type: Content type of the file
* @returns The Matrix Message/event ID
*/
export async function uploadFile(
user_id: string,
ts: number,
filePath: string,
fileName: string,
content_type: string
): Promise<string> {
const fileStream = fs.createReadStream(filePath);
const accessToken = await getAccessToken(user_id)
log.http(
`Uploading ${fileName}...`
)

return (
await axios.post(
`/_matrix/media/v3/upload?user_id=${user_id}&ts=${ts}&filename=${fileName}`,
fileStream,
{
headers: {
"Content-Type": content_type,
"Content-Length": fs.statSync(filePath).size,
"Authorization": `Bearer ${accessToken}`
}
}
)
).data.content_uri
}

/**
* Add reactions to the event
* @param reactions A Rocket.Chat reactions object
Expand Down Expand Up @@ -301,6 +359,44 @@ export async function handle(rcMessage: RcMessage): Promise<void> {
}
}

const ts = new Date(rcMessage.ts.$date).valueOf()
if (rcMessage.file) {
if (rcMessage.attachments?.length == 1) {
const path = "./inputs/files/" + rcMessage.file._id
if (!fs.existsSync(path)) {
log.warn(
`File doesn't exist locally, skipping Upload.`
)
return

}
const mxcurl = await uploadFile(rcMessage.u._id, ts, path, rcMessage.file.name, rcMessage.file.type)
rcMessage.msg = rcMessage.file.name
rcMessage.file.url = mxcurl
if (rcMessage.attachments[0].image_type) {
rcMessage.type = 'm.image'
} else {
rcMessage.type = 'm.file'
}
} else {
log.warn(
`Many attachments in ${rcMessage.u._id} not handled, skipping Upload.`
)
return
}
} else if (rcMessage.attachments && rcMessage.attachments.length > 0) {
log.warn(
`Attachment in ${rcMessage.u._id} not handled, skipping.`
)
return
} else {
rcMessage.type = 'm.text'
}

await handleMessage(rcMessage, room_id, ts)
}

async function handleMessage(rcMessage: RcMessage, room_id: string, ts: number) {
const user_id = await getUserId(rcMessage.u._id)
if (!user_id) {
log.warn(
Expand All @@ -309,7 +405,9 @@ export async function handle(rcMessage: RcMessage): Promise<void> {
return
}
const matrixMessage = mapMessage(rcMessage)
const ts = new Date(rcMessage.ts.$date).valueOf()
if (rcMessage.file) {
matrixMessage.url = rcMessage.file.url
}

if (rcMessage.tmid) {
const event_id = await getMessageId(rcMessage.tmid)
Expand Down

0 comments on commit a437a75

Please sign in to comment.