-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feat: 特定ユーザーからのリアクションをブロックする機能の追加 #14992
base: develop
Are you sure you want to change the base?
Feat: 特定ユーザーからのリアクションをブロックする機能の追加 #14992
Conversation
…トを追加 ユーザー単位でリアクションをブロックするため、blocking-reaction-userエンドポイントを追加。 ロジックは別途実装する。
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #14992 +/- ##
============================================
- Coverage 39.97% 23.56% -16.41%
============================================
Files 1561 731 -830
Lines 197256 109570 -87686
Branches 3607 1059 -2548
============================================
- Hits 78849 25820 -53029
+ Misses 117835 83197 -34638
+ Partials 572 553 -19 ☔ View full report in Codecov by Sentry. |
このPRによるapi.jsonの差分 差分はこちら--- base
+++ head
@@ -20952,6 +20952,580 @@
}
}
},
+ "/blocking-reaction-user/create": {
+ "post": {
+ "operationId": "blocking-reaction-user___create",
+ "summary": "blocking-reaction-user/create",
+ "description": "No description provided.\n\n**Credential required**: *Yes* / **Permission**: *write:blocks*",
+ "externalDocs": {
+ "description": "Source code",
+ "url": "https://github.com/misskey-dev/misskey/blob/develop/packages/backend/src/server/api/endpoints/blocking-reaction-user/create.ts"
+ },
+ "tags": [
+ "account"
+ ],
+ "security": [
+ {
+ "bearerAuth": []
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "userId": {
+ "type": "string",
+ "format": "misskey:id"
+ }
+ },
+ "required": [
+ "userId"
+ ]
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "OK (with results)",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "$ref": "#/components/schemas/UserDetailedNotMe"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Client error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ },
+ "examples": {
+ "NO_SUCH_USER": {
+ "value": {
+ "error": {
+ "message": "No such user.",
+ "code": "NO_SUCH_USER",
+ "id": "7cc4f851-e2f1-4621-9633-ec9e1d00c01e"
+ }
+ }
+ },
+ "BLOCKEE_IS_YOURSELF": {
+ "value": {
+ "error": {
+ "message": "Blockee is yourself.",
+ "code": "BLOCKEE_IS_YOURSELF",
+ "id": "88b19138-f28d-42c0-8499-6a31bbd0fdc6"
+ }
+ }
+ },
+ "ALREADY_BLOCKING": {
+ "value": {
+ "error": {
+ "message": "You are already blocking that user.",
+ "code": "ALREADY_BLOCKING",
+ "id": "787fed64-acb9-464a-82eb-afbd745b9614"
+ }
+ }
+ },
+ "INVALID_PARAM": {
+ "value": {
+ "error": {
+ "message": "Invalid param.",
+ "code": "INVALID_PARAM",
+ "id": "3d81ceae-475f-4600-b2a8-2bc116157532"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "Authentication error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ },
+ "examples": {
+ "CREDENTIAL_REQUIRED": {
+ "value": {
+ "error": {
+ "message": "Credential required.",
+ "code": "CREDENTIAL_REQUIRED",
+ "id": "1384574d-a912-4b81-8601-c7b1c4085df1"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ },
+ "examples": {
+ "AUTHENTICATION_FAILED": {
+ "value": {
+ "error": {
+ "message": "Authentication failed. Please ensure your token is correct.",
+ "code": "AUTHENTICATION_FAILED",
+ "id": "b0a7f5f8-dc2f-4171-b91f-de88ad238e14"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "418": {
+ "description": "I'm Ai",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ },
+ "examples": {
+ "I_AM_AI": {
+ "value": {
+ "error": {
+ "message": "You sent a request to Ai-chan, Misskey's showgirl, instead of the server.",
+ "code": "I_AM_AI",
+ "id": "60c46cd1-f23a-46b1-bebe-5d2b73951a84"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "429": {
+ "description": "To many requests",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ },
+ "examples": {
+ "RATE_LIMIT_EXCEEDED": {
+ "value": {
+ "error": {
+ "message": "Rate limit exceeded. Please try again later.",
+ "code": "RATE_LIMIT_EXCEEDED",
+ "id": "d5826d14-3982-4d2e-8011-b9e9f02499ef"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Internal server error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ },
+ "examples": {
+ "INTERNAL_ERROR": {
+ "value": {
+ "error": {
+ "message": "Internal error occurred. Please contact us if the error persists.",
+ "code": "INTERNAL_ERROR",
+ "id": "5d37dbcb-891e-41ca-a3d6-e690c97775ac"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/blocking-reaction-user/delete": {
+ "post": {
+ "operationId": "blocking-reaction-user___delete",
+ "summary": "blocking-reaction-user/delete",
+ "description": "No description provided.\n\n**Credential required**: *Yes* / **Permission**: *write:blocks*",
+ "externalDocs": {
+ "description": "Source code",
+ "url": "https://github.com/misskey-dev/misskey/blob/develop/packages/backend/src/server/api/endpoints/blocking-reaction-user/delete.ts"
+ },
+ "tags": [
+ "account"
+ ],
+ "security": [
+ {
+ "bearerAuth": []
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "userId": {
+ "type": "string",
+ "format": "misskey:id"
+ }
+ },
+ "required": [
+ "userId"
+ ]
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "OK (with results)",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "$ref": "#/components/schemas/UserDetailedNotMe"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Client error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ },
+ "examples": {
+ "NO_SUCH_USER": {
+ "value": {
+ "error": {
+ "message": "No such user.",
+ "code": "NO_SUCH_USER",
+ "id": "8621d8bf-c358-4303-a066-5ea78610eb3f"
+ }
+ }
+ },
+ "BLOCKEE_IS_YOURSELF": {
+ "value": {
+ "error": {
+ "message": "Blockee is yourself.",
+ "code": "BLOCKEE_IS_YOURSELF",
+ "id": "06f6fac6-524b-473c-a354-e97a40ae6eac"
+ }
+ }
+ },
+ "NOT_BLOCKING": {
+ "value": {
+ "error": {
+ "message": "You are not blocking that user.",
+ "code": "NOT_BLOCKING",
+ "id": "291b2efa-60c6-45c0-9f6a-045c8f9b02cd"
+ }
+ }
+ },
+ "INVALID_PARAM": {
+ "value": {
+ "error": {
+ "message": "Invalid param.",
+ "code": "INVALID_PARAM",
+ "id": "3d81ceae-475f-4600-b2a8-2bc116157532"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "Authentication error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ },
+ "examples": {
+ "CREDENTIAL_REQUIRED": {
+ "value": {
+ "error": {
+ "message": "Credential required.",
+ "code": "CREDENTIAL_REQUIRED",
+ "id": "1384574d-a912-4b81-8601-c7b1c4085df1"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ },
+ "examples": {
+ "AUTHENTICATION_FAILED": {
+ "value": {
+ "error": {
+ "message": "Authentication failed. Please ensure your token is correct.",
+ "code": "AUTHENTICATION_FAILED",
+ "id": "b0a7f5f8-dc2f-4171-b91f-de88ad238e14"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "418": {
+ "description": "I'm Ai",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ },
+ "examples": {
+ "I_AM_AI": {
+ "value": {
+ "error": {
+ "message": "You sent a request to Ai-chan, Misskey's showgirl, instead of the server.",
+ "code": "I_AM_AI",
+ "id": "60c46cd1-f23a-46b1-bebe-5d2b73951a84"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "429": {
+ "description": "To many requests",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ },
+ "examples": {
+ "RATE_LIMIT_EXCEEDED": {
+ "value": {
+ "error": {
+ "message": "Rate limit exceeded. Please try again later.",
+ "code": "RATE_LIMIT_EXCEEDED",
+ "id": "d5826d14-3982-4d2e-8011-b9e9f02499ef"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Internal server error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ },
+ "examples": {
+ "INTERNAL_ERROR": {
+ "value": {
+ "error": {
+ "message": "Internal error occurred. Please contact us if the error persists.",
+ "code": "INTERNAL_ERROR",
+ "id": "5d37dbcb-891e-41ca-a3d6-e690c97775ac"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/blocking-reaction-user/list": {
+ "post": {
+ "operationId": "blocking-reaction-user___list",
+ "summary": "blocking-reaction-user/list",
+ "description": "No description provided.\n\n**Credential required**: *Yes* / **Permission**: *read:blocks*",
+ "externalDocs": {
+ "description": "Source code",
+ "url": "https://github.com/misskey-dev/misskey/blob/develop/packages/backend/src/server/api/endpoints/blocking-reaction-user/list.ts"
+ },
+ "tags": [
+ "account"
+ ],
+ "security": [
+ {
+ "bearerAuth": []
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "limit": {
+ "type": "integer",
+ "minimum": 1,
+ "maximum": 100,
+ "default": 30
+ },
+ "sinceId": {
+ "type": "string",
+ "format": "misskey:id"
+ },
+ "untilId": {
+ "type": "string",
+ "format": "misskey:id"
+ }
+ }
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "OK (with results)",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "$ref": "#/components/schemas/Blocking"
+ }
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Client error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ },
+ "examples": {
+ "INVALID_PARAM": {
+ "value": {
+ "error": {
+ "message": "Invalid param.",
+ "code": "INVALID_PARAM",
+ "id": "3d81ceae-475f-4600-b2a8-2bc116157532"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "Authentication error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ },
+ "examples": {
+ "CREDENTIAL_REQUIRED": {
+ "value": {
+ "error": {
+ "message": "Credential required.",
+ "code": "CREDENTIAL_REQUIRED",
+ "id": "1384574d-a912-4b81-8601-c7b1c4085df1"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ },
+ "examples": {
+ "AUTHENTICATION_FAILED": {
+ "value": {
+ "error": {
+ "message": "Authentication failed. Please ensure your token is correct.",
+ "code": "AUTHENTICATION_FAILED",
+ "id": "b0a7f5f8-dc2f-4171-b91f-de88ad238e14"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "418": {
+ "description": "I'm Ai",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ },
+ "examples": {
+ "I_AM_AI": {
+ "value": {
+ "error": {
+ "message": "You sent a request to Ai-chan, Misskey's showgirl, instead of the server.",
+ "code": "I_AM_AI",
+ "id": "60c46cd1-f23a-46b1-bebe-5d2b73951a84"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Internal server error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ },
+ "examples": {
+ "INTERNAL_ERROR": {
+ "value": {
+ "error": {
+ "message": "Internal error occurred. Please contact us if the error persists.",
+ "code": "INTERNAL_ERROR",
+ "id": "5d37dbcb-891e-41ca-a3d6-e690c97775ac"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
"/channels/create": {
"post": {
"operationId": "channels___create",
@@ -77751,6 +78325,12 @@
"isBlocked": {
"type": "boolean"
},
+ "isReactionBlocking": {
+ "type": "boolean"
+ },
+ "isReactionBlocked": {
+ "type": "boolean"
+ },
"isMuted": {
"type": "boolean"
},
@@ -80325,13 +80905,17 @@
"blockee": {
"type": "object",
"$ref": "#/components/schemas/UserDetailedNotMe"
+ },
+ "isReactionBlock": {
+ "type": "boolean"
}
},
"required": [
"id",
"createdAt",
"blockeeId",
- "blockee"
+ "blockee",
+ "isReactionBlock"
]
},
"Hashtag": { |
export class AddBlockingReactionUser1731898598469 { | ||
name = 'AddBlockingReactionUser1731898598469' | ||
|
||
async up(queryRunner) { | ||
await queryRunner.query(`ALTER TABLE "blocking" ADD "isReactionBlock" boolean NOT NULL DEFAULT false`); | ||
await queryRunner.query(`COMMENT ON COLUMN "blocking"."isReactionBlock" IS 'Whether the blockee is a reaction block.'`); | ||
await queryRunner.query(`CREATE INDEX "IDX_7b0698c38d27a5554bed4858bd" ON "blocking" ("isReactionBlock") `); | ||
} | ||
|
||
async down(queryRunner) { | ||
await queryRunner.query(`DELETE FROM blocking WHERE "isReactionBlock" = 'true'`); // blockingテーブルのisReactionBlockカラムがtrueの行を削除する | ||
await queryRunner.query(`DROP INDEX "IDX_7b0698c38d27a5554bed4858bd"`); | ||
await queryRunner.query(`ALTER TABLE "blocking" DROP COLUMN "isReactionBlock"`); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
①
この変更は、blocking.blockeeId
とblocking.blockerId
の組み合わせが2つ以上存在しうることを許容する前提のように見受けられますが、相違ございませんか?(通常のブロックで1レコード、リアクションブロックで1レコードずつ)
もし上記の状態を期待するのであれば…やり方を変える必要があると考えます。
以下の画像の通り、blocking.blockeeId
とblocking.blockerId
のユニークインデックスが既に存在しているので重複する組み合わせは登録できないようになっています。
なので…blockingの1レコードでやりくりする必要があるかと思います。
②
isReactionBlock
よりもblockType
としてenumを保持するようにすると後から手を入れやすいかも…?
this.cacheService.userBlockingCache.refresh(blocker.id); | ||
this.cacheService.userBlockedCache.refresh(blockee.id); | ||
this.cacheService.userReactionBlockedCache.refresh(blocker.id); | ||
this.cacheService.userReactionBlockedCache.refresh(blockee.id); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
このServiceは通常のブロック向けかと思いますが、ここでリアクションブロック向けの機能を更新しているのは特殊な理由がありますか…?
|
||
this.globalEventService.publishInternalEvent('blockingDeleted', { | ||
this.globalEventService.publishInternalEvent('blockingReactionDeleted', { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
こちらも、配信するイベントが変わっています
if (this.userEntityService.isLocalUser(blocker) && this.userEntityService.isRemoteUser(blockee)) { | ||
const content = this.apRendererService.addContext(this.apRendererService.renderUndo(this.apRendererService.renderBlock(blocking), blocker)); | ||
this.queueService.deliver(blocker, content, blockee.inbox, false); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ActivityPub向けにブロックイベントの配信をする処理なのですが、こちらも意図を確認させてください
this.cacheService.userBlockingCache.refresh(blocker.id); | ||
this.cacheService.userBlockedCache.refresh(blockee.id); | ||
|
||
this.globalEventService.publishInternalEvent('blockingDeleted', { | ||
blockerId: blocker.id, | ||
blockeeId: blockee.id, | ||
}); | ||
|
||
// deliver if remote bloking | ||
if (this.userEntityService.isLocalUser(blocker) && this.userEntityService.isRemoteUser(blockee)) { | ||
const content = this.apRendererService.addContext(this.apRendererService.renderUndo(this.apRendererService.renderBlock(blocking), blocker)); | ||
this.queueService.deliver(blocker, content, blockee.inbox, false); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
もしかして通常のブロック側と逆になっています…?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
すみません、完全に全て逆になっていたようです。修正しました。
あと、「blockingテーブルに該当レコードが在るか無いか」でのみ判断している個所にも条件追加などの対応が必要かと思います。以下はその一例です。 misskey/packages/backend/src/core/QueryService.ts Lines 71 to 94 in c1514ce
※Redisの代わり(FTT有効時のフォールバックやFTT無効時)にDBから各種タイムラインのノートを取得するときに呼ばれるクエリです |
Migrationがあります。
What
特定ユーザーからのリアクションをブロックする
Why
脈絡がなかったりよくわからん絵文字でリアクションをする人からリアクションを受け取りたくないが、ブロックまではする必要がないことがある。
Fix #14987
Additional info (optional)
以下PRの再提出です。
#14986
Checklist