Skip to content
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: UserWebhook/SystemWebhookのテスト送信機能を追加 #14489

Merged
merged 7 commits into from
Sep 19, 2024

Conversation

samunohito
Copy link
Member

What

UserWebhookとSystemWebhookにテスト送信機能が追加されます。

Why

fix #14445

Additional info (optional)

ローカルにWebサーバを立てて実際に送信確認

Checklist

  • Read the contribution guide
  • Test working in a local environment
  • (If needed) Add story of storybook
  • (If needed) Update CHANGELOG.md
  • (If possible) Add tests

@github-actions github-actions bot added packages/frontend Client side specific issue/PR packages/backend Server side specific issue/PR packages/misskey-js packages/backend:test labels Sep 2, 2024
Copy link

codecov bot commented Sep 2, 2024

Codecov Report

Attention: Patch coverage is 75.20958% with 207 lines in your changes missing coverage. Please review.

Project coverage is 41.50%. Comparing base (3bf63dd) to head (81363ec).
Report is 2 commits behind head on develop.

Files with missing lines Patch % Lines
...kages/frontend/src/pages/settings/webhook.edit.vue 0.00% 78 Missing ⚠️
.../frontend/src/components/MkSystemWebhookEditor.vue 0.00% 66 Missing ⚠️
.../server/api/endpoints/admin/system-webhook/test.ts 75.32% 19 Missing ⚠️
...ackend/src/server/api/endpoints/i/webhooks/test.ts 75.00% 19 Missing ⚠️
packages/backend/src/core/QueueService.ts 12.50% 14 Missing ⚠️
packages/backend/src/core/WebhookTestService.ts 97.92% 9 Missing ⚠️
...ntend/src/components/MkSystemWebhookEditor.impl.ts 0.00% 2 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##           develop   #14489       +/-   ##
============================================
+ Coverage    19.72%   41.50%   +21.77%     
============================================
  Files          714     1543      +829     
  Lines       100375   197423    +97048     
  Branches       996     2709     +1713     
============================================
+ Hits         19802    81937    +62135     
- Misses       80030   114924    +34894     
- Partials       543      562       +19     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Contributor

github-actions bot commented Sep 2, 2024

このPRによるapi.jsonの差分

差分はこちら
--- base
+++ head
@@ -16797,6 +16797,204 @@
         }
       }
     },
+    "/admin/system-webhook/test": {
+      "post": {
+        "operationId": "admin___system-webhook___test",
+        "summary": "admin/system-webhook/test",
+        "description": "No description provided.\n\n**Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties.\n**Credential required**: *Yes* / **Permission**: *read:admin:system-webhook*",
+        "externalDocs": {
+          "description": "Source code",
+          "url": "https://github.com/misskey-dev/misskey/blob/develop/packages/backend/src/server/api/endpoints/admin/system-webhook/test.ts"
+        },
+        "tags": [
+          "webhooks"
+        ],
+        "security": [
+          {
+            "bearerAuth": []
+          }
+        ],
+        "requestBody": {
+          "required": true,
+          "content": {
+            "application/json": {
+              "schema": {
+                "type": "object",
+                "properties": {
+                  "webhookId": {
+                    "type": "string",
+                    "format": "misskey:id"
+                  },
+                  "type": {
+                    "type": "string",
+                    "enum": [
+                      "abuseReport",
+                      "abuseReportResolved",
+                      "userCreated"
+                    ]
+                  },
+                  "override": {
+                    "type": "object",
+                    "properties": {
+                      "url": {
+                        "type": "string"
+                      },
+                      "secret": {
+                        "type": "string"
+                      }
+                    }
+                  }
+                },
+                "required": [
+                  "webhookId",
+                  "type"
+                ]
+              }
+            }
+          }
+        },
+        "responses": {
+          "204": {
+            "description": "OK (without any results)"
+          },
+          "400": {
+            "description": "Client error",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/Error"
+                },
+                "examples": {
+                  "NO_SUCH_WEBHOOK": {
+                    "value": {
+                      "error": {
+                        "message": "No such webhook.",
+                        "code": "NO_SUCH_WEBHOOK",
+                        "id": "0c52149c-e913-18f8-5dc7-74870bfe0cf9"
+                      }
+                    }
+                  },
+                  "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"
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    },
     "/announcements": {
       "post": {
         "operationId": "announcements",
@@ -51784,6 +51982,209 @@
                       }
                     }
                   }
+                }
+              }
+            }
+          },
+          "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"
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/i/webhooks/test": {
+      "post": {
+        "operationId": "i___webhooks___test",
+        "summary": "i/webhooks/test",
+        "description": "No description provided.\n\n**Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties.\n**Credential required**: *Yes* / **Permission**: *read:account*",
+        "externalDocs": {
+          "description": "Source code",
+          "url": "https://github.com/misskey-dev/misskey/blob/develop/packages/backend/src/server/api/endpoints/i/webhooks/test.ts"
+        },
+        "tags": [
+          "webhooks"
+        ],
+        "security": [
+          {
+            "bearerAuth": []
+          }
+        ],
+        "requestBody": {
+          "required": true,
+          "content": {
+            "application/json": {
+              "schema": {
+                "type": "object",
+                "properties": {
+                  "webhookId": {
+                    "type": "string",
+                    "format": "misskey:id"
+                  },
+                  "type": {
+                    "type": "string",
+                    "enum": [
+                      "mention",
+                      "unfollow",
+                      "follow",
+                      "followed",
+                      "note",
+                      "reply",
+                      "renote",
+                      "reaction"
+                    ]
+                  },
+                  "override": {
+                    "type": "object",
+                    "properties": {
+                      "url": {
+                        "type": "string"
+                      },
+                      "secret": {
+                        "type": "string"
+                      }
+                    }
+                  }
+                },
+                "required": [
+                  "webhookId",
+                  "type"
+                ]
+              }
+            }
+          }
+        },
+        "responses": {
+          "204": {
+            "description": "OK (without any results)"
+          },
+          "400": {
+            "description": "Client error",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/Error"
+                },
+                "examples": {
+                  "NO_SUCH_WEBHOOK": {
+                    "value": {
+                      "error": {
+                        "message": "No such webhook.",
+                        "code": "NO_SUCH_WEBHOOK",
+                        "id": "0c52149c-e913-18f8-5dc7-74870bfe0cf9"
+                      }
+                    }
+                  },
+                  "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"
+                      }
+                    }
+                  }
                 }
               }
             }

Get diff files from Workflow Page

Comment on lines +21 to +24
limit: {
duration: ms('15min'),
max: 60,
},
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UIがボタンであるゆえに連打できてしまうので15分/60回までとしています。

@@ -13,6 +13,7 @@ import { DI } from '@/di-symbols.js';
import { RoleService } from '@/core/RoleService.js';
import { ApiError } from '@/server/api/error.js';

// TODO: UserWebhook schemaの適用
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

リファクタの余地があります。…が、このprではスコープ外なのでTODOコメントに留めています。
ここを含めて複数個所でmeta.res配下に直接UserWebhookのスキーマが記述されていますが、いずれも内容に差はないので単独のスキーマとした方がよいと考えます。

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UserWebhookServiceとSystemWebhookServiceはテストWebhookである旨を知らなくてもいいと思ったので、テスト系の処理をこのServiceに分離しています。

@samunohito samunohito marked this pull request as ready for review September 2, 2024 23:09
@samunohito

This comment was marked as resolved.

@samunohito
Copy link
Member Author

テスト送信時は設定をリクエストパラメータから上書き出来るようにする…?
テスト送信を行うエンドポイント自体は認証必要になってるし、レートリミットあるし、イタズラのリスクはそこまでないはず…

@samunohito samunohito marked this pull request as draft September 2, 2024 23:30
@samunohito
Copy link
Member Author

Revertできる形にしつつ↑を試します(のでdraftに)

@samunohito
Copy link
Member Author

テスト送信時は設定をリクエストパラメータから上書き出来るようにする…?

これにしました。
urlとsecretをエンドポイントのパラメータとして引き込み、その値で送信確認できるようになりました。

@samunohito samunohito marked this pull request as ready for review September 3, 2024 12:24
@syuilo
Copy link
Member

syuilo commented Sep 3, 2024

/preview

* UserWebhook の一覧を取得する.
*/
@bindThis
public async fetchWebhooks(params?: {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

async不要そう

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

fd3793a

@syuilo
Copy link
Member

syuilo commented Sep 5, 2024

/preview

1 similar comment
@syuilo
Copy link
Member

syuilo commented Sep 5, 2024

/preview

@syuilo
Copy link
Member

syuilo commented Sep 16, 2024

misskey-jsのautogen生成するのどうするんだっけ

@syuilo
Copy link
Member

syuilo commented Sep 16, 2024

autogenがない状態で pnpm build-misskey-js-with-types や pnpm build してもエラーになる

@syuilo
Copy link
Member

syuilo commented Sep 17, 2024

TASUKETE

@samunohito
Copy link
Member Author

pnpm build-misskey-js-with-types

これやればできるはずですが…いったいなにが
夜以降でよければ確認します

@syuilo
Copy link
Member

syuilo commented Sep 18, 2024

ゔわー

# Conflicts:
#	packages/misskey-js/src/autogen/endpoint.ts
@samunohito
Copy link
Member Author

@syuilo たぶんなおったはず

@syuilo
Copy link
Member

syuilo commented Sep 18, 2024

今後同様のことが起こったらどう治せばいいかしら

@samunohito
Copy link
Member Author

pnpm clean -> pnpm build-misskey-js-with-types -> pnpm build
のような感じでビルドしたら直りました。
ちょっと怪しいので、cloneしたてのまっさらな環境で確認したほうがいいかも…?

@syuilo syuilo merged commit 4ac8aad into misskey-dev:develop Sep 19, 2024
32 of 33 checks passed
@syuilo
Copy link
Member

syuilo commented Sep 19, 2024

👍🏿

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
packages/backend:test packages/backend Server side specific issue/PR packages/frontend Client side specific issue/PR packages/misskey-js
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Webhookのテスト送信ボタンが欲しい
2 participants