mirror of
https://github.com/fumiama/NanoBot.git
synced 2026-06-12 14:10:47 +08:00
统一Message结构体
This commit is contained in:
@@ -485,14 +485,14 @@ func (ctx *Ctx) GetMyGuilds(before, after string, limit int) (guilds []Guild, er
|
|||||||
// PostFileToQQUser 发送文件到 QQ 用户的 openid
|
// PostFileToQQUser 发送文件到 QQ 用户的 openid
|
||||||
//
|
//
|
||||||
// https://bot.q.qq.com/wiki/develop/api-231017/server-inter/message/send-receive/rich-text-media.html#%E5%8F%91%E9%80%81%E5%88%B0%E5%8D%95%E8%81%8A
|
// https://bot.q.qq.com/wiki/develop/api-231017/server-inter/message/send-receive/rich-text-media.html#%E5%8F%91%E9%80%81%E5%88%B0%E5%8D%95%E8%81%8A
|
||||||
func (ctx *Ctx) PostFileToQQUser(id string, content *FilePost) (*IDTimestampMessageResult, error) {
|
func (ctx *Ctx) PostFileToQQUser(id string, content *FilePost) (*Message, error) {
|
||||||
return ctx.caller.PostFileToQQUser(id, content)
|
return ctx.caller.PostFileToQQUser(id, content)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PostFileToQQGroup 发送文件到 QQ 群的 openid
|
// PostFileToQQGroup 发送文件到 QQ 群的 openid
|
||||||
//
|
//
|
||||||
// https://bot.q.qq.com/wiki/develop/api-231017/server-inter/message/send-receive/rich-text-media.html#%E5%8F%91%E9%80%81%E5%88%B0%E7%BE%A4%E8%81%8A
|
// https://bot.q.qq.com/wiki/develop/api-231017/server-inter/message/send-receive/rich-text-media.html#%E5%8F%91%E9%80%81%E5%88%B0%E7%BE%A4%E8%81%8A
|
||||||
func (ctx *Ctx) PostFileToQQGroup(id string, content *FilePost) (*IDTimestampMessageResult, error) {
|
func (ctx *Ctx) PostFileToQQGroup(id string, content *FilePost) (*Message, error) {
|
||||||
return ctx.caller.PostFileToQQGroup(id, content)
|
return ctx.caller.PostFileToQQGroup(id, content)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -503,14 +503,14 @@ func (ctx *Ctx) PostFileToQQGroup(id string, content *FilePost) (*IDTimestampMes
|
|||||||
// PostMessageToQQUser 向 openid 指定的用户发送消息
|
// PostMessageToQQUser 向 openid 指定的用户发送消息
|
||||||
//
|
//
|
||||||
// https://bot.q.qq.com/wiki/develop/api-231017/server-inter/message/send-receive/send.html#%E5%8D%95%E8%81%8A
|
// https://bot.q.qq.com/wiki/develop/api-231017/server-inter/message/send-receive/send.html#%E5%8D%95%E8%81%8A
|
||||||
func (ctx *Ctx) PostMessageToQQUser(id string, content *MessagePostV2) (*IDTimestampMessageResult, error) {
|
func (ctx *Ctx) PostMessageToQQUser(id string, content *MessagePost) (*Message, error) {
|
||||||
return ctx.caller.PostMessageToQQUser(id, content)
|
return ctx.caller.PostMessageToQQUser(id, content)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PostMessageToQQGroup 向 openid 指定的群发送消息
|
// PostMessageToQQGroup 向 openid 指定的群发送消息
|
||||||
//
|
//
|
||||||
// https://bot.q.qq.com/wiki/develop/api-231017/server-inter/message/send-receive/send.html#%E7%BE%A4%E8%81%8A
|
// https://bot.q.qq.com/wiki/develop/api-231017/server-inter/message/send-receive/send.html#%E7%BE%A4%E8%81%8A
|
||||||
func (ctx *Ctx) PostMessageToQQGroup(id string, content *MessagePostV2) (*IDTimestampMessageResult, error) {
|
func (ctx *Ctx) PostMessageToQQGroup(id string, content *MessagePost) (*Message, error) {
|
||||||
return ctx.caller.PostMessageToQQGroup(id, content)
|
return ctx.caller.PostMessageToQQGroup(id, content)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
65
context.go
65
context.go
@@ -6,7 +6,6 @@ import (
|
|||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:generate go run codegen/context/main.go
|
//go:generate go run codegen/context/main.go
|
||||||
@@ -86,9 +85,9 @@ func (ctx *Ctx) Send(messages Messages) (m []*Message, err error) {
|
|||||||
var reply *Message
|
var reply *Message
|
||||||
for _, msg := range messages {
|
for _, msg := range messages {
|
||||||
switch msg.Type {
|
switch msg.Type {
|
||||||
case MessageTypeText:
|
case MessageSegmentTypeText:
|
||||||
textlist = append(textlist, msg.Data)
|
textlist = append(textlist, msg.Data)
|
||||||
case MessageTypeImage:
|
case MessageSegmentTypeImage:
|
||||||
reply, err = ctx.SendImage(msg.Data, isnextreply, textlist...)
|
reply, err = ctx.SendImage(msg.Data, isnextreply, textlist...)
|
||||||
if isnextreply {
|
if isnextreply {
|
||||||
isnextreply = false
|
isnextreply = false
|
||||||
@@ -98,7 +97,7 @@ func (ctx *Ctx) Send(messages Messages) (m []*Message, err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
case MessageTypeImageBytes:
|
case MessageSegmentTypeImageBytes:
|
||||||
if ctx.IsQQ {
|
if ctx.IsQQ {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -111,30 +110,29 @@ func (ctx *Ctx) Send(messages Messages) (m []*Message, err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
case MessageTypeReply:
|
case MessageSegmentTypeReply:
|
||||||
isnextreply = true
|
isnextreply = true
|
||||||
case MessageTypeAudio, MessageTypeVideo:
|
case MessageSegmentTypeAudio, MessageSegmentTypeVideo:
|
||||||
if !ctx.IsQQ {
|
if !ctx.IsQQ {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
fp := &FilePost{
|
fp := &FilePost{
|
||||||
URL: msg.Data,
|
URL: msg.Data,
|
||||||
}
|
}
|
||||||
if msg.Type == MessageTypeAudio {
|
if msg.Type == MessageSegmentTypeAudio {
|
||||||
fp.Type = FileTypeAudio
|
fp.Type = FileTypeAudio
|
||||||
} else if msg.Type == MessageTypeVideo {
|
} else if msg.Type == MessageSegmentTypeVideo {
|
||||||
fp.Type = FileTypeVideo
|
fp.Type = FileTypeVideo
|
||||||
}
|
}
|
||||||
var idts *IDTimestampMessageResult
|
|
||||||
if OnlyQQGroup(ctx) {
|
if OnlyQQGroup(ctx) {
|
||||||
idts, err = ctx.PostFileToQQGroup(ctx.Message.ChannelID, fp)
|
reply, err = ctx.PostFileToQQGroup(ctx.Message.ChannelID, fp)
|
||||||
} else if OnlyQQPrivate(ctx) {
|
} else if OnlyQQPrivate(ctx) {
|
||||||
idts, err = ctx.PostFileToQQUser(ctx.Message.Author.ID, fp)
|
reply, err = ctx.PostFileToQQUser(ctx.Message.Author.ID, fp)
|
||||||
}
|
}
|
||||||
|
m = append(m, reply)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
reply = &Message{ID: idts.ID, Timestamp: time.Unix(int64(idts.Timestamp), 0)}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(textlist) > 0 {
|
if len(textlist) > 0 {
|
||||||
@@ -168,35 +166,21 @@ func (ctx *Ctx) Post(replytosender bool, post *MessagePost) (reply *Message, err
|
|||||||
} else if OnlyChannel(ctx) {
|
} else if OnlyChannel(ctx) {
|
||||||
reply, err = ctx.PostMessageToChannel(msg.ChannelID, post)
|
reply, err = ctx.PostMessageToChannel(msg.ChannelID, post)
|
||||||
} else { // v2
|
} else { // v2
|
||||||
var idts *IDTimestampMessageResult
|
|
||||||
typ := MessageTypeV2Text
|
|
||||||
switch {
|
switch {
|
||||||
case post.Markdown != nil:
|
case post.Markdown != nil:
|
||||||
typ = MessageTypeV2Markdown
|
post.Type = MessageTypeMarkdown
|
||||||
case post.Ark != nil:
|
case post.Ark != nil:
|
||||||
typ = MessageTypeV2Ark
|
post.Type = MessageTypeArk
|
||||||
case post.Embed != nil:
|
case post.Embed != nil:
|
||||||
typ = MessageTypeV2Embed
|
post.Type = MessageTypeEmbed
|
||||||
}
|
default:
|
||||||
v2post := &MessagePostV2{
|
post.Type = MessageTypeText
|
||||||
Type: typ,
|
|
||||||
Seq: len(GetTriggeredMessages(msg.ID)) + 1,
|
|
||||||
Content: post.Content,
|
|
||||||
ReplyMessageID: post.ReplyMessageID,
|
|
||||||
MessageReference: post.MessageReference,
|
|
||||||
Markdown: post.Markdown,
|
|
||||||
KeyBoard: post.KeyBoard,
|
|
||||||
Ark: post.Ark,
|
|
||||||
Embed: post.Embed,
|
|
||||||
}
|
}
|
||||||
|
post.Seq = len(GetTriggeredMessages(msg.ID)) + 1
|
||||||
if OnlyQQGroup(ctx) {
|
if OnlyQQGroup(ctx) {
|
||||||
idts, err = ctx.PostMessageToQQGroup(msg.ChannelID, v2post)
|
reply, err = ctx.PostMessageToQQGroup(msg.ChannelID, post)
|
||||||
} else if OnlyQQPrivate(ctx) {
|
} else if OnlyQQPrivate(ctx) {
|
||||||
idts, err = ctx.PostMessageToQQUser(msg.ChannelID, v2post)
|
reply, err = ctx.PostMessageToQQUser(msg.ChannelID, post)
|
||||||
}
|
|
||||||
reply = &Message{
|
|
||||||
ID: idts.ID,
|
|
||||||
Timestamp: time.Unix(int64(idts.Timestamp), 0),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err != nil && msg != nil && reply != nil && reply.ID != "" {
|
if err != nil && msg != nil && reply != nil && reply.ID != "" {
|
||||||
@@ -213,24 +197,19 @@ func (ctx *Ctx) SendPlainMessage(replytosender bool, printable ...any) (*Message
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SendImage 发送带图片消息到对方
|
// SendImage 发送带图片消息到对方
|
||||||
func (ctx *Ctx) SendImage(file string, replytosender bool, caption ...any) (*Message, error) {
|
func (ctx *Ctx) SendImage(file string, replytosender bool, caption ...any) (reply *Message, err error) {
|
||||||
if OnlyQQ(ctx) {
|
if OnlyQQ(ctx) {
|
||||||
var idts *IDTimestampMessageResult
|
|
||||||
var err error
|
|
||||||
fp := &FilePost{
|
fp := &FilePost{
|
||||||
Type: FileTypeImage,
|
Type: FileTypeImage,
|
||||||
URL: file,
|
URL: file,
|
||||||
}
|
}
|
||||||
_, _ = ctx.SendPlainMessage(replytosender, caption...)
|
_, _ = ctx.SendPlainMessage(replytosender, caption...)
|
||||||
if OnlyQQGroup(ctx) {
|
if OnlyQQGroup(ctx) {
|
||||||
idts, err = ctx.PostFileToQQGroup(ctx.Message.ChannelID, fp)
|
reply, err = ctx.PostFileToQQGroup(ctx.Message.ChannelID, fp)
|
||||||
} else if OnlyQQPrivate(ctx) {
|
} else if OnlyQQPrivate(ctx) {
|
||||||
idts, err = ctx.PostFileToQQUser(ctx.Message.Author.ID, fp)
|
reply, err = ctx.PostFileToQQUser(ctx.Message.Author.ID, fp)
|
||||||
}
|
}
|
||||||
if err != nil {
|
return
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &Message{ID: idts.ID, Timestamp: time.Unix(int64(idts.Timestamp), 0)}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
post := &MessagePost{
|
post := &MessagePost{
|
||||||
|
|||||||
28
event.go
28
event.go
@@ -82,27 +82,15 @@ func (bot *Bot) processEvent(payload *WebsocketPayload) {
|
|||||||
ctx.value = x
|
ctx.value = x
|
||||||
switch tp {
|
switch tp {
|
||||||
case "Message":
|
case "Message":
|
||||||
|
ctx.Message = (*Message)(x.UnsafePointer())
|
||||||
|
if ctx.Message.MentionEveryone {
|
||||||
|
ctx.IsToMe = true
|
||||||
|
}
|
||||||
if ctx.IsQQ {
|
if ctx.IsQQ {
|
||||||
msgv2 := (*MessageV2)(x.UnsafePointer())
|
if ctx.Message.Author.UserOpenID != "" {
|
||||||
ctx.Message = &Message{
|
ctx.Message.Author.ID = ctx.Message.Author.UserOpenID
|
||||||
ID: msgv2.ID,
|
} else if ctx.Message.Author.MemberOpenID != "" {
|
||||||
Content: msgv2.Content,
|
ctx.Message.Author.ID = ctx.Message.Author.MemberOpenID
|
||||||
ChannelID: msgv2.GroupOpenID,
|
|
||||||
GuildID: payload.T,
|
|
||||||
Timestamp: msgv2.Timestamp,
|
|
||||||
Attachments: msgv2.Attachments,
|
|
||||||
Author: &User{},
|
|
||||||
}
|
|
||||||
if msgv2.Author.UserOpenID != "" {
|
|
||||||
ctx.Message.Author.ID = msgv2.Author.UserOpenID
|
|
||||||
} else if msgv2.Author.MemberOpenID != "" {
|
|
||||||
ctx.Message.Author.ID = msgv2.Author.MemberOpenID
|
|
||||||
}
|
|
||||||
ctx.Value = ctx.Message
|
|
||||||
} else {
|
|
||||||
ctx.Message = (*Message)(x.UnsafePointer())
|
|
||||||
if ctx.Message.MentionEveryone {
|
|
||||||
ctx.IsToMe = true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log.Infoln(getLogHeader(), "=>", ctx.Message)
|
log.Infoln(getLogHeader(), "=>", ctx.Message)
|
||||||
|
|||||||
@@ -70,8 +70,8 @@ type Handler struct {
|
|||||||
OnAudioOrLiveChannelMemberExit func(s uint32, bot *Bot, d *AudioLiveChannelUsersChange)
|
OnAudioOrLiveChannelMemberExit func(s uint32, bot *Bot, d *AudioLiveChannelUsersChange)
|
||||||
// QQ (1<<25) QQ 的一堆事件
|
// QQ (1<<25) QQ 的一堆事件
|
||||||
|
|
||||||
OnC2cMessageCreate func(s uint32, bot *Bot, d *MessageV2)
|
OnC2cMessageCreate func(s uint32, bot *Bot, d *Message)
|
||||||
OnGroupAtMessageCreate func(s uint32, bot *Bot, d *MessageV2)
|
OnGroupAtMessageCreate func(s uint32, bot *Bot, d *Message)
|
||||||
OnGroupAddRobot func(s uint32, bot *Bot, d *QQRobotStatus)
|
OnGroupAddRobot func(s uint32, bot *Bot, d *QQRobotStatus)
|
||||||
OnGroupDelRobot func(s uint32, bot *Bot, d *QQRobotStatus)
|
OnGroupDelRobot func(s uint32, bot *Bot, d *QQRobotStatus)
|
||||||
OnGroupMsgReject func(s uint32, bot *Bot, d *QQRobotStatus)
|
OnGroupMsgReject func(s uint32, bot *Bot, d *QQRobotStatus)
|
||||||
|
|||||||
36
message.go
36
message.go
@@ -27,15 +27,15 @@ func GetTriggeredMessages(id string) []string {
|
|||||||
return triggeredMessages.Get(id)
|
return triggeredMessages.Get(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
type MessageType int
|
type MessageSegmentType int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
MessageTypeText MessageType = iota
|
MessageSegmentTypeText MessageSegmentType = iota
|
||||||
MessageTypeImage
|
MessageSegmentTypeImage
|
||||||
MessageTypeImageBytes
|
MessageSegmentTypeImageBytes
|
||||||
MessageTypeReply
|
MessageSegmentTypeReply
|
||||||
MessageTypeAudio
|
MessageSegmentTypeAudio
|
||||||
MessageTypeVideo
|
MessageSegmentTypeVideo
|
||||||
)
|
)
|
||||||
|
|
||||||
// Message impl the array form of message
|
// Message impl the array form of message
|
||||||
@@ -44,7 +44,7 @@ type Messages []MessageSegment
|
|||||||
// MessageSegment impl the single message
|
// MessageSegment impl the single message
|
||||||
// MessageSegment 消息数组
|
// MessageSegment 消息数组
|
||||||
type MessageSegment struct {
|
type MessageSegment struct {
|
||||||
Type MessageType
|
Type MessageSegmentType
|
||||||
Data string
|
Data string
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,7 +56,7 @@ func (m MessageSegment) String() string {
|
|||||||
// Text 纯文本
|
// Text 纯文本
|
||||||
func Text(text ...interface{}) MessageSegment {
|
func Text(text ...interface{}) MessageSegment {
|
||||||
return MessageSegment{
|
return MessageSegment{
|
||||||
Type: MessageTypeText,
|
Type: MessageSegmentTypeText,
|
||||||
Data: HideURL(MessageEscape(fmt.Sprint(text...))),
|
Data: HideURL(MessageEscape(fmt.Sprint(text...))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -65,7 +65,7 @@ func Text(text ...interface{}) MessageSegment {
|
|||||||
// https://bot.q.qq.com/wiki/develop/api/openapi/message/message_format.html#%E6%94%AF%E6%8C%81%E7%9A%84%E6%A0%BC%E5%BC%8F
|
// https://bot.q.qq.com/wiki/develop/api/openapi/message/message_format.html#%E6%94%AF%E6%8C%81%E7%9A%84%E6%A0%BC%E5%BC%8F
|
||||||
func Face(id int) MessageSegment {
|
func Face(id int) MessageSegment {
|
||||||
return MessageSegment{
|
return MessageSegment{
|
||||||
Type: MessageTypeText,
|
Type: MessageSegmentTypeText,
|
||||||
Data: "<emoji:" + strconv.Itoa(id) + ">",
|
Data: "<emoji:" + strconv.Itoa(id) + ">",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -73,7 +73,7 @@ func Face(id int) MessageSegment {
|
|||||||
// Image 普通图片
|
// Image 普通图片
|
||||||
func Image(file string) MessageSegment {
|
func Image(file string) MessageSegment {
|
||||||
return MessageSegment{
|
return MessageSegment{
|
||||||
Type: MessageTypeImage,
|
Type: MessageSegmentTypeImage,
|
||||||
Data: file,
|
Data: file,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -81,7 +81,7 @@ func Image(file string) MessageSegment {
|
|||||||
// ImageBytes 普通图片
|
// ImageBytes 普通图片
|
||||||
func ImageBytes(data []byte) MessageSegment {
|
func ImageBytes(data []byte) MessageSegment {
|
||||||
return MessageSegment{
|
return MessageSegment{
|
||||||
Type: MessageTypeImageBytes,
|
Type: MessageSegmentTypeImageBytes,
|
||||||
Data: BytesToString(data),
|
Data: BytesToString(data),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -93,7 +93,7 @@ func At(id string) MessageSegment {
|
|||||||
return AtAll()
|
return AtAll()
|
||||||
}
|
}
|
||||||
return MessageSegment{
|
return MessageSegment{
|
||||||
Type: MessageTypeText,
|
Type: MessageSegmentTypeText,
|
||||||
Data: "<@!" + id + ">",
|
Data: "<@!" + id + ">",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -102,7 +102,7 @@ func At(id string) MessageSegment {
|
|||||||
// https://bot.q.qq.com/wiki/develop/api/openapi/message/message_format.html#%E6%94%AF%E6%8C%81%E7%9A%84%E6%A0%BC%E5%BC%8F
|
// https://bot.q.qq.com/wiki/develop/api/openapi/message/message_format.html#%E6%94%AF%E6%8C%81%E7%9A%84%E6%A0%BC%E5%BC%8F
|
||||||
func AtAll() MessageSegment {
|
func AtAll() MessageSegment {
|
||||||
return MessageSegment{
|
return MessageSegment{
|
||||||
Type: MessageTypeText,
|
Type: MessageSegmentTypeText,
|
||||||
Data: "@everyone",
|
Data: "@everyone",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -111,7 +111,7 @@ func AtAll() MessageSegment {
|
|||||||
// https://bot.q.qq.com/wiki/develop/api/openapi/message/message_format.html#%E6%94%AF%E6%8C%81%E7%9A%84%E6%A0%BC%E5%BC%8F
|
// https://bot.q.qq.com/wiki/develop/api/openapi/message/message_format.html#%E6%94%AF%E6%8C%81%E7%9A%84%E6%A0%BC%E5%BC%8F
|
||||||
func AtChannel(id string) MessageSegment {
|
func AtChannel(id string) MessageSegment {
|
||||||
return MessageSegment{
|
return MessageSegment{
|
||||||
Type: MessageTypeText,
|
Type: MessageSegmentTypeText,
|
||||||
Data: "<#channel_id>",
|
Data: "<#channel_id>",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -120,7 +120,7 @@ func AtChannel(id string) MessageSegment {
|
|||||||
// https://bot.q.qq.com/wiki/develop/api-231017/server-inter/message/send-receive/rich-text-media.html
|
// https://bot.q.qq.com/wiki/develop/api-231017/server-inter/message/send-receive/rich-text-media.html
|
||||||
func Record(url string) MessageSegment {
|
func Record(url string) MessageSegment {
|
||||||
return MessageSegment{
|
return MessageSegment{
|
||||||
Type: MessageTypeAudio,
|
Type: MessageSegmentTypeAudio,
|
||||||
Data: url,
|
Data: url,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -129,7 +129,7 @@ func Record(url string) MessageSegment {
|
|||||||
// https://bot.q.qq.com/wiki/develop/api-231017/server-inter/message/send-receive/rich-text-media.html
|
// https://bot.q.qq.com/wiki/develop/api-231017/server-inter/message/send-receive/rich-text-media.html
|
||||||
func Video(url string) MessageSegment {
|
func Video(url string) MessageSegment {
|
||||||
return MessageSegment{
|
return MessageSegment{
|
||||||
Type: MessageTypeVideo,
|
Type: MessageSegmentTypeVideo,
|
||||||
Data: url,
|
Data: url,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -138,7 +138,7 @@ func Video(url string) MessageSegment {
|
|||||||
// https://github.com/botuniverse/onebot-11/tree/master/message/segment.md#%E5%9B%9E%E5%A4%8D
|
// https://github.com/botuniverse/onebot-11/tree/master/message/segment.md#%E5%9B%9E%E5%A4%8D
|
||||||
func ReplyTo(id string) MessageSegment {
|
func ReplyTo(id string) MessageSegment {
|
||||||
return MessageSegment{
|
return MessageSegment{
|
||||||
Type: MessageTypeReply,
|
Type: MessageSegmentTypeReply,
|
||||||
Data: id,
|
Data: id,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ func (bot *Bot) DeleteOpenAPIWithPtr(ep, contenttype string, ptr any, body io.Re
|
|||||||
return bot.dohttprequest(NewHTTPEndpointDeleteRequestWithAuth, ep, contenttype, ptr, body)
|
return bot.dohttprequest(NewHTTPEndpointDeleteRequestWithAuth, ep, contenttype, ptr, body)
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:generate go run codegen/postopenapiof/main.go Channel GuildRoleCreate Message DMS IDTimestampMessageResult
|
//go:generate go run codegen/postopenapiof/main.go Channel GuildRoleCreate Message DMS
|
||||||
|
|
||||||
// PostOpenAPI 从 ep 得到 json 结构化数据返回值写到 ptr, ptr 除 Slice 外必须在开头继承 CodeMessageBase
|
// PostOpenAPI 从 ep 得到 json 结构化数据返回值写到 ptr, ptr 除 Slice 外必须在开头继承 CodeMessageBase
|
||||||
func (bot *Bot) PostOpenAPI(ep, contenttype string, ptr any, body io.Reader) error {
|
func (bot *Bot) PostOpenAPI(ep, contenttype string, ptr any, body io.Reader) error {
|
||||||
|
|||||||
@@ -55,15 +55,3 @@ func (bot *Bot) postOpenAPIofDMS(ep, contenttype string, body io.Reader) (*DMS,
|
|||||||
}
|
}
|
||||||
return &resp.DMS, err
|
return &resp.DMS, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bot *Bot) postOpenAPIofIDTimestampMessageResult(ep, contenttype string, body io.Reader) (*IDTimestampMessageResult, error) {
|
|
||||||
resp := &struct {
|
|
||||||
CodeMessageBase
|
|
||||||
IDTimestampMessageResult
|
|
||||||
}{}
|
|
||||||
err := bot.PostOpenAPI(ep, contenttype, resp, body)
|
|
||||||
if err != nil {
|
|
||||||
err = errors.Wrap(err, getCallerFuncName())
|
|
||||||
}
|
|
||||||
return &resp.IDTimestampMessageResult, err
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ type Message struct {
|
|||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
ChannelID string `json:"channel_id"`
|
ChannelID string `json:"channel_id"`
|
||||||
GuildID string `json:"guild_id"`
|
GuildID string `json:"guild_id"`
|
||||||
|
GroupOpenID string `json:"group_openid"`
|
||||||
Content string `json:"content"`
|
Content string `json:"content"`
|
||||||
Timestamp time.Time `json:"timestamp"`
|
Timestamp time.Time `json:"timestamp"`
|
||||||
EditedTimestamp time.Time `json:"edited_timestamp"`
|
EditedTimestamp time.Time `json:"edited_timestamp"`
|
||||||
@@ -224,6 +225,9 @@ func (bot *Bot) GetMessageFromChannel(messageid, channelid string) (*Message, er
|
|||||||
//
|
//
|
||||||
// https://bot.q.qq.com/wiki/develop/api/openapi/message/post_messages.html#%E9%80%9A%E7%94%A8%E5%8F%82%E6%95%B0
|
// https://bot.q.qq.com/wiki/develop/api/openapi/message/post_messages.html#%E9%80%9A%E7%94%A8%E5%8F%82%E6%95%B0
|
||||||
type MessagePost struct {
|
type MessagePost struct {
|
||||||
|
// https://bot.q.qq.com/wiki/develop/api-231017/server-inter/message/send-receive/send.html
|
||||||
|
Type MessageType `json:"msg_type"`
|
||||||
|
Seq int `json:"msg_seq,omitempty"` // 回复消息的序号,与 msg_id 联合使用,避免相同消息id回复重复发送,不填默认是1。相同的 msg_id + msg_seq 重复发送会失败。
|
||||||
Content string `json:"content,omitempty"`
|
Content string `json:"content,omitempty"`
|
||||||
Embed *MessageEmbed `json:"embed,omitempty"` // https://bot.q.qq.com/wiki/develop/api/openapi/message/template/embed_message.html
|
Embed *MessageEmbed `json:"embed,omitempty"` // https://bot.q.qq.com/wiki/develop/api/openapi/message/template/embed_message.html
|
||||||
Ark *MessageArk `json:"ark,omitempty"` // https://bot.q.qq.com/wiki/develop/api/openapi/message/message_template.html
|
Ark *MessageArk `json:"ark,omitempty"` // https://bot.q.qq.com/wiki/develop/api/openapi/message/message_template.html
|
||||||
@@ -239,6 +243,13 @@ type MessagePost struct {
|
|||||||
|
|
||||||
func (mp *MessagePost) String() string {
|
func (mp *MessagePost) String() string {
|
||||||
sb := strings.Builder{}
|
sb := strings.Builder{}
|
||||||
|
if mp.Seq > 0 {
|
||||||
|
sb.WriteString("[v2:")
|
||||||
|
sb.WriteString(mp.Type.String())
|
||||||
|
sb.WriteString("#")
|
||||||
|
sb.WriteString(strconv.Itoa(mp.Seq))
|
||||||
|
sb.WriteString("]")
|
||||||
|
}
|
||||||
if mp.Content == "" {
|
if mp.Content == "" {
|
||||||
sb.WriteString("无文本")
|
sb.WriteString("无文本")
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ type User struct {
|
|||||||
Bot bool `json:"bot"`
|
Bot bool `json:"bot"`
|
||||||
UnionOpenid string `json:"union_openid"`
|
UnionOpenid string `json:"union_openid"`
|
||||||
UnionUserAccount string `json:"union_user_account"`
|
UnionUserAccount string `json:"union_user_account"`
|
||||||
|
UserOpenID string `json:"user_openid"`
|
||||||
|
MemberOpenID string `json:"member_openid"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// At 返回 <@!u.ID>
|
// At 返回 <@!u.ID>
|
||||||
|
|||||||
@@ -1,10 +1,5 @@
|
|||||||
package nano
|
package nano
|
||||||
|
|
||||||
type IDTimestampMessageResult struct {
|
|
||||||
ID string `json:"id"`
|
|
||||||
Timestamp int `json:"timestamp"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// QQRobotStatus https://bot.q.qq.com/wiki/develop/api-231017/server-inter/group.html#%E4%BA%8B%E4%BB%B6
|
// QQRobotStatus https://bot.q.qq.com/wiki/develop/api-231017/server-inter/group.html#%E4%BA%8B%E4%BB%B6
|
||||||
type QQRobotStatus struct {
|
type QQRobotStatus struct {
|
||||||
OpenID string `json:"openid"`
|
OpenID string `json:"openid"`
|
||||||
|
|||||||
@@ -59,17 +59,17 @@ func (fp *FilePost) String() string {
|
|||||||
// PostFileToQQUser 发送文件到 QQ 用户的 openid
|
// PostFileToQQUser 发送文件到 QQ 用户的 openid
|
||||||
//
|
//
|
||||||
// https://bot.q.qq.com/wiki/develop/api-231017/server-inter/message/send-receive/rich-text-media.html#%E5%8F%91%E9%80%81%E5%88%B0%E5%8D%95%E8%81%8A
|
// https://bot.q.qq.com/wiki/develop/api-231017/server-inter/message/send-receive/rich-text-media.html#%E5%8F%91%E9%80%81%E5%88%B0%E5%8D%95%E8%81%8A
|
||||||
func (bot *Bot) PostFileToQQUser(id string, content *FilePost) (*IDTimestampMessageResult, error) {
|
func (bot *Bot) PostFileToQQUser(id string, content *FilePost) (*Message, error) {
|
||||||
logrus.Infoln(getLogHeader(), "<= [Q]单:", id+",", content)
|
logrus.Infoln(getLogHeader(), "<= [Q]单:", id+",", content)
|
||||||
content.MotherFuckingAlwaysTrue = true
|
content.MotherFuckingAlwaysTrue = true
|
||||||
return bot.postOpenAPIofIDTimestampMessageResult("/v2/users/"+id+"/files", "", WriteBodyFromJSON(content))
|
return bot.postOpenAPIofMessage("/v2/users/"+id+"/files", "", WriteBodyFromJSON(content))
|
||||||
}
|
}
|
||||||
|
|
||||||
// PostFileToQQGroup 发送文件到 QQ 群的 openid
|
// PostFileToQQGroup 发送文件到 QQ 群的 openid
|
||||||
//
|
//
|
||||||
// https://bot.q.qq.com/wiki/develop/api-231017/server-inter/message/send-receive/rich-text-media.html#%E5%8F%91%E9%80%81%E5%88%B0%E7%BE%A4%E8%81%8A
|
// https://bot.q.qq.com/wiki/develop/api-231017/server-inter/message/send-receive/rich-text-media.html#%E5%8F%91%E9%80%81%E5%88%B0%E7%BE%A4%E8%81%8A
|
||||||
func (bot *Bot) PostFileToQQGroup(id string, content *FilePost) (*IDTimestampMessageResult, error) {
|
func (bot *Bot) PostFileToQQGroup(id string, content *FilePost) (*Message, error) {
|
||||||
logrus.Infoln(getLogHeader(), "<= [Q]群:", id+",", content)
|
logrus.Infoln(getLogHeader(), "<= [Q]群:", id+",", content)
|
||||||
content.MotherFuckingAlwaysTrue = true
|
content.MotherFuckingAlwaysTrue = true
|
||||||
return bot.postOpenAPIofIDTimestampMessageResult("/v2/groups/"+id+"/files", "", WriteBodyFromJSON(content))
|
return bot.postOpenAPIofMessage("/v2/groups/"+id+"/files", "", WriteBodyFromJSON(content))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,149 +2,49 @@ package nano
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
type MessageTypeV2 int
|
type MessageType int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
MessageTypeV2Text MessageTypeV2 = iota
|
MessageTypeText MessageType = iota
|
||||||
MessageTypeV2TextImage
|
MessageTypeTextImage
|
||||||
MessageTypeV2Markdown
|
MessageTypeMarkdown
|
||||||
MessageTypeV2Ark
|
MessageTypeArk
|
||||||
MessageTypeV2Embed
|
MessageTypeEmbed
|
||||||
)
|
)
|
||||||
|
|
||||||
func (mt2 MessageTypeV2) String() string {
|
func (mt2 MessageType) String() string {
|
||||||
switch mt2 {
|
switch mt2 {
|
||||||
case MessageTypeV2Text:
|
case MessageTypeText:
|
||||||
return "文本"
|
return "文本"
|
||||||
case MessageTypeV2TextImage:
|
case MessageTypeTextImage:
|
||||||
return "图文混排"
|
return "图文混排"
|
||||||
case MessageTypeV2Markdown:
|
case MessageTypeMarkdown:
|
||||||
return "MD"
|
return "MD"
|
||||||
case MessageTypeV2Ark:
|
case MessageTypeArk:
|
||||||
return "模版"
|
return "模版"
|
||||||
case MessageTypeV2Embed:
|
case MessageTypeEmbed:
|
||||||
return "嵌入"
|
return "嵌入"
|
||||||
default:
|
default:
|
||||||
return "未知类型" + strconv.Itoa(int(mt2))
|
return "未知类型" + strconv.Itoa(int(mt2))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type MessageV2 struct {
|
|
||||||
Author struct {
|
|
||||||
UserOpenID string `json:"user_openid"`
|
|
||||||
MemberOpenID string `json:"member_openid"`
|
|
||||||
} `json:"author"`
|
|
||||||
Content string `json:"content"`
|
|
||||||
ID string `json:"id"`
|
|
||||||
GroupOpenID string `json:"group_openid"`
|
|
||||||
Timestamp time.Time `json:"timestamp"`
|
|
||||||
Attachments []MessageAttachment `json:"attachments"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// MessagePostV2 V2 发消息结构体
|
|
||||||
//
|
|
||||||
// https://bot.q.qq.com/wiki/develop/api-231017/server-inter/message/send-receive/send.html
|
|
||||||
type MessagePostV2 struct {
|
|
||||||
Type MessageTypeV2 `json:"msg_type"`
|
|
||||||
Seq int `json:"msg_seq,omitempty"` // 回复消息的序号,与 msg_id 联合使用,避免相同消息id回复重复发送,不填默认是1。相同的 msg_id + msg_seq 重复发送会失败。
|
|
||||||
Content string `json:"content"`
|
|
||||||
ReplyEventID string `json:"event_id,omitempty"` // 前置收到的事件ID,用于发送被动消息
|
|
||||||
ReplyMessageID string `json:"msg_id,omitempty"`
|
|
||||||
|
|
||||||
// image 否 【暂不支持】
|
|
||||||
MessageReference *MessageReference `json:"message_reference,omitempty"` // 【暂未支持】消息引用
|
|
||||||
|
|
||||||
Markdown *MessageMarkdown `json:"markdown,omitempty"`
|
|
||||||
KeyBoard *MessageKeyboard `json:"keyboard,omitempty"`
|
|
||||||
Ark *MessageArk `json:"ark,omitempty"`
|
|
||||||
Embed *MessageEmbed `json:"embed,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mp *MessagePostV2) String() string {
|
|
||||||
sb := strings.Builder{}
|
|
||||||
sb.WriteString("[v2.")
|
|
||||||
sb.WriteString(mp.Type.String())
|
|
||||||
sb.WriteString(".")
|
|
||||||
sb.WriteString(strconv.Itoa(mp.Seq))
|
|
||||||
sb.WriteString("]")
|
|
||||||
if mp.Content == "" {
|
|
||||||
sb.WriteString("无文本")
|
|
||||||
} else {
|
|
||||||
sb.WriteString("文本: ")
|
|
||||||
sb.WriteString(mp.Content)
|
|
||||||
}
|
|
||||||
if mp.ReplyMessageID != "" {
|
|
||||||
sb.WriteString(", 回应消息: ")
|
|
||||||
sb.WriteString(mp.ReplyMessageID)
|
|
||||||
}
|
|
||||||
if mp.ReplyEventID != "" {
|
|
||||||
sb.WriteString(", 回应事件: ")
|
|
||||||
sb.WriteString(mp.ReplyEventID)
|
|
||||||
}
|
|
||||||
if mp.Embed != nil {
|
|
||||||
sb.WriteString(", 嵌入: <标题:")
|
|
||||||
sb.WriteString(mp.Embed.Title)
|
|
||||||
sb.WriteString(",提示:")
|
|
||||||
sb.WriteString(mp.Embed.Prompt)
|
|
||||||
sb.WriteByte('>')
|
|
||||||
}
|
|
||||||
if mp.Ark != nil {
|
|
||||||
sb.WriteString(", 模版: ")
|
|
||||||
sb.WriteString(strconv.Itoa(mp.Ark.TemplateID))
|
|
||||||
}
|
|
||||||
if mp.MessageReference != nil {
|
|
||||||
sb.WriteString(", 回复: ")
|
|
||||||
sb.WriteString(mp.MessageReference.MessageID)
|
|
||||||
}
|
|
||||||
/*if mp.Image != "" {
|
|
||||||
sb.WriteString(", 图片URL: ")
|
|
||||||
sb.WriteString(mp.Image)
|
|
||||||
}
|
|
||||||
if mp.ImageFile != "" {
|
|
||||||
sb.WriteString(", 图片内容: ")
|
|
||||||
x := mp.ImageFile
|
|
||||||
if len(x) > 64 {
|
|
||||||
x = x[:64] + "..."
|
|
||||||
}
|
|
||||||
sb.WriteString(x)
|
|
||||||
}
|
|
||||||
if len(mp.ImageBytes) > 0 {
|
|
||||||
sb.WriteString(", 图片大小: ")
|
|
||||||
sb.WriteString(strconv.Itoa(len(mp.ImageBytes)))
|
|
||||||
}*/
|
|
||||||
if mp.Markdown != nil {
|
|
||||||
sb.WriteString(", MD模版: ")
|
|
||||||
sb.WriteString(strconv.Itoa(mp.Markdown.TemplateID))
|
|
||||||
}
|
|
||||||
if mp.KeyBoard != nil {
|
|
||||||
sb.WriteString(", KB模版: ")
|
|
||||||
sb.WriteString(mp.KeyBoard.ID)
|
|
||||||
}
|
|
||||||
return sb.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (bot *Bot) postV2MessageTo(ep string, content *MessagePostV2) (*IDTimestampMessageResult, error) {
|
|
||||||
return bot.postOpenAPIofIDTimestampMessageResult(ep, "", WriteBodyFromJSON(content))
|
|
||||||
}
|
|
||||||
|
|
||||||
// PostMessageToQQUser 向 openid 指定的用户发送消息
|
// PostMessageToQQUser 向 openid 指定的用户发送消息
|
||||||
//
|
//
|
||||||
// https://bot.q.qq.com/wiki/develop/api-231017/server-inter/message/send-receive/send.html#%E5%8D%95%E8%81%8A
|
// https://bot.q.qq.com/wiki/develop/api-231017/server-inter/message/send-receive/send.html#%E5%8D%95%E8%81%8A
|
||||||
func (bot *Bot) PostMessageToQQUser(id string, content *MessagePostV2) (*IDTimestampMessageResult, error) {
|
func (bot *Bot) PostMessageToQQUser(id string, content *MessagePost) (*Message, error) {
|
||||||
logrus.Infoln(getLogHeader(), "<= [Q]单:", id+",", content)
|
logrus.Infoln(getLogHeader(), "<= [Q]单:", id+",", content)
|
||||||
return bot.postV2MessageTo("/v2/users/"+id+"/messages", content)
|
return bot.postMessageTo("/v2/users/"+id+"/messages", content)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PostMessageToQQGroup 向 openid 指定的群发送消息
|
// PostMessageToQQGroup 向 openid 指定的群发送消息
|
||||||
//
|
//
|
||||||
// https://bot.q.qq.com/wiki/develop/api-231017/server-inter/message/send-receive/send.html#%E7%BE%A4%E8%81%8A
|
// https://bot.q.qq.com/wiki/develop/api-231017/server-inter/message/send-receive/send.html#%E7%BE%A4%E8%81%8A
|
||||||
func (bot *Bot) PostMessageToQQGroup(id string, content *MessagePostV2) (*IDTimestampMessageResult, error) {
|
func (bot *Bot) PostMessageToQQGroup(id string, content *MessagePost) (*Message, error) {
|
||||||
logrus.Infoln(getLogHeader(), "<= [Q]群:", id+",", content)
|
logrus.Infoln(getLogHeader(), "<= [Q]群:", id+",", content)
|
||||||
return bot.postV2MessageTo("/v2/groups/"+id+"/messages", content)
|
return bot.postMessageTo("/v2/groups/"+id+"/messages", content)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user