v2.1 添加docker部署
This commit is contained in:
parent
225af04ed8
commit
fba9d342a1
14
Dockerfile
14
Dockerfile
@ -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
|
59
README.md
59
README.md
@ -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`删掉重新建一个。
|
||||||

|

|
||||||
|
|
||||||
### 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)
|
@ -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)
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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()))
|
||||||
|
3
main.go
3
main.go
@ -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()
|
||||||
|
@ -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 {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user