TestWebhook tests a webhook.
(ctx context.Context, req *connect.Request[v1pb.TestWebhookRequest])
| 944 | |
| 945 | // TestWebhook tests a webhook. |
| 946 | func (s *ProjectService) TestWebhook(ctx context.Context, req *connect.Request[v1pb.TestWebhookRequest]) (*connect.Response[v1pb.TestWebhookResponse], error) { |
| 947 | externalURL, err := utils.GetEffectiveExternalURL(ctx, s.store, s.profile, common.GetWorkspaceIDFromContext(ctx)) |
| 948 | if err != nil { |
| 949 | return nil, err |
| 950 | } |
| 951 | |
| 952 | projectID, err := common.GetProjectID(req.Msg.Project) |
| 953 | if err != nil { |
| 954 | return nil, connect.NewError(connect.CodeInvalidArgument, err) |
| 955 | } |
| 956 | project, err := s.store.GetProject(ctx, &store.FindProjectMessage{ |
| 957 | Workspace: common.GetWorkspaceIDFromContext(ctx), |
| 958 | ResourceID: &projectID, |
| 959 | }) |
| 960 | if err != nil { |
| 961 | return nil, connect.NewError(connect.CodeInternal, err) |
| 962 | } |
| 963 | if project == nil { |
| 964 | return nil, connect.NewError(connect.CodeNotFound, errors.Errorf("project %q not found", req.Msg.Project)) |
| 965 | } |
| 966 | if project.Deleted { |
| 967 | return nil, connect.NewError(connect.CodeNotFound, errors.Errorf("project %q has been deleted", req.Msg.Project)) |
| 968 | } |
| 969 | |
| 970 | webhook, err := convertToStoreProjectWebhookMessage(req.Msg.Webhook) |
| 971 | if err != nil { |
| 972 | return nil, connect.NewError(connect.CodeInvalidArgument, err) |
| 973 | } |
| 974 | |
| 975 | // Validate webhook URL against allowed domains |
| 976 | if err := webhookplugin.ValidateWebhookURL(webhook.Payload.GetType(), webhook.Payload.GetUrl()); err != nil { |
| 977 | return nil, connect.NewError(connect.CodeInvalidArgument, errors.Wrapf(err, "invalid webhook URL")) |
| 978 | } |
| 979 | |
| 980 | user, ok := GetUserFromContext(ctx) |
| 981 | if !ok { |
| 982 | return nil, connect.NewError(connect.CodeInternal, errors.Errorf("user not found")) |
| 983 | } |
| 984 | |
| 985 | userMessage, err := s.store.GetUserByEmail(ctx, user.Email) |
| 986 | if err != nil { |
| 987 | return nil, connect.NewError(connect.CodeInternal, errors.Wrapf(err, "failed to get user")) |
| 988 | } |
| 989 | if userMessage == nil { |
| 990 | return nil, connect.NewError(connect.CodeInternal, errors.Errorf("user not found for email %q", user.Email)) |
| 991 | } |
| 992 | |
| 993 | resp := &v1pb.TestWebhookResponse{} |
| 994 | err = webhookplugin.Post( |
| 995 | webhook.Payload.GetType(), |
| 996 | webhookplugin.Context{ |
| 997 | URL: webhook.Payload.GetUrl(), |
| 998 | Level: webhookplugin.WebhookInfo, |
| 999 | EventType: storepb.Activity_ISSUE_CREATED.String(), |
| 1000 | Title: fmt.Sprintf("Test webhook %q", webhook.Payload.GetTitle()), |
| 1001 | TitleZh: fmt.Sprintf("测试 webhook %q", webhook.Payload.GetTitle()), |
| 1002 | Description: "This is a test", |
| 1003 | Link: fmt.Sprintf("%s/projects/%s/webhooks/%s", externalURL, project.ResourceID, fmt.Sprintf("%s-%s", slug.Make(webhook.Payload.GetTitle()), webhook.ResourceID)), |
nothing calls this directly
no test coverage detected