matrix-dimension/src/matrix/MatrixStickerBot.ts
Tony Stipanic 4954de2a96
Upgrade everything to Angular 12 and more + build changes
This is a very big commit that does an initial job of upgrading everything to the latest version. TSLint gets replaced by ESLint. Instead of plain node, now ts-node is being used. Old modules also get replaced with new ones (mostly ng2 to ngx). Also obsolete configs have been replaced with how it's used today with Angular.

This includes:

* Upgrade to:
** Angular 12
** Typescript 4
** ESLint 7 and replace TSLint
** Bootstrap 5
** Eerything connected to these
* Run with ts-node
* Convert wepack config to angular config
* Remove typescript-ioc
* Update tsconfigs
* Run a git command instead of using a library for sshort hash
* Move assets to a new location align with default Angular settings
* Database migration for new avatarUrl locations
* Simplify Model extension align with newest sequelize version
* Remove breadcrumb hack
* Fix homeserver typo
* A few general fixes that are necessary with newest Typescript rules
* Define Express.User interface
2021-08-29 19:39:43 +02:00

175 lines
7.3 KiB
TypeScript

import {
AutojoinUpgradedRoomsMixin,
MatrixClient,
SimpleFsStorageProvider,
SimpleRetryJoinStrategy
} from "matrix-bot-sdk";
import config from "../config";
import { LogService } from "matrix-js-snippets";
import StickerPack from "../db/models/StickerPack";
import Sticker from "../db/models/Sticker";
import { MatrixLiteClient } from "./MatrixLiteClient";
import { Cache, CACHE_STICKERS } from "../MemoryCache";
import { LicenseMap } from "../utils/LicenseMap";
import { OpenId } from "../models/OpenId";
class _MatrixStickerBot {
private readonly client: MatrixClient;
private updatingPackIds: { [packId: string]: boolean } = {};
constructor() {
this.client = new MatrixClient(
config.homeserver.clientServerUrl,
config.homeserver.accessToken,
new SimpleFsStorageProvider(config.database.botData));
this.client.setJoinStrategy(new SimpleRetryJoinStrategy());
this.client.on("room.event", this.onEvent.bind(this));
AutojoinUpgradedRoomsMixin.setupOnClient(this.client);
}
public start(): Promise<any> {
return this.client.start().then(() => LogService.info("MatrixStickerBot", "Sticker bot started"));
}
public getUserId(): Promise<string> {
return this.client.getUserId();
}
public getOpenId(): Promise<OpenId> {
const liteClient = new MatrixLiteClient(config.homeserver.accessToken);
return liteClient.getOpenId();
}
private async onEvent(roomId, event) {
LogService.info("MatrixStickerBot", `Event ${event.type} in ${roomId}`);
if (event.type !== "io.t2bot.stickers.metadata" || event.state_key !== "") return;
const canonicalAlias = await this.client.getRoomStateEvent(roomId, "m.room.canonical_alias", "");
const stickerPacks = await StickerPack.findAll({where: {trackingRoomAlias: canonicalAlias.alias}});
if (stickerPacks.length > 0) {
return this.updateStickersInPacks(stickerPacks, roomId);
}
}
public trackStickerpack(alias: string): Promise<any> {
return this.client.joinRoom(alias).then(async (roomId) => {
const stickerPacks = await StickerPack.findAll({where: {trackingRoomAlias: alias}});
if (stickerPacks.length > 0) {
return this.updateStickersInPacks(stickerPacks, roomId);
} else {
const pack = await StickerPack.create({
type: "stickerpack",
name: "PLACEHOLDER",
description: "PLACEHOLDER",
avatarUrl: "mxc://localhost/NotYetLoaded",
isEnabled: false,
isPublic: true,
authorType: "matrix",
authorName: await this.getUserId(),
authorReference: "https://matrix.to/#/" + (await this.getUserId()),
license: "Imported",
licensePath: "/assets/licenses/general-imported.txt",
trackingRoomAlias: alias,
});
return this.updateStickersInPacks([pack], roomId);
}
});
}
private async updateStickersInPacks(stickerPacks: StickerPack[], roomId: string) {
if (this.updatingPackIds[roomId]) return;
this.updatingPackIds[roomId] = true;
try {
const nameEvent = await this.client.getRoomStateEvent(roomId, "m.room.name", "");
if (!nameEvent) return null;
const canconicalAliasEvent = await this.client.getRoomStateEvent(roomId, "m.room.canonical_alias", "");
if (!canconicalAliasEvent) return null;
const packEvent = await this.client.getRoomStateEvent(roomId, "io.t2bot.stickers.metadata", "");
if (!packEvent) return null;
let authorDisplayName = packEvent.creatorId;
try {
const profile = await this.client.getUserProfile(packEvent.creatorId);
if (profile && profile.displayname) authorDisplayName = profile.displayname;
} catch (e) {
LogService.warn("MatrixStickerBot", e);
}
const mx = new MatrixLiteClient(config.homeserver.accessToken);
const stickerEvents = [];
for (const stickerId of packEvent.activeStickers) {
const stickerEvent = await this.client.getRoomStateEvent(roomId, "io.t2bot.stickers.sticker", stickerId);
if (!stickerEvent) continue;
const mxc = stickerEvent.contentUri;
if (!mxc.startsWith("mxc://")) continue;
const serverName = mxc.substring("mxc://".length).split("/")[0];
const contentId = mxc.substring("mxc://".length).split("/")[1];
stickerEvent.thumbMxc = await mx.uploadFromUrl(await mx.getThumbnailUrl(serverName, contentId, 512, 512, "scale", false), "image/png");
stickerEvents.push(stickerEvent);
}
const creatorId = packEvent.creatorId;
const authorName = packEvent.authorName || packEvent.creatorId;
const authorUrl = packEvent.authorUrl || `https://matrix.to/#/${packEvent.creatorId}`;
const authorIsCreator = creatorId === authorName;
let license = LicenseMap.find(packEvent.license || "");
if (!license) license = LicenseMap.find(LicenseMap.LICENSE_IMPORTED);
for (const pack of stickerPacks) {
pack.isEnabled = true;
pack.trackingRoomAlias = canconicalAliasEvent.alias;
pack.name = nameEvent.name;
if (authorIsCreator) {
pack.authorType = "matrix";
pack.authorReference = "https://matrix.to/#/" + packEvent.creatorId;
pack.authorName = authorDisplayName;
} else {
pack.authorType = "website";
pack.authorReference = authorUrl;
pack.authorName = authorName;
}
pack.description = "Matrix sticker pack created by " + authorDisplayName;
pack.license = license.name;
pack.licensePath = license.url;
if (stickerEvents.length > 0) pack.avatarUrl = stickerEvents[0].contentUri;
await pack.save();
const existingStickers = await Sticker.findAll({where: {packId: pack.id}});
for (const sticker of existingStickers) await sticker.destroy();
for (const stickerEvent of stickerEvents) {
await Sticker.create({
packId: pack.id,
name: stickerEvent.description,
description: stickerEvent.description,
imageMxc: stickerEvent.contentUri,
thumbnailMxc: stickerEvent.thumbMxc,
thumbnailWidth: 512,
thumbnailHeight: 512,
mimetype: "image/png",
});
}
}
LogService.info("MatrixStickerBot", `Updated ${stickerPacks.length} stickerpacks`);
Cache.for(CACHE_STICKERS).clear();
} catch (e) {
LogService.error("MatrixStickerBot", e);
}
delete this.updatingPackIds[roomId];
}
}
export const MatrixStickerBot = new _MatrixStickerBot();