客服系统机器人源码-微信专属个人助理可对接GPT

发布时间 2023-07-04 23:45:17作者: 唯一客服系统开发笔记

我们大家都见过很多微信机器人,对接了GPT以后效果非常好,可以作为微信群里的助理,帮助我们回答各种问题

 

现在我来分享一下微信机器人的源码,该源码是golang开发,可以实现模拟个人微信桌面版登录,监听到微信的各种消息。

下面就是完整代码

package main

import (
    "fmt"
    "github.com/eatmoreapple/openwechat"
    "github.com/gin-gonic/gin"
    "github.com/joho/godotenv"
    "github.com/tidwall/gjson"
    "log"
    "net/http"
    "net/url"
    "os"
    "strings"
)

func main() {
    myUID := ""
    myNicname := ""
    // 读取环境变量
    err := godotenv.Load(".env")
    api := os.Getenv("API_BASE")
    entId := os.Getenv("API_ENT_ID")
    kefuName := os.Getenv("API_KEFU_NAME")
    replyType := os.Getenv("REPLY_TYPE")
    replyOn := os.Getenv("REPLY_ON")
    bot := openwechat.DefaultBot(openwechat.Desktop) // 桌面模式
    // 注册消息处理函数
    bot.MessageHandler = func(msg *openwechat.Message) {

        if msg.IsText() {

            log.Printf("收到消息:%s\n", msg.Content)
            if msg.Content == "" {
                return
            }
            isSend := false
            //单聊
            sender, err := msg.Sender()
            senderId := ""

            //群聊
            if msg.IsSendByGroup() {
                sender, err = msg.SenderInGroup()
                senderId = Md5(sender.NickName)
                if err == nil {
                    log.Println("消息发送者:" + sender.NickName)
                }
                if strings.Contains(msg.Content, "@"+myNicname) && !strings.Contains(msg.Content, "结束") {
                    msg.Content = strings.TrimSpace(strings.ReplaceAll(msg.Content, "@"+myNicname, ""))
                    isSend = true
                } else {
                    isSend = false
                }
            } else {
                if err == nil {
                    log.Println("消息发送者:" + sender.NickName)
                }
                if replyType != "GROUP" && sender.NickName != myNicname {
                    senderId = sender.ID()
                    isSend = true
                }
            }
            if isSend && replyOn == "on" {
                data := url.Values{}
                data.Set("ent_id", entId)
                data.Set("visitor_id", senderId)
                data.Set("content", msg.Content)
                data.Set("nickname", sender.NickName)
                data.Set("kefu_name", kefuName)
                res, err := PostForm(api, data)
                if err == nil {
                    log.Println(res)
                    r := gjson.Get(res, "result.content").String()
                    if r == "" {
                        return
                    }
                    r = TrimHtml(r)
                    if msg.IsSendByGroup() {
                        r = fmt.Sprintf("@%s\u2005\u2005\u2005 %s", sender.NickName, r)
                    }
                    msg.ReplyText(r)
                }
            }

        }
    }
    // 注册登陆二维码回调
    bot.UUIDCallback = openwechat.PrintlnQrcodeUrl

    // 登陆
    reloadStorage := openwechat.NewFileHotReloadStorage("storage.json")
    defer reloadStorage.Close()
    err = bot.PushLogin(reloadStorage, openwechat.NewRetryLoginOption())
    if err != nil {
        fmt.Println(err)
        return
    }

    // 获取登陆的用户
    self, err := bot.GetCurrentUser()
    if err != nil {
        fmt.Println(err)
        return
    }
    myUID = self.ID()
    myNicname = self.NickName
    log.Printf("当前登录用户:%s,uid:%s \n", myNicname, myUID)
    // 获取所有的好友
    //friends, err := self.Friends()
    //fmt.Println(friends, err)
    // 创建 Gin 引擎
    router := gin.Default()
    //启用跨域中间件
    router.Use(func(c *gin.Context) {
        c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
        c.Writer.Header().Set("Access-Control-Allow-Methods", "GET,POST,OPTIONS,DELETE,PUT")
        c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization, Origin")
        if c.Request.Method == "OPTIONS" {
            c.AbortWithStatus(204)
            return
        }
        c.Next()
    })
    router.LoadHTMLGlob("templates/*")
    router.GET("/main", func(c *gin.Context) {
        c.HTML(http.StatusOK, "main.html", gin.H{})
    })
    //配置信息
    router.GET("/configs", func(c *gin.Context) {
        c.JSON(200, gin.H{
            "code": 200,
            "result": gin.H{
                "api_base":      api,
                "api_kefu_name": kefuName,
                "api_ent_id":    entId,
                "reply_type":    replyType,
                "reply_on":      replyOn,
            },
        })
    })
    //修改配置
    router.POST("/saveConfigs", func(c *gin.Context) {
        api = c.PostForm("api_base")
        kefuName = c.PostForm("api_kefu_name")
        entId = c.PostForm("api_ent_id")
        replyType = c.PostForm("reply_type")
        replyOn = c.PostForm("reply_on")
        data := map[string]string{
            "API_BASE":      api,
            "API_KEFU_NAME": kefuName,
            "API_ENT_ID":    entId,
            "REPLY_TYPE":    replyType,
            "REPLY_ON":      replyOn,
        }
        err := WriteToEnvFile(data, ".env")
        if err != nil {
            log.Println(err)
        }
        c.JSON(200, gin.H{
            "code": 200,
        })
    })
    router.GET("/firends", func(c *gin.Context) {
        friends, _ := self.Friends()
        c.JSON(200, gin.H{
            "code":   200,
            "result": friends,
        })
    })
    router.POST("/sendMsg", func(c *gin.Context) {
        username := c.PostForm("username")
        content := c.PostForm("content")
        friends, _ := self.Friends()
        for _, f := range friends {
            if f.UserName == username {
                f.SendText(content)
                break
            }
        }
        c.JSON(200, gin.H{
            "code": 200,
        })
    })
    // 启动服务器
    go router.Run(":8084")
    // 获取所有的群组
    //groups, err := self.Groups()
    //fmt.Println(groups, err)
    Open("http://127.0.0.1:8084/main")
    // 阻塞主goroutine, 直到发生异常或者用户主动退出
    bot.Block()
}

利用一个第三方库实现模拟桌面版微信登录,并监听微信消息

读取了本地的.env配置文件,该配置文件里面是

API_BASE=https://gofly.v1kf.com/2/wechatRobotMessage
API_KEFU_NAME=taoshihan
API_ENT_ID=5
REPLY_TYPE=GROUP
REPLY_ON=on

该配置的详细解释可以查看运行后的配置页面

消息会回调给我自己的机器人接口,这个接口可以换成你们自己开发的,消息格式可以参考代码里回调接口部分