WeChatFerry/go/wcf/wcf.go
2023-04-29 10:00:48 +08:00

343 lines
6.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package wcf
import (
logs "github.com/danbai225/go-logs"
"go.nanomsg.org/mangos/v3"
"go.nanomsg.org/mangos/v3/protocol"
"go.nanomsg.org/mangos/v3/protocol/pair1"
_ "go.nanomsg.org/mangos/v3/transport/all"
"google.golang.org/protobuf/proto"
"strconv"
"strings"
)
type Client struct {
add string
socket protocol.Socket
RecvTxt bool
}
func (c *Client) conn() error {
socket, err := pair1.NewSocket()
if err != nil {
return err
}
err = socket.Dial(c.add)
if err != nil {
return err
}
c.socket = socket
return err
}
func (c *Client) send(data []byte) error {
return c.socket.Send(data)
}
func (c *Client) Recv() (*Response, error) {
msg := &Response{}
recv, err := c.socket.Recv()
if err != nil {
return msg, err
}
err = proto.Unmarshal(recv, msg)
return msg, err
}
func (c *Client) IsLogin() bool {
err := c.send(genFunReq(Functions_FUNC_IS_LOGIN).build())
if err != nil {
logs.Err(err)
}
recv, err := c.Recv()
if err != nil {
logs.Err(err)
}
if recv.GetStatus() == 1 {
return true
}
return false
}
func (c *Client) GetSelfWXID() string {
err := c.send(genFunReq(Functions_FUNC_GET_SELF_WXID).build())
if err != nil {
logs.Err(err)
}
recv, err := c.Recv()
if err != nil {
logs.Err(err)
}
return recv.GetStr()
}
func (c *Client) GetMsgTypes() map[int32]string {
err := c.send(genFunReq(Functions_FUNC_GET_MSG_TYPES).build())
if err != nil {
logs.Err(err)
}
recv, err := c.Recv()
if err != nil {
logs.Err(err)
}
return recv.GetTypes().GetTypes()
}
func (c *Client) GetContacts() []*RpcContact {
err := c.send(genFunReq(Functions_FUNC_GET_CONTACTS).build())
if err != nil {
logs.Err(err)
}
recv, err := c.Recv()
if err != nil {
logs.Err(err)
}
return recv.GetContacts().GetContacts()
}
func (c *Client) GetDBNames() []string {
err := c.send(genFunReq(Functions_FUNC_GET_DB_NAMES).build())
if err != nil {
logs.Err(err)
}
recv, err := c.Recv()
if err != nil {
logs.Err(err)
}
return recv.GetDbs().Names
}
func (c *Client) GetDBTables(tab string) []*DbTable {
req := genFunReq(Functions_FUNC_GET_DB_TABLES)
str := &Request_Str{Str: tab}
req.Msg = str
err := c.send(req.build())
if err != nil {
logs.Err(err)
}
recv, err := c.Recv()
if err != nil {
logs.Err(err)
}
return recv.GetTables().GetTables()
}
func (c *Client) ExecDBQuery(db, sql string) []*DbRow {
req := genFunReq(Functions_FUNC_EXEC_DB_QUERY)
q := Request_Query{
Query: &DbQuery{
Db: db,
Sql: sql,
},
}
req.Msg = &q
err := c.send(req.build())
if err != nil {
logs.Err(err)
}
recv, err := c.Recv()
if err != nil {
logs.Err(err)
}
return recv.GetRows().GetRows()
}
func (c *Client) AcceptFriend() int32 {
err := c.send(genFunReq(Functions_FUNC_ACCEPT_FRIEND).build())
if err != nil {
logs.Err(err)
}
recv, err := c.Recv()
if err != nil {
logs.Err(err)
}
return recv.GetStatus()
}
func (c *Client) AddChatRoomMembers(roomId string, wxIds []string) int32 {
req := genFunReq(Functions_FUNC_ADD_ROOM_MEMBERS)
q := Request_M{
M: &AddMembers{Roomid: roomId,
Wxids: strings.Join(wxIds, ",")},
}
req.Msg = &q
err := c.send(req.build())
if err != nil {
logs.Err(err)
}
recv, err := c.Recv()
if err != nil {
logs.Err(err)
}
return recv.GetStatus()
}
func (c *Client) GetUserInfo() *UserInfo {
err := c.send(genFunReq(Functions_FUNC_GET_USER_INFO).build())
if err != nil {
logs.Err(err)
}
recv, err := c.Recv()
if err != nil {
logs.Err(err)
}
return recv.GetUi()
}
/*
SendTxt
@param msg: 消息内容(如果是 @ 消息则需要有跟 @ 的人数量相同的 @
@param receiver: 消息接收人,私聊为 wxidwxid_xxxxxxxxxxxxxx群聊为roomidxxxxxxxxxx@chatroom
@param ates: 群聊时要 @ 的人(私聊时为空字符串),多个用逗号分隔。@所有人 用notify@all必须是群主或者管理员才有权限
*/
func (c *Client) SendTxt(msg string, receiver string, ates []string) int32 {
req := genFunReq(Functions_FUNC_SEND_TXT)
req.Msg = &Request_Txt{
Txt: &TextMsg{
Msg: msg,
Receiver: receiver,
Aters: strings.Join(ates, ","),
},
}
err := c.send(req.build())
if err != nil {
logs.Err(err)
}
recv, err := c.Recv()
if err != nil {
logs.Err(err)
}
return recv.GetStatus()
}
/*
SendIMG
path 绝对路径
*/
func (c *Client) SendIMG(path string, receiver string) int32 {
req := genFunReq(Functions_FUNC_SEND_IMG)
req.Msg = &Request_File{
File: &PathMsg{
Path: path,
Receiver: receiver,
},
}
err := c.send(req.build())
if err != nil {
logs.Err(err)
}
recv, err := c.Recv()
if err != nil {
logs.Err(err)
}
return recv.GetStatus()
}
/*
SendFile
path 绝对路径
*/
func (c *Client) SendFile(path string, receiver string) int32 {
req := genFunReq(Functions_FUNC_SEND_FILE)
req.Msg = &Request_File{
File: &PathMsg{
Path: path,
Receiver: receiver,
},
}
err := c.send(req.build())
if err != nil {
logs.Err(err)
}
recv, err := c.Recv()
if err != nil {
logs.Err(err)
}
return recv.GetStatus()
}
func (c *Client) SendXml(path, content, receiver string, Type int32) int32 {
req := genFunReq(Functions_FUNC_SEND_XML)
req.Msg = &Request_Xml{
Xml: &XmlMsg{
Receiver: receiver,
Content: content,
Path: path,
Type: Type,
},
}
err := c.send(req.build())
if err != nil {
logs.Err(err)
}
recv, err := c.Recv()
if err != nil {
logs.Err(err)
}
return recv.GetStatus()
}
func (c *Client) EnableRecvTxt() int32 {
err := c.send(genFunReq(Functions_FUNC_ENABLE_RECV_TXT).build())
if err != nil {
logs.Err(err)
}
recv, err := c.Recv()
if err != nil {
logs.Err(err)
}
c.RecvTxt = true
return recv.GetStatus()
}
func (c *Client) DisableRecvTxt() int32 {
err := c.send(genFunReq(Functions_FUNC_DISABLE_RECV_TXT).build())
if err != nil {
logs.Err(err)
}
recv, err := c.Recv()
if err != nil {
logs.Err(err)
}
c.RecvTxt = false
return recv.GetStatus()
}
func (c *Client) OnMSG(f func(msg *WxMsg)) error {
socket, err := pair1.NewSocket()
if err != nil {
return err
}
socket.SetOption(mangos.OptionRecvDeadline, 2000)
socket.SetOption(mangos.OptionSendDeadline, 2000)
err = socket.Dial(addPort(c.add))
if err != nil {
return err
}
for c.RecvTxt {
msg := &Response{}
recv, err := socket.Recv()
if err != nil {
return err
}
logs.Info(len(recv))
_ = proto.Unmarshal(recv, msg)
go f(msg.GetWxmsg())
}
return err
}
func NewWCF(add string) (*Client, error) {
if add == "" {
add = "tcp://127.0.0.1:10086"
}
client := &Client{add: add}
err := client.conn()
return client, err
}
type cmdMSG struct {
*Request
}
func (c *cmdMSG) build() []byte {
marshal, _ := proto.Marshal(c)
return marshal
}
func genFunReq(fun Functions) *cmdMSG {
return &cmdMSG{
&Request{Func: fun,
Msg: nil},
}
}
func addPort(add string) string {
parts := strings.Split(add, ":")
port, _ := strconv.Atoi(parts[2])
newPort := port + 1
return parts[0] + ":" + parts[1] + ":" + strconv.Itoa(newPort)
}