v2.1 添加docker部署

This commit is contained in:
Evan 2022-12-14 13:38:10 +09:00
parent 225af04ed8
commit fba9d342a1
7 changed files with 105 additions and 41 deletions

View File

@ -0,0 +1,14 @@
FROM golang:1.19-alpine
ENV apiKey=""
ENV telegram=""
RUN export GOPRIVATE=github.com/houko/wechatgpt
WORKDIR /app
COPY . /app
RUN go mod download && go build -o server main.go
CMD ./server

View File

@ -1,5 +1,6 @@
## 欢迎使用`wechatgpt`智能机器人Let's Chat with ChatGPT ## 欢迎使用`wechatgpt`智能机器人Let's Chat with ChatGPT
如果觉得不错,请麻烦点个`Star`,非常感谢。
如果觉得不错,请麻烦点个`Star`非常感谢。最新己经添加了docker部署的方式
<p> <p>
<img alt="Version" src="https://img.shields.io/badge/version-2.0.0-blue.svg?cacheSeconds=86400" /> <img alt="Version" src="https://img.shields.io/badge/version-2.0.0-blue.svg?cacheSeconds=86400" />
@ -12,16 +13,20 @@
</p> </p>
## 仓库地址 ## 仓库地址
https://github.com/houko/wechatgpt https://github.com/houko/wechatgpt
## 准备运行环境 ## 准备运行环境
``` ```
go mod tidy go mod tidy
cp config/config.yaml.example local/config.yaml cp config/config.yaml.example local/config.yaml
``` ```
## 修改你的token ## 修改你的token
打开 [openai](https://beta.openai.com/account/api-keys) 并注册一个账号, 生成一个apiKey并把apiKey放到`local/config.yaml`的token下请看如下示例
打开 [openai](https://beta.openai.com/account/api-keys) 并注册一个账号, 生成一个apiKey并把apiKey放到`local/config.yaml`
的token下请看如下示例
大陆用户注册`openai`请参考 [注册ChatGPT详细指南](https://sms-activate.org/cn/info/ChatGPT) 大陆用户注册`openai`请参考 [注册ChatGPT详细指南](https://sms-activate.org/cn/info/ChatGPT)
@ -32,13 +37,28 @@ chatgpt:
``` ```
## 运行App ## 运行App
``` ```
go run main.go go run main.go
``` ```
## `Docker` 方式运行`wechatgpt`
同时启动微信和telegram
```
docker run -d --name="wechatgpt" -e apiKey="你的chatgpt apiKey" telegram="你的telegram token" wechatgpt:latest
```
如果只想运行微信智能机器人的话运行下面这段代码
```
docker run --name wechatgpt -e apiKey="你的chatgpt apiKey" wechatgpt:latest
```
### 微信 ### 微信
``` ```
ain.go #gosetup ain.go #gosetup
go: downloading github.com/eatmoreapple/openwechat v1.2.1 go: downloading github.com/eatmoreapple/openwechat v1.2.1
@ -62,44 +82,47 @@ INFO[0099] 1 <Friend:刘葵>
INFO[0099] 2 <Friend:吕> INFO[0099] 2 <Friend:吕>
INFO[0099] 3 <Friend:wloscar> INFO[0099] 3 <Friend:wloscar>
``` ```
登陆成功后会拉取微信的好友和群组 登陆成功后会拉取微信的好友和群组
### 如何使用 ### 如何使用
默认为`chatgpt`,如果想设置其他的触发方式可以修改`local/config.yaml`的keyword。此时如果别人给你发消息带有关键字`chatgpt`,你的微信就会调用`chatGPT`AI自动回复你的好友。
默认为`chatgpt`,如果想设置其他的触发方式可以修改`local/config.yaml`的keyword。此时如果别人给你发消息带有关键字`chatgpt`
,你的微信就会调用`chatGPT`AI自动回复你的好友。
当然,在群里也是可以的。 当然,在群里也是可以的。
### 使用场景1 ### 使用场景1
别人给你发消息时如果消息中带有关键字系统就会调用AI自动帮你回复此问题。 别人给你发消息时如果消息中带有关键字系统就会调用AI自动帮你回复此问题。
<img src="screenshots/IMG_3837.png" alt="drawing" style="width:250px;"/><img src="screenshots/IMG_3840.png" alt="drawing" style="width:250px;"/><img src="screenshots/IMG_3850.png" alt="drawing" style="width:250px;"/> <img src="screenshots/IMG_3837.png" alt="drawing" style="width:250px;"/><img src="screenshots/IMG_3840.png" alt="drawing" style="width:250px;"/><img src="screenshots/IMG_3850.png" alt="drawing" style="width:250px;"/>
### 使用场景2 ### 使用场景2
别人在群里发消息时如果消息中带有关键字系统就会调用AI自动帮你回复此问题。 别人在群里发消息时如果消息中带有关键字系统就会调用AI自动帮你回复此问题。
<img src="screenshots/IMG_3845.png" alt="drawing" style="width:250px;"/><img src="screenshots/IMG_3847.png" alt="drawing" style="width:250px;"/> <img src="screenshots/IMG_3845.png" alt="drawing" style="width:250px;"/><img src="screenshots/IMG_3847.png" alt="drawing" style="width:250px;"/>
### 使用场景3 ### 使用场景3
自己给自己发消息时如果消息中带有关键字系统会也调用AI自动帮你回复此问题。 自己给自己发消息时如果消息中带有关键字系统会也调用AI自动帮你回复此问题。
<img src="screenshots/IMG_3844.png" alt="drawing" style="width:250px;"/> <img src="screenshots/IMG_3844.png" alt="drawing" style="width:250px;"/>
### 意外之喜 ### 意外之喜
<img src="screenshots/IMG_3843.png" alt="drawing" style="width:250px;"/> <img src="screenshots/IMG_3843.png" alt="drawing" style="width:250px;"/>
这不比对象来的贴心? 这不比对象来的贴心?
### telegram机器人使用方式 ### telegram机器人使用方式
- 方式1: 直接添加小莫的bot进行使用 - 方式1: 直接添加小莫的bot进行使用
<img src="screenshots/telegram.png" alt="drawing" style="width:250px;"/> <img src="screenshots/telegram.png" alt="drawing" style="width:250px;"/>
- 方式2自己部署 - 方式2自己部署
修改 config下的 `chatgpt.telegram`的token后运行`go run main.go`进行启动,参考如下: 修改 config下的 `chatgpt.telegram`的token后运行`go run main.go`进行启动,参考如下:
``` ```
chatgpt: chatgpt:
@ -112,41 +135,51 @@ chatgpt:
<img src="screenshots/IMG_3991.png" alt="drawing" style="width:250px;"/> <img src="screenshots/IMG_3991.png" alt="drawing" style="width:250px;"/>
## 总结 ## 总结
- 你可以把它当作你的智能助理,帮助你快速回复消息。 - 你可以把它当作你的智能助理,帮助你快速回复消息。
- 你可以把它当作一个智能机器人,邀请在群里之后通过关键字帮助大家解答问题。 - 你可以把它当作一个智能机器人,邀请在群里之后通过关键字帮助大家解答问题。
- 你可以把它当作你的智多星,有什么问题不懂的时候随时问它。 - 你可以把它当作你的智多星,有什么问题不懂的时候随时问它。
## 变爸爸事件 ## 变爸爸事件
放在B站 放在B站
[用chatgpt写了个微信机器人结果变爸爸了](https://www.bilibili.com/video/BV1B24y1Q7us/) [用chatgpt写了个微信机器人结果变爸爸了](https://www.bilibili.com/video/BV1B24y1Q7us/)
## 贡献本仓库 ## 贡献本仓库
如果大家有玩的时候有遇到一些奇怪的对话可以截图发PR分享给大家。另外对本项目有什么想法或者贡献的话欢迎提[issue](https://github.com/houko/wechatgpt/issues)或[pr](https://github.com/houko/wechatgpt/pulls)
如果大家有玩的时候有遇到一些奇怪的对话可以截图发PR分享给大家。另外对本项目有什么想法或者贡献的话欢迎提[issue](https://github.com/houko/wechatgpt/issues)
或[pr](https://github.com/houko/wechatgpt/pulls)
## Q&A ## Q&A
### 1. 返回错误`invalid_api_key` ### 1. 返回错误`invalid_api_key`
这是因为`openai``API`需要付费,价格非常便宜具体可以官网查看。按照如下参考绑定一下信息卡就可以正常使用了,如果还是有错就把`API Key`删掉重新建一个。
这是因为`openai``API`
需要付费,价格非常便宜具体可以官网查看。按照如下参考绑定一下信息卡就可以正常使用了,如果还是有错就把`API Key`删掉重新建一个。
![img.png](screenshots/billing.png) ![img.png](screenshots/billing.png)
### 2. Cannot load io/fs: malformed module path "io/fs": missing dot in first path element ### 2. Cannot load io/fs: malformed module path "io/fs": missing dot in first path element
golang版本太低需要`1.16`以上,查看方式为`go version` golang版本太低需要`1.16`以上,查看方式为`go version`
``` ```
$ go version $ go version
go version go1.17.3 linux/amd64 go version go1.17.3 linux/amd64
``` ```
### 3. 扫码登陆时出现错误 FATA【0023】write token.json: bad file descriptor ### 3. 扫码登陆时出现错误 FATA【0023】write token.json: bad file descriptor
删除项目根目录下的`token.json`后重新扫码登陆即可 删除项目根目录下的`token.json`后重新扫码登陆即可
### 4. go mod tidy时connect: connection refused ### 4. go mod tidy时connect: connection refused
``` ```
go: github.com/eatmoreapple/openwechat@v1.2.1: Get https://proxy.golang.org/github.com/eatmoreapple/openwechat/@v/v1.2.1.mod: dial tcp 142.251.43.17:443: go: github.com/eatmoreapple/openwechat@v1.2.1: Get https://proxy.golang.org/github.com/eatmoreapple/openwechat/@v/v1.2.1.mod: dial tcp 142.251.43.17:443:
``` ```
自身网络环境问题,请排查网络设置 自身网络环境问题,请排查网络设置
## 协议 ## 协议
[MIT LICENSE](LICENSE) [MIT LICENSE](LICENSE)

View File

@ -6,23 +6,30 @@ import (
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"github.com/wechatgpt/wechatbot/config" "github.com/wechatgpt/wechatbot/config"
"github.com/wechatgpt/wechatbot/handler/telegram" "github.com/wechatgpt/wechatbot/handler/telegram"
"os"
"time" "time"
) )
func StartTelegramBot() { func StartTelegramBot() {
telegramKey := os.Getenv("telegram")
if len(telegramKey) == 0 {
getConfig := config.GetConfig() getConfig := config.GetConfig()
if getConfig == nil { if getConfig == nil {
return return
} }
botConfig := getConfig.ChatGpt botConfig := getConfig.ChatGpt
bot, err := tgbotapi.NewBotAPI(botConfig.Telegram) telegramKey = botConfig.Telegram
log.Info("读取本地本置文件中的telegram token:", telegramKey)
} else {
log.Info("找到环境变量: telegram token:", telegramKey)
}
bot, err := tgbotapi.NewBotAPI(telegramKey)
if err != nil { if err != nil {
return return
} }
bot.Debug = false bot.Debug = false
log.Info("Authorized on account: ", bot.Self.UserName)
log.Printf("Authorized on account %s", bot.Self.UserName)
u := tgbotapi.NewUpdate(0) u := tgbotapi.NewUpdate(0)
updates := bot.GetUpdatesChan(u) updates := bot.GetUpdatesChan(u)

View File

@ -2,18 +2,13 @@ package telegram
import ( import (
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"github.com/wechatgpt/wechatbot/config"
"github.com/wechatgpt/wechatbot/openai" "github.com/wechatgpt/wechatbot/openai"
"strings" "strings"
) )
func Handle(msg string) *string { func Handle(msg string) *string {
appConfig := config.GetConfig()
if appConfig == nil {
return nil
}
requestText := strings.TrimSpace(msg) requestText := strings.TrimSpace(msg)
reply, err := openai.Completions(requestText, appConfig.ChatGpt.Token) reply, err := openai.Completions(requestText)
if err != nil { if err != nil {
log.Println(err) log.Println(err)
} }

View File

@ -1,7 +1,6 @@
package wechat package wechat
import ( import (
"errors"
"fmt" "fmt"
"github.com/eatmoreapple/openwechat" "github.com/eatmoreapple/openwechat"
"github.com/wechatgpt/wechatbot/config" "github.com/wechatgpt/wechatbot/config"
@ -32,12 +31,12 @@ func (gmh *GroupMessageHandler) ReplyText(msg *openwechat.Message) error {
group := openwechat.Group{User: sender} group := openwechat.Group{User: sender}
log.Printf("Received Group %v Text Msg : %v", group.NickName, msg.Content) log.Printf("Received Group %v Text Msg : %v", group.NickName, msg.Content)
keyword := "chatgpt"
appConfig := config.GetConfig() appConfig := config.GetConfig()
if appConfig == nil { if appConfig != nil {
return errors.New("can not get appConfig file,please check") keyword = appConfig.ChatGpt.Keyword
} }
keyword := appConfig.ChatGpt.Keyword
if !strings.Contains(msg.Content, keyword) { if !strings.Contains(msg.Content, keyword) {
return nil return nil
} }
@ -46,7 +45,7 @@ func (gmh *GroupMessageHandler) ReplyText(msg *openwechat.Message) error {
return nil return nil
} }
requestText := strings.TrimSpace(splitItems[1]) requestText := strings.TrimSpace(splitItems[1])
reply, err := openai.Completions(requestText, appConfig.ChatGpt.Token) reply, err := openai.Completions(requestText)
if err != nil { if err != nil {
log.Println(err) log.Println(err)
text, err := msg.ReplyText(fmt.Sprintf("bot error: %s", err.Error())) text, err := msg.ReplyText(fmt.Sprintf("bot error: %s", err.Error()))

View File

@ -1,6 +1,7 @@
package main package main
import ( import (
log "github.com/sirupsen/logrus"
"github.com/wechatgpt/wechatbot/bootstrap" "github.com/wechatgpt/wechatbot/bootstrap"
"github.com/wechatgpt/wechatbot/config" "github.com/wechatgpt/wechatbot/config"
) )
@ -8,7 +9,7 @@ import (
func main() { func main() {
err := config.LoadConfig() err := config.LoadConfig()
if err != nil { if err != nil {
panic(err) log.Warn("没有找到配置文件,尝试读取环境变量")
} }
go bootstrap.StartTelegramBot() go bootstrap.StartTelegramBot()
bootstrap.StartWebChat() bootstrap.StartWebChat()

View File

@ -3,11 +3,14 @@ package openai
import ( import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"errors"
"fmt" "fmt"
log "github.com/sirupsen/logrus"
"github.com/wechatgpt/wechatbot/config"
"io" "io"
"io/ioutil" "io/ioutil"
"log"
"net/http" "net/http"
"os"
"strings" "strings"
) )
@ -53,7 +56,19 @@ type ChatGPTRequestBody struct {
// }); // });
// //
// Completions sendMsg // Completions sendMsg
func Completions(msg string, token string) (*string, error) { func Completions(msg string) (*string, error) {
apiKey := os.Getenv("apiKey")
if len(apiKey) == 0 {
appConfig := config.GetConfig()
if appConfig == nil {
return nil, errors.New("config not found")
}
apiKey = appConfig.ChatGpt.Token
log.Info("找到本地配置文件中的chatgpt apiKey:", apiKey)
} else {
log.Info("找到环境变量中的chatgpt apiKey:", apiKey)
}
requestBody := ChatGPTRequestBody{ requestBody := ChatGPTRequestBody{
Model: "text-davinci-003", Model: "text-davinci-003",
Prompt: msg, Prompt: msg,
@ -77,7 +92,7 @@ func Completions(msg string, token string) (*string, error) {
} }
req.Header.Set("Content-Type", "application/json") req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token)) req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", apiKey))
client := &http.Client{} client := &http.Client{}
response, err := client.Do(req) response, err := client.Do(req)
if err != nil { if err != nil {