多分動くと思うからリリースしようぜ

This commit is contained in:
mattyatea 2023-12-23 10:44:01 +09:00
parent 68b48bc16f
commit 2a9ddf2bc8
16 changed files with 161 additions and 433 deletions

View file

@ -549,4 +549,9 @@ export class MiMeta {
default: 0,
})
public notesPerOneAd: number;
@Column('boolean', {
default: false,
})
public requestEmojiAllOk: boolean;
}

View file

@ -1,129 +0,0 @@
import { Inject, Injectable } from '@nestjs/common';
import { Endpoint } from '@/server/api/endpoint-base.js';
import type { DriveFilesRepository } from '@/models/_.js';
import { DI } from '@/di-symbols.js';
import { CustomEmojiService } from '@/core/CustomEmojiService.js';
import { ModerationLogService } from '@/core/ModerationLogService.js';
import { ApiError } from '../../../error.js';
import { MetaService } from '@/core/MetaService.js';
import {DriveService} from "@/core/DriveService.js";
export const meta = {
tags: ['admin'],
requireCredential: true,
requireRolePolicy: 'canRequestCustomEmojis',
errors: {
noSuchFile: {
message: 'No such file.',
code: 'NO_SUCH_FILE',
id: 'fc46b5a4-6b92-4c33-ac66-b806659bb5cf',
},
},
} as const;
export const paramDef = {
type: 'object',
properties: {
name: { type: 'string', pattern: '^[a-zA-Z0-9_]+$' },
category: {
type: 'string',
nullable: true,
description: 'Use `null` to reset the category.',
},
aliases: { type: 'array', items: {
type: 'string',
} },
license: { type: 'string', nullable: true },
fileId: { type: 'string', format: 'misskey:id' },
isSensitive: { type: 'boolean' },
localOnly: { type: 'boolean' },
isNotifyIsHome: { type: 'boolean', default: false },
},
required: ['name', 'fileId'],
} as const;
// TODO: ロジックをサービスに切り出す
// eslint-disable-next-line import/no-default-export
@Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> {
constructor(
@Inject(DI.driveFilesRepository)
private driveFilesRepository: DriveFilesRepository,
private metaService: MetaService,
private customEmojiService: CustomEmojiService,
private moderationLogService: ModerationLogService,
private driveService: DriveService,
) {
super(meta, paramDef, async (ps, me) => {
let driveFile;
let tmp = await this.driveFilesRepository.findOneBy({ id: ps.fileId });
if (tmp == null) throw new ApiError(meta.errors.noSuchFile);
try {
driveFile = await this.driveService.uploadFromUrl({ url: tmp.url , user: null, force: true });
} catch (e) {
throw new ApiError();
}
const emoji = await this.customEmojiService.add({
driveFile,
name: ps.name,
category: ps.category ?? null,
aliases: ps.aliases ?? [],
license: ps.license ?? null,
host: null,
draft: false,
isSensitive: ps.isSensitive ?? false,
localOnly: ps.localOnly ?? false,
roleIdsThatCanBeUsedThisEmojiAsReaction: [],
});
const {ApiBase,EmojiBotToken,DiscordWebhookUrl} = (await this.metaService.fetch())
if (EmojiBotToken){
const data_Miss = {
'i': EmojiBotToken,
'visibility': ps.isNotifyIsHome ? 'home' : 'public',
'text':
'絵文字名 : :' + ps.name + ':\n' +
'カテゴリ : ' + ps.category + '\n' +
'ライセンス : ' + ps.license + '\n' +
'タグ : ' + ps.aliases + '\n' +
'追加したユーザー : ' + '@' + me.username + '\n'
};
await fetch(ApiBase+'/notes/create', {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body:JSON.stringify( data_Miss)
})
}
if (DiscordWebhookUrl){
const data_disc = {"username": "絵文字追加通知ちゃん",
'content':
'絵文字名 : :'+ ps.name +':\n' +
'カテゴリ : ' + ps.category + '\n'+
'ライセンス : '+ ps.license + '\n'+
'タグ : '+ps.aliases+ '\n'+
'追加したユーザー : ' + '@'+me.username + '\n'
}
await fetch(DiscordWebhookUrl, {
'method':'post',
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(data_disc),
})
}
return {
id: emoji.id,
};
});
}
}

View file

@ -5,6 +5,8 @@ import { DI } from '@/di-symbols.js';
import { CustomEmojiService } from '@/core/CustomEmojiService.js';
import { ModerationLogService } from '@/core/ModerationLogService.js';
import { ApiError } from '../../../error.js';
import {MetaService} from "@/core/MetaService.js";
import {DriveService} from "@/core/DriveService.js";
export const meta = {
tags: ['admin'],
@ -54,9 +56,9 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
constructor(
@Inject(DI.driveFilesRepository)
private driveFilesRepository: DriveFilesRepository,
private metaService: MetaService,
private customEmojiService: CustomEmojiService,
private driveService: DriveService,
private moderationLogService: ModerationLogService,
) {
super(meta, paramDef, async (ps, me) => {
@ -64,25 +66,81 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
const isRequestDuplicate = await this.customEmojiService.checkRequestDuplicate(ps.name);
if (isDuplicate || isRequestDuplicate) throw new ApiError(meta.errors.duplicateName);
const driveFile = await this.driveFilesRepository.findOneBy({ id: ps.fileId });
let driveFile;
driveFile = await this.driveFilesRepository.findOneBy({ id: ps.fileId });
if (driveFile == null) throw new ApiError(meta.errors.noSuchFile);
const emoji = await this.customEmojiService.request({
driveFile,
name: ps.name,
category: ps.category ?? null,
aliases: ps.aliases ?? [],
license: ps.license ?? null,
isSensitive: ps.isSensitive ?? false,
localOnly: ps.localOnly ?? false,
});
if (driveFile == null) throw new ApiError(meta.errors.noSuchFile);
const {ApiBase,EmojiBotToken,DiscordWebhookUrl,requestEmojiAllOk} = (await this.metaService.fetch())
let emoji;
if (requestEmojiAllOk){
emoji = await this.customEmojiService.add({
driveFile,
name: ps.name,
category: ps.category ?? null,
aliases: ps.aliases ?? [],
license: ps.license ?? null,
host: null,
draft: false,
isSensitive: ps.isSensitive ?? false,
localOnly: ps.localOnly ?? false,
roleIdsThatCanBeUsedThisEmojiAsReaction: [],
});
}else{
emoji = await this.customEmojiService.request({
driveFile,
name: ps.name,
category: ps.category ?? null,
aliases: ps.aliases ?? [],
license: ps.license ?? null,
isSensitive: ps.isSensitive ?? false,
localOnly: ps.localOnly ?? false,
});
}
await this.moderationLogService.log(me, 'addCustomEmoji', {
emojiId: emoji.id,
emoji: emoji,
});
if (EmojiBotToken){
const data_Miss = {
'i': EmojiBotToken,
'visibility': ps.isNotifyIsHome ? 'home' : 'public',
'text':
'絵文字名 : :' + ps.name + ':\n' +
'カテゴリ : ' + ps.category + '\n' +
'ライセンス : ' + ps.license + '\n' +
'タグ : ' + ps.aliases + '\n' +
'追加したユーザー : ' + '@' + me.username + '\n'
};
await fetch(ApiBase+'/notes/create', {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body:JSON.stringify( data_Miss)
})
}
if (DiscordWebhookUrl){
const data_disc = {"username": "絵文字追加通知ちゃん",
'content':
'絵文字名 : :'+ ps.name +':\n' +
'カテゴリ : ' + ps.category + '\n'+
'ライセンス : '+ ps.license + '\n'+
'タグ : '+ps.aliases+ '\n'+
'追加したユーザー : ' + '@'+me.username + '\n'
}
await fetch(DiscordWebhookUrl, {
'method':'post',
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(data_disc),
})
}
return {
id: emoji.id,
};

View file

@ -455,6 +455,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
turnstileSiteKey: instance.turnstileSiteKey,
swPublickey: instance.swPublicKey,
themeColor: instance.themeColor,
requestEmojiAllOk: instance.requestEmojiAllOk,
mascotImageUrl: instance.mascotImageUrl,
bannerUrl: instance.bannerUrl,
serverErrorImageUrl: instance.serverErrorImageUrl,

View file

@ -103,6 +103,7 @@ export const paramDef = {
privacyPolicyUrl: { type: 'string', nullable: true },
useObjectStorage: { type: 'boolean' },
objectStorageBaseUrl: { type: 'string', nullable: true },
requestEmojiAllOk: { type: 'boolean', nullable: true },
objectStorageBucket: { type: 'string', nullable: true },
objectStoragePrefix: { type: 'string', nullable: true },
objectStorageEndpoint: { type: 'string', nullable: true },
@ -221,6 +222,9 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
set.infoImageUrl = ps.infoImageUrl;
}
if (ps.requestEmojiAllOk !== undefined) {
set.requestEmojiAllOk = ps.requestEmojiAllOk;
}
if (ps.notFoundImageUrl !== undefined) {
set.notFoundImageUrl = ps.notFoundImageUrl;
}