mirror of
https://github.com/misskey-dev/misskey.git
synced 2024-12-23 00:29:22 +09:00
enhance(antenna): Botの投稿を除外できるように (MisskeyIO#545)
This commit is contained in:
parent
c45edf2564
commit
a95ce067c6
@ -406,6 +406,7 @@ name: "Name"
|
||||
antennaSource: "Antenna source"
|
||||
antennaKeywords: "Keywords to listen to"
|
||||
antennaExcludeKeywords: "Keywords to exclude"
|
||||
antennaExcludeBots: "Exclude bots"
|
||||
antennaKeywordsDescription: "Separate with spaces for an AND condition or with line breaks for an OR condition."
|
||||
notifyAntenna: "Notify about new notes"
|
||||
withFileAntenna: "Only notes with files"
|
||||
|
4
locales/index.d.ts
vendored
4
locales/index.d.ts
vendored
@ -1640,6 +1640,10 @@ export interface Locale extends ILocale {
|
||||
* 除外キーワード
|
||||
*/
|
||||
"antennaExcludeKeywords": string;
|
||||
/**
|
||||
* Botアカウントを除外
|
||||
*/
|
||||
"antennaExcludeBots": string;
|
||||
/**
|
||||
* スペースで区切るとAND指定になり、改行で区切るとOR指定になります
|
||||
*/
|
||||
|
@ -406,6 +406,7 @@ name: "名前"
|
||||
antennaSource: "受信ソース"
|
||||
antennaKeywords: "受信キーワード"
|
||||
antennaExcludeKeywords: "除外キーワード"
|
||||
antennaExcludeBots: "Botアカウントを除外"
|
||||
antennaKeywordsDescription: "スペースで区切るとAND指定になり、改行で区切るとOR指定になります"
|
||||
notifyAntenna: "新しいノートを通知する"
|
||||
withFileAntenna: "ファイルが添付されたノートのみ"
|
||||
|
@ -405,6 +405,7 @@ name: "이름"
|
||||
antennaSource: "받을 소스"
|
||||
antennaKeywords: "받을 검색어"
|
||||
antennaExcludeKeywords: "제외할 검색어"
|
||||
antennaExcludeBots: "봇 제외"
|
||||
antennaKeywordsDescription: "공백으로 구분하는 경우 AND, 줄바꿈으로 구분하는 경우 OR로 지정됩니다"
|
||||
notifyAntenna: "새로운 노트를 알림"
|
||||
withFileAntenna: "파일이 첨부된 노트만"
|
||||
|
@ -0,0 +1,11 @@
|
||||
export class AntennaExcludeBots1710919614510 {
|
||||
name = 'AntennaExcludeBots1710919614510'
|
||||
|
||||
async up(queryRunner) {
|
||||
await queryRunner.query(`ALTER TABLE "antenna" ADD "excludeBots" boolean NOT NULL DEFAULT false`);
|
||||
}
|
||||
|
||||
async down(queryRunner) {
|
||||
await queryRunner.query(`ALTER TABLE "antenna" DROP COLUMN "excludeBots"`);
|
||||
}
|
||||
}
|
@ -97,7 +97,7 @@ export class AntennaService implements OnApplicationShutdown {
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public async addNoteToAntennas(note: MiNote, noteUser: { id: MiUser['id']; username: string; host: string | null; }): Promise<void> {
|
||||
public async addNoteToAntennas(note: MiNote, noteUser: { id: MiUser['id']; username: string; host: string | null; isBot: boolean; }): Promise<void> {
|
||||
const antennas = await this.getAntennas();
|
||||
const antennasWithMatchResult = await Promise.all(antennas.map(antenna => this.checkHitAntenna(antenna, note, noteUser).then(hit => [antenna, hit] as const)));
|
||||
const matchedAntennas = antennasWithMatchResult.filter(([, hit]) => hit).map(([antenna]) => antenna);
|
||||
@ -121,10 +121,12 @@ export class AntennaService implements OnApplicationShutdown {
|
||||
// NOTE: フォローしているユーザーのノート、リストのユーザーのノート、グループのユーザーのノート指定はパフォーマンス上の理由で無効になっている
|
||||
|
||||
@bindThis
|
||||
public async checkHitAntenna(antenna: MiAntenna, note: (MiNote | Packed<'Note'>), noteUser: { id: MiUser['id']; username: string; host: string | null; }): Promise<boolean> {
|
||||
public async checkHitAntenna(antenna: MiAntenna, note: (MiNote | Packed<'Note'>), noteUser: { id: MiUser['id']; username: string; host: string | null; isBot: boolean; }): Promise<boolean> {
|
||||
if (note.visibility === 'specified') return false;
|
||||
if (note.visibility === 'followers') return false;
|
||||
|
||||
if (antenna.excludeBots && noteUser.isBot) return false;
|
||||
|
||||
if (antenna.localOnly && noteUser.host != null) return false;
|
||||
|
||||
if (!antenna.withReplies && note.replyId != null) return false;
|
||||
|
@ -39,6 +39,7 @@ export class AntennaEntityService {
|
||||
caseSensitive: antenna.caseSensitive,
|
||||
localOnly: antenna.localOnly,
|
||||
notify: antenna.notify,
|
||||
excludeBots: antenna.excludeBots,
|
||||
withReplies: antenna.withReplies,
|
||||
withFile: antenna.withFile,
|
||||
isActive: antenna.isActive,
|
||||
|
@ -79,6 +79,11 @@ export class MiAntenna {
|
||||
})
|
||||
public caseSensitive: boolean;
|
||||
|
||||
@Column('boolean', {
|
||||
default: false,
|
||||
})
|
||||
public excludeBots: boolean;
|
||||
|
||||
@Column('boolean', {
|
||||
default: false,
|
||||
})
|
||||
|
@ -76,6 +76,11 @@ export const packedAntennaSchema = {
|
||||
type: 'boolean',
|
||||
optional: false, nullable: false,
|
||||
},
|
||||
excludeBots: {
|
||||
type: 'boolean',
|
||||
optional: false, nullable: false,
|
||||
default: false,
|
||||
},
|
||||
withReplies: {
|
||||
type: 'boolean',
|
||||
optional: false, nullable: false,
|
||||
|
@ -81,6 +81,7 @@ export class ExportAntennasProcessorService {
|
||||
}) : null,
|
||||
caseSensitive: antenna.caseSensitive,
|
||||
localOnly: antenna.localOnly,
|
||||
excludeBots: antenna.excludeBots,
|
||||
withReplies: antenna.withReplies,
|
||||
withFile: antenna.withFile,
|
||||
notify: antenna.notify,
|
||||
|
@ -44,6 +44,7 @@ const validate = new Ajv().compile({
|
||||
} },
|
||||
caseSensitive: { type: 'boolean' },
|
||||
localOnly: { type: 'boolean' },
|
||||
excludeBots: { type: 'boolean' },
|
||||
withReplies: { type: 'boolean' },
|
||||
withFile: { type: 'boolean' },
|
||||
notify: { type: 'boolean' },
|
||||
@ -88,6 +89,7 @@ export class ImportAntennasProcessorService {
|
||||
users: (antenna.src === 'list' && antenna.userListAccts !== null ? antenna.userListAccts : antenna.users).filter(Boolean),
|
||||
caseSensitive: antenna.caseSensitive,
|
||||
localOnly: antenna.localOnly,
|
||||
excludeBots: antenna.excludeBots,
|
||||
withReplies: antenna.withReplies,
|
||||
withFile: antenna.withFile,
|
||||
notify: antenna.notify,
|
||||
|
@ -65,6 +65,7 @@ export const paramDef = {
|
||||
} },
|
||||
caseSensitive: { type: 'boolean' },
|
||||
localOnly: { type: 'boolean' },
|
||||
excludeBots: { type: 'boolean' },
|
||||
withReplies: { type: 'boolean' },
|
||||
withFile: { type: 'boolean' },
|
||||
notify: { type: 'boolean' },
|
||||
@ -125,6 +126,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||
users: ps.users,
|
||||
caseSensitive: ps.caseSensitive,
|
||||
localOnly: ps.localOnly,
|
||||
excludeBots: ps.excludeBots,
|
||||
withReplies: ps.withReplies,
|
||||
withFile: ps.withFile,
|
||||
notify: ps.notify,
|
||||
|
@ -64,6 +64,7 @@ export const paramDef = {
|
||||
} },
|
||||
caseSensitive: { type: 'boolean' },
|
||||
localOnly: { type: 'boolean' },
|
||||
excludeBots: { type: 'boolean' },
|
||||
withReplies: { type: 'boolean' },
|
||||
withFile: { type: 'boolean' },
|
||||
notify: { type: 'boolean' },
|
||||
@ -121,6 +122,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||
users: ps.users,
|
||||
caseSensitive: ps.caseSensitive,
|
||||
localOnly: ps.localOnly,
|
||||
excludeBots: ps.excludeBots,
|
||||
withReplies: ps.withReplies,
|
||||
withFile: ps.withFile,
|
||||
notify: ps.notify,
|
||||
|
@ -45,6 +45,7 @@ describe('アンテナ', () => {
|
||||
users: [''],
|
||||
withFile: false,
|
||||
withReplies: false,
|
||||
excludeBots: false,
|
||||
};
|
||||
|
||||
let root: User;
|
||||
@ -159,6 +160,7 @@ describe('アンテナ', () => {
|
||||
users: [''],
|
||||
withFile: false,
|
||||
withReplies: false,
|
||||
excludeBots: false,
|
||||
localOnly: false,
|
||||
};
|
||||
assert.deepStrictEqual(response, expected);
|
||||
|
@ -26,6 +26,7 @@ const draft = ref({
|
||||
users: [],
|
||||
keywords: [],
|
||||
excludeKeywords: [],
|
||||
excludeBots: false,
|
||||
withReplies: false,
|
||||
caseSensitive: false,
|
||||
localOnly: false,
|
||||
|
@ -26,6 +26,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
<template #label>{{ i18n.ts.users }}</template>
|
||||
<template #caption>{{ i18n.ts.antennaUsersDescription }} <button class="_textButton" @click="addUser">{{ i18n.ts.addUser }}</button></template>
|
||||
</MkTextarea>
|
||||
<MkSwitch v-model="excludeBots">{{ i18n.ts.antennaExcludeBots }}</MkSwitch>
|
||||
<MkSwitch v-model="withReplies">{{ i18n.ts.withReplies }}</MkSwitch>
|
||||
<MkTextarea v-model="keywords">
|
||||
<template #label>{{ i18n.ts.antennaKeywords }}</template>
|
||||
@ -78,6 +79,7 @@ const keywords = ref<string>(props.antenna.keywords.map(x => x.join(' ')).join('
|
||||
const excludeKeywords = ref<string>(props.antenna.excludeKeywords.map(x => x.join(' ')).join('\n'));
|
||||
const caseSensitive = ref<boolean>(props.antenna.caseSensitive);
|
||||
const localOnly = ref<boolean>(props.antenna.localOnly);
|
||||
const excludeBots = ref<boolean>(props.antenna.excludeBots);
|
||||
const withReplies = ref<boolean>(props.antenna.withReplies);
|
||||
const withFile = ref<boolean>(props.antenna.withFile);
|
||||
const notify = ref<boolean>(props.antenna.notify);
|
||||
@ -94,6 +96,7 @@ async function saveAntenna() {
|
||||
name: name.value,
|
||||
src: src.value,
|
||||
userListId: userListId.value,
|
||||
excludeBots: excludeBots.value,
|
||||
withReplies: withReplies.value,
|
||||
withFile: withFile.value,
|
||||
notify: notify.value,
|
||||
|
@ -4586,6 +4586,8 @@ export type components = {
|
||||
localOnly: boolean;
|
||||
notify: boolean;
|
||||
/** @default false */
|
||||
excludeBots: boolean;
|
||||
/** @default false */
|
||||
withReplies: boolean;
|
||||
withFile: boolean;
|
||||
isActive: boolean;
|
||||
@ -10618,6 +10620,7 @@ export type operations = {
|
||||
users: string[];
|
||||
caseSensitive: boolean;
|
||||
localOnly?: boolean;
|
||||
excludeBots?: boolean;
|
||||
withReplies: boolean;
|
||||
withFile: boolean;
|
||||
notify: boolean;
|
||||
@ -10899,6 +10902,7 @@ export type operations = {
|
||||
users?: string[];
|
||||
caseSensitive?: boolean;
|
||||
localOnly?: boolean;
|
||||
excludeBots?: boolean;
|
||||
withReplies?: boolean;
|
||||
withFile?: boolean;
|
||||
notify?: boolean;
|
||||
|
Loading…
Reference in New Issue
Block a user