diff --git a/go.mod b/go.mod index 06b570b..83fbdfd 100644 --- a/go.mod +++ b/go.mod @@ -3,3 +3,5 @@ module github.com/wechaty/go-wechaty require github.com/otiai10/opengraph v1.1.1 go 1.14 + +require github.com/hashicorp/golang-lru v0.5.4 diff --git a/src/wechaty-puppet/puppet.go b/src/wechaty-puppet/puppet.go index 289d0f9..f25edab 100644 --- a/src/wechaty-puppet/puppet.go +++ b/src/wechaty-puppet/puppet.go @@ -1,9 +1,60 @@ 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 { 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 _, message := range messagePayloadList { + 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 +} diff --git a/src/wechaty-puppet/schemas/image.go b/src/wechaty-puppet/schemas/image.go index 17dfad4..f53a221 100644 --- a/src/wechaty-puppet/schemas/image.go +++ b/src/wechaty-puppet/schemas/image.go @@ -3,8 +3,8 @@ package schemas type ImageType uint8 const ( - Unknown ImageType = 0 - Thumbnail ImageType = 1 - HD ImageType = 2 - Artwork ImageType = 3 + ImageTypeUnknown ImageType = 0 + ImageTypeThumbnail = 1 + ImageTypeHD = 2 + ImageTypeArtwork = 3 ) diff --git a/src/wechaty-puppet/schemas/message.go b/src/wechaty-puppet/schemas/message.go index e450b69..8ed34b5 100644 --- a/src/wechaty-puppet/schemas/message.go +++ b/src/wechaty-puppet/schemas/message.go @@ -73,12 +73,16 @@ const ( ) type MessagePayloadBase struct { - Id string - MentionIdList []string - Filename string - Text string - Timestamp string - Type MessageType + 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 + Type MessageType } type MessagePayloadRoom struct { @@ -94,11 +98,13 @@ type MessagePayload struct { MessagePayloadRoom } -type MessageQueryFilter struct { - FromId string - Id string - RoomId string - Text string - ToId string - Type MessageType +type MessageUserQueryFilter struct { + FromId string + Id string + RoomId string + Text string // todo:: RegExp + ToId string + Type MessageType } + +type MessagePayloadFilterFunction func(payload MessagePayload) bool diff --git a/src/wechaty/accessory.go b/src/wechaty/accessory.go index c6c7027..f2390f9 100644 --- a/src/wechaty/accessory.go +++ b/src/wechaty/accessory.go @@ -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 { + SetPuppet(puppet wechatyPuppet.Puppet) + GetPuppet() *wechatyPuppet.Puppet + + SetWechaty(wechaty Wechaty) + GetWechaty() *Wechaty } diff --git a/src/wechaty/type.go b/src/wechaty/type.go new file mode 100644 index 0000000..683f18f --- /dev/null +++ b/src/wechaty/type.go @@ -0,0 +1,9 @@ +package wechaty + +import ( + "github.com/wechaty/go-wechaty/src/wechaty/user" +) + +type Sayable interface { + Say(text string, replyTo ...user.Contact) +} diff --git a/src/wechaty/user/contact.go b/src/wechaty/user/contact.go index de207e1..533ed59 100644 --- a/src/wechaty/user/contact.go +++ b/src/wechaty/user/contact.go @@ -4,4 +4,14 @@ import "github.com/wechaty/go-wechaty/src/wechaty" type Contact struct { wechaty.Accessory + + Id string +} + +func (r *Contact) Load(id string) Contact { + return Contact{} +} + +func (r *Contact) Ready(forceSync bool) bool { + return true } diff --git a/src/wechaty/user/image.go b/src/wechaty/user/image.go index bb9b04e..87f30d9 100644 --- a/src/wechaty/user/image.go +++ b/src/wechaty/user/image.go @@ -13,7 +13,7 @@ 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 instantiated without a puppet!") } return &Images{accessory, id} @@ -21,15 +21,15 @@ func NewImages(id string, accessory wechaty.Accessory) *Images { // 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) } diff --git a/src/wechaty/user/message.go b/src/wechaty/user/message.go new file mode 100644 index 0000000..db9e93d --- /dev/null +++ b/src/wechaty/user/message.go @@ -0,0 +1,106 @@ +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 len(m.Payload.Id) == 0 { + // todo:: should not panic, because not recover + panic("no payload") + } + + m.GetWechaty().Room.Load(m.Payload.RoomId).Ready(false) + m.GetWechaty().Contact.Load(m.Payload.RoomId).Ready(false) + m.GetWechaty().Contact.Load(m.Payload.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) +} diff --git a/src/wechaty/user/room.go b/src/wechaty/user/room.go new file mode 100644 index 0000000..4dcce74 --- /dev/null +++ b/src/wechaty/user/room.go @@ -0,0 +1,13 @@ +package user + +type Room struct { + Id string +} + +func (r *Room) Load(id string) Room { + return Room{} +} + +func (r *Room) Ready(forceSync bool) bool { + return true +} diff --git a/src/wechaty/wechaty.go b/src/wechaty/wechaty.go index 4ea3d37..f198830 100644 --- a/src/wechaty/wechaty.go +++ b/src/wechaty/wechaty.go @@ -1,7 +1,15 @@ package wechaty +import ( + "github.com/wechaty/go-wechaty/src/wechaty/user" +) + // Wechaty type Wechaty struct { + Message user.Message + Image user.Images + Room user.Room + Contact user.Contact } // NewWechaty