songtianyi / wechat-go

go version wechat web api and message framework for building wechat robot
MIT License
1.84k stars 343 forks source link

如何给某个特定的好友/群发消息,前提对方没给我发消息 #12

Open yusank opened 7 years ago

yusank commented 7 years ago

就是说每天或者在特定的情况下给特定的用户发消息,就是通过他的 nickname or wechatid 而不是动态 id 因为动态 id 是对方发起聊天才能获取的好像

songtianyi commented 7 years ago
  1. 找到UserName
    friend := session.Cm.GetContactByPYQuanPin("SONGTIANYI")
  2. 发送消息
    session.SendText("hello", session.Bot.UserName, friend.UserName)

插件里的代码并不是说只有在收消息的时候才能用到,和msg无关的代码都可以拿来在其他地方用

yusank commented 7 years ago

嗯嗯,知道了,但是登录的时候 session.LoginAndServe() 函数内部的 server() 会一直等待消息的传进来,也就是说,我在 main 函数里调用session.LoginAndServe()之后就没办法往后执行

type WeChat struct {
    session     *wxweb.Session
}

func (wx *WeChat)HandleDebug() {
    var err error

    wx.session, err = wxweb.CreateSession(nil, nil, wxweb.TERMINAL_MODE)
    if err != nil {
        logs.Error(err)
        return
    }

    monitor.Register(wx.session)

    wx.session.HandlerRegister.EnableByName("monitor")

    if err := wx.session.LoginAndServe(false); err != nil {
        logs.Error("session exit, %s", err)
    }
    wx.session.SendText("hello", wx.session.Bot.UserName, "filehelper")
}

在这儿,SendText() 函数就一直没执行,

希望作者能解惑,O(∩_∩)O谢谢

songtianyi commented 7 years ago

@yusank 把LoginAndServe用go包起来就行了, 但是有一个问题,在这里你是不知道是否已经登录成功。需要做些改进,写好了告诉你。

songtianyi commented 7 years ago

@yusank

type WeChat struct {
    session     *wxweb.Session
}

func (wx *WeChat)HandleDebug() {
    var err error

    wx.session, err = wxweb.CreateSession(nil, nil, wxweb.TERMINAL_MODE)
    if err != nil {
        logs.Error(err)
        return
    }

    monitor.Register(wx.session)

    wx.session.HandlerRegister.EnableByName("monitor")

    errChan := make(chan error)
    go func(errChan chan error) {
        if err := wx.session.LoginAndServe(false); err != nil {
            logs.Error("session exit, %s", err)
            errChan <- err
        }
    }(errChan)
    tick := time.Tick(2 * time.Second)
    for {
        select {
            case err := <-errChan:
                panic(err)
            case <-tick:
                // check login status
                if wx.session.Cookies != nil && wx.session.Cm != nil {
                    break
                }
        }

    }
    // now it is ok to send message
    wx.session.SendText("hello", wx.session.Bot.UserName, "filehelper")
    <- errChan
}

没有测过,你看懂意思就行

songtianyi commented 7 years ago

@yusank 这个方式并不优雅,后续我会加个watch channel,目前可以这么做。

yusank commented 7 years ago

@songtianyi 嗯,谢谢!看懂了,麻烦你了. 我想到另一种方法就是通过插件的思路,用户给发发特定消息(类似秘钥吧),然后我就记住他,然后就给他发我要发的消息,也是用到了 channel wechat-monitor

songtianyi commented 7 years ago

@yusank 这样方式需要微信端来触发,那这样就和插件模式无异了。 无状态推送是可以做的,我的代码对这方面支持的不好,后边会改进,case暂时开放,改进好了再关闭。

yusank commented 7 years ago

@songtianyi
确实是,需要触发一次微信端。不过目前我的需求应该能满足,毕竟只要不登出的话,可以随时给特定的用户发消息。但是做到无状态发送就最好了。 已经关注你的项目了,坐等更新~😊

miniframework commented 5 years ago

@yusank @songtianyi 什么叫无状态发送,不需要登录么?

yusank commented 5 years ago

@yusank @songtianyi 什么叫无状态发送,不需要登录么?

这里的无状态是说无需目标用户触发,做到随时给任何好友发消息,目前的逻辑是需要用户触发从而得到用户的动态id,才能进行发消息