Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: add user/message.go #4

Merged
merged 10 commits into from
Apr 3, 2020
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
module github.com/wechaty/go-wechaty

go 1.14

require github.com/hashicorp/golang-lru v0.5.4
59 changes: 58 additions & 1 deletion src/wechaty-puppet/puppet.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,66 @@
package wechaty_puppet

import (
lru "github.com/hashicorp/golang-lru"

"github.com/wechaty/go-wechaty/src/wechaty-puppet/schemas"
)

type Puppet interface {
type PuppetInterface interface {
dingdayu marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about IPuppet?

MessageImage(messageId string, imageType schemas.ImageType) FileBox
}

type Puppet struct {
PuppetInterface

CacheMessagePayload *lru.Cache
}

// MessageList
func (p *Puppet) MessageList() (ks []string) {
keys := p.CacheMessagePayload.Keys()
for _, v := range keys {
if k, ok := v.(string); ok {
ks = append(ks, k)
}
}
return
}

func (p *Puppet) MessageSearch(query schemas.MessageUserQueryFilter) []string {
allMessageIdList := p.MessageList()
if len(allMessageIdList) <= 0 {
return allMessageIdList
}

// load
var messagePayloadList []schemas.MessagePayload
for _, v := range allMessageIdList {
messagePayloadList = append(messagePayloadList, p.MessagePayload(v))
}
// Filter todo:: messageQueryFilterFactory
var messageIdList []string
for _, v := range messagePayloadList {
if message, ok := v.(schemas.MessagePayloadRoom); ok {
if message.FromId == query.FromId || message.RoomId == query.RoomId || message.ToId == query.ToId {
messageIdList = append(messageIdList, message.Id)
}
} else if message, ok := v.(schemas.MessagePayloadTo); ok {
if message.FromId == query.FromId || message.RoomId == query.RoomId || message.ToId == query.ToId {
messageIdList = append(messageIdList, message.Id)
}
}
}

return messageIdList
}

// messageQueryFilterFactory 实现正则和直接匹配
func (p *Puppet) messageQueryFilterFactory(query string) schemas.MessagePayloadFilterFunction {
return nil
}

// todo:: no finish
func (p *Puppet) MessagePayload(messageId string) schemas.MessagePayload {
return nil
}
8 changes: 4 additions & 4 deletions src/wechaty-puppet/schemas/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package schemas
type ImageType uint8

const (
Unknown ImageType = 0
Thumbnail = 1
HD = 2
Artwork = 3
ImageTypeUnknown ImageType = 0
dingdayu marked this conversation as resolved.
Show resolved Hide resolved
ImageTypeThumbnail = 1
ImageTypeHD = 2
ImageTypeArtwork = 3
)
117 changes: 117 additions & 0 deletions src/wechaty-puppet/schemas/message.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package schemas

type MessageType uint8

const (
MessageTypeUnknown MessageType = 0

MessageTypeAttachment // Attach(6)
MessageTypeAudio // Audio(1) Voice(34)
MessageTypeContact // ShareCard(42)
MessageTypeChatHistory // ChatHistory(19)
MessageTypeEmoticon // Sticker Emoticon(15) Emoticon(47)
MessageTypeImage // Img(2) Image(3)
MessageTypeText // Text(1)
MessageTypeLocation // Location(48)
MessageTypeMiniProgram // MiniProgram(33)
MessageTypeTransfer // Transfers(2000)
MessageTypeRedEnvelope // RedEnvelopes(2001)
MessageTypeRecalled // Recalled(10002)
MessageTypeUrl // Url(5)
MessageTypeVideo // Video(4) Video(43)
)

type WechatAppMessageType uint8

const (
WechatAppMessageTypeText WechatAppMessageType = 1
WechatAppMessageTypeImg = 2
WechatAppMessageTypeAudio = 3
WechatAppMessageTypeVideo = 4
WechatAppMessageTypeUrl = 5
WechatAppMessageTypeAttach = 6
WechatAppMessageTypeOpen = 7
WechatAppMessageTypeEmoji = 8
WechatAppMessageTypeVoiceRemind = 9
WechatAppMessageTypeScanGood = 10
WechatAppMessageTypeGood = 13
WechatAppMessageTypeEmotion = 15
WechatAppMessageTypeCardTicket = 16
WechatAppMessageTypeRealtimeShareLocation = 17
WechatAppMessageTypeChatHistory = 19
WechatAppMessageTypeMiniProgram = 33
WechatAppMessageTypeTransfers = 2000
WechatAppMessageTypeRedEnvelopes = 2001
WechatAppMessageTypeReaderType = 100001
)

type WechatMessageType uint8

const (
WechatMessageTypeText = 1
WechatMessageTypeImage = 3
WechatMessageTypeVoice = 34
WechatMessageTypeVerifyMsg = 37
WechatMessageTypePossibleFriendMsg = 40
WechatMessageTypeShareCard = 42
WechatMessageTypeVideo = 43
WechatMessageTypeEmoticon = 47
WechatMessageTypeLocation = 48
WechatMessageTypeApp = 49
WechatMessageTypeVoipMsg = 50
WechatMessageTypeStatusNotify = 51
WechatMessageTypeVoipNotify = 52
WechatMessageTypeVoipInvite = 53
WechatMessageTypeMicroVideo = 62
WechatMessageTypeTransfer = 2000 // 转账
WechatMessageTypeRedEnvelope = 2001 // 红包
WechatMessageTypeMiniProgram = 2002 // 小程序
WechatMessageTypeGroupInvite = 2003 // 群邀请
WechatMessageTypeFile = 2004 // 文件消息
WechatMessageTypeSysNotice = 9999
WechatMessageTypeSys = 10000
WechatMessageTypeRecalled = 10002 // NOTIFY 服务通知
)

type MessagePayloadBase struct {
Id string

// use message id to get rawPayload to get those informations when needed
// contactId string // Contact ShareCard
MentionIdList []string // Mentioned Contacts' Ids

FileName string
Text string
Timestamp int
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

我的代码里,timestamp使用的int64,可以考虑一下统一成哪种?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK

Type MessageType
}

type MessagePayloadRoom struct {
MessagePayloadBase

FromId string
RoomId string
ToId string // if to is not set then room must be set
}

type MessagePayloadTo struct {
MessagePayloadBase

FromId string
RoomId string
ToId string // if to is not set then room must be set
}

// todo:: MessagePayload
type MessagePayload interface{}

type MessageUserQueryFilter struct {
FromId string
Id string
RoomId string
Text string // todo:: RegExp
ToId string
Type MessageType
}

type MessagePayloadFilterFunction func(payload MessagePayload) bool
8 changes: 6 additions & 2 deletions src/wechaty/accessory.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ import (
wechatyPuppet "github.com/wechaty/go-wechaty/src/wechaty-puppet"
)

type Accessory struct {
Puppet wechatyPuppet.Puppet // wechat-puppet 的 Puppet 接口
type Accessory interface {
dingdayu marked this conversation as resolved.
Show resolved Hide resolved
SetPuppet(puppet wechatyPuppet.Puppet)
GetPuppet() *wechatyPuppet.Puppet

SetWechaty(wechaty Wechaty)
GetWechaty() *Wechaty
}
9 changes: 9 additions & 0 deletions src/wechaty/type.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package wechaty

import (
"github.com/wechaty/go-wechaty/src/wechaty/user"
)

type Sayable interface {
Say(text string, replyTo ...user.Contact)
}
13 changes: 13 additions & 0 deletions src/wechaty/user/contact.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package user

type Contact struct {
Id string
}

func (r *Contact) Load(id string) Contact {
return Contact{}
}

func (r *Contact) Ready(forceSync bool) bool {
return true
}
8 changes: 4 additions & 4 deletions src/wechaty/user/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,23 @@ type Images struct {

// NewImages create image struct
func NewImages(id string, accessory wechaty.Accessory) *Images {
if accessory.Puppet == nil {
if accessory.GetPuppet() == nil {
panic("Image class can not be instanciated without a puppet!")
}
return &Images{accessory, id}
}

// Thumbnail message thumbnail images
func (img *Images) Thumbnail() wechatyPuppet.FileBox {
return img.Accessory.Puppet.MessageImage(img.ImageId, schemas.Thumbnail)
return img.Accessory.GetPuppet().MessageImage(img.ImageId, schemas.ImageTypeThumbnail)
}

// HD message hd images
func (img *Images) HD() wechatyPuppet.FileBox {
return img.Accessory.Puppet.MessageImage(img.ImageId, schemas.HD)
return img.Accessory.GetPuppet().MessageImage(img.ImageId, schemas.ImageTypeHD)
}

// Artwork message artwork images
func (img *Images) Artwork() wechatyPuppet.FileBox {
return img.Accessory.Puppet.MessageImage(img.ImageId, schemas.Artwork)
return img.Accessory.GetPuppet().MessageImage(img.ImageId, schemas.ImageTypeArtwork)
}
117 changes: 117 additions & 0 deletions src/wechaty/user/message.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package user

import (
"fmt"

"github.com/wechaty/go-wechaty/src/wechaty"
"github.com/wechaty/go-wechaty/src/wechaty-puppet/schemas"
)

type MessageUserQueryFilter struct {
From Contact
Text string // todo:: RegExp
Room Room
Type schemas.MessageType
To Contact
}

type Message struct {
wechaty.Accessory

Type schemas.MessageType

InvalidDict map[string]bool

Id string
Payload schemas.MessagePayload
}

// Find
// userQuery: MessageUserQueryFilter | string
func (m *Message) Find(query interface{}) Message {
var userQuery MessageUserQueryFilter
if q, ok := query.(string); ok {
userQuery.Text = q
} else if q, ok := query.(MessageUserQueryFilter); ok {
userQuery = q
}

messageList := m.FindAll(userQuery)
if len(messageList) > 0 {
return messageList[0]
}
return Message{}
}

// FindAll
func (m *Message) FindAll(userQuery MessageUserQueryFilter) (messages []Message) {
puppetQuery := schemas.MessageUserQueryFilter{
FromId: userQuery.From.Id,
RoomId: userQuery.Room.Id,
Text: userQuery.Text,
ToId: userQuery.To.Id,
Type: userQuery.Type,
}

ids := m.GetPuppet().MessageSearch(puppetQuery)

// check invalid message
for _, v := range ids {
message := m.Load(v)
if message.Ready() {
messages = append(messages, message)
}
}
return
}

// Ready todo:: no finish
func (m *Message) Ready() bool {
if m.IsReady() {
return true
}

m.Payload = m.GetPuppet().MessagePayload(m.Id)

if m.Payload == nil {
// todo:: should not panic, because not recover
panic("no payload")
}

var fromId, roomId, toId string
if p, ok := m.Payload.(schemas.MessagePayloadTo); ok {
fromId = p.FromId
roomId = p.RoomId
toId = p.ToId
} else if p, ok := m.Payload.(schemas.MessagePayloadRoom); ok {
fromId = p.FromId
roomId = p.RoomId
toId = p.ToId
}

m.GetWechaty().Room.Load(roomId).Ready(false)
m.GetWechaty().Contact.Load(roomId).Ready(false)
m.GetWechaty().Contact.Load(roomId).Ready(false)

return false
}

func (m *Message) IsReady() bool {
return m.Payload != nil
}

// Load load message
func (m *Message) Load(id string) Message {
return Message{Id: id}
}

// Create load message alias
func (m *Message) Create(id string) Message {
return m.Load(id)
}

// ToString message to print string
// todo:: no finish
func (m *Message) ToString() string {
return fmt.Sprintf("%s", m.Payload)
}
Loading