1
0
mirror of https://github.com/Mrs4s/go-cqhttp.git synced 2025-05-05 11:33:48 +08:00

Merge pull request #526 from wdvxdr1123/patch/forwardmsg

支持复读转发 和 合并转发中套娃[CQ:forward]
This commit is contained in:
Mrs4s 2020-12-31 22:59:48 +08:00 committed by GitHub
commit a6a78dfcac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 126 additions and 20 deletions

View File

@ -781,7 +781,7 @@ func (bot *CQBot) CQGetMessage(messageId int32) MSG {
"nickname": sender.Nickname,
},
"time": msg["time"],
"message_raw": raw,
"raw_message": raw,
"message": ToFormattedMessage(bot.ConvertStringMessage(raw, isGroup), func() int64 {
if isGroup {
return gid.(int64)

View File

@ -402,6 +402,12 @@ func (bot *CQBot) ConvertStringMessage(msg string, group bool) (r []message.IMes
}
}
}
if t == "forward" { // 单独处理转发
if id, ok := params["id"]; ok {
r = []message.IMessageElement{bot.Client.DownloadForwardMessage(id)}
return
}
}
elem, err := bot.ToElement(t, params, group)
if err != nil {
org := "[" + string(cqCode) + "]"
@ -475,6 +481,10 @@ func (bot *CQBot) ConvertObjectMessage(m gjson.Result, group bool) (r []message.
}
}
}
if t == "forward" {
r = []message.IMessageElement{bot.Client.DownloadForwardMessage(e.Get("data.id").String())}
return
}
d := make(map[string]string)
e.Get("data").ForEach(func(key, value gjson.Result) bool {
d[key.Str] = value.String()
@ -491,7 +501,6 @@ func (bot *CQBot) ConvertObjectMessage(m gjson.Result, group bool) (r []message.
case []message.IMessageElement:
r = append(r, i...)
}
}
if m.Type == gjson.String {
return bot.ConvertStringMessage(m.Str, group)

View File

@ -107,6 +107,14 @@ enable ws?(Y/n)
# 进阶指南
## 跳过启动的五秒延时
使用命令行参数 `faststart`即可跳过启动的五秒钟延时,例如
```
.\go-cqhttp.exe faststart
```
## 如何自己构建
1. [下载源码](https://github.com/Mrs4s/go-cqhttp/archive/master.zip)并解压 || 使用`git clone https://github.com/Mrs4s/go-cqhttp.git`来拉取

74
docs/slider.md Normal file
View File

@ -0,0 +1,74 @@
# 滑块验证码
由于TX最新的限制, 所有协议在陌生设备/IP登录时都有可能被要求通过滑块验证码, 否则将会出现 `当前上网环境异常` 的错误. 目前我们准备了两个临时方案应对该验证码.
> 如果您有一台运行Windows的PC/Server 并且不会抓包操作, 我们建议直接使用方案B
## 方案A: 自行抓包
由于滑块验证码和QQ本体的协议独立, 我们无法直接处理并提交. 需要在浏览器通过后抓包并获取 `Ticket` 提交.
该方案为具体的抓包教程, 如果您已经知道如何在浏览器中抓包. 可以略过接下来的文档并直接抓取 `cap_union_new_verify` 的返回值, 提取 `Ticket` 并在命令行提交.
首先获取滑块验证码的地址, 并在浏览器中打开. 这里以 *Microsoft Edge* 浏览器为例, *Chrome* 同理.
![image.png](https://i.loli.net/2020/12/27/yXdomOnQ8tkauMe.png)
首先选择 `1` 并提取链接在浏览器中打开
![image.png](https://i.loli.net/2020/12/27/HYhmZv1wARMV7Uq.png)
![image.png](https://i.loli.net/2020/12/27/otk9Hz7lBCaRFMV.png)
此时不要滑动验证码, 首先按下 `F12` (键盘右上角退格键上方) 打开 *开发者工具*
![image.png](https://i.loli.net/2020/12/27/JDioadLPwcKWpt1.png)
点击 `Network` 选项卡 (在某些浏览器它可能叫做 `网络`)
![image.png](https://i.loli.net/2020/12/27/qEzTB5jrDZUWSwp.png)
点开 `Filter` (箭头) 按钮以确定您能看到下面的工具栏, 勾选 `Preserve log`(红框)
此时可以滑动并通过验证码
![image.png](https://i.loli.net/2020/12/27/Id4hxzyDprQuF2G.png)
回到 *开发者工具*, 我们可以看到已经有了一个请求.
![image.png](https://i.loli.net/2020/12/27/3C6Y2XVKBRv1z9E.png)
此时如果有多个请求, 请不要慌张. 看到上面的 `Filter` 没? 此时在 `Filter` 输入框中输入 `cap_union_new`, 就应该只剩一个请求了.
然后点击该请求. 点开 `Preview` 选项卡 (箭头):
![image.png](https://i.loli.net/2020/12/27/P1VtxRWpjY8524Z.png)
此时就能看到一个标准的 `JSON`, 复制 `ticket` 字段并回到 `go-cqhttp` 粘贴. 即可通过滑块验证.
如果您看到这里还是不会如何操作, 没关系! 我们还准备了方案B.
## 方案B: 使用专用工具
此方案需要您有一台可以操作的 `Windows` 电脑.
首先下载工具: [蓝奏云](https://wws.lanzous.com/i2vn0jrofte) [Google Drive](https://drive.google.com/file/d/1peMDHqgP8AgWBVp5vP-cfhcGrb2ksSrE/view?usp=sharing)
解压并打开工具:
![image.png](https://i.loli.net/2020/12/27/winG4SkxhgLoNDZ.png)
打开 `go-cqhttp` 并选择 `2`:
![image.png](https://i.loli.net/2020/12/27/yXdomOnQ8tkauMe.png)
复制 `ID` 并前往工具粘贴:
![image.png](https://i.loli.net/2020/12/27/fIwXx5nN9r8Zbc7.png)
![image.png](https://i.loli.net/2020/12/27/WZsTCyGwSjc9mb5.png)
点击 `OK` 并处理滑块, 完成即可登录成功. (OK可能反应稍微慢点, 请不要多次点击)
![image.png](https://i.loli.net/2020/12/27/UnvAuxreijYzgLC.png)

View File

@ -64,17 +64,12 @@ func GetBytes(url string) ([]byte, error) {
return body, nil
}
func GetSilderTicket(raw, version string) (string, error) {
u, err := url.Parse(raw)
if err != nil {
return "", err
}
q := u.Query()
func GetSliderTicket(raw, id string) (string, error) {
var rsp string
if err = gout.GET(fmt.Sprintf("https://api.shkong.com/gocqhttpapi/silder/ticket?uin=%v&sid=%v&cap=%v", q["uin"][0], q["sid"][0], q["cap_cd"][0])).
SetHeader(gout.H{"User-Agent": "go-cqhttp/" + version}).
BindBody(&rsp).
Do(); err != nil {
if err := gout.POST("https://api.shkong.com/gocqhttpapi/task").SetJSON(gout.H{
"id": id,
"url": raw,
}).SetTimeout(time.Second * 35).BindBody(&rsp).Do(); err != nil {
return "", err
}
g := gjson.Parse(rsp)

2
go.mod
View File

@ -3,7 +3,7 @@ module github.com/Mrs4s/go-cqhttp
go 1.15
require (
github.com/Mrs4s/MiraiGo v0.0.0-20201225164755-c519c532d0d5
github.com/Mrs4s/MiraiGo v0.0.0-20201231081106-eaa543ae8683
github.com/dustin/go-humanize v1.0.0
github.com/getlantern/go-update v0.0.0-20190510022740-79c495ab728c
github.com/getlantern/golog v0.0.0-20201105130739-9586b8bde3a9 // indirect

4
go.sum
View File

@ -1,7 +1,7 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/Mrs4s/MiraiGo v0.0.0-20201225164755-c519c532d0d5 h1:kvaZXnhjdOtRip6xlXu9hEyJhPzKs8ylrdE2eb+N4NQ=
github.com/Mrs4s/MiraiGo v0.0.0-20201225164755-c519c532d0d5/go.mod h1:7brUNAmygY22+PDCUiVT4MLeyvGHDBjW9f+67DKeHTw=
github.com/Mrs4s/MiraiGo v0.0.0-20201231081106-eaa543ae8683 h1:Hh7GPsqvYzfS2sn7oCK5bv1cWGLO/bpLL16w5WBlWv0=
github.com/Mrs4s/MiraiGo v0.0.0-20201231081106-eaa543ae8683/go.mod h1:7brUNAmygY22+PDCUiVT4MLeyvGHDBjW9f+67DKeHTw=
github.com/a8m/syncmap v0.0.0-20200818084611-4bbbd178de97/go.mod h1:f3iF7/3t9i9hsYF8DPgT0XeIVyNzevhMCKf2445Q6pE=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=

View File

@ -5,6 +5,7 @@ import (
"bytes"
"encoding/base64"
"fmt"
"github.com/Mrs4s/MiraiGo/utils"
"github.com/gin-contrib/pprof"
"image"
"io/ioutil"
@ -112,6 +113,7 @@ func (s *webServer) Dologin() {
s.Console = bufio.NewReader(os.Stdin)
readLine := func() (str string) {
str, _ = s.Console.ReadString('\n')
str = strings.TrimSpace(str)
return
}
conf := GetConf()
@ -125,15 +127,33 @@ func (s *webServer) Dologin() {
if !rsp.Success {
switch rsp.Error {
case client.SliderNeededError:
log.Warnf("正在处理滑条验证码, 这可能需要一段时间.")
ticket, err := global.GetSilderTicket(rsp.VerifyUrl, coolq.Version)
if err != nil {
log.Warnf("处理滑条验证码时出现错误: %v 将尝试跳过.", err)
log.Warnf("登录需要滑条验证码, 请选择解决方案: ")
log.Warnf("1. 自行抓包. (推荐)")
log.Warnf("2. 使用Cef自动处理.")
log.Warnf("3. 不提交滑块并继续.(可能会导致上网环境异常错误)")
log.Warnf("详细信息请参考文档 -> https://github.com/Mrs4s/go-cqhttp/blob/master/docs/slider.md <-")
log.Warn("请输入(1 - 3): ")
text = readLine()
if strings.Contains(text, "1") {
log.Warnf("请用浏览器打开 -> %v <- 并获取Ticket.", rsp.VerifyUrl)
log.Warn("请输入Ticket (Enter 提交)")
text = readLine()
rsp, err = cli.SubmitTicket(strings.TrimSpace(text))
continue
}
if strings.Contains(text, "3") {
cli.AllowSlider = false
cli.Disconnect()
rsp, err = cli.Login()
continue
}
id := utils.RandomStringRange(6, "0123456789")
log.Warnf("滑块ID为 %v 请在30S内处理.", id)
ticket, err := global.GetSliderTicket(rsp.VerifyUrl, id)
if err != nil {
log.Warnf("错误: " + err.Error())
os.Exit(0)
}
rsp, err = cli.SubmitTicket(ticket)
continue
case client.NeedCaptcha:
@ -205,7 +225,7 @@ func (s *webServer) Dologin() {
cli.Disconnect()
rsp, err = cli.Login()
count++
log.Warnf("错误: 当前上网环境异常. 将更换服务器并重试. 如果频繁遇到此问题请打开设备锁.")
log.Warnf("错误: 当前上网环境异常. 将更换服务器并重试.")
time.Sleep(time.Second)
continue
}