init push
This commit is contained in:
246
backend/handler/share/app.go
Normal file
246
backend/handler/share/app.go
Normal file
@@ -0,0 +1,246 @@
|
||||
package share
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
wechat_v2 "github.com/silenceper/wechat/v2"
|
||||
"github.com/silenceper/wechat/v2/cache"
|
||||
offConfig "github.com/silenceper/wechat/v2/officialaccount/config"
|
||||
"github.com/silenceper/wechat/v2/officialaccount/message"
|
||||
|
||||
"github.com/chaitin/panda-wiki/consts"
|
||||
"github.com/chaitin/panda-wiki/domain"
|
||||
"github.com/chaitin/panda-wiki/handler"
|
||||
"github.com/chaitin/panda-wiki/log"
|
||||
"github.com/chaitin/panda-wiki/usecase"
|
||||
)
|
||||
|
||||
type ShareAppHandler struct {
|
||||
*handler.BaseHandler
|
||||
logger *log.Logger
|
||||
usecase *usecase.AppUsecase
|
||||
}
|
||||
|
||||
func NewShareAppHandler(
|
||||
e *echo.Echo,
|
||||
baseHandler *handler.BaseHandler,
|
||||
logger *log.Logger,
|
||||
usecase *usecase.AppUsecase,
|
||||
) *ShareAppHandler {
|
||||
h := &ShareAppHandler{
|
||||
BaseHandler: baseHandler,
|
||||
logger: logger.WithModule("handler.share.app"),
|
||||
usecase: usecase,
|
||||
}
|
||||
|
||||
share := e.Group("share/v1/app",
|
||||
func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||
return func(c echo.Context) error {
|
||||
c.Response().Header().Set("Access-Control-Allow-Origin", "*")
|
||||
c.Response().Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
|
||||
c.Response().Header().Set("Access-Control-Allow-Headers", "Content-Type, Origin, Accept")
|
||||
if c.Request().Method == "OPTIONS" {
|
||||
return c.NoContent(http.StatusOK)
|
||||
}
|
||||
return next(c)
|
||||
}
|
||||
})
|
||||
share.GET("/web/info", h.GetWebAppInfo)
|
||||
share.GET("/widget/info", h.GetWidgetAppInfo)
|
||||
share.GET("/wechat/info", h.WechatAppInfo)
|
||||
|
||||
// wechat official account
|
||||
share.GET("/wechat/official_account", h.VerifyUrlWechatOfficialAccount)
|
||||
share.POST("/wechat/official_account", h.WechatHandlerOfficialAccount)
|
||||
return h
|
||||
}
|
||||
|
||||
// GetWebAppInfo
|
||||
//
|
||||
// @Summary GetAppInfo
|
||||
// @Description GetAppInfo
|
||||
// @Tags share_app
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param X-KB-ID header string true "kb id"
|
||||
// @Success 200 {object} domain.Response{data=domain.AppInfoResp}
|
||||
// @Router /share/v1/app/web/info [get]
|
||||
func (h *ShareAppHandler) GetWebAppInfo(c echo.Context) error {
|
||||
kbID := c.Request().Header.Get("X-KB-ID")
|
||||
if kbID == "" {
|
||||
return h.NewResponseWithError(c, "kb_id is required", nil)
|
||||
}
|
||||
ctx := context.WithValue(c.Request().Context(), consts.ContextKeyEdition, consts.GetLicenseEdition(c))
|
||||
appInfo, err := h.usecase.ShareGetWebAppInfo(ctx, kbID, domain.GetAuthID(c))
|
||||
if err != nil {
|
||||
return h.NewResponseWithError(c, err.Error(), err)
|
||||
}
|
||||
return h.NewResponseWithData(c, appInfo)
|
||||
}
|
||||
|
||||
// GetWidgetAppInfo
|
||||
//
|
||||
// @Summary GetWidgetAppInfo
|
||||
// @Description GetWidgetAppInfo
|
||||
// @Tags share_app
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param X-KB-ID header string true "kb id"
|
||||
// @Success 200 {object} domain.Response
|
||||
// @Router /share/v1/app/widget/info [get]
|
||||
func (h *ShareAppHandler) GetWidgetAppInfo(c echo.Context) error {
|
||||
kbID := c.Request().Header.Get("X-KB-ID")
|
||||
if kbID == "" {
|
||||
return h.NewResponseWithError(c, "kb_id is required", nil)
|
||||
}
|
||||
appInfo, err := h.usecase.GetWidgetAppInfo(c.Request().Context(), kbID)
|
||||
if err != nil {
|
||||
return h.NewResponseWithError(c, err.Error(), err)
|
||||
}
|
||||
return h.NewResponseWithData(c, appInfo)
|
||||
}
|
||||
|
||||
// WechatAppInfo
|
||||
//
|
||||
// @Summary WechatAppInfo
|
||||
// @Description WechatAppInfo
|
||||
// @Tags share_chat
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param X-KB-ID header string true "kb id"
|
||||
// @Success 200 {object} domain.Response{data=v1.WechatAppInfoResp}
|
||||
// @Router /share/v1/app/wechat/info [get]
|
||||
func (h *ShareAppHandler) WechatAppInfo(c echo.Context) error {
|
||||
kbID := c.Request().Header.Get("X-KB-ID")
|
||||
if kbID == "" {
|
||||
return h.NewResponseWithError(c, "kb_id is required", nil)
|
||||
}
|
||||
appInfo, err := h.usecase.GetWechatAppInfo(c.Request().Context(), kbID)
|
||||
if err != nil {
|
||||
return h.NewResponseWithError(c, err.Error(), err)
|
||||
}
|
||||
return h.NewResponseWithData(c, appInfo)
|
||||
}
|
||||
|
||||
func (h *ShareAppHandler) VerifyUrlWechatOfficialAccount(c echo.Context) error {
|
||||
kbID := c.Request().Header.Get("X-KB-ID")
|
||||
|
||||
if kbID == "" {
|
||||
return h.NewResponseWithError(c, "kb_id is required", nil)
|
||||
}
|
||||
ctx := c.Request().Context()
|
||||
|
||||
// get wechat official account info
|
||||
appInfo, err := h.usecase.GetAppDetailByKBIDAndAppType(ctx, kbID, domain.AppTypeWechatOfficialAccount)
|
||||
if err != nil {
|
||||
h.logger.Error("get app detail failed")
|
||||
return h.NewResponseWithError(c, "GetAppDetailByKBIDAndAppType failed", err)
|
||||
}
|
||||
|
||||
if appInfo.Settings.WechatOfficialAccountIsEnabled != nil && !*appInfo.Settings.WechatOfficialAccountIsEnabled {
|
||||
return h.NewResponseWithError(c, "wechat official account is not enabled", err)
|
||||
}
|
||||
wc := wechat_v2.NewWechat()
|
||||
memory := cache.NewMemory()
|
||||
cfg := &offConfig.Config{
|
||||
AppID: appInfo.Settings.WechatOfficialAccountAppID,
|
||||
AppSecret: appInfo.Settings.WechatOfficialAccountAppSecret,
|
||||
Token: appInfo.Settings.WechatOfficialAccountToken,
|
||||
EncodingAESKey: appInfo.Settings.WechatOfficialAccountEncodingAESKey,
|
||||
Cache: memory,
|
||||
}
|
||||
officialAccount := wc.GetOfficialAccount(cfg)
|
||||
server := officialAccount.GetServer(c.Request(), c.Response().Writer)
|
||||
|
||||
// success
|
||||
err = server.Serve()
|
||||
if err != nil {
|
||||
return h.NewResponseWithError(c, "serve message failed", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *ShareAppHandler) WechatHandlerOfficialAccount(c echo.Context) error {
|
||||
kbID := c.Request().Header.Get("X-KB-ID")
|
||||
|
||||
if kbID == "" {
|
||||
return h.NewResponseWithError(c, "kb_id is required", nil)
|
||||
}
|
||||
ctx := c.Request().Context()
|
||||
|
||||
// get wechat official account info
|
||||
appInfo, err := h.usecase.GetAppDetailByKBIDAndAppType(ctx, kbID, domain.AppTypeWechatOfficialAccount)
|
||||
if err != nil {
|
||||
h.logger.Error("get app detail failed")
|
||||
return h.NewResponseWithError(c, "GetAppDetailByKBIDAndAppType failed", err)
|
||||
}
|
||||
|
||||
if appInfo.Settings.WechatOfficialAccountIsEnabled != nil && !*appInfo.Settings.WechatOfficialAccountIsEnabled {
|
||||
return h.NewResponseWithError(c, "wechat official account is not enabled", err)
|
||||
}
|
||||
wc := wechat_v2.NewWechat()
|
||||
memory := cache.NewMemory()
|
||||
cfg := &offConfig.Config{
|
||||
AppID: appInfo.Settings.WechatOfficialAccountAppID,
|
||||
AppSecret: appInfo.Settings.WechatOfficialAccountAppSecret,
|
||||
Token: appInfo.Settings.WechatOfficialAccountToken,
|
||||
EncodingAESKey: appInfo.Settings.WechatOfficialAccountEncodingAESKey,
|
||||
Cache: memory,
|
||||
}
|
||||
officialAccount := wc.GetOfficialAccount(cfg)
|
||||
server := officialAccount.GetServer(c.Request(), c.Response().Writer)
|
||||
|
||||
// message handler
|
||||
server.SetMessageHandler(func(msg *message.MixMessage) *message.Reply {
|
||||
h.logger.Info("received message:", log.Any("msgtype", msg.MsgType), log.Any("fromUserName", msg.FromUserName), log.String("content", msg.Content), log.Any("event type", msg.Event))
|
||||
|
||||
switch msg.MsgType {
|
||||
case message.MsgTypeText:
|
||||
// text消息
|
||||
userOpenID := msg.FromUserName
|
||||
userContent := msg.Content
|
||||
h.logger.Info("user_open_id user_content", log.Any("user_open_id", userOpenID), log.Any("user content", userContent))
|
||||
// 异步发送
|
||||
go func(openID, content string) {
|
||||
ctx := context.Background()
|
||||
// send content to ai
|
||||
result, err := h.usecase.GetWechatOfficialAccountResponse(ctx, officialAccount, kbID, openID, content)
|
||||
if err != nil {
|
||||
h.logger.Error("get wechat official account response failed", log.Error(err))
|
||||
return
|
||||
}
|
||||
// send response to user --> 需要开启客服消息权限
|
||||
err = h.usecase.SendCustomerServiceMessage(officialAccount, string(userOpenID), result)
|
||||
if err != nil {
|
||||
h.logger.Error("send to customer service failed", log.Error(err))
|
||||
}
|
||||
}(string(userOpenID), userContent)
|
||||
return &message.Reply{MsgType: message.MsgTypeText, MsgData: message.NewText("您的问题已经收到,正在努力思考中,请稍候...")}
|
||||
case message.MsgTypeEvent:
|
||||
if msg.Event == message.EventSubscribe {
|
||||
return &message.Reply{MsgType: message.MsgTypeText, MsgData: message.NewText("感谢关注,欢迎提问!")} // 立即回复简单信息
|
||||
}
|
||||
return nil
|
||||
default:
|
||||
h.logger.Info("unknown message type", log.Any("message type", msg.MsgType))
|
||||
return &message.Reply{MsgType: message.MsgTypeText, MsgData: message.NewText("未知消息类型,请发送正确的类型...")}
|
||||
}
|
||||
})
|
||||
|
||||
// success
|
||||
err = server.Serve()
|
||||
if err != nil {
|
||||
h.logger.Error("serve message failed", log.Error(err))
|
||||
return h.NewResponseWithError(c, "serve message failed", err)
|
||||
}
|
||||
|
||||
// send message to user
|
||||
err = server.Send()
|
||||
if err != nil {
|
||||
h.logger.Error("send message failed", log.Error(err))
|
||||
return h.NewResponseWithError(c, "send message failed", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user