@ -145,6 +145,10 @@ export const meta = {
|
||||
validator: $.optional.nullable.str,
|
||||
},
|
||||
|
||||
deeplAuthKey: {
|
||||
validator: $.optional.nullable.str,
|
||||
},
|
||||
|
||||
enableTwitterIntegration: {
|
||||
validator: $.optional.bool,
|
||||
},
|
||||
@ -562,6 +566,14 @@ export default define(meta, async (ps, me) => {
|
||||
set.objectStorageS3ForcePathStyle = ps.objectStorageS3ForcePathStyle;
|
||||
}
|
||||
|
||||
if (ps.deeplAuthKey !== undefined) {
|
||||
if (ps.deeplAuthKey === '') {
|
||||
set.deeplAuthKey = null;
|
||||
} else {
|
||||
set.deeplAuthKey = ps.deeplAuthKey;
|
||||
}
|
||||
}
|
||||
|
||||
await getConnection().transaction(async transactionalEntityManager => {
|
||||
const meta = await transactionalEntityManager.findOne(Meta, {
|
||||
order: {
|
||||
|
@ -232,6 +232,10 @@ export const meta = {
|
||||
type: 'boolean' as const,
|
||||
optional: false as const, nullable: false as const
|
||||
},
|
||||
translatorAvailable: {
|
||||
type: 'boolean' as const,
|
||||
optional: false as const, nullable: false as const
|
||||
},
|
||||
proxyAccountName: {
|
||||
type: 'string' as const,
|
||||
optional: false as const, nullable: true as const
|
||||
@ -512,6 +516,8 @@ export default define(meta, async (ps, me) => {
|
||||
|
||||
enableServiceWorker: instance.enableServiceWorker,
|
||||
|
||||
translatorAvailable: instance.deeplAuthKey != null,
|
||||
|
||||
...(ps.detail ? {
|
||||
pinnedPages: instance.pinnedPages,
|
||||
pinnedClipId: instance.pinnedClipId,
|
||||
|
79
src/server/api/endpoints/notes/translate.ts
Normal file
79
src/server/api/endpoints/notes/translate.ts
Normal file
@ -0,0 +1,79 @@
|
||||
import $ from 'cafy';
|
||||
import { ID } from '@/misc/cafy-id';
|
||||
import define from '../../define';
|
||||
import { getNote } from '../../common/getters';
|
||||
import { ApiError } from '../../error';
|
||||
import fetch from 'node-fetch';
|
||||
import config from '@/config';
|
||||
import { getAgentByUrl } from '@/misc/fetch';
|
||||
import { URLSearchParams } from 'url';
|
||||
import { fetchMeta } from '@/misc/fetch-meta';
|
||||
|
||||
export const meta = {
|
||||
tags: ['notes'],
|
||||
|
||||
requireCredential: false as const,
|
||||
|
||||
params: {
|
||||
noteId: {
|
||||
validator: $.type(ID),
|
||||
},
|
||||
targetLang: {
|
||||
validator: $.str,
|
||||
},
|
||||
},
|
||||
|
||||
res: {
|
||||
type: 'object' as const,
|
||||
optional: false as const, nullable: false as const,
|
||||
},
|
||||
|
||||
errors: {
|
||||
noSuchNote: {
|
||||
message: 'No such note.',
|
||||
code: 'NO_SUCH_NOTE',
|
||||
id: 'bea9b03f-36e0-49c5-a4db-627a029f8971'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, async (ps, user) => {
|
||||
const note = await getNote(ps.noteId).catch(e => {
|
||||
if (e.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote);
|
||||
throw e;
|
||||
});
|
||||
|
||||
if (note.text == null) {
|
||||
return 204;
|
||||
}
|
||||
|
||||
const instance = await fetchMeta();
|
||||
|
||||
if (instance.deeplAuthKey == null) {
|
||||
return 204; // TODO: 良い感じのエラー返す
|
||||
}
|
||||
|
||||
const params = new URLSearchParams();
|
||||
params.append('auth_key', instance.deeplAuthKey);
|
||||
params.append('text', note.text);
|
||||
params.append('target_lang', ps.targetLang);
|
||||
|
||||
const res = await fetch('https://api-free.deepl.com/v2/translate', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
'User-Agent': config.userAgent,
|
||||
Accept: 'application/json, */*'
|
||||
},
|
||||
body: params,
|
||||
timeout: 10000,
|
||||
agent: getAgentByUrl,
|
||||
});
|
||||
|
||||
const json = await res.json();
|
||||
|
||||
return {
|
||||
sourceLang: json.translations[0].detected_source_language,
|
||||
text: json.translations[0].text
|
||||
};
|
||||
});
|
Reference in New Issue
Block a user