Skip to content

Commit

Permalink
工程化项目
Browse files Browse the repository at this point in the history
  • Loading branch information
869413421 committed Dec 6, 2022
1 parent 2439a75 commit 2fbf264
Show file tree
Hide file tree
Showing 6 changed files with 237 additions and 144 deletions.
48 changes: 48 additions & 0 deletions bootstrap/bootstrap.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package bootstrap

import (
"fmt"
"github.com/869413421/wechatbot/handlers"
"github.com/eatmoreapple/openwechat"
)

func Run() {
//bot := openwechat.DefaultBot()
bot := openwechat.DefaultBot(openwechat.Desktop) // 桌面模式,上面登录不上的可以尝试切换这种模式

// 注册消息处理函数
bot.MessageHandler = handlers.Handler
// 注册登陆二维码回调
bot.UUIDCallback = openwechat.PrintlnQrcodeUrl

// 登陆
// 创建热存储容器对象
reloadStorage := openwechat.NewJsonFileHotReloadStorage("storage.json")
// 执行热登录
err := bot.HotLogin(reloadStorage)
if err != nil {
if err = bot.Login(); err != nil {
fmt.Println(err)
return
}
}


// 获取登陆的用户
self, err := bot.GetCurrentUser()
if err != nil {
fmt.Println(err)
return
}

// 获取所有的好友
friends, err := self.Friends()
fmt.Println(friends, err)

// 获取所有的群组
groups, err := self.Groups()
fmt.Println(groups, err)

// 阻塞主goroutine, 直到发生异常或者用户主动退出
bot.Block()
}
90 changes: 90 additions & 0 deletions gtp/gtp.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package gtp

import (
"bytes"
"encoding/json"
"io/ioutil"
"log"
"net/http"
)

// ChatGPTResponseBody 请求体
type ChatGPTResponseBody struct {
ID string `json:"id"`
Object string `json:"object"`
Created int `json:"created"`
Model string `json:"model"`
Choices []map[string]interface{} `json:"choices"`
Usage map[string]interface{} `json:"usage"`
}

// ChatGPTRequestBody 响应体
type ChatGPTRequestBody struct {
Model string `json:"model"`
Prompt string `json:"prompt"`
MaxTokens int `json:"max_tokens"`
Temperature float32 `json:"temperature"`
TopP int `json:"top_p"`
FrequencyPenalty int `json:"frequency_penalty"`
PresencePenalty int `json:"presence_penalty"`
}

//curl https://api.openai.com/v1/completions
//-H "Content-Type: application/json"
//-H "Authorization: Bearer your chatGPT key"
//-d '{"model": "text-davinci-003", "prompt": "give me good song", "temperature": 0, "max_tokens": 7}'
// Completions gtp文本模型回复
func Completions(msg string) (string, error) {
requestBody := ChatGPTRequestBody{
Model: "text-davinci-003",
Prompt: msg,
MaxTokens: 2048,
Temperature: 0.7,
TopP: 1,
FrequencyPenalty: 0,
PresencePenalty: 0,
}
requestData, err := json.Marshal(requestBody)

if err != nil {
log.Println(err)
return "", err
}
log.Printf("request gtp json string : %v", string(requestData))
req, err := http.NewRequest("POST", "https://api.openai.com/v1/completions", bytes.NewBuffer(requestData))
if err != nil {
log.Println(err)
return "", err
}

req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer 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")
client := &http.Client{}
response, err := client.Do(req)
if err != nil {
return "", err
}
defer response.Body.Close()

body, err := ioutil.ReadAll(response.Body)
if err != nil {
return "", err
}

gptResponseBody := &ChatGPTResponseBody{}
log.Println(string(body))
err = json.Unmarshal(body, gptResponseBody)
if err != nil {
log.Println(err)
return "", err
}
var reply string
if len(gptResponseBody.Choices) > 0 {
for _, v := range gptResponseBody.Choices {
reply = v["text"].(string)
break
}
}
log.Printf("gpt response text: %s \n", reply)
return reply, nil
}
56 changes: 56 additions & 0 deletions handlers/group_msg_handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package handlers

import (
"github.com/869413421/wechatbot/gtp"
"github.com/eatmoreapple/openwechat"
"log"
"strings"
)

var _ MessageHandlerInterface = (*GroupMessageHandler)(nil)

// GroupMessageHandler 群消息处理
type GroupMessageHandler struct {
}

// handle 处理消息
func (g *GroupMessageHandler) handle(msg *openwechat.Message) error {
if msg.IsText() {
return g.ReplyText(msg)
}
return nil
}

// NewGroupMessageHandler 创建群消息处理器
func NewGroupMessageHandler() MessageHandlerInterface {
return &GroupMessageHandler{}
}

// ReplyText 发送文本消息到群
func (g *GroupMessageHandler) ReplyText(msg *openwechat.Message) error {
// 接收群消息
sender, err := msg.Sender()
group := openwechat.Group{sender}
log.Printf("Received Group %v Text Msg : %v", group.NickName, msg.Content)

if !strings.Contains(msg.Content, "向大兄弟提问") {
return nil
}
splitItems := strings.Split(msg.Content, "向大兄弟提问")
if len(splitItems) < 2 {
return nil
}
requestText := strings.TrimSpace(splitItems[1])
reply, err := gtp.Completions(requestText)
if err != nil {
log.Println(err)
msg.ReplyText("机器人神了,我一会发现了就去修。")
return err
}

_, err = msg.ReplyText(strings.TrimSpace(reply))
if err != nil{
log.Println(err)
}
return err
}
40 changes: 40 additions & 0 deletions handlers/handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package handlers

import (
"github.com/eatmoreapple/openwechat"
)

// MessageHandlerInterface 消息处理接口
type MessageHandlerInterface interface {
handle(*openwechat.Message) error
ReplyText(*openwechat.Message) error
}

type HandlerType string

const (
GroupHandler = "group"
)

var handlers map[HandlerType]MessageHandlerInterface

func init() {
handlers = make(map[HandlerType]MessageHandlerInterface)
handlers[GroupHandler] = NewGroupMessageHandler()
}

// Handler 全局处理入口
func Handler(msg *openwechat.Message) {
//if msg.IsSendBySelf() {
// return
//}
//sender, err := msg.Sender()
//if err != nil {
// log.Println(err)
// return
//}
if msg.IsSendByGroup() {
handlers[GroupHandler].handle(msg)
return
}
}
146 changes: 2 additions & 144 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,149 +1,7 @@
package main

import (
"bytes"
"encoding/json"
"fmt"
"github.com/eatmoreapple/openwechat"
"io/ioutil"
"log"
"net/http"
)

type ChatGPTResponseBody struct {
ID string `json:"id"`
Object string `json:"object"`
Created int `json:"created"`
Model string `json:"model"`
Choices []map[string]interface{} `json:"choices"`
Usage map[string]interface{} `json:"usage"`
}

type ChatGPTRequestBody struct {
Model string `json:"model"`
Prompt string `json:"prompt"`
MaxTokens int `json:"max_tokens"`
Temperature float32 `json:"temperature"`
TopP int `json:"top_p"`
FrequencyPenalty int `json:"frequency_penalty"`
PresencePenalty int `json:"presence_penalty"`
}

//curl https://api.openai.com/v1/completions
//-H "Content-Type: application/json"
//-H "Authorization: Bearer your chatGPT key"
//-d '{"model": "text-davinci-003", "prompt": "give me good song", "temperature": 0, "max_tokens": 7}'
func replyByGPT(msg string) (string, error) {
requestBody := ChatGPTRequestBody{
Model: "text-davinci-003",
Prompt: msg,
MaxTokens: 256,
Temperature: 0.7,
TopP: 1,
FrequencyPenalty: 0,
PresencePenalty: 0,
}
log.Println(requestBody)
requestData, err := json.Marshal(requestBody)
fmt.Println(string(requestData))
if err != nil {
return "", err
}

req, err := http.NewRequest("POST", "https://api.openai.com/v1/completions", bytes.NewBuffer(requestData))
if err != nil {
log.Println(err)
return "", err
}

req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer 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")
client := &http.Client{}
response, err := client.Do(req)
if err != nil {
return "", err
}
defer response.Body.Close()

body, err := ioutil.ReadAll(response.Body)
if err != nil {
return "", err
}

gptResponseBody := &ChatGPTResponseBody{}
log.Println(string(body))
err = json.Unmarshal(body, gptResponseBody)
if err != nil {
log.Println(err)
return "", err
}
var reply string
if len(gptResponseBody.Choices) > 0 {
for _, v := range gptResponseBody.Choices {
reply = v["text"].(string)
break
}
}
log.Printf("gpt response text: %s \n", reply)
return reply, nil
}
import "github.com/869413421/wechatbot/bootstrap"

func main() {

//bot := openwechat.DefaultBot()
bot := openwechat.DefaultBot(openwechat.Desktop) // 桌面模式,上面登录不上的可以尝试切换这种模式

// 注册消息处理函数
bot.MessageHandler = func(msg *openwechat.Message) {
if msg.IsSendBySelf() {
return
}
sender, err := msg.Sender()
if err != nil {
log.Println(err)
return
}
if msg.IsSendByGroup() {
group := openwechat.Group{sender}
fmt.Println(group.NickName)
if group.NickName != "学习嗦粉交流群" {
return
}
}
if msg.IsText() {
log.Printf("Received Msg : %v", msg.Content)
reply, err := replyByGPT(msg.Content)
if err != nil {
msg.ReplyText("机器人神了,我一会发现了就去修。")
return
}
msg.ReplyText(reply)
}
}
// 注册登陆二维码回调
bot.UUIDCallback = openwechat.PrintlnQrcodeUrl

// 登陆
if err := bot.Login(); err != nil {
fmt.Println(err)
return
}

// 获取登陆的用户
self, err := bot.GetCurrentUser()
if err != nil {
fmt.Println(err)
return
}

// 获取所有的好友
friends, err := self.Friends()
fmt.Println(friends, err)

// 获取所有的群组
groups, err := self.Groups()
fmt.Println(groups, err)

// 阻塞主goroutine, 直到发生异常或者用户主动退出
bot.Block()
bootstrap.Run()
}
1 change: 1 addition & 0 deletions storage.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"Cookies":{"https://login.wx.qq.com/cgi-bin/mmwebwx-bin/login":[],"https://login.wx.qq.com/jslogin":[],"https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage":[{"Name":"wxuin","Value":"78739441","Path":"/","Domain":"wx.qq.com","Expires":"2022-12-07T02:35:51Z","RawExpires":"Wed, 07-Dec-2022 02:35:51 GMT","MaxAge":0,"Secure":true,"HttpOnly":false,"SameSite":0,"Raw":"wxuin=78739441; Domain=wx.qq.com; Path=/; Expires=Wed, 07-Dec-2022 02:35:51 GMT; Secure","Unparsed":null},{"Name":"wxsid","Value":"+uEUvqfUGBQm7G9W","Path":"/","Domain":"wx.qq.com","Expires":"2022-12-07T02:35:51Z","RawExpires":"Wed, 07-Dec-2022 02:35:51 GMT","MaxAge":0,"Secure":true,"HttpOnly":false,"SameSite":0,"Raw":"wxsid=+uEUvqfUGBQm7G9W; Domain=wx.qq.com; Path=/; Expires=Wed, 07-Dec-2022 02:35:51 GMT; Secure","Unparsed":null},{"Name":"wxloadtime","Value":"1670337351","Path":"/","Domain":"wx.qq.com","Expires":"2022-12-07T02:35:51Z","RawExpires":"Wed, 07-Dec-2022 02:35:51 GMT","MaxAge":0,"Secure":true,"HttpOnly":false,"SameSite":0,"Raw":"wxloadtime=1670337351; Domain=wx.qq.com; Path=/; Expires=Wed, 07-Dec-2022 02:35:51 GMT; Secure","Unparsed":null},{"Name":"mm_lang","Value":"zh_CN","Path":"/","Domain":"wx.qq.com","Expires":"2022-12-07T02:35:51Z","RawExpires":"Wed, 07-Dec-2022 02:35:51 GMT","MaxAge":0,"Secure":true,"HttpOnly":false,"SameSite":0,"Raw":"mm_lang=zh_CN; Domain=wx.qq.com; Path=/; Expires=Wed, 07-Dec-2022 02:35:51 GMT; Secure","Unparsed":null},{"Name":"wxuin","Value":"78739441","Path":"/","Domain":".qq.com","Expires":"2022-12-07T02:35:51Z","RawExpires":"Wed, 07-Dec-2022 02:35:51 GMT","MaxAge":0,"Secure":true,"HttpOnly":false,"SameSite":0,"Raw":"wxuin=78739441; Domain=.qq.com; Path=/; Expires=Wed, 07-Dec-2022 02:35:51 GMT; Secure","Unparsed":null},{"Name":"webwx_data_ticket","Value":"gSdopa1ZyjNBRz1Tea2WaI0Q","Path":"/","Domain":".qq.com","Expires":"2022-12-07T02:35:51Z","RawExpires":"Wed, 07-Dec-2022 02:35:51 GMT","MaxAge":0,"Secure":true,"HttpOnly":false,"SameSite":0,"Raw":"webwx_data_ticket=gSdopa1ZyjNBRz1Tea2WaI0Q; Domain=.qq.com; Path=/; Expires=Wed, 07-Dec-2022 02:35:51 GMT; Secure","Unparsed":null},{"Name":"webwxuvid","Value":"4773b12d5299369a0b7ec45bafb2b9e4de4e23850e5f3d955e3cd954dfe4cf601bfabff9ae2857999bc35f611482d3b6","Path":"/","Domain":"wx.qq.com","Expires":"2032-12-03T14:35:51Z","RawExpires":"Fri, 03-Dec-2032 14:35:51 GMT","MaxAge":0,"Secure":true,"HttpOnly":false,"SameSite":0,"Raw":"webwxuvid=4773b12d5299369a0b7ec45bafb2b9e4de4e23850e5f3d955e3cd954dfe4cf601bfabff9ae2857999bc35f611482d3b6; Domain=wx.qq.com; Path=/; Expires=Fri, 03-Dec-2032 14:35:51 GMT; Secure","Unparsed":null},{"Name":"webwx_auth_ticket","Value":"CIsBEPHp9uQPGoABTvhTG8nSFhiYmUKdUNNZDw2CHdNIePsS+O/h0S197n0fbxNQJdIcAWKUpSvnvb4Ef+Ntw4Nhh2hFVXZz6sxLeyKF+3gbLjZVCjaNCV/EG0lZBqrEQczq4gMhYflYIJ8C+rM895nkXGS5dWe/bDKbI45eh7BDRuUGjvjo/5vxPTc=","Path":"/","Domain":"wx.qq.com","Expires":"2032-12-03T14:35:51Z","RawExpires":"Fri, 03-Dec-2032 14:35:51 GMT","MaxAge":0,"Secure":true,"HttpOnly":false,"SameSite":0,"Raw":"webwx_auth_ticket=CIsBEPHp9uQPGoABTvhTG8nSFhiYmUKdUNNZDw2CHdNIePsS+O/h0S197n0fbxNQJdIcAWKUpSvnvb4Ef+Ntw4Nhh2hFVXZz6sxLeyKF+3gbLjZVCjaNCV/EG0lZBqrEQczq4gMhYflYIJ8C+rM895nkXGS5dWe/bDKbI45eh7BDRuUGjvjo/5vxPTc=; Domain=wx.qq.com; Path=/; Expires=Fri, 03-Dec-2032 14:35:51 GMT; Secure","Unparsed":null}]},"BaseRequest":{"Uin":78739441,"Sid":"+uEUvqfUGBQm7G9W","Skey":"@crypt_caed92d1_0130adcb8c3a63d50fda82bb9e2b8d35","DeviceID":"e826250712034751"},"LoginInfo":{"Ret":0,"WxUin":78739441,"IsGrayScale":1,"Message":"","SKey":"@crypt_caed92d1_0130adcb8c3a63d50fda82bb9e2b8d35","WxSid":"+uEUvqfUGBQm7G9W","PassTicket":"Jc2ThSk1Aa5IyPqR12wfALzpAlO8y5hGto0dqZzvhfU1ROanKf8kEU6YmxPlaqgf"},"WechatDomain":"wx.qq.com","UUID":"4Z_a0X0c5g=="}

0 comments on commit 2fbf264

Please sign in to comment.