update
This commit is contained in:
+194
@@ -0,0 +1,194 @@
|
||||
package qq
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
qrcodeTerminal "github.com/Baozisoftware/qrcode-terminal-go"
|
||||
"github.com/Mrs4s/MiraiGo/client"
|
||||
"github.com/pkg/errors"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/tuotoo/qrcode"
|
||||
|
||||
"github.com/Mrs4s/go-cqhttp/global"
|
||||
)
|
||||
|
||||
var console = bufio.NewReader(os.Stdin)
|
||||
|
||||
var readLine = func() (str string) {
|
||||
str, _ = console.ReadString('\n')
|
||||
str = strings.TrimSpace(str)
|
||||
return
|
||||
}
|
||||
|
||||
var readLineTimeout = func(t time.Duration, de string) (str string) {
|
||||
r := make(chan string)
|
||||
go func() {
|
||||
select {
|
||||
case r <- readLine():
|
||||
case <-time.After(t):
|
||||
}
|
||||
}()
|
||||
str = de
|
||||
select {
|
||||
case str = <-r:
|
||||
case <-time.After(t):
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
var cli *client.QQClient
|
||||
|
||||
// ErrSMSRequestError SMS请求出错
|
||||
var ErrSMSRequestError = errors.New("sms request error")
|
||||
|
||||
func commonLogin() error {
|
||||
res, err := cli.Login()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return loginResponseProcessor(res)
|
||||
}
|
||||
|
||||
func qrcodeLogin() error {
|
||||
rsp, err := cli.FetchQRCode()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fi, err := qrcode.Decode(bytes.NewReader(rsp.ImageData))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_ = os.WriteFile("qrcode.png", rsp.ImageData, 0o644)
|
||||
defer func() { _ = os.Remove("qrcode.png") }()
|
||||
if cli.Uin != 0 {
|
||||
log.Infof("请使用账号 %v 登录手机QQ扫描二维码 (qrcode.png) : ", cli.Uin)
|
||||
} else {
|
||||
log.Infof("请使用手机QQ扫描二维码 (qrcode.png) : ")
|
||||
}
|
||||
time.Sleep(time.Second)
|
||||
qrcodeTerminal.New().Get(fi.Content).Print()
|
||||
s, err := cli.QueryQRCodeStatus(rsp.Sig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
prevState := s.State
|
||||
for {
|
||||
time.Sleep(time.Second)
|
||||
s, _ = cli.QueryQRCodeStatus(rsp.Sig)
|
||||
if s == nil {
|
||||
continue
|
||||
}
|
||||
if prevState == s.State {
|
||||
continue
|
||||
}
|
||||
prevState = s.State
|
||||
switch s.State {
|
||||
case client.QRCodeCanceled:
|
||||
log.Fatalf("扫码被用户取消.")
|
||||
case client.QRCodeTimeout:
|
||||
log.Fatalf("二维码过期")
|
||||
case client.QRCodeWaitingForConfirm:
|
||||
log.Infof("扫码成功, 请在手机端确认登录.")
|
||||
case client.QRCodeConfirmed:
|
||||
res, err := cli.QRCodeLogin(s.LoginInfo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return loginResponseProcessor(res)
|
||||
case client.QRCodeImageFetch, client.QRCodeWaitingForScan:
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func loginResponseProcessor(res *client.LoginResponse) error {
|
||||
var err error
|
||||
for {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if res.Success {
|
||||
return nil
|
||||
}
|
||||
var text string
|
||||
switch res.Error {
|
||||
case client.SliderNeededError:
|
||||
log.Warnf("登录需要滑条验证码. ")
|
||||
log.Warnf("请参考文档 -> https://docs.go-cqhttp.org/faq/slider.html <- 进行处理")
|
||||
log.Warnf("1. 自行抓包并获取 Ticket 输入.")
|
||||
log.Warnf("2. 使用手机QQ扫描二维码登入. (推荐)")
|
||||
log.Warn("请输入(1 - 2) (将在10秒后自动选择2):")
|
||||
text = readLineTimeout(time.Second*10, "2")
|
||||
if strings.Contains(text, "1") {
|
||||
println()
|
||||
log.Warnf("请用浏览器打开 -> %v <- 并获取Ticket.", res.VerifyUrl)
|
||||
println()
|
||||
log.Warn("请输入Ticket: (Enter 提交)")
|
||||
text = readLine()
|
||||
res, err = cli.SubmitTicket(text)
|
||||
continue
|
||||
}
|
||||
cli.Disconnect()
|
||||
cli.Release()
|
||||
cli = client.NewClientEmpty()
|
||||
return qrcodeLogin()
|
||||
case client.NeedCaptcha:
|
||||
log.Warnf("登录需要验证码.")
|
||||
_ = os.WriteFile("captcha.jpg", res.CaptchaImage, 0o644)
|
||||
log.Warnf("请输入验证码 (captcha.jpg): (Enter 提交)")
|
||||
text = readLine()
|
||||
global.DelFile("captcha.jpg")
|
||||
res, err = cli.SubmitCaptcha(text, res.CaptchaSign)
|
||||
continue
|
||||
case client.SMSNeededError:
|
||||
log.Warnf("账号已开启设备锁, 按 Enter 向手机 %v 发送短信验证码.", res.SMSPhone)
|
||||
readLine()
|
||||
if !cli.RequestSMS() {
|
||||
log.Warnf("发送验证码失败,可能是请求过于频繁.")
|
||||
return errors.WithStack(ErrSMSRequestError)
|
||||
}
|
||||
log.Warn("请输入短信验证码: (Enter 提交)")
|
||||
text = readLine()
|
||||
res, err = cli.SubmitSMS(text)
|
||||
continue
|
||||
case client.SMSOrVerifyNeededError:
|
||||
log.Warnf("账号已开启设备锁,请选择验证方式:")
|
||||
log.Warnf("1. 向手机 %v 发送短信验证码", res.SMSPhone)
|
||||
log.Warnf("2. 使用手机QQ扫码验证.")
|
||||
log.Warn("请输入(1 - 2) (将在10秒后自动选择2):")
|
||||
text = readLineTimeout(time.Second*10, "2")
|
||||
if strings.Contains(text, "1") {
|
||||
if !cli.RequestSMS() {
|
||||
log.Warnf("发送验证码失败,可能是请求过于频繁.")
|
||||
return errors.WithStack(ErrSMSRequestError)
|
||||
}
|
||||
log.Warn("请输入短信验证码: (Enter 提交)")
|
||||
text = readLine()
|
||||
res, err = cli.SubmitSMS(text)
|
||||
continue
|
||||
}
|
||||
fallthrough
|
||||
case client.UnsafeDeviceError:
|
||||
log.Warnf("账号已开启设备锁,请前往 -> %v <- 验证后重启Bot.", res.VerifyUrl)
|
||||
log.Infof("按 Enter 或等待 5s 后继续....")
|
||||
readLineTimeout(time.Second*5, "")
|
||||
// os.Exit(0)
|
||||
case client.OtherLoginError, client.UnknownLoginError, client.TooManySMSRequestError:
|
||||
msg := res.ErrorMessage
|
||||
if strings.Contains(msg, "版本") {
|
||||
msg = "密码错误或账号被冻结"
|
||||
}
|
||||
if strings.Contains(msg, "冻结") {
|
||||
log.Fatalf("账号被冻结")
|
||||
}
|
||||
log.Warnf("登录失败: %v", msg)
|
||||
log.Infof("按 Enter 或等待 5s 后继续....")
|
||||
readLineTimeout(time.Second*5, "")
|
||||
// os.Exit(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
+218
@@ -0,0 +1,218 @@
|
||||
package qq
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"os"
|
||||
"path"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/Mrs4s/go-cqhttp/coolq"
|
||||
"github.com/Mrs4s/go-cqhttp/global"
|
||||
"github.com/Mrs4s/go-cqhttp/global/config"
|
||||
"github.com/cdle/sillyGirl/core"
|
||||
|
||||
"github.com/Mrs4s/MiraiGo/binary"
|
||||
"github.com/Mrs4s/MiraiGo/client"
|
||||
"github.com/Mrs4s/MiraiGo/message"
|
||||
rotatelogs "github.com/lestrrat-go/file-rotatelogs"
|
||||
log "github.com/sirupsen/logrus"
|
||||
easy "github.com/t-tomalak/logrus-easy-formatter"
|
||||
)
|
||||
|
||||
var (
|
||||
conf *config.Config
|
||||
PasswordHash [16]byte
|
||||
AccountToken []byte
|
||||
allowStatus = [...]client.UserOnlineStatus{
|
||||
client.StatusOnline, client.StatusAway, client.StatusInvisible, client.StatusBusy,
|
||||
client.StatusListening, client.StatusConstellation, client.StatusWeather, client.StatusMeetSpring,
|
||||
client.StatusTimi, client.StatusEatChicken, client.StatusLoving, client.StatusWangWang, client.StatusCookedRice,
|
||||
client.StatusStudy, client.StatusStayUp, client.StatusPlayBall, client.StatusSignal, client.StatusStudyOnline,
|
||||
client.StatusGaming, client.StatusVacationing, client.StatusWatchingTV, client.StatusFitness,
|
||||
}
|
||||
)
|
||||
|
||||
var bot *coolq.CQBot
|
||||
var qq = core.NewBucket("qq")
|
||||
|
||||
func init() {
|
||||
conf = &config.Config{}
|
||||
conf.Account.Uin = int64(qq.GetInt("uin", 0))
|
||||
conf.Account.Password = qq.Get("password")
|
||||
conf.Message.ReportSelfMessage = true
|
||||
if conf.Output.Debug {
|
||||
log.SetReportCaller(true)
|
||||
}
|
||||
logFormatter := &easy.Formatter{
|
||||
TimestampFormat: "2006/01/02 15:04:05.000",
|
||||
LogFormat: "%time% [Q] %msg% \n",
|
||||
}
|
||||
rotateOptions := []rotatelogs.Option{
|
||||
rotatelogs.WithRotationTime(time.Hour * 24),
|
||||
}
|
||||
|
||||
if conf.Output.LogAging > 0 {
|
||||
rotateOptions = append(rotateOptions, rotatelogs.WithMaxAge(time.Hour*24*time.Duration(conf.Output.LogAging)))
|
||||
}
|
||||
if conf.Output.LogForceNew {
|
||||
rotateOptions = append(rotateOptions, rotatelogs.ForceNewFile())
|
||||
}
|
||||
|
||||
w, err := rotatelogs.New(path.Join("logs/qq", "%Y-%m-%d.log"), rotateOptions...)
|
||||
if err != nil {
|
||||
log.Errorf("rotatelogs init err: %v", err)
|
||||
panic(err)
|
||||
}
|
||||
|
||||
log.AddHook(global.NewLocalHook(w, logFormatter, global.GetLogLevel(conf.Output.LogLevel)...))
|
||||
|
||||
if device := qq.Get("device.json"); device == "" {
|
||||
client.GenRandomDevice()
|
||||
qq.Set("device.json", string(client.SystemDeviceInfo.ToJson()))
|
||||
} else {
|
||||
if err := client.SystemDeviceInfo.ReadJson([]byte(device)); err != nil {
|
||||
log.Fatalf("加载设备信息失败: %v", err)
|
||||
}
|
||||
}
|
||||
PasswordHash = md5.Sum([]byte(conf.Account.Password))
|
||||
log.Info("开始尝试登录并同步消息...")
|
||||
log.Infof("使用协议: %v", func() string {
|
||||
switch client.SystemDeviceInfo.Protocol {
|
||||
case client.IPad:
|
||||
return "iPad"
|
||||
case client.AndroidPhone:
|
||||
return "Android Phone"
|
||||
case client.AndroidWatch:
|
||||
return "Android Watch"
|
||||
case client.MacOS:
|
||||
return "MacOS"
|
||||
case client.QiDian:
|
||||
return "企点"
|
||||
}
|
||||
return "未知"
|
||||
}())
|
||||
cli = client.NewClientEmpty()
|
||||
global.Proxy = conf.Message.ProxyRewrite
|
||||
isQRCodeLogin := (conf.Account.Uin == 0 || len(conf.Account.Password) == 0) && !conf.Account.Encrypt
|
||||
isTokenLogin := false
|
||||
saveToken := func() {
|
||||
AccountToken = cli.GenToken()
|
||||
qq.Set("session.token", string(AccountToken))
|
||||
}
|
||||
if token := qq.Get("session.token"); token != "" {
|
||||
if err == nil {
|
||||
if conf.Account.Uin != 0 {
|
||||
r := binary.NewReader([]byte(token))
|
||||
cu := r.ReadInt64()
|
||||
if cu != conf.Account.Uin {
|
||||
log.Warnf("警告: 配置文件内的QQ号 (%v) 与缓存内的QQ号 (%v) 不相同", conf.Account.Uin, cu)
|
||||
}
|
||||
}
|
||||
if err = cli.TokenLogin([]byte(token)); err != nil {
|
||||
qq.Set("session.token", "")
|
||||
log.Warnf("恢复会话失败: %v , 尝试使用正常流程登录.", err)
|
||||
time.Sleep(time.Second)
|
||||
cli.Disconnect()
|
||||
cli.Release()
|
||||
cli = client.NewClientEmpty()
|
||||
} else {
|
||||
isTokenLogin = true
|
||||
}
|
||||
}
|
||||
}
|
||||
if conf.Account.Uin != 0 && PasswordHash != [16]byte{} {
|
||||
cli.Uin = conf.Account.Uin
|
||||
cli.PasswordMd5 = PasswordHash
|
||||
}
|
||||
if !isTokenLogin {
|
||||
if !isQRCodeLogin {
|
||||
if err := commonLogin(); err != nil {
|
||||
log.Fatalf("登录时发生致命错误: %v", err)
|
||||
}
|
||||
} else {
|
||||
if err := qrcodeLogin(); err != nil {
|
||||
log.Fatalf("登录时发生致命错误: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
var times uint = 10 // 重试次数
|
||||
var reLoginLock sync.Mutex
|
||||
cli.OnDisconnected(func(_ *client.QQClient, e *client.ClientDisconnectedEvent) {
|
||||
reLoginLock.Lock()
|
||||
defer reLoginLock.Unlock()
|
||||
times = 1
|
||||
if cli.Online {
|
||||
return
|
||||
}
|
||||
log.Warnf("Bot已离线: %v", e.Message)
|
||||
time.Sleep(time.Second * time.Duration(conf.Account.ReLogin.Delay))
|
||||
for {
|
||||
if conf.Account.ReLogin.Disabled {
|
||||
os.Exit(1)
|
||||
}
|
||||
if times > conf.Account.ReLogin.MaxTimes && conf.Account.ReLogin.MaxTimes != 0 {
|
||||
log.Fatalf("Bot重连次数超过限制, 停止")
|
||||
}
|
||||
times++
|
||||
if conf.Account.ReLogin.Interval > 0 {
|
||||
log.Warnf("将在 %v 秒后尝试重连. 重连次数:%v/%v", conf.Account.ReLogin.Interval, times, conf.Account.ReLogin.MaxTimes)
|
||||
time.Sleep(time.Second * time.Duration(conf.Account.ReLogin.Interval))
|
||||
} else {
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
log.Warnf("尝试重连...")
|
||||
err := cli.TokenLogin(AccountToken)
|
||||
if err == nil {
|
||||
saveToken()
|
||||
return
|
||||
}
|
||||
log.Warnf("快速重连失败: %v", err)
|
||||
if isQRCodeLogin {
|
||||
log.Fatalf("快速重连失败, 扫码登录无法恢复会话.")
|
||||
}
|
||||
log.Warnf("快速重连失败, 尝试普通登录. 这可能是因为其他端强行T下线导致的.")
|
||||
time.Sleep(time.Second)
|
||||
if err := commonLogin(); err != nil {
|
||||
log.Errorf("登录时发生致命错误: %v", err)
|
||||
} else {
|
||||
saveToken()
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
saveToken()
|
||||
cli.AllowSlider = true
|
||||
log.Infof("登录成功 欢迎使用: %v", cli.Nickname)
|
||||
global.Check(cli.ReloadFriendList(), true)
|
||||
global.Check(cli.ReloadGroupList(), true)
|
||||
if conf.Account.Status >= int32(len(allowStatus)) || conf.Account.Status < 0 {
|
||||
conf.Account.Status = 0
|
||||
}
|
||||
cli.SetOnlineStatus(allowStatus[int(conf.Account.Status)])
|
||||
bot = coolq.NewQQBot(cli, conf)
|
||||
_ = bot.Client
|
||||
coolq.SetMessageFormat("string")
|
||||
onPrivateMessage := func(c *client.QQClient, m *message.PrivateMessage) {
|
||||
core.Senders <- &Sender{
|
||||
Message: m,
|
||||
}
|
||||
|
||||
// cqm := coolq.ToStringMessage(m.Elements, 0, true)
|
||||
// fmt.Println(cqm, m.Self, m.Target, m.Sender.Uin)
|
||||
if m.Sender.Uin != c.Uin {
|
||||
c.MarkPrivateMessageReaded(m.Sender.Uin, int64(m.Time))
|
||||
}
|
||||
}
|
||||
OnGroupMessage := func(c *client.QQClient, m *message.GroupMessage) {
|
||||
// cqm := coolq.ToStringMessage(m.Elements, m.GroupCode, true)
|
||||
// fmt.Println(cqm, m.GroupCode, m.Sender.Uin)
|
||||
core.Senders <- &Sender{
|
||||
Message: m,
|
||||
}
|
||||
}
|
||||
bot.Client.OnPrivateMessage(onPrivateMessage)
|
||||
bot.Client.OnSelfPrivateMessage(onPrivateMessage)
|
||||
bot.Client.OnGroupMessage(OnGroupMessage)
|
||||
bot.Client.OnSelfGroupMessage(OnGroupMessage)
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
package qq
|
||||
+152
@@ -0,0 +1,152 @@
|
||||
package qq
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/Mrs4s/MiraiGo/message"
|
||||
"github.com/Mrs4s/go-cqhttp/coolq"
|
||||
)
|
||||
|
||||
type Sender struct {
|
||||
Message interface{}
|
||||
matches [][]string
|
||||
}
|
||||
|
||||
func (sender *Sender) GetContent() string {
|
||||
text := ""
|
||||
switch sender.Message.(type) {
|
||||
case *message.PrivateMessage:
|
||||
text = coolq.ToStringMessage(sender.Message.(*message.PrivateMessage).Elements, 0, true)
|
||||
case *message.GroupMessage:
|
||||
m := sender.Message.(*message.GroupMessage)
|
||||
text = coolq.ToStringMessage(m.Elements, m.GroupCode, true)
|
||||
}
|
||||
return text
|
||||
}
|
||||
|
||||
func (sender *Sender) GetUserID() int {
|
||||
id := 0
|
||||
switch sender.Message.(type) {
|
||||
case *message.PrivateMessage:
|
||||
id = int(sender.Message.(*message.PrivateMessage).Sender.Uin)
|
||||
case *message.GroupMessage:
|
||||
id = int(sender.Message.(*message.GroupMessage).Sender.Uin)
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
func (sender *Sender) GetChatID() int {
|
||||
id := 0
|
||||
switch sender.Message.(type) {
|
||||
case *message.PrivateMessage:
|
||||
case *message.GroupMessage:
|
||||
id = int(sender.Message.(*message.GroupMessage).GroupCode)
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
func (sender *Sender) GetImType() string {
|
||||
return "qq"
|
||||
}
|
||||
|
||||
func (sender *Sender) GetMessageID() int {
|
||||
id := 0
|
||||
switch sender.Message.(type) {
|
||||
case *message.PrivateMessage:
|
||||
id = int(sender.Message.(*message.PrivateMessage).Id)
|
||||
case *message.GroupMessage:
|
||||
id = int(sender.Message.(*message.GroupMessage).Id)
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
func (sender *Sender) GetUsername() string {
|
||||
name := ""
|
||||
switch sender.Message.(type) {
|
||||
case *message.PrivateMessage:
|
||||
name = sender.Message.(*message.PrivateMessage).Sender.Nickname
|
||||
case *message.GroupMessage:
|
||||
name = sender.Message.(*message.GroupMessage).Sender.Nickname
|
||||
}
|
||||
return name
|
||||
}
|
||||
|
||||
func (sender *Sender) IsReply() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (sender *Sender) GetReplySenderUserID() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (sender *Sender) GetRawMessage() interface{} {
|
||||
return sender.Message
|
||||
}
|
||||
|
||||
func (sender *Sender) SetMatch(ss []string) {
|
||||
sender.matches = [][]string{ss}
|
||||
}
|
||||
func (sender *Sender) SetAllMatch(ss [][]string) {
|
||||
sender.matches = ss
|
||||
}
|
||||
|
||||
func (sender *Sender) GetMatch() []string {
|
||||
return sender.matches[0]
|
||||
}
|
||||
|
||||
func (sender *Sender) GetAllMatch() [][]string {
|
||||
return sender.matches
|
||||
}
|
||||
|
||||
func (sender *Sender) Get(index ...int) string {
|
||||
i := 0
|
||||
if len(index) != 0 {
|
||||
i = index[0]
|
||||
}
|
||||
if len(sender.matches) == 0 {
|
||||
return ""
|
||||
}
|
||||
if len(sender.matches[0]) < i+1 {
|
||||
return ""
|
||||
}
|
||||
return sender.matches[0][i]
|
||||
}
|
||||
|
||||
func (sender *Sender) IsAdmin() bool {
|
||||
return true
|
||||
// return sender.Message.Sender.ID == qq.GetInt("master")
|
||||
}
|
||||
|
||||
func (sender *Sender) IsMedia() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (sender *Sender) Reply(msg interface{}) error {
|
||||
switch sender.Message.(type) {
|
||||
case *message.PrivateMessage:
|
||||
m := sender.Message.(*message.PrivateMessage)
|
||||
switch msg.(type) {
|
||||
case string:
|
||||
bot.SendPrivateMessage(m.Sender.Uin, int64(qq.GetInt("groupCode")), &message.SendingMessage{Elements: []message.IMessageElement{&message.TextElement{Content: msg.(string)}}})
|
||||
case *http.Response:
|
||||
data, _ := ioutil.ReadAll(msg.(*http.Response).Body)
|
||||
bot.SendPrivateMessage(m.Sender.Uin, int64(qq.GetInt("groupCode")), &message.SendingMessage{Elements: []message.IMessageElement{&coolq.LocalImageElement{Stream: bytes.NewReader(data)}}})
|
||||
}
|
||||
case *message.GroupMessage:
|
||||
m := sender.Message.(*message.GroupMessage)
|
||||
switch msg.(type) {
|
||||
case string:
|
||||
if strings.Contains(msg.(string), "\n") {
|
||||
msg = "\n" + msg.(string)
|
||||
}
|
||||
bot.SendGroupMessage(m.GroupCode, &message.SendingMessage{Elements: []message.IMessageElement{&message.AtElement{Target: m.Sender.Uin}, &message.TextElement{Content: msg.(string)}}})
|
||||
case *http.Response:
|
||||
data, _ := ioutil.ReadAll(msg.(*http.Response).Body)
|
||||
bot.SendGroupMessage(m.GroupCode, &message.SendingMessage{Elements: []message.IMessageElement{&message.AtElement{Target: m.Sender.Uin}, &message.TextElement{Content: "\n"}, &coolq.LocalImageElement{Stream: bytes.NewReader(data)}}})
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user