Add image/audio/file/location bridging. Fixes #9
This commit is contained in:
Generated
+5
@@ -1652,6 +1652,11 @@
|
|||||||
"object-assign": "4.1.1"
|
"object-assign": "4.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"file-type": {
|
||||||
|
"version": "7.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/file-type/-/file-type-7.3.0.tgz",
|
||||||
|
"integrity": "sha1-GIaXYOEMNsBBbVMINoT8/A1Z3zo="
|
||||||
|
},
|
||||||
"finalhandler": {
|
"finalhandler": {
|
||||||
"version": "0.3.6",
|
"version": "0.3.6",
|
||||||
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-0.3.6.tgz",
|
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-0.3.6.tgz",
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
"colors": "1.1.x",
|
"colors": "1.1.x",
|
||||||
"commander": "2.12.x",
|
"commander": "2.12.x",
|
||||||
"escape-html": "1.0.x",
|
"escape-html": "1.0.x",
|
||||||
|
"file-type": "^7.3.0",
|
||||||
"marked": "0.3.x",
|
"marked": "0.3.x",
|
||||||
"matrix-appservice-bridge": "1.x.x",
|
"matrix-appservice-bridge": "1.x.x",
|
||||||
"matrix-js-sdk": "0.x.x",
|
"matrix-js-sdk": "0.x.x",
|
||||||
|
|||||||
+45
-7
@@ -64,8 +64,36 @@ class Portal {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async copyPhotoSize(telegramPOV, sender, photo) {
|
||||||
|
const size = photo.sizes.slice(-1)[0]
|
||||||
|
const uploaded = await this.copyFile(telegramPOV, sender, size.location, photo.id)
|
||||||
|
uploaded.info.h = size.h
|
||||||
|
uploaded.info.w = size.w
|
||||||
|
uploaded.info.size = size.size
|
||||||
|
uploaded.info.orientation = 0
|
||||||
|
return uploaded
|
||||||
|
}
|
||||||
|
|
||||||
|
async copyFile(telegramPOV, sender, location, id) {
|
||||||
|
console.log(JSON.stringify(location, "", " "))
|
||||||
|
id = id || location.id
|
||||||
|
const file = await telegramPOV.getFile(location)
|
||||||
|
const uploaded = await sender.intent.getClient().uploadContent({
|
||||||
|
stream: file.buffer,
|
||||||
|
name: `${id}.${file.extension}`,
|
||||||
|
type: file.mimetype,
|
||||||
|
}, { rawResponse: false })
|
||||||
|
uploaded.matrixtype = file.matrixtype
|
||||||
|
uploaded.info = {
|
||||||
|
mimetype: file.mimetype,
|
||||||
|
size: location.size,
|
||||||
|
}
|
||||||
|
return uploaded
|
||||||
|
}
|
||||||
|
|
||||||
async updateAvatar(telegramPOV, chat) {
|
async updateAvatar(telegramPOV, chat) {
|
||||||
if (!chat.photo) {
|
if (!chat.photo || this.peer.type === "user") {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,12 +108,11 @@ class Portal {
|
|||||||
const file = await telegramPOV.getFile(photo)
|
const file = await telegramPOV.getFile(photo)
|
||||||
const name = `${photo.volume_id}_${photo.local_id}.${file.extension}`
|
const name = `${photo.volume_id}_${photo.local_id}.${file.extension}`
|
||||||
|
|
||||||
const uploaded = await this.app.botIntent.getClient()
|
const uploaded = await this.app.botIntent.getClient().uploadContent({
|
||||||
.uploadContent({
|
stream: file.buffer,
|
||||||
stream: Buffer.from(file.bytes),
|
name,
|
||||||
name,
|
type: file.mimetype,
|
||||||
type: file.mimetype,
|
}, { rawResponse: false })
|
||||||
}, { rawResponse: false })
|
|
||||||
|
|
||||||
this.avatarURL = uploaded.content_uri
|
this.avatarURL = uploaded.content_uri
|
||||||
this.photo = {
|
this.photo = {
|
||||||
@@ -113,6 +140,17 @@ class Portal {
|
|||||||
if (evt.text.length > 0) {
|
if (evt.text.length > 0) {
|
||||||
sender.sendText(this.roomID, evt.text)
|
sender.sendText(this.roomID, evt.text)
|
||||||
}
|
}
|
||||||
|
if (evt.photo) {
|
||||||
|
const photo = await this.copyPhoto(evt.source, sender, evt.photo)
|
||||||
|
photo.name = evt.caption || "Photo"
|
||||||
|
sender.sendFile(this.roomID, photo)
|
||||||
|
} else if (evt.document) {
|
||||||
|
const file = await this.copyFile(evt.source, sender, evt.document)
|
||||||
|
file.name = evt.caption || "File upload"
|
||||||
|
sender.sendFile(this.roomID, file)
|
||||||
|
} else if (evt.geo) {
|
||||||
|
sender.sendLocation(this.roomID, evt.geo)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async handleMatrixEvent(sender, evt) {
|
async handleMatrixEvent(sender, evt) {
|
||||||
|
|||||||
+87
-20
@@ -14,25 +14,56 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
const telegram = require("telegram-mtproto")
|
const telegram = require("telegram-mtproto")
|
||||||
|
const fileType = require("file-type")
|
||||||
const pkg = require("../package.json")
|
const pkg = require("../package.json")
|
||||||
const TelegramPeer = require("./telegram-peer")
|
const TelegramPeer = require("./telegram-peer")
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mapping from Telegram file types to MIME types and extensions.
|
* Mapping from Telegram file types to MIME types and extensions.
|
||||||
*/
|
*/
|
||||||
const META_FROM_FILETYPE = {
|
function metaFromFileType(type) {
|
||||||
"storage.fileGif": {
|
const extension = type.substr("storage.file".length).toLowerCase()
|
||||||
mimetype: "image/gif",
|
let fileClass, mimetype, matrixtype
|
||||||
extension: "gif",
|
/*eslint no-fallthrough: "off"*/
|
||||||
},
|
switch (type) {
|
||||||
"storage.fileJpeg": {
|
case "storage.fileGif":
|
||||||
mimetype: "image/jpeg",
|
case "storage.fileJpeg":
|
||||||
extension: "jpeg",
|
case "storage.filePng":
|
||||||
},
|
case "storage.fileWebp":
|
||||||
"storage.filePng": {
|
fileClass = "image"
|
||||||
mimetype: "image/png",
|
break
|
||||||
extension: "png",
|
case "storage.fileMov":
|
||||||
},
|
mimetype = "quicktime"
|
||||||
|
case "storage.fileMp4":
|
||||||
|
fileClass = "video"
|
||||||
|
break
|
||||||
|
case "storage.fileMp3":
|
||||||
|
mimetype = "mpeg"
|
||||||
|
fileClass = "audio"
|
||||||
|
break
|
||||||
|
case "storage.filePartial":
|
||||||
|
throw new Error("Partial files should be completed before fetching their type.")
|
||||||
|
case "storage.fileUnknown":
|
||||||
|
fileClass = "application"
|
||||||
|
mimetype = "octet-stream"
|
||||||
|
matrixtype = "m.file"
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
mimetype = `${fileClass}/${mimetype || extension}`
|
||||||
|
matrixtype = matrixtype || `m.${fileClass}`
|
||||||
|
return { mimetype, extension, matrixtype }
|
||||||
|
}
|
||||||
|
|
||||||
|
function matrixFromMime(mime) {
|
||||||
|
if (mime.startsWith("audio/")) {
|
||||||
|
return "m.audio"
|
||||||
|
} else if (mime.startsWith("video/")) {
|
||||||
|
return "m.video"
|
||||||
|
} else if (mime.startsWith("image/")) {
|
||||||
|
return "m.image"
|
||||||
|
}
|
||||||
|
return "m.file"
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -278,6 +309,18 @@ class TelegramPuppet {
|
|||||||
to,
|
to,
|
||||||
source: this,
|
source: this,
|
||||||
text: update.message,
|
text: update.message,
|
||||||
|
photo: update.media && update.media._ === "messageMediaPhoto"
|
||||||
|
? update.media.photo
|
||||||
|
: undefined,
|
||||||
|
document: update.media && update.media._ === "messageMediaDocument"
|
||||||
|
? update.media.document
|
||||||
|
: undefined,
|
||||||
|
geo: update.media && update.media._ === "messageMediaGeo"
|
||||||
|
? update.media.geo
|
||||||
|
: undefined,
|
||||||
|
caption: update.media ?
|
||||||
|
update.media.caption
|
||||||
|
: undefined,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -352,17 +395,41 @@ class TelegramPuppet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async getFile(location) {
|
async getFile(location) {
|
||||||
location = Object.assign({}, location, { _: "inputFileLocation" })
|
if (location.volume_id && location.local_id) {
|
||||||
delete location.dc_id
|
location = {
|
||||||
|
_: "inputFileLocation",
|
||||||
|
volume_id: location.volume_id,
|
||||||
|
local_id: location.local_id,
|
||||||
|
secret: location.secret,
|
||||||
|
}
|
||||||
|
} else if (location.id && location.access_hash) {
|
||||||
|
location = {
|
||||||
|
_: "inputDocumentFileLocation",
|
||||||
|
id: location.id,
|
||||||
|
access_hash: location.access_hash,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new Error("Unrecognized file location type.")
|
||||||
|
}
|
||||||
const file = await this.client("upload.getFile", {
|
const file = await this.client("upload.getFile", {
|
||||||
location,
|
location,
|
||||||
offset: 0,
|
offset: 0,
|
||||||
|
// Max download size: 100mb
|
||||||
limit: 100 * 1024 * 1024,
|
limit: 100 * 1024 * 1024,
|
||||||
})
|
})
|
||||||
const meta = META_FROM_FILETYPE[file.type._]
|
file.buffer = Buffer.from(file.bytes)
|
||||||
if (meta) {
|
if (file.type._ === "storage.filePartial") {
|
||||||
file.mimetype = meta.mimetype
|
const { mime, ext } = fileType(file.buffer)
|
||||||
file.extension = meta.extension
|
file.mimetype = mime
|
||||||
|
file.extension = ext
|
||||||
|
file.matrixtype = matrixFromMime(mime)
|
||||||
|
} else {
|
||||||
|
const meta = metaFromFileType(file.type._)
|
||||||
|
if (meta) {
|
||||||
|
file.mimetype = meta.mimetype
|
||||||
|
file.extension = meta.extension
|
||||||
|
file.matrixtype = meta.matrixtype
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return file
|
return file
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-5
@@ -138,12 +138,20 @@ class TelegramUser {
|
|||||||
return this.intent.sendText(roomID, text)
|
return this.intent.sendText(roomID, text)
|
||||||
}
|
}
|
||||||
|
|
||||||
sendImage(roomID, opts) {
|
sendFile(roomID, file) {
|
||||||
return this.intent.sendMessage(roomID, {
|
return this.intent.sendMessage(roomID, {
|
||||||
msgtype: "m.image",
|
msgtype: file.matrixtype || "m.file",
|
||||||
url: opts.content_uri,
|
url: file.content_uri,
|
||||||
body: opts.name,
|
body: file.name || "Uploaded file",
|
||||||
info: opts.info,
|
info: file.info,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
sendLocation(roomID, { long = 0.0, lat = 0.0, body = "Location" } = {}) {
|
||||||
|
return this.intent.sendMessage(roomID, {
|
||||||
|
msgtype: "m.location",
|
||||||
|
geo_uri: `geo:${lat},${long}`,
|
||||||
|
body,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user