From ffab4144be10e61390ca1f21181c438f34f17187 Mon Sep 17 00:00:00 2001 From: Ke Jie Date: Fri, 17 Nov 2023 16:41:39 +0800 Subject: [PATCH] feat: support card instance callback Signed-off-by: Ke Jie --- card/handler.go | 44 ++++++++++++++++++++++++++++++++++++++++++++ card/model.go | 44 ++++++++++++++++++++++++++++++++++++++++++++ client/client.go | 8 +++++++- example/example.go | 11 +++++++++++ payload/utils.go | 5 +++-- 5 files changed, 109 insertions(+), 3 deletions(-) create mode 100644 card/handler.go create mode 100644 card/model.go diff --git a/card/handler.go b/card/handler.go new file mode 100644 index 0000000..3e483fd --- /dev/null +++ b/card/handler.go @@ -0,0 +1,44 @@ +package card + +import ( + "context" + "encoding/json" + "github.com/open-dingtalk/dingtalk-stream-sdk-go/payload" +) + +type ICardCallbackHandler func(c context.Context, request *CardRequest) (*CardResponse, error) + +type DefaultCardCallbackFrameHandler struct { + defaultHandler ICardCallbackHandler +} + +func NewDefaultPluginFrameHandler(defaultHandler ICardCallbackHandler) *DefaultCardCallbackFrameHandler { + return &DefaultCardCallbackFrameHandler{ + defaultHandler: defaultHandler, + } +} + +func (h *DefaultCardCallbackFrameHandler) OnEventReceived(ctx context.Context, df *payload.DataFrame) (*payload.DataFrameResponse, error) { + msgData := &CardRequest{} + err := json.Unmarshal([]byte(df.Data), msgData) + if err != nil { + return nil, err + } + json.Unmarshal([]byte(msgData.Content), &msgData.CardActionData) + + if h.defaultHandler == nil { + return payload.NewDataFrameResponse(payload.DataFrameResponseStatusCodeKHandlerNotFound), nil + } + + result, err := h.defaultHandler(ctx, msgData) + if err != nil { + return nil, err + } + frameResp := payload.NewSuccessDataFrameResponse() + callbackData := make(map[string]any) + callbackData["response"] = result + if err = frameResp.SetJson(callbackData); err != nil { + return nil, err + } + return frameResp, nil +} diff --git a/card/model.go b/card/model.go new file mode 100644 index 0000000..bc6d773 --- /dev/null +++ b/card/model.go @@ -0,0 +1,44 @@ +package card + +type PrivateCardActionData struct { + CardPrivateData CardPrivateData `json:"cardPrivateData"` +} + +type CardPrivateData struct { + ActionIdList []string `json:"actionIds"` + Params map[string]any `json:"params"` +} + +type CardDataDto struct { + CardParamMap map[string]string `json:"cardParamMap"` +} + +type CardRequest struct { + Content string `json:"content"` + CorpId string `json:"corpId"` + Extension string `json:"extension"` + OutTrackId string `json:"outTrackId"` + SpaceId string `json:"spaceId"` + SpaceType string `json:"spaceType"` + Type string `json:"type"` + UserId string `json:"userId"` + UserIdType int `json:"userIdType"` + CardActionData PrivateCardActionData +} + +type CardResponse struct { + CardData *CardDataDto `json:"cardData"` + PrivateCardData *CardDataDto `json:"privateCardData"` +} + +func (r *CardRequest) GetActionString(name string) string { + value, ok := r.CardActionData.CardPrivateData.Params[name] + if !ok { + return "" + } + s, ok := value.(string) + if ok { + return s + } + return "" +} diff --git a/client/client.go b/client/client.go index f601de8..2d7baed 100644 --- a/client/client.go +++ b/client/client.go @@ -6,6 +6,7 @@ import ( "encoding/json" "errors" "fmt" + "github.com/open-dingtalk/dingtalk-stream-sdk-go/card" "io" "net/http" "sync" @@ -405,12 +406,17 @@ func (cli *StreamClient) RegisterPluginCallbackRouter(messageHandler plugin.IPlu cli.RegisterRouter(utils.SubscriptionTypeKCallback, payload.PluginMessageCallbackTopic, plugin.NewDefaultPluginFrameHandler(messageHandler).OnEventReceived) } +// 互动卡片的注册函数 +func (cli *StreamClient) RegisterCardCallbackRouter(messageHandler card.ICardCallbackHandler) { + cli.RegisterRouter(utils.SubscriptionTypeKCallback, payload.CardInstanceCallbackTopic, card.NewDefaultPluginFrameHandler(messageHandler).OnEventReceived) +} + // 事件类型的注册函数 func (cli *StreamClient) RegisterEventRouter(topic string, frameHandler handler.IFrameHandler) { cli.RegisterRouter(utils.SubscriptionTypeKEvent, topic, frameHandler) } -// 事件类型的注册函数 +// 所有事件的注册函数 func (cli *StreamClient) RegisterAllEventRouter(frameHandler handler.IFrameHandler) { cli.RegisterRouter(utils.SubscriptionTypeKEvent, "*", frameHandler) } diff --git a/example/example.go b/example/example.go index 3d447a2..762cca2 100644 --- a/example/example.go +++ b/example/example.go @@ -4,6 +4,7 @@ import ( "context" "flag" "fmt" + "github.com/open-dingtalk/dingtalk-stream-sdk-go/card" "github.com/open-dingtalk/dingtalk-stream-sdk-go/chatbot" "github.com/open-dingtalk/dingtalk-stream-sdk-go/client" @@ -61,6 +62,14 @@ func OnEventReceived(ctx context.Context, df *payload.DataFrame) (frameResp *pay return } +func OnCardCallbackReceived(ctx context.Context, request *card.CardRequest) (*card.CardResponse, error) { + logger.GetLogger().Infof("receive card data: %v", request) + response := &card.CardResponse{ + CardData: &card.CardDataDto{}, + } + return response, nil +} + // go run example/*.go --client_id your-client-id --client_secret your-client-secret func main() { var clientId, clientSecret string @@ -79,6 +88,8 @@ func main() { cli.RegisterChatBotCallbackRouter(OnChatBotMessageReceived) //注册插件的处理函数 cli.RegisterPluginCallbackRouter(OnPluginMessageReceived) + //注册互动卡片类型的处理函数 + cli.RegisterCardCallbackRouter(OnCardCallbackReceived) err := cli.Start(context.Background()) if err != nil { diff --git a/payload/utils.go b/payload/utils.go index dbd89f8..fd76374 100644 --- a/payload/utils.go +++ b/payload/utils.go @@ -24,8 +24,9 @@ const ( DataFrameResponseStatusCodeKInternalError = 500 DataFrameResponseStatusCodeKHandlerNotFound = 404 - BotMessageCallbackTopic = "/v1.0/im/bot/messages/get" //机器人消息统一回调topic - PluginMessageCallbackTopic = "/v1.0/graph/api/invoke" //AI插件消息统一回调topic + BotMessageCallbackTopic = "/v1.0/im/bot/messages/get" // 机器人消息统一回调 topic + PluginMessageCallbackTopic = "/v1.0/graph/api/invoke" // AI插件消息统一回调 topic + CardInstanceCallbackTopic = "/v1.0/card/instances/callback" // 卡片回调的 topic ) func GenerateMessageId(prefix string) string {