|
- // Copyright © 2023 OpenIM open source community. All rights reserved.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
-
- package service
-
- import (
- "context"
- "encoding/json"
- "fmt"
- "net"
-
- "github.com/gin-gonic/gin"
- "github.com/pkg/errors"
- "github.com/shomali11/slacker"
- "github.com/slack-go/slack"
-
- "github.com/openimsdk/openkf/server/internal/config"
- "github.com/openimsdk/openkf/server/internal/dal/dao"
- "github.com/openimsdk/openkf/server/internal/models/base"
- customerroles "github.com/openimsdk/openkf/server/internal/models/customer_roles"
- responseparams "github.com/openimsdk/openkf/server/internal/params/response"
- "github.com/openimsdk/openkf/server/pkg/log"
- "github.com/openimsdk/openkf/server/pkg/openim/param/request"
- "github.com/openimsdk/openkf/server/pkg/openim/sdk/constant"
- "github.com/openimsdk/openkf/server/pkg/openim/sdk/msg"
- "github.com/openimsdk/openkf/server/pkg/utils"
- )
-
- // SlackService slack service.
- type SlackService struct {
- Service
-
- CustomerSlackDao *dao.CustomerSlackDao
- }
-
- // NewSlackService return new service with Background context.
- func NewSlackService(ctx context.Context) *SlackService {
- return &SlackService{
- Service: Service{
- ctx: ctx,
- },
- CustomerSlackDao: dao.NewCustomerSlackDao(),
- }
- }
-
- // GetSlackConfig get slack config.
- func (svc *SlackService) GetSlackConfig() (*responseparams.SlackConfigResponse, error) {
- return &responseparams.SlackConfigResponse{
- BotToken: config.Config.Slack.BotToken,
- AppToken: config.Config.Slack.AppToken,
- AppID: config.Config.Slack.AppID,
- ClientID: config.Config.Slack.ClientID,
- ClientSecret: config.Config.Slack.ClientSecret,
- SigningSecret: config.Config.Slack.SigningSecret,
- VerificationToken: config.Config.Slack.VerificationToken,
- }, nil
- }
-
- // CreateCustomer create customer if not exists.
- func (svc *SlackService) CreateCustomer(userId string, profile *slack.UserProfile) (string, uint, error) {
- // check if exists
- temp, err := svc.CustomerSlackDao.FindFirstByUUID(userId)
- if temp != nil || err == nil {
- return temp.UUID, temp.Id, err
- }
-
- // Set unique email
- if profile.Email == "" {
- profile.Email = fmt.Sprintf("%s %s", "NOEMAIL", utils.GenUUIDWithoutHyphen())
- }
-
- customerSlack := customerroles.CustomerSlack{
- UserBase: base.UserBase{
- // UUID: fmt.Sprintf("%s%s", dao.SLACK_PERFIX, userId),
- UUID: userId,
- Email: profile.Email,
- Nickname: profile.FirstName,
- Avatar: profile.Image512,
- Description: profile.Title,
- IsEnable: true,
- },
- FirstName: profile.FirstName,
- LastName: profile.LastName,
- RealName: profile.RealName,
- RealNameNormalized: profile.RealNameNormalized,
- DisplayName: profile.DisplayName,
- DisplayNameNormalized: profile.DisplayNameNormalized,
- Skype: profile.Skype,
- Phone: profile.Phone,
- Image24: profile.Image24,
- Image32: profile.Image32,
- Image48: profile.Image48,
- Image72: profile.Image72,
- Image192: profile.Image192,
- Image512: profile.Image512,
- ImageOriginal: profile.ImageOriginal,
- Title: profile.Title,
- BotID: profile.BotID,
- ApiAppID: profile.ApiAppID,
- StatusText: profile.StatusText,
- StatusEmoji: profile.StatusEmoji,
- StatusExpiration: profile.StatusExpiration,
- Team: profile.Team,
- }
- if err = svc.CustomerSlackDao.Create(&customerSlack); err != nil {
- return customerSlack.UUID, 0, err
- }
-
- s, _ := svc.CustomerSlackDao.FindFirstByUUID(userId)
-
- param := &request.RegisterUserParams{
- Secret: config.Config.OpenIM.Secret,
- Users: []request.User{
- {
- UserID: userId,
- Nickname: customerSlack.Nickname,
- FaceURL: "", // Use OpenKF avatar
- },
- },
- }
- ok, err := registerUserToOpenIM(param)
- if err != nil || !ok {
- // Assume that the user has been created/deleted successfully
- _ = svc.CustomerSlackDao.Delete(s)
-
- return userId, s.Id, err
- }
-
- return userId, s.Id, nil
- }
-
- // GetSlackUser get slack user.
- func (svc *SlackService) GetSlackUser(userId string) (*customerroles.CustomerSlack, error) {
- return svc.CustomerSlackDao.FindFirstByUUID(userId)
- }
-
- // SendMsg send message to openkf.
- func (svc *SlackService) SendMsg(uid, question string, botContext slacker.BotContext) error {
- udSvc := NewUserDispatchService(svc.ctx)
-
- // Get default staff id
- sMap := udSvc.GetSlackMap(uid)
- staffId := sMap.StaffID
-
- if sMap.StaffID == "" || sMap.SlackChannelID == "" {
- // Get staff id
- tempStaffId, err := udSvc.GetUser()
- if err != nil {
- return err
- }
-
- // Store staff, writer to cache redis map
- err = udSvc.SetSlackMap(uid, tempStaffId, botContext)
- if err != nil {
- return errors.Wrapf(err, "set slack map failed")
- }
- staffId = tempStaffId
- }
-
- // Get OpenIM admin token
- uSvc := NewUserService(&gin.Context{}) // TODO: Change context to same
- token, err := uSvc.GetAdminToken()
- if err != nil {
- return errors.Wrapf(err, "get admin token failed")
- }
-
- // Get custom info
- customer, err := svc.CustomerSlackDao.FindFirstByUUID(uid)
- if err != nil {
- return errors.Wrapf(err, "find customer failed")
- }
-
- msgInfo := &request.MsgInfo{
- SendID: uid,
- RecvID: staffId,
- GroupID: "",
- SenderNickname: customer.Nickname,
- SenderFaceURL: customer.Avatar,
- SenderPlatformID: constant.PLATFORMID_WEB,
- Content: &request.TextContent{
- Text: fmt.Sprintf("{\"content\":\"%s\"}", question),
- },
- ContentType: constant.CONTENT_TYPE_TEXT,
- SessionType: constant.SESSION_TYPE_SINGLE_CHAT,
- IsOnlineOnly: false,
- NotOfflinePush: false,
- OfflinePushInfo: &request.OfflinePushInfo{},
- }
- res, err := json.Marshal(msgInfo)
- if err != nil {
- return errors.Wrapf(err, "marshal msgInfo failed")
- }
- log.Debugf("msgInfo", string(res))
- host := fmt.Sprintf("http://%s", net.JoinHostPort(config.Config.OpenIM.Ip, fmt.Sprintf("%d", config.Config.OpenIM.ApiPort)))
- resp, err := msg.AdminSendMsg(msgInfo, "sendMsg:"+uid, host, token.Token)
- if err != nil {
- return errors.Wrapf(err, "send msg failed")
- }
- log.Debugf("AdminSendMsg", "Resp: %+v", resp)
-
- return nil
- }
|