Commit aaa73ef5 authored by wdvxdr1123's avatar wdvxdr1123 Committed by GitHub

Merge

Dev
parents 2a5f7849 a72a688a
...@@ -66,6 +66,7 @@ func NewQQBot(cli *client.QQClient, conf *global.JsonConfig) *CQBot { ...@@ -66,6 +66,7 @@ func NewQQBot(cli *client.QQClient, conf *global.JsonConfig) *CQBot {
bot.Client.OnGroupMemberJoined(bot.memberJoinEvent) bot.Client.OnGroupMemberJoined(bot.memberJoinEvent)
bot.Client.OnGroupMemberLeaved(bot.memberLeaveEvent) bot.Client.OnGroupMemberLeaved(bot.memberLeaveEvent)
bot.Client.OnGroupMemberPermissionChanged(bot.memberPermissionChangedEvent) bot.Client.OnGroupMemberPermissionChanged(bot.memberPermissionChangedEvent)
bot.Client.OnGroupMemberCardUpdated(bot.memberCardUpdatedEvent)
bot.Client.OnNewFriendRequest(bot.friendRequestEvent) bot.Client.OnNewFriendRequest(bot.friendRequestEvent)
bot.Client.OnNewFriendAdded(bot.friendAddedEvent) bot.Client.OnNewFriendAdded(bot.friendAddedEvent)
bot.Client.OnGroupInvited(bot.groupInvitedEvent) bot.Client.OnGroupInvited(bot.groupInvitedEvent)
...@@ -151,6 +152,48 @@ func (bot *CQBot) SendGroupMessage(groupId int64, m *message.SendingMessage) int ...@@ -151,6 +152,48 @@ func (bot *CQBot) SendGroupMessage(groupId int64, m *message.SendingMessage) int
bot.Client.SendGroupGift(uint64(groupId), uint64(i.Target), i.GiftId) bot.Client.SendGroupGift(uint64(groupId), uint64(i.Target), i.GiftId)
return 0 return 0
} }
if i, ok := elem.(*QQMusicElement); ok {
var msgStyle uint32 = 4
if i.MusicUrl == "" {
msgStyle = 0 // fix vip song
}
ret, err := bot.Client.SendGroupRichMessage(groupId, 100497308, 1, msgStyle, client.RichClientInfo{
Platform: 1,
SdkVersion: "0.0.0",
PackageName: "com.tencent.qqmusic",
Signature: "cbd27cd7c861227d013a25b2d10f0799",
}, &message.RichMessage{
Title: i.Title,
Summary: i.Summary,
Url: i.Url,
PictureUrl: i.PictureUrl,
MusicUrl: i.MusicUrl,
})
if err != nil {
log.Warnf("警告: 群 %v 富文本消息发送失败: %v", groupId, err)
return -1
}
return bot.InsertGroupMessage(ret)
}
if i, ok := elem.(*CloudMusicElement); ok {
ret, err := bot.Client.SendGroupRichMessage(groupId, 100495085, 1, 4, client.RichClientInfo{
Platform: 1,
SdkVersion: "0.0.0",
PackageName: "com.netease.cloudmusic",
Signature: "da6b069da1e2982db3e386233f68d76d",
}, &message.RichMessage{
Title: i.Title,
Summary: i.Summary,
Url: i.Url,
PictureUrl: i.PictureUrl,
MusicUrl: i.MusicUrl,
})
if err != nil {
log.Warnf("警告: 群 %v 富文本消息发送失败: %v", groupId, err)
return -1
}
return bot.InsertGroupMessage(ret)
}
newElem = append(newElem, elem) newElem = append(newElem, elem)
} }
m.Elements = newElem m.Elements = newElem
......
...@@ -35,10 +35,30 @@ type GiftElement struct { ...@@ -35,10 +35,30 @@ type GiftElement struct {
GiftId message.GroupGift GiftId message.GroupGift
} }
type MusicElement struct {
Title string
Summary string
Url string
PictureUrl string
MusicUrl string
}
type QQMusicElement struct {
MusicElement
}
type CloudMusicElement struct {
MusicElement
}
func (e *GiftElement) Type() message.ElementType { func (e *GiftElement) Type() message.ElementType {
return message.At return message.At
} }
func (e *MusicElement) Type() message.ElementType {
return message.Service
}
var GiftId = []message.GroupGift{ var GiftId = []message.GroupGift{
message.SweetWink, message.SweetWink,
message.HappyCola, message.HappyCola,
...@@ -429,8 +449,13 @@ func (bot *CQBot) ToElement(t string, d map[string]string, group bool) (message. ...@@ -429,8 +449,13 @@ func (bot *CQBot) ToElement(t string, d map[string]string, group bool) (message.
if d["content"] != "" { if d["content"] != "" {
content = d["content"] content = d["content"]
} }
json := fmt.Sprintf("{\"app\": \"com.tencent.structmsg\",\"desc\": \"音乐\",\"meta\": {\"music\": {\"desc\": \"%s\",\"jumpUrl\": \"%s\",\"musicUrl\": \"%s\",\"preview\": \"%s\",\"tag\": \"QQ音乐\",\"title\": \"%s\"}},\"prompt\": \"[分享]%s\",\"ver\": \"0.0.0.1\",\"view\": \"music\"}", content, jumpUrl, purl, preview, name, name) return &QQMusicElement{MusicElement: MusicElement{
return message.NewLightApp(json), nil Title: name,
Summary: content,
Url: jumpUrl,
PictureUrl: preview,
MusicUrl: purl,
}}, nil
} }
if d["type"] == "163" { if d["type"] == "163" {
info, err := global.NeteaseMusicSongInfo(d["id"]) info, err := global.NeteaseMusicSongInfo(d["id"])
...@@ -448,8 +473,13 @@ func (bot *CQBot) ToElement(t string, d map[string]string, group bool) (message. ...@@ -448,8 +473,13 @@ func (bot *CQBot) ToElement(t string, d map[string]string, group bool) (message.
if info.Get("artists.0").Exists() { if info.Get("artists.0").Exists() {
artistName = info.Get("artists.0.name").Str artistName = info.Get("artists.0.name").Str
} }
json := fmt.Sprintf("{\"app\": \"com.tencent.structmsg\",\"desc\":\"音乐\",\"view\":\"music\",\"prompt\":\"[分享]%s\",\"ver\":\"0.0.0.1\",\"meta\":{ \"music\": { \"desc\": \"%s\", \"jumpUrl\": \"%s\", \"musicUrl\": \"%s\", \"preview\": \"%s\", \"tag\": \"网易云音乐\", \"title\":\"%s\"}}}", name, artistName, jumpUrl, musicUrl, picUrl, name) return &CloudMusicElement{MusicElement{
return message.NewLightApp(json), nil Title: name,
Summary: artistName,
Url: jumpUrl,
PictureUrl: picUrl,
MusicUrl: musicUrl,
}}, nil
} }
if d["type"] == "custom" { if d["type"] == "custom" {
xml := fmt.Sprintf(`<?xml version='1.0' encoding='UTF-8' standalone='yes' ?><msg serviceID="2" templateID="1" action="web" brief="[分享] %s" sourceMsgId="0" url="%s" flag="0" adverSign="0" multiMsgFlag="0"><item layout="2"><audio cover="%s" src="%s"/><title>%s</title><summary>%s</summary></item><source name="音乐" icon="https://i.gtimg.cn/open/app_icon/01/07/98/56/1101079856_100_m.png" url="http://web.p.qq.com/qqmpmobile/aio/app.html?id=1101079856" action="app" a_actionData="com.tencent.qqmusic" i_actionData="tencent1101079856://" appid="1101079856" /></msg>`, xml := fmt.Sprintf(`<?xml version='1.0' encoding='UTF-8' standalone='yes' ?><msg serviceID="2" templateID="1" action="web" brief="[分享] %s" sourceMsgId="0" url="%s" flag="0" adverSign="0" multiMsgFlag="0"><item layout="2"><audio cover="%s" src="%s"/><title>%s</title><summary>%s</summary></item><source name="音乐" icon="https://i.gtimg.cn/open/app_icon/01/07/98/56/1101079856_100_m.png" url="http://web.p.qq.com/qqmpmobile/aio/app.html?id=1101079856" action="app" a_actionData="com.tencent.qqmusic" i_actionData="tencent1101079856://" appid="1101079856" /></msg>`,
......
...@@ -310,6 +310,20 @@ func (bot *CQBot) memberPermissionChangedEvent(c *client.QQClient, e *client.Mem ...@@ -310,6 +310,20 @@ func (bot *CQBot) memberPermissionChangedEvent(c *client.QQClient, e *client.Mem
}) })
} }
func (bot *CQBot) memberCardUpdatedEvent(c *client.QQClient, e *client.MemberCardUpdatedEvent) {
log.Infof("群 %v 的 %v 更新了名片 %v -> %v", formatGroupName(e.Group), formatMemberName(e.Member), e.OldCard, e.Member.CardName)
bot.dispatchEventMessage(MSG{
"post_type": "notice",
"notice_type": "group_card",
"group_id": e.Group.Code,
"user_id": e.Member.Uin,
"card_new": e.Member.CardName,
"card_old": e.OldCard,
"time": time.Now().Unix(),
"self_id": c.Uin,
})
}
func (bot *CQBot) memberJoinEvent(c *client.QQClient, e *client.MemberJoinGroupEvent) { func (bot *CQBot) memberJoinEvent(c *client.QQClient, e *client.MemberJoinGroupEvent) {
log.Infof("新成员 %v 进入了群 %v.", formatMemberName(e.Member), formatGroupName(e.Group)) log.Infof("新成员 %v 进入了群 %v.", formatMemberName(e.Member), formatGroupName(e.Group))
bot.dispatchEventMessage(bot.groupIncrease(e.Group.Code, 0, e.Member.Uin)) bot.dispatchEventMessage(bot.groupIncrease(e.Group.Code, 0, e.Member.Uin))
......
...@@ -520,3 +520,20 @@ Type: `tts` ...@@ -520,3 +520,20 @@ Type: `tts`
| `sub_type` | string | `honor` | 提示类型 | | `sub_type` | string | `honor` | 提示类型 |
| `user_id` | int64 | | 成员id | | `user_id` | int64 | | 成员id |
| `honor_type` | string | `talkative:龙王` `performer:群聊之火` `emotion:快乐源泉` | 荣誉类型 | | `honor_type` | string | `talkative:龙王` `performer:群聊之火` `emotion:快乐源泉` | 荣誉类型 |
#### 群成员名片更新
> 注意: 此事件不保证时效性,仅在收到消息时校验卡片
**上报数据**
| 字段 | 类型 | 可能的值 | 说明 |
| ------------- | ------ | -------------- | -------------- |
| `post_type` | string | `notice` | 上报类型 |
| `notice_type` | string | `group_card` | 消息类型 |
| `group_id` | int64 | | 群号 |
| `user_id` | int64 | | 成员id |
| `card_new` | int64 | | 新名片 |
| `card_old` | int64 | | 旧名片 |
> PS: 当名片为空时 `card_xx` 字段为空字符串, 并不是昵称
\ No newline at end of file
...@@ -3,7 +3,7 @@ module github.com/Mrs4s/go-cqhttp ...@@ -3,7 +3,7 @@ module github.com/Mrs4s/go-cqhttp
go 1.14 go 1.14
require ( require (
github.com/Mrs4s/MiraiGo v0.0.0-20201005155759-f9b3c399e5e0 github.com/Mrs4s/MiraiGo v0.0.0-20201008134448-b53aaceaa1b4
github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 // indirect github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 // indirect
github.com/gin-gonic/gin v1.6.3 github.com/gin-gonic/gin v1.6.3
github.com/go-playground/validator/v10 v10.4.0 // indirect github.com/go-playground/validator/v10 v10.4.0 // indirect
...@@ -23,7 +23,7 @@ require ( ...@@ -23,7 +23,7 @@ require (
github.com/tebeka/strftime v0.1.5 // indirect github.com/tebeka/strftime v0.1.5 // indirect
github.com/tidwall/gjson v1.6.1 github.com/tidwall/gjson v1.6.1
github.com/ugorji/go v1.1.10 // indirect github.com/ugorji/go v1.1.10 // indirect
github.com/wdvxdr1123/go-silk v0.0.0-20201006020916-0398076200ea github.com/wdvxdr1123/go-silk v0.0.0-20201007123416-b982fd3d91d6
github.com/xujiajun/nutsdb v0.5.0 github.com/xujiajun/nutsdb v0.5.0
github.com/yinghau76/go-ascii-art v0.0.0-20190517192627-e7f465a30189 github.com/yinghau76/go-ascii-art v0.0.0-20190517192627-e7f465a30189
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0 // indirect golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0 // indirect
......
This diff is collapsed.
...@@ -98,12 +98,24 @@ func (s *webServer) Dologin() { ...@@ -98,12 +98,24 @@ func (s *webServer) Dologin() {
s.Console = bufio.NewReader(os.Stdin) s.Console = bufio.NewReader(os.Stdin)
conf := GetConf() conf := GetConf()
cli := s.Cli cli := s.Cli
cli.AllowSlider = true
rsp, err := cli.Login() rsp, err := cli.Login()
for { for {
global.Check(err) global.Check(err)
var text string var text string
if !rsp.Success { if !rsp.Success {
switch rsp.Error { switch rsp.Error {
case client.SliderNeededError:
if client.SystemDeviceInfo.Protocol == client.AndroidPhone {
log.Warnf("警告: Android Phone 强制要求暂不支持的滑条验证码, 请开启设备锁或切换到Watch协议验证通过后再使用.")
log.Infof("按 Enter 继续....")
_, _ = s.Console.ReadString('\n')
os.Exit(0)
}
cli.AllowSlider = false
cli.Disconnect()
rsp, err = cli.Login()
continue
case client.NeedCaptcha: case client.NeedCaptcha:
_ = ioutil.WriteFile("captcha.jpg", rsp.CaptchaImage, 0644) _ = ioutil.WriteFile("captcha.jpg", rsp.CaptchaImage, 0644)
img, _, _ := image.Decode(bytes.NewReader(rsp.CaptchaImage)) img, _, _ := image.Decode(bytes.NewReader(rsp.CaptchaImage))
...@@ -118,20 +130,57 @@ func (s *webServer) Dologin() { ...@@ -118,20 +130,57 @@ func (s *webServer) Dologin() {
rsp, err = cli.SubmitCaptcha(strings.ReplaceAll(text, "\n", ""), rsp.CaptchaSign) rsp, err = cli.SubmitCaptcha(strings.ReplaceAll(text, "\n", ""), rsp.CaptchaSign)
global.DelFile("captcha.jpg") global.DelFile("captcha.jpg")
continue continue
case client.SMSNeededError:
log.Warnf("账号已开启设备锁, 按下 Enter 向手机 %v 发送短信验证码.", rsp.SMSPhone)
_, _ = s.Console.ReadString('\n')
if !cli.RequestSMS() {
log.Warnf("发送验证码失败,可能是请求过于频繁.")
time.Sleep(time.Second * 5)
os.Exit(0)
}
log.Warn("请输入短信验证码: (Enter 提交)")
text, _ = s.Console.ReadString('\n')
rsp, err = cli.SubmitSMS(strings.ReplaceAll(strings.ReplaceAll(text, "\n", ""), "\r", ""))
continue
case client.SMSOrVerifyNeededError:
log.Warnf("账号已开启设备锁,请选择验证方式:")
log.Warnf("1. 向手机 %v 发送短信验证码", rsp.SMSPhone)
log.Warnf("2. 使用手机QQ扫码验证.")
log.Warn("请输入(1 - 2): ")
text, _ = s.Console.ReadString('\n')
if strings.Contains(text, "1") {
if !cli.RequestSMS() {
log.Warnf("发送验证码失败,可能是请求过于频繁.")
time.Sleep(time.Second * 5)
os.Exit(0)
}
log.Warn("请输入短信验证码: (Enter 提交)")
text, _ = s.Console.ReadString('\n')
rsp, err = cli.SubmitSMS(strings.ReplaceAll(strings.ReplaceAll(text, "\n", ""), "\r", ""))
continue
}
log.Warnf("请前往 -> %v <- 验证并重启Bot.", rsp.VerifyUrl)
log.Infof("按 Enter 继续....")
_, _ = s.Console.ReadString('\n')
os.Exit(0)
return
case client.UnsafeDeviceError: case client.UnsafeDeviceError:
log.Warnf("账号已开启设备锁,请前往 -> %v <- 验证并重启Bot.", rsp.VerifyUrl) log.Warnf("账号已开启设备锁,请前往 -> %v <- 验证并重启Bot.", rsp.VerifyUrl)
if conf.WebUi.WebInput { if conf.WebUi.WebInput {
log.Infof(" (http://%s:%d/admin/do_web_write 确认后继续)....", conf.WebUi.Host, conf.WebUi.WebUiPort) log.Infof(" (http://%s:%d/admin/do_web_write 确认后继续)....", conf.WebUi.Host, conf.WebUi.WebUiPort)
text = <-WebInput text = <-WebInput
} else { } else {
log.Infof(" 按 Enter 继续....") log.Infof("按 Enter 继续....")
_, _ = s.Console.ReadString('\n') _, _ = s.Console.ReadString('\n')
} }
log.Info(text) log.Info(text)
os.Exit(0) os.Exit(0)
return return
case client.OtherLoginError, client.UnknownLoginError: case client.OtherLoginError, client.UnknownLoginError:
log.Fatalf("登录失败: %v", rsp.ErrorMessage) log.Warnf("登录失败: %v", rsp.ErrorMessage)
log.Infof("按 Enter 继续....")
_, _ = s.Console.ReadString('\n')
os.Exit(0)
return return
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment