diff --git a/client/client.go b/client/client.go index ce117b4..86251dc 100644 --- a/client/client.go +++ b/client/client.go @@ -343,3 +343,26 @@ func (cli *StreamClient) SendDataFrameResponse(ctx context.Context, resp *payloa } return cli.conn.WriteJSON(resp) } + +// 通用注册函数 +func (cli *StreamClient) RegisterRouter(stype, stopic string, frameHandler handler.IFrameHandler) { + if cli.subscriptions == nil { + cli.subscriptions = make(map[string]map[string]handler.IFrameHandler) + } + + if _, ok := cli.subscriptions[stype]; !ok { + cli.subscriptions[stype] = make(map[string]handler.IFrameHandler) + } + + cli.subscriptions[stype][stopic] = frameHandler +} + +// callback类型注册函数 +func (cli *StreamClient) RegisterCallbackRouter(topic string, frameHandler handler.IFrameHandler) { + cli.RegisterRouter(utils.SubscriptionTypeKCallback, topic, frameHandler) +} + +// 事件类型的注册函数 +func (cli *StreamClient) RegisterEventRouter(topic string, frameHandler handler.IFrameHandler) { + cli.RegisterRouter(utils.SubscriptionTypeKEvent, topic, frameHandler) +} diff --git a/client/option.go b/client/option.go index ea74a0f..8f4b8c9 100644 --- a/client/option.go +++ b/client/option.go @@ -23,15 +23,7 @@ func WithAppCredential(cred *AppCredentialConfig) ClientOption { func WithSubscription(stype, stopic string, frameHandler handler.IFrameHandler) ClientOption { return func(c *StreamClient) { - if c.subscriptions == nil { - c.subscriptions = make(map[string]map[string]handler.IFrameHandler) - } - - if _, ok := c.subscriptions[stype]; !ok { - c.subscriptions[stype] = make(map[string]handler.IFrameHandler) - } - - c.subscriptions[stype][stopic] = frameHandler + c.RegisterRouter(stype, stopic, frameHandler) } } diff --git a/example/example.go b/example/example.go new file mode 100644 index 0000000..f6e0ea3 --- /dev/null +++ b/example/example.go @@ -0,0 +1,128 @@ +package main + +import ( + "bytes" + "context" + "encoding/json" + "flag" + "fmt" + "github.com/open-dingtalk/dingtalk-stream-sdk-go/chatbot" + "github.com/open-dingtalk/dingtalk-stream-sdk-go/client" + "github.com/open-dingtalk/dingtalk-stream-sdk-go/event" + "github.com/open-dingtalk/dingtalk-stream-sdk-go/logger" + "github.com/open-dingtalk/dingtalk-stream-sdk-go/payload" + "net/http" + "time" +) + +/** + * @Author linya.jj + * @Date 2023/3/22 18:30 + */ + +func OnChatBotMessageReceived(ctx context.Context, df *payload.DataFrame) (*payload.DataFrameResponse, error) { + frameResp := &payload.DataFrameResponse{ + Code: 200, + Headers: payload.DataFrameHeader{ + payload.DataFrameHeaderKContentType: payload.DataFrameContentTypeKJson, + payload.DataFrameHeaderKMessageId: df.GetMessageId(), + }, + Message: "ok", + Data: "", + } + + // 反序列化机器人回调消息 + msgData := &chatbot.BotCallbackDataModel{} + err := json.Unmarshal([]byte(df.Data), msgData) + if err != nil { + // TODO 处理错误:回调消息反序列化出错 + return frameResp, nil + } + + //处理方式:回复文本消息,通过SessionWebhook来回复消息 + requestBody := map[string]interface{}{ + "msgtype": "text", + "text": map[string]interface{}{ + "content": fmt.Sprintf("msg received: [%s]", msgData.Text.Content), + }, + } + + requestJsonBody, _ := json.Marshal(requestBody) + req, err := http.NewRequestWithContext(ctx, http.MethodPost, msgData.SessionWebhook, bytes.NewReader(requestJsonBody)) + if err != nil { + // TODO 处理错误 + return frameResp, nil + } + + req.Header.Set("Content-Type", "application/json") + req.Header.Set("Accept", "*/*") + + httpClient := &http.Client{ + Transport: http.DefaultTransport, + Timeout: 5 * time.Second, //设置超时,包含connection时间、任意重定向时间、读取response body时间 + } + + _, err = httpClient.Do(req) + if err != nil { + // TODO 处理错误: 回复消息出错 + return frameResp, nil + } + + return frameResp, nil +} + +// 事件处理函数 +func OnEventReceived(ctx context.Context, df *payload.DataFrame) (*payload.DataFrameResponse, error) { + eventHeader := event.NewEventHeaderFromDataFrame(df) + + logger.GetLogger().Infof("received event, eventId=[%s] eventBornTime=[%d] eventCorpId=[%s] eventType=[%s] eventUnifiedAppId=[%s] data=[%s]", + eventHeader.EventId, + eventHeader.EventBornTime, + eventHeader.EventCorpId, + eventHeader.EventType, + eventHeader.EventUnifiedAppId, + df.Data) + + resultStr, _ := json.Marshal(event.NewEventProcessResultSuccess()) + + frameResp := &payload.DataFrameResponse{ + Code: payload.DataFrameResponseStatusCodeKOK, + Headers: payload.DataFrameHeader{ + payload.DataFrameHeaderKContentType: payload.DataFrameContentTypeKJson, + payload.DataFrameHeaderKMessageId: df.GetMessageId(), + }, + Message: "ok", + Data: string(resultStr), + } + + return frameResp, nil +} + +func main() { + var clientId, clientSecret string + flag.StringVar(&clientId, "client_id", "", "your-client-id") + flag.StringVar(&clientSecret, "client_secret", "", "your-client-secret") + + flag.Parse() + + logger.SetLogger(logger.NewStdTestLogger()) + + cli := client.NewStreamClient( + client.WithAppCredential(client.NewAppCredentialConfig(clientId, clientSecret)), + client.WithUserAgent(client.NewDingtalkGoSDKUserAgent()), + ) + + //注册事件类型的处理函数 + cli.RegisterEventRouter("*", OnEventReceived) + //注册callback类型的处理函数 + cli.RegisterCallbackRouter(payload.BotMessageCallbackTopic, OnChatBotMessageReceived) + + err := cli.Start(context.Background()) + if err != nil { + panic(err) + } + + defer cli.Close() + + select {} +} diff --git a/example/example_bot.go b/example/example_bot.go deleted file mode 100644 index 9638275..0000000 --- a/example/example_bot.go +++ /dev/null @@ -1,83 +0,0 @@ -package main - -import ( - "bytes" - "context" - "encoding/json" - "fmt" - "github.com/open-dingtalk/dingtalk-stream-sdk-go/chatbot" - "github.com/open-dingtalk/dingtalk-stream-sdk-go/client" - "github.com/open-dingtalk/dingtalk-stream-sdk-go/logger" - "github.com/open-dingtalk/dingtalk-stream-sdk-go/payload" - "github.com/open-dingtalk/dingtalk-stream-sdk-go/utils" - "net/http" - "time" -) - -/** - * @Author linya.jj - * @Date 2023/3/22 18:30 - */ - -func OnBotCallback(ctx context.Context, df *payload.DataFrame) (*payload.DataFrameResponse, error) { - frameResp := &payload.DataFrameResponse{ - Code: 200, - Headers: payload.DataFrameHeader{ - payload.DataFrameHeaderKContentType: payload.DataFrameContentTypeKJson, - payload.DataFrameHeaderKMessageId: df.GetMessageId(), - }, - Message: "ok", - Data: "", - } - - return frameResp, nil -} - -func OnChatReceive(ctx context.Context, data *chatbot.BotCallbackDataModel) error { - requestBody := map[string]interface{}{ - "msgtype": "text", - "text": map[string]interface{}{ - "content": fmt.Sprintf("msg received: [%s]", data.Text.Content), - }, - } - - requestJsonBody, _ := json.Marshal(requestBody) - req, err := http.NewRequestWithContext(ctx, http.MethodPost, data.SessionWebhook, bytes.NewReader(requestJsonBody)) - if err != nil { - return err - } - - req.Header.Set("Content-Type", "application/json") - req.Header.Set("Accept", "*/*") - - httpClient := &http.Client{ - Transport: http.DefaultTransport, - Timeout: 5 * time.Second, //设置超时,包含connection时间、任意重定向时间、读取response body时间 - } - - _, err = httpClient.Do(req) - if err != nil { - return err - } - - return nil -} - -func RunBotListener(clientId, clientSecret string) { - logger.SetLogger(logger.NewStdTestLogger()) - - cli := client.NewStreamClient( - client.WithAppCredential(client.NewAppCredentialConfig(clientId, clientSecret)), - client.WithUserAgent(client.NewDingtalkGoSDKUserAgent()), - client.WithSubscription(utils.SubscriptionTypeKCallback, payload.BotMessageCallbackTopic, chatbot.NewDefaultChatBotFrameHandler(OnChatReceive).OnEventReceived), - ) - - err := cli.Start(context.Background()) - if err != nil { - panic(err) - } - - defer cli.Close() - - select {} -} diff --git a/example/example_event.go b/example/example_event.go deleted file mode 100644 index f0ffbbb..0000000 --- a/example/example_event.go +++ /dev/null @@ -1,35 +0,0 @@ -package main - -import ( - "context" - "github.com/open-dingtalk/dingtalk-stream-sdk-go/client" - "github.com/open-dingtalk/dingtalk-stream-sdk-go/event" - "github.com/open-dingtalk/dingtalk-stream-sdk-go/logger" - "github.com/open-dingtalk/dingtalk-stream-sdk-go/utils" -) - -/** - * @Author linya.jj - * @Date 2023/3/22 18:30 - */ - -func RunEventListener(clientId, clientSecret string) { - logger.SetLogger(logger.NewStdTestLogger()) - - eventHandler := event.NewDefaultEventFrameHandler(event.EventHandlerDoNothing) - - cli := client.NewStreamClient( - client.WithAppCredential(client.NewAppCredentialConfig(clientId, clientSecret)), - client.WithUserAgent(client.NewDingtalkGoSDKUserAgent()), - client.WithSubscription(utils.SubscriptionTypeKEvent, "*", eventHandler.OnEventReceived), - ) - - err := cli.Start(context.Background()) - if err != nil { - panic(err) - } - - defer cli.Close() - - select {} -} diff --git a/example/example_main.go b/example/example_main.go deleted file mode 100644 index 6997e80..0000000 --- a/example/example_main.go +++ /dev/null @@ -1,22 +0,0 @@ -package main - -import ( - "flag" -) - -/** - * @Author linya.jj - * @Date 2023/3/22 18:30 - */ - -func main() { - var clientId, clientSecret string - flag.StringVar(&clientId, "client_id", "", "your-client-id") - flag.StringVar(&clientSecret, "client_secret", "", "your-client-secret") - - flag.Parse() - - RunBotListener(clientId, clientSecret) - - select {} -} diff --git a/payload/data_frame.go b/payload/data_frame.go index 3ac7b7a..0230caf 100644 --- a/payload/data_frame.go +++ b/payload/data_frame.go @@ -24,7 +24,7 @@ type DataFrame struct { SpecVersion string `json:"specVersion"` Type string `json:"type"` Time int64 `json:"time"` - Headers DataFrameHeader `json:"headers""` + Headers DataFrameHeader `json:"headers"` Data string `json:"data"` }