Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

login error: wechat network error #3

Open
wants to merge 40 commits into
base: main
Choose a base branch
from
Open
Changes from 1 commit
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
22b8cf4
优化gtp请求代码,请求失败有固定回复
869413421 Dec 7, 2022
e3a8ac6
修改readme
Dec 8, 2022
9b979d8
增加提问上下问,接近官网效果。
Dec 8, 2022
ba9003e
修改README
Dec 8, 2022
f80a211
1.增加会话时长配置功能
Dec 8, 2022
6cd1ccc
修改README
Dec 8, 2022
ef2fa38
支持linux运行
869413421 Dec 8, 2022
1b22bee
修改README
869413421 Dec 8, 2022
529905d
修改README
869413421 Dec 8, 2022
e8298bb
添加自动构建项目镜像的能力
eryajf Dec 9, 2022
c761ab4
添加readme说明
eryajf Dec 9, 2022
04b51e7
readme添加docker运行受命
eryajf Dec 9, 2022
db61c4d
readme添加docker运行说明
eryajf Dec 9, 2022
aa3f9d5
Merge pull request #20 from eryajf/main
869413421 Dec 9, 2022
e3dba40
Update README.md
adsian Dec 9, 2022
652b7ce
修改配置文件
Dec 9, 2022
9247d4e
Merge pull request #27 from adsian/patch-1
869413421 Dec 9, 2022
cfeded5
Merge branch 'cofing' of https://github.com/869413421/wechatbot into …
869413421 Dec 9, 2022
c5b5304
1.增加GTP参数配置
869413421 Dec 9, 2022
eca0451
1.优化日志代码,GPT请求直接返回给用户
869413421 Dec 10, 2022
8af217f
修复群上下文无法清空bug
869413421 Dec 10, 2022
70d4b20
修改配置默认项
869413421 Dec 10, 2022
5092d2a
修改配置默认值
869413421 Dec 10, 2022
efb539f
配置文件模板少个逗号
lafeier888 Dec 10, 2022
ac478c8
增加热登录重试
869413421 Dec 10, 2022
4039fb4
Merge pull request #40 from lafeier888/main
869413421 Dec 10, 2022
1a0adcf
修复配置文件映射的问题
eryajf Dec 11, 2022
df47621
Merge pull request #45 from eryajf/patch-1
869413421 Dec 11, 2022
afec292
1.重构项目代码,增加阅读性
869413421 Dec 11, 2022
0640a26
Merge branch 'main' of https://github.com/869413421/wechatbot
869413421 Dec 11, 2022
1e1e3ca
feat: add build go binary to release
eryajf Dec 11, 2022
a71895f
feat: add build go binary to release
eryajf Dec 11, 2022
0e36038
feat: 调整说明文档
eryajf Dec 11, 2022
4a32233
Merge pull request #48 from eryajf/main
869413421 Dec 11, 2022
6e6fdb1
修改README和GPT错误命名
Dec 12, 2022
6e56c52
使用openwechat dispatcher优化hanlers
Dec 12, 2022
b908859
1.群聊需要@才能清空上下文
869413421 Dec 12, 2022
70df388
Merge pull request #62 from slzheng2017/main
869413421 Dec 12, 2022
1b94ec0
编写Readme文档:
zhang-cuishan Dec 13, 2022
a24dc53
Merge pull request #72 from zhang-cuishan/main
869413421 Dec 13, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
1.增加GTP参数配置
2.Dockerfile优化,增加supervisord,进程异常自动拉起
3.消息处理器捕获异常,避免程序崩溃
4.优化二位码尺寸,linux上更容易扫码
869413421 committed Dec 9, 2022
commit c5b53041aa84208d7ab3c757847575f3f368666d
67 changes: 58 additions & 9 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,16 +1,65 @@
FROM golang:1.17.10 AS builder
#FROM golang:1.17.10 AS builder
#
## ENV GOPROXY https://goproxy.io
#
#RUN mkdir /app
#ADD . /app/
#WORKDIR /app
#RUN go build -o wechatbot .
#
#FROM centos:centos7
#RUN mkdir /app
#WORKDIR /app
#COPY --from=builder /app/ .
#RUN chmod +x wechatbot && cp config.dev.json config.json && yum -y install vim net-tools telnet wget curl && yum clean all
#
#CMD ./wechatbot

# ENV GOPROXY https://goproxy.io
# wechatbot/Dockerfile

RUN mkdir /app
ADD . /app/
# 使用 golang 官方镜像提供 Go 运行环境,并且命名为 buidler 以便后续引用
FROM golang:1.16-alpine as builder

# 启用 Go Modules 并设置 GOPROXY
ENV GO111MODULE on
ENV GOPROXY https://goproxy.cn

# 更新安装源
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories

# 安装 git
RUN apk --no-cache add git

# 设置工作目录
WORKDIR /app
RUN go build -o wechatbot .

FROM centos:centos7
# 将当前项目所在目录代码拷贝到镜像中
COPY . .

# 下载依赖
RUN go mod download

# 构建二进制文件,添加来一些额外参数以便可以在 Alpine 中运行它
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o wechatbot

# 下面是第二阶段的镜像构建,和之前保持一致
FROM alpine:latest

# 更新安装源
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories

# 安装相关软件
RUN apk update && apk add --no-cache bash supervisor ca-certificates

# 和上个阶段一样设置工作目录
RUN mkdir /app
WORKDIR /app
COPY --from=builder /app/ .
RUN chmod +x wechatbot && cp config.dev.json config.json && yum -y install vim net-tools telnet wget curl && yum clean all

CMD ./wechatbot
# 而是从上一个阶段构建的 builder容器中拉取
COPY --from=builder /app/wechatbot .
ADD supervisord.conf /etc/supervisord.conf
ADD config.dev.json /app/config.dev.json
RUN cp config.dev.json config.json

# 通过 Supervisor 管理服务
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisord.conf"]
7 changes: 7 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.PHONY: build
build:
CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -ldflags '-w' -o wechatbot ./main.go

.PHONY: docker
docker:
docker build . -t wechatbot:latest
23 changes: 16 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@
![Forks](https://img.shields.io/github/forks/869413421/wechatbot.svg?style=flat-square)

### 目前实现了以下功能
* GPT机器人模型热度可配置
* 提问增加上下文,更接近官网效果
* 机器人群聊@回复
* 机器人私聊回复
@@ -28,11 +29,12 @@
`第一种:基于环境变量运行`

```sh
# 运行项目
$ docker run -itd --name wechatbot -e ApiKey=xxxx -e AutoPass=false -e SessionTimeout=60s docker.mirrors.sjtug.sjtu.edu.cn/qingshui869413421/wechatbot:latest
# 运行项目,环境变量参考下方配置说明
$ docker run -itd --name wechatbot --restart=always -e APIKEY=xxxx -e AUTO_PASS=false -e SESSION_TIMEOUT=60s -e MODEL=text-davinci-003 -e MAX_TOKENS=512 -e TEMPREATURE=0.9 docker.mirrors.sjtug.sjtu.edu.cn/qingshui869413421/wechatbot:latest

# 查看二维码
$ docker logs -f wechatbot
$ docker exec -it wechatbot bash
$ tail -f -n 50 /app/run.log
```

运行命令中映射的配置文件参考下边的配置文件说明。
@@ -47,7 +49,8 @@ cp config.dev.json config.json # 其中 config.dev.json 从项目的根目录
docker run -itd --name wechatbot -v ./config.json:/app/config.json docker.mirrors.sjtug.sjtu.edu.cn/qingshui869413421/wechatbot:latest

# 查看二维码
$ docker logs -f wechatbot
$ docker exec -it wechatbot bash
$ tail -f -n 50 /app/run.log
```

其中配置文件参考下边的配置文件说明。
@@ -77,14 +80,20 @@ nohup ./wechatbot > run.log &
# 配置文件说明
````
{
"api_key": "your api key",
"auto_pass": true,
"session_timeout": 60
"api_key": "your api key",
"auto_pass": false,
"session_timeout": 60,
"max_tokens": 512,
"model": "text-davinci-003",
"temperature": 0.9
}

api_key:openai api_key
auto_pass:是否自动通过好友添加
session_timeout:会话超时时间,默认60秒,单位秒,在会话时间内所有发送给机器人的信息会作为上下文。
max_tokens: GPT响应字符数,最大2048,默认值512。max_tokens会影响接口响应速度,字符越大响应越慢。
model: GTP选用模型,默认text-davinci-003,具体选项参考官网训练场
temperature: GTP热度,0到1,默认0.9。数字越大创造力越强,但更偏离训练事实,越低越接近训练事实
````

# 使用示例
7 changes: 5 additions & 2 deletions config.dev.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
{
"api_key": "your api key",
"auto_pass": true,
"session_timeout": 60
"auto_pass": false,
"session_timeout": 60,
"max_tokens": 512,
"model": "text-davinci-003",
"temperature": 0.9
}
78 changes: 58 additions & 20 deletions config/config.go
Original file line number Diff line number Diff line change
@@ -4,6 +4,7 @@ import (
"encoding/json"
"log"
"os"
"strconv"
"sync"
"time"
)
@@ -21,7 +22,7 @@ type Configuration struct {
// GPT模型
Model string `json:"model"`
// 热度
Temperature float32 `json:"temperature"`
Temperature float64 `json:"temperature"`
}

var config *Configuration
@@ -30,28 +31,40 @@ var once sync.Once
// LoadConfig 加载配置
func LoadConfig() *Configuration {
once.Do(func() {
// 从文件中读取
// 给配置赋默认值
config = &Configuration{
AutoPass: false,
SessionTimeout: 60,
}
f, err := os.Open("config.json")
if err != nil {
log.Fatalf("open config err: %v", err)
return
}
defer f.Close()
encoder := json.NewDecoder(f)
err = encoder.Decode(config)
if err != nil {
log.Fatalf("decode config err: %v", err)
return
MaxTokens: 512,
Model: "text-davinci-003",
Temperature: 0.9,
}

// 如果环境变量有配置,读取环境变量
ApiKey := os.Getenv("ApiKey")
AutoPass := os.Getenv("AutoPass")
SessionTimeout := os.Getenv("SessionTimeout")
if ApiKey != "" {
// 判断配置文件是否存在,存在直接JSON读取
_, err := os.Stat("config.json")
if err == nil {
f, err := os.Open("config.json")
if err != nil {
log.Fatalf("open config err: %v", err)
return
}
defer f.Close()
encoder := json.NewDecoder(f)
err = encoder.Decode(config)
if err != nil {
log.Fatalf("decode config err: %v", err)
return
}
}
log.Println(config)
// 有环境变量使用环境变量
ApiKey := os.Getenv("APIKEY")
AutoPass := os.Getenv("AUTO_PASS")
SessionTimeout := os.Getenv("SESSION_TIMEOUT")
Model := os.Getenv("MODEL")
MaxTokens := os.Getenv("MAX_TOKENS")
Temperature := os.Getenv("TEMPREATURE")
if ApiKey != "" {
config.ApiKey = ApiKey
}
if AutoPass == "true" {
@@ -60,11 +73,36 @@ func LoadConfig() *Configuration {
if SessionTimeout != "" {
duration, err := time.ParseDuration(SessionTimeout)
if err != nil {
log.Fatalf("config decode session timeout err: %v ,get is %v", err, SessionTimeout)
log.Fatalf("config session timeout err: %v ,get is %v", err, SessionTimeout)
return
}
config.SessionTimeout = duration
}
if Model != "" {
config.Model = Model
}
if MaxTokens != "" {
max, err := strconv.Atoi(MaxTokens)
if err != nil {
log.Fatalf("config MaxTokens err: %v ,get is %v", err, MaxTokens)
return
}
config.MaxTokens = uint(max)
}
if Temperature != "" {
temp, err := strconv.ParseFloat(Temperature, 64)
if err != nil {
log.Fatalf("config Temperature err: %v ,get is %v", err, Temperature)
return
}
config.Temperature = temp
}
})
log.Println(config)
if config.ApiKey == "" {
log.Fatalf("config err: api key reqired")
}


return config
}
13 changes: 8 additions & 5 deletions gtp/gtp.go
Original file line number Diff line number Diff line change
@@ -34,8 +34,8 @@ type ChoiceItem struct {
type ChatGPTRequestBody struct {
Model string `json:"model"`
Prompt string `json:"prompt"`
MaxTokens int `json:"max_tokens"`
Temperature float32 `json:"temperature"`
MaxTokens uint `json:"max_tokens"`
Temperature float64 `json:"temperature"`
TopP int `json:"top_p"`
FrequencyPenalty int `json:"frequency_penalty"`
PresencePenalty int `json:"presence_penalty"`
@@ -47,11 +47,12 @@ type ChatGPTRequestBody struct {
//-H "Authorization: Bearer your chatGPT key"
//-d '{"model": "text-davinci-003", "prompt": "give me good song", "temperature": 0, "max_tokens": 7}'
func Completions(msg string) (string, error) {
cfg := config.LoadConfig()
requestBody := ChatGPTRequestBody{
Model: "text-davinci-003",
Model: cfg.Model,
Prompt: msg,
MaxTokens: 1024,
Temperature: 0.7,
MaxTokens: cfg.MaxTokens,
Temperature: cfg.Temperature,
TopP: 1,
FrequencyPenalty: 0,
PresencePenalty: 0,
@@ -77,6 +78,8 @@ func Completions(msg string) (string, error) {
}
defer response.Body.Close()
if response.StatusCode != 200 {
body, _ := ioutil.ReadAll(response.Body)
log.Println(string(body))
return "", errors.New(fmt.Sprintf("gtp api status code not equals 200,code is %d", response.StatusCode))
}
body, err := ioutil.ReadAll(response.Body)
12 changes: 10 additions & 2 deletions handlers/handler.go
Original file line number Diff line number Diff line change
@@ -30,8 +30,10 @@ func QrCodeCallBack(uuid string) {
openwechat.PrintlnQrcodeUrl(uuid)
} else {
log.Println("login in linux")
q, _ := qrcode.New("https://login.weixin.qq.com/l/"+uuid, qrcode.Low)
fmt.Println(q.ToString(true))
url := "https://login.weixin.qq.com/l/" + uuid
log.Printf("如果二维码无法扫描,请尝试请复制链接到浏览器:%s", url)
q, _ := qrcode.New(url, qrcode.High)
fmt.Println(q.ToSmallString(true))
}
}

@@ -48,6 +50,12 @@ func init() {

// Handler 全局处理入口
func Handler(msg *openwechat.Message) {
defer func() {
err := recover()
if err != nil {
log.Printf("handler recover error: %v", err)
}
}()
log.Printf("hadler Received msg : %v", msg.Content)
// 处理群消息
if msg.IsSendByGroup() {
13 changes: 13 additions & 0 deletions supervisord.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[supervisord]
nodaemon=true

[program:wechatbot] ; 程序名称,在 supervisorctl 中通过这个值来对程序进行一系列的操作
autorestart=True ; 程序异常退出后自动重启
autostart=True ; 在 supervisord 启动的时候也自动启动
redirect_stderr=True ; 把 stderr 重定向到 stdout,默认 false
command=/app/wechatbot ; 启动命令,与手动在命令行启动的命令是一样的
user=root ; 用哪个用户启动
stdout_logfile_maxbytes = 20MB ; stdout 日志文件大小,默认 50MB
stdout_logfile_backups = 20 ; stdout 日志文件备份数
; stdout 日志文件,需要注意当指定目录不存在时无法正常启动,所以需要手动创建目录(supervisord 会自动创建日志文件)
stdout_logfile = /app/run.log