Commit f33571fe authored by Steven's avatar Steven

feat: update webhook request payload

parent d1599759
...@@ -662,10 +662,10 @@ paths: ...@@ -662,10 +662,10 @@ paths:
creatorId: creatorId:
type: integer type: integer
format: int32 format: int32
createdTime: createTime:
type: string type: string
format: date-time format: date-time
updatedTime: updateTime:
type: string type: string
format: date-time format: date-time
rowStatus: rowStatus:
...@@ -3117,10 +3117,10 @@ definitions: ...@@ -3117,10 +3117,10 @@ definitions:
creatorId: creatorId:
type: integer type: integer
format: int32 format: int32
createdTime: createTime:
type: string type: string
format: date-time format: date-time
updatedTime: updateTime:
type: string type: string
format: date-time format: date-time
rowStatus: rowStatus:
......
...@@ -8,6 +8,9 @@ import ( ...@@ -8,6 +8,9 @@ import (
"time" "time"
"github.com/pkg/errors" "github.com/pkg/errors"
"google.golang.org/protobuf/encoding/protojson"
v1pb "github.com/usememos/memos/proto/gen/api/v1"
) )
var ( var (
...@@ -15,45 +18,16 @@ var ( ...@@ -15,45 +18,16 @@ var (
timeout = 30 * time.Second timeout = 30 * time.Second
) )
type Memo struct {
// The name of the memo.
// Format: memos/{id}
// id is the system generated id.
Name string
// The name of the creator.
// Format: users/{id}
Creator string
// The raw content.
Content string
}
// WebhookPayload is the payload of webhook request.
// nolint
type WebhookPayload struct {
URL string `json:"url"`
ActivityType string `json:"activityType"`
CreatorID int32 `json:"creatorId"`
CreatedTs int64 `json:"createdTs"`
Memo *Memo `json:"memo"`
}
// WebhookResponse is the response of webhook request.
// nolint
type WebhookResponse struct {
Code int `json:"code"`
Message string `json:"message"`
}
// Post posts the message to webhook endpoint. // Post posts the message to webhook endpoint.
func Post(payload WebhookPayload) error { func Post(requestPayload *v1pb.WebhookRequestPayload) error {
body, err := json.Marshal(&payload) body, err := protojson.Marshal(requestPayload)
if err != nil { if err != nil {
return errors.Wrapf(err, "failed to marshal webhook request to %s", payload.URL) return errors.Wrapf(err, "failed to marshal webhook request to %s", requestPayload.Url)
} }
req, err := http.NewRequest("POST", payload.URL, bytes.NewBuffer(body)) req, err := http.NewRequest("POST", requestPayload.Url, bytes.NewBuffer(body))
if err != nil { if err != nil {
return errors.Wrapf(err, "failed to construct webhook request to %s", payload.URL) return errors.Wrapf(err, "failed to construct webhook request to %s", requestPayload.Url)
} }
req.Header.Set("Content-Type", "application/json") req.Header.Set("Content-Type", "application/json")
...@@ -62,22 +36,25 @@ func Post(payload WebhookPayload) error { ...@@ -62,22 +36,25 @@ func Post(payload WebhookPayload) error {
} }
resp, err := client.Do(req) resp, err := client.Do(req)
if err != nil { if err != nil {
return errors.Wrapf(err, "failed to post webhook to %s", payload.URL) return errors.Wrapf(err, "failed to post webhook to %s", requestPayload.Url)
} }
b, err := io.ReadAll(resp.Body) b, err := io.ReadAll(resp.Body)
if err != nil { if err != nil {
return errors.Wrapf(err, "failed to read webhook response from %s", payload.URL) return errors.Wrapf(err, "failed to read webhook response from %s", requestPayload.Url)
} }
defer resp.Body.Close() defer resp.Body.Close()
if resp.StatusCode < 200 || resp.StatusCode > 299 { if resp.StatusCode < 200 || resp.StatusCode > 299 {
return errors.Errorf("failed to post webhook %s, status code: %d, response body: %s", payload.URL, resp.StatusCode, b) return errors.Errorf("failed to post webhook %s, status code: %d, response body: %s", requestPayload.Url, resp.StatusCode, b)
} }
response := &WebhookResponse{} response := &struct {
Code int `json:"code"`
Message string `json:"message"`
}{}
if err := json.Unmarshal(b, response); err != nil { if err := json.Unmarshal(b, response); err != nil {
return errors.Wrapf(err, "failed to unmarshal webhook response from %s", payload.URL) return errors.Wrapf(err, "failed to unmarshal webhook response from %s", requestPayload.Url)
} }
if response.Code != 0 { if response.Code != 0 {
......
...@@ -3,6 +3,7 @@ syntax = "proto3"; ...@@ -3,6 +3,7 @@ syntax = "proto3";
package memos.api.v1; package memos.api.v1;
import "api/v1/common.proto"; import "api/v1/common.proto";
import "api/v1/memo_service.proto";
import "google/api/annotations.proto"; import "google/api/annotations.proto";
import "google/api/client.proto"; import "google/api/client.proto";
import "google/protobuf/empty.proto"; import "google/protobuf/empty.proto";
...@@ -48,9 +49,9 @@ message Webhook { ...@@ -48,9 +49,9 @@ message Webhook {
int32 creator_id = 2; int32 creator_id = 2;
google.protobuf.Timestamp created_time = 3; google.protobuf.Timestamp create_time = 3;
google.protobuf.Timestamp updated_time = 4; google.protobuf.Timestamp update_time = 4;
RowStatus row_status = 5; RowStatus row_status = 5;
...@@ -86,3 +87,15 @@ message UpdateWebhookRequest { ...@@ -86,3 +87,15 @@ message UpdateWebhookRequest {
message DeleteWebhookRequest { message DeleteWebhookRequest {
int32 id = 1; int32 id = 1;
} }
message WebhookRequestPayload {
string url = 1;
string activity_type = 2;
int32 creator_id = 3;
google.protobuf.Timestamp create_time = 4;
Memo memo = 5;
}
This diff is collapsed.
...@@ -1243,26 +1243,22 @@ func (s *APIV1Service) dispatchMemoRelatedWebhook(ctx context.Context, memo *v1p ...@@ -1243,26 +1243,22 @@ func (s *APIV1Service) dispatchMemoRelatedWebhook(ctx context.Context, memo *v1p
return errors.Wrap(err, "failed to convert memo to webhook payload") return errors.Wrap(err, "failed to convert memo to webhook payload")
} }
payload.ActivityType = activityType payload.ActivityType = activityType
payload.URL = hook.URL payload.Url = hook.URL
if err := webhook.Post(*payload); err != nil { if err := webhook.Post(payload); err != nil {
return errors.Wrap(err, "failed to post webhook") return errors.Wrap(err, "failed to post webhook")
} }
} }
return nil return nil
} }
func convertMemoToWebhookPayload(memo *v1pb.Memo) (*webhook.WebhookPayload, error) { func convertMemoToWebhookPayload(memo *v1pb.Memo) (*v1pb.WebhookRequestPayload, error) {
creatorID, err := ExtractUserIDFromName(memo.Creator) creatorID, err := ExtractUserIDFromName(memo.Creator)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "invalid memo creator") return nil, errors.Wrap(err, "invalid memo creator")
} }
return &webhook.WebhookPayload{ return &v1pb.WebhookRequestPayload{
CreatorID: creatorID, CreatorId: creatorID,
CreatedTs: time.Now().Unix(), CreateTime: timestamppb.New(time.Now()),
Memo: &webhook.Memo{ Memo: memo,
Name: memo.Name,
Creator: memo.Creator,
Content: memo.Content,
},
}, nil }, nil
} }
...@@ -103,12 +103,12 @@ func (s *APIV1Service) DeleteWebhook(ctx context.Context, request *v1pb.DeleteWe ...@@ -103,12 +103,12 @@ func (s *APIV1Service) DeleteWebhook(ctx context.Context, request *v1pb.DeleteWe
func convertWebhookFromStore(webhook *store.Webhook) *v1pb.Webhook { func convertWebhookFromStore(webhook *store.Webhook) *v1pb.Webhook {
return &v1pb.Webhook{ return &v1pb.Webhook{
Id: webhook.ID, Id: webhook.ID,
CreatedTime: timestamppb.New(time.Unix(webhook.CreatedTs, 0)), CreateTime: timestamppb.New(time.Unix(webhook.CreatedTs, 0)),
UpdatedTime: timestamppb.New(time.Unix(webhook.UpdatedTs, 0)), UpdateTime: timestamppb.New(time.Unix(webhook.UpdatedTs, 0)),
RowStatus: convertRowStatusFromStore(webhook.RowStatus), RowStatus: convertRowStatusFromStore(webhook.RowStatus),
CreatorId: webhook.CreatorID, CreatorId: webhook.CreatorID,
Name: webhook.Name, Name: webhook.Name,
Url: webhook.URL, Url: webhook.URL,
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment