Giter Site home page Giter Site logo

openwechat's Introduction

Hi there, I'm eatmoreapple! 👋

Welcome to my GitHub profile! I'm a passionate developer with expertise in golang python. I love creating innovative solutions and contributing to open-source projects.

github stats

Projects

openwechat

juice

Contact Me

I'm always interested in connecting with fellow developers and exploring new opportunities.

You can reach me via email at [email protected] or send me a message on WeChat at eatmoreapple.

Let's collaborate and build amazing things together! ✨

Support Me

If you like my work, please consider supporting me by buying me a coffee.

Buy Me A Coffee

openwechat's People

Contributors

496672097 avatar 757368663 avatar blogbin avatar caiyaonan avatar eatmoreapple avatar gdmec07150942 avatar gowsp avatar helloyiyu avatar igophper avatar itxiaolin avatar ivy-fish avatar ivy8253948 avatar jiajie99 avatar li-xunhuan avatar lixh00 avatar miiw avatar minqpple avatar onism68 avatar sml2h3 avatar suntong avatar suyu7777 avatar taropowder avatar tgnothouse avatar tossp avatar viadroid avatar wenyoufu avatar xdpcs avatar xiaobinqt avatar zangwill avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

openwechat's Issues

the socket is not connected

访问下面网址扫描二维码登录
https://login.weixin.qq.com/qrcode/oeS-atTcCQ==
Get "https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?ticket=A6vgjp-VkZyiDwOGBsc__31Y@qrticket_0&uuid=oeS-atTcCQ==&lang=zh_CN&scan=1624880429": dial tcp 61.241.49.55:443: setsockopt: A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied.

statusScanned(201) error

文档

大佬:能否文档,稍微详细点,可以吗?

Using Message GetFile()

Hi @eatmoreapple,

Do you have sample code how to use the func (*Message) GetFile and save it to disk please?

I assume it'll be another FAQ, and I don't know how you derive a file name for that GetFile. Thx!

Please go fmt your code

In the book Go Programming Language, in the first chapter author strongly recommends using the gofmt tool before each save.

Go takes a strong stance on code formatting . The gofmt tool rewrites code into the standard
format, and the go tool’s fmt subcommand applies gofmt to all the files in the specified package, or the ones in the cur rent directory by default. All Go source files in the book have been
run through gofmt, and you should get into the habit of doing the same for your own code.
Decaring a standard format by fiat eliminates a lot of point less deb ate about trivia and, more
importantly, enables a variety of automated source code transformations that would be
infeasible if arbitrary formatting were allowed.

We need to do that as well, as there has been some recent cases that the entire file seems to have changed, even the actual changes are small, like this one, #72

I'll reformat the whole repo as per the gofmt standard then close this one.

Any concerns?

Need message types

Following up on
#32 (comment)

I wish we can have a way to get the WX message original types. The #32 (comment) has listed many message types in WX raw format, like 3, 5, 51, 54 etc.

I want to be able to print out "Received message type = %s", which prints directly 3, 5, 51, 54 etc, instead of I have to query one by one, is it text? is it image? is it map? etc, etc.

THX!

群消息的群组

Regarding

openwechat/message.go

Lines 352 to 363 in 9eb8483

// 如果是群消息
if m.IsSendByGroup() {
// 将Username和正文分开
data := strings.Split(m.Content, ":<br/>")
m.Content = strings.Join(data[1:], "")
m.senderInGroupUserName = data[0]
receiver, err := m.Receiver()
if err == nil {
displayName := receiver.DisplayName
if displayName == "" {
displayName = receiver.NickName
}

@ivy-fish , I'm trying to implement #64, and I'm wondering the data[0] part in

m.senderInGroupUserName = data[0]

that's group ID, right?
and I remember that you said, group ID change every time after fresh login, right?

All in all, if I want to mock a WX group chat message (from WX server), what would you think the best way to give a group ID that is OK with every/any one?

thx!!

More insight into the login handshaking

Following up on #11,

Please add a debug option so that people can completely trace the login handshaking steps, logging to console what request is being sending over, and what the response and its headers are as well.

Thus when people experience problem similar to #11, by sending the detailed login handshaking trace, we can have a pretty good understanding of what's going on, and might be able to pinpoint the problem right away.

Pls consider. thx

Demo code not working when qq.com is blocked

$ cat /tmp/main.go 
package main

import (
	"fmt"
	"github.com/eatMoreApple/openwechat"
)

func main() {
	bot := openwechat.DefaultBot()

	// 注册消息处理函数
	bot.MessageHandler = func(msg *openwechat.Message) {
		if msg.IsText() {
			fmt.Println("你收到了一条新的文本消息")
		}
	}
	// 注册登陆二维码回调
	bot.UUIDCallback = openwechat.PrintlnQrcodeUrl

	// 登陆
	if err := bot.Login(); err != nil {
		fmt.Println(err)
		return
	}

	// 获取登陆的用户
	self, err := bot.GetCurrentUser()
	if err != nil {
		fmt.Println(err)
		return
	}

	// 获取所有的好友
	friends, err := self.Friends()
	fmt.Println(friends, err)

	// 获取所有的群组
	groups, err := self.Groups()
	fmt.Println(groups, err)

	// 阻塞主goroutine, 知道发生异常或者用户主动退出
	bot.Block()
}

cd /tmp

go build main.go

$ main
Get "https://login.wx.qq.com/jslogin?_=1620437631&appid=wx782c26e4c19acffb&fun=new&lang=zh_CN&redirect_uri=https%3A%2F%2Fwx.qq.com%2Fcgi-bin%2Fmmwebwx-bin%2Fwebwxnewloginpage": EOF

$ go version
go version go1.15.9 linux/amd64

$ lsb_release -a
No LSB modules are available.
Distributor ID:	Debian
Description:	Debian GNU/Linux 10 (buster)
Release:	10
Codename:	buster

It wasn't like this before. What happened? Because this time I'm running under WSL? (was under Linux before)

如何搞定啊大佬?

Error: invalid host

Following up on #11 & #12,

Same code from #9 is still not working for me, despite that I updated openwechat just now.
Neither of my two accounts is working for me.

  • For the first one I got cannot use WX desktop from my phone, while
  • for the second one, I'm getting this:
openwechat
访问下面网址扫描二维码登录
https://login.weixin.qq.com/qrcode/gfVccJbBsA==
invalid host

So still badly need #12 to understand what's going on and where does that invalid host error coming form. thx

Failed to 获取最新的好友

friends, err := self.Friends(true)

Friends:可接受bool值来判断是否获取最新的好友

I'm using self.Friends(true) but still unable to 获取最新的好友 -- The friend list that I got is still old, even after my friend-editing has done for 1+ hours.

List of projects using openwechat

Hi @eatmoreapple,

Do you think it is a good idea to list all open source projects that are using openwechat at the end of Readme or in wiki?

If OK, I can get the ball rolling by submit the first PR.

cheers

无需重复扫码登录?

The "无需重复扫码登录" in Readme, what does it exactly mean?

I run my openwechat client, ^C to quit, and then run again.

  • With wechaty, I indeed do not need to login again, yet,
  • With code from #9, I still need to login again --
$ openwechat
访问下面网址扫描二维码登录
https://login.weixin.qq.com/qrcode/4f5GhMUjNw==
^C

OnGroupByGroupName() or OnGroupByGroupID()

根据群名是否匹配的消息处理函数,只能注册 OnGroupByGroupName. But the problem is that sometime the group changes its name from time to time.

The Group ID never change, right? If so, that would be a better/safer option.

FromUserName and ToUserName

I tried to print out FromUserName and ToUserName from the Message struct

openwechat/message.go

Lines 45 to 49 in 5120404

FromUserName string
OriContent string
StatusNotifyUserName string
Ticket string
ToUserName string

but all I got is:

from=@@d68e3047e7b651cca.....bae9096c1780d128478 [email protected]

why it's like that, instead of the actual WX User Names?

HTML in 收到的文本消息

收到文本消息: 高兴<span class="emoji emoji1f604"></span> 生气<span class="emoji emoji1f64e"></span> 点赞<span class="emoji emoji1f44d"></span>

I've fixed that in nodejs, will fix it soon in Go...

每天晚上自动掉线

2021/07/01 00:46:02 exit with : Get "https://webpush.wx.qq.com/cgi-bin/mmwebwx-b
in/synccheck?_=1625071562&deviceid=e808322456474126&r=1625071562&sid=40nGHnRY5FJ
YuVzQ&skey=%40crypt_b940ac04_4217d3d7187588aa0b977f013429122c&synckey=1_73832721
6%7C2_738327218%7C3_738327163%7C11_738327174%7C19_13599%7C201_1625070781%7C203_1
625059066%7C206_101%7C1000_1625057416%7C1001_1625057420&uin=47260****": net/http
: HTTP/1.x transport connection broken: malformed HTTP status code "0"

2021/07/02 00:19:11 exit with : Get "https://webpush.wx.qq.com/cgi-bin/mmwebwx-b
in/synccheck?_=1625156351&deviceid=e473567460463755&r=1625156351&sid=SV82nd8KfFh
4ZhQK&skey=%40crypt_b940ac04_16e01eeef2f77d0cbc7c4c971fdbdc94&synckey=1_73832724
3%7C2_738327394%7C3_738327163%7C11_738327174%7C19_13614%7C201_1625152664%7C203_1
625059066%7C206_101%7C1000_1625143120%7C1001_1625143820&uin=47260****": net/http
: HTTP/1.x transport connection broken: malformed HTTP status code "0"

Caller and Client

Just curious,

  • what are the Caller and Client?
  • why a certain function belong to Caller or Client?

301 response missing Location header

Following up on #5 & #6,

Thanks for icepie's effort, I've made it pass the login scan step.
But this is what I'm getting now:

访问下面网址扫描二维码登录
https://login.weixin.qq.com/qrcode/obQ...Ztg==
Get "https://web.wechat.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?ticket=ArU...V3NX@qrticket_0&uuid=obQ...Ztg==&lang=zh_CN&scan=1620481397": 301 response missing Location header

I'm logging in from oversea BTW. That might be the reason why WX asking for "Location header".

I've tried to use KW of mmwebwx-bin or webwxnewloginpage to search in this repo, but didn't find anything.
So I cannot tell where the problem comes from as of now.

Please take a look.

msg.ReplyText() not working

Using code from #9 with:

	// 注册消息处理函数
	bot.MessageHandler = func(msg *openwechat.Message) {
		if msg.IsText() {
			if msg.Content == "ping" {
				msg.ReplyText("pong")
				fmt.Println("回文本消息", msg.Content)
			} else  {
				fmt.Println("收到文本消息", msg.Content)
			}
		}
	}

When I got ping (sent from myself), I can see "回文本消息 ping" being printed on console, but I was never able to get that pong back.

New openwechat org

Reopen from #20,

I still think it is a good idea to create a new openwechat GH organization, put openwechat under it, and collect all different sample/demo projects there as well.

So the next person who comes along, can just pick and choose which sample/demo projects to start with, or know which demo projects to turn to troubleshoot (without the need to hunt for it), like having more insight into the login handshaking.

New error handling logic

This is how I used to do error handling:
https://github.com/go-openwechat/owc-insight/blob/3463e407dddce8b0187ec2bc9ec77d031540ef31/main.go#L94-L107

	bot.GetMessageErrorHandler = func(err error) {
		t := time.Now()
		if t.Sub(lastError) < 30*time.Minute {
			count++
		} else {
			count = 1
		}
		// 如果发生了三次错误,那么直接退出
		if count > 3 {
			abortOn("Too many errors", err)
		}
		logIf(0, "catch-and-skip", "count", count, "err", err)
		lastError = time.Now()
	}

But the error-resuming is not working any more, after the recent error handling logic change.

I saw in my log:

TS=0731T22:42:57 Msg=catch-and-skip count=1 err="Post \"https://web.wechat.com/cgi-bin/mmwebwx-bin/webwxsync?pass_ticket=Dg%252BlKiL53lu3OWQoX%252BbrpGPBCS%252FEz6YdHeW431WCvfU%253D&sid=fzHyectwb4p0PXWd&skey=%40crypt_60175222_bca13b8cf30a7748a9a71edf111ea98d\": EOF"

And that is the last entry in my log. Nothing else logged afterwards, yet I know lots happened afterwards.

So, what's the new error handling logic supposed to be? Thx.

Logging messages in its raw format

Following up on #31, if I want to collect different raw message strings received by openwechat and display them in terminal, what shall I do?

The purpose of this is that, when I got an attachment, say a .pdf file, I want to see if the file name is anywhere within the message itself. And same for other cases like getting pictures, or voices, etc.

You can use code in README or from #9 as the starting point. THX!

Fully automate our tests

Last time I did a test under openwechat using

go test ./...

It just hang there doing nothing. Then I realized that the first step is to login into WX, and the test waits there for me to do it.

I'm thinking that doing fully automated tests with a mock WX server should not be that difficult. Here are the things that I find that might be useful for it:

Mocking HTTP Requests in Golang
https://www.thegreatcodeadventure.com/mocking-http-requests-in-golang/

Testing Your (HTTP) Handlers in Go
https://blog.questionable.services/article/testing-http-handlers-go/

The awesomeness of the httptest package in Go
https://gianarb.it/blog/golang-mockmania-httptest

OnLogout()?

Need OnLogout() callback (回调函数) so that people can do their own clean up.

Comments?

BUG: SenderInGroup 处理某些消息时异常

目的:获取发送者名称
代码:

fromName = sender.NickName
if msg.IsSendByGroup() {
	sender, err := msg.SenderInGroup()
	if err != nil {
		fmt.Println(fmt.Printf("b: %v", msg))
		fmt.Println(fmt.Printf("b: %s", err))
		return
	}

	finalFromName = sender.NickName
}

打印出的错误日志:

b: &{false {0 } AppMessageType(0) 0 0 1 0 0 系统消息 4 0 0 0 1628064082 4196907953977413027 0  4196907953977413027     @@bb8a392b94ddd9700fab41540d0422c9b16adafa498820e4896ed97594d508ed    @ce1697cb3776797cac2220c79a0b6db0  "<span class="emoji emoji1f3c3"></span>干饭人🥣" 拍了拍 "摸鱼大户 WYZ" {0 0 0 0 0 0        } 0xc00012c000 {{0 0} 0 0 0 0} <nil> map[]}374 <nil>
b: no such user found21 <nil>
b: &{false {0 } AppMessageType(0) 0 0 1 0 0 系统消息 4 0 0 0 1628064088 2271488550016042960 0  2271488550016042960     @@bb8a392b94ddd9700fab41540d0422c9b16adafa498820e4896ed97594d508ed    @ce1697cb3776797cac2220c79a0b6db0  "<span class="emoji emoji1f3c3"></span>干饭人🥣" 拍了拍 "undefined" 的狗被咬了一口[庆祝] {0 0 0 0 0 0        } 0xc00012c000 {{0 0} 0 0 0 0} <nil> map[]}397 <nil>
b: no such user found21 <nil>
b: &{false {0 } AppMessageType(0) 0 0 1 0 0 系统消息 4 0 0 0 1628064087 3299594708350225420 0  3299594708350225420     @@bb8a392b94ddd9700fab41540d0422c9b16adafa498820e4896ed97594d508ed    @ce1697cb3776797cac2220c79a0b6db0  "<span class="emoji emoji1f3c3"></span>干饭人🥣" 拍了拍 "杨丶小贱很邪恶" ,然后吃了一口屎 {0 0 0 0 0 0        } 0xc00012c000 {{0 0} 0 0 0 0} <nil> map[]}404 <nil>
b: no such user found21 <nil>
b: &{false {0 } AppMessageType(0) 0 0 1 0 0 系统消息 4 0 0 0 1628064834 6792327054925259398 0  6792327054925259398     @@56af87722699cbfcc6cfa903a182ea6da25328ad3cdf7acf15b3e4408dc63aa8    @ce1697cb3776797cac2220c79a0b6db0  "畅捷通开放平台-运营-翟政辉"邀请"用友软件@杨鹏"加入了群聊 {0 0 0 0 0 0        } 0xc00012c000 {{0 0} 0 0 0 0} <nil> map[]}374 <nil>
b: no such user found21 <nil>
b: &{false {0 } AppMessageType(0) 0 0 1 0 0 系统消息 4 0 0 0 1628065015 7779435549229314372 0  7779435549229314372     @@56af87722699cbfcc6cfa903a182ea6da25328ad3cdf7acf15b3e4408dc63aa8    @ce1697cb3776797cac2220c79a0b6db0  "用友软件@杨鹏"邀请"无名"加入了群聊 {0 0 0 0 0 0        } 0xc00012c000 {{0 0} 0 0 0 0} <nil> map[]}342 <nil>
b: no such user found21 <nil>
b: &{false {0 } AppMessageType(0) 0 0 1 0 0 系统消息 4 0 0 0 1628065147 4309966679970233175 0  4309966679970233175     @@56af87722699cbfcc6cfa903a182ea6da25328ad3cdf7acf15b3e4408dc63aa8    @ce1697cb3776797cac2220c79a0b6db0  "用友软件@杨鹏"邀请"十二"加入了群聊 {0 0 0 0 0 0        } 0xc00012c000 {{0 0} 0 0 0 0} <nil> map[]}342 <nil>
b: no such user found21 <nil>

因此,针对:拍一拍、邀请加入群聊消息类型,不能使用SenderInGroup正确获取消息发送者。

热登陆 cookie 失效

Following on #7 (comment), for my

Error: not login check

https://github.com/eatMoreApple/openwechat/blob/b2178d32a28d61fb195adbc1575d574afbaed49f/items.go#L155-L156

I saw that 热登陆 cookie only get updated when trying to 获取新的消息:

更新SyncKey并且重新存入storage
https://github.com/eatMoreApple/openwechat/blob/b2178d32a28d61fb195adbc1575d574afbaed49f/bot.go#L258-L259

which is called from

https://github.com/eatMoreApple/openwechat/blob/b2178d32a28d61fb195adbc1575d574afbaed49f/bot.go#L224-L240

The problem is that when an account doesn't have any new messages for a prolong time, the cookie will 失效, because it hasn't been updated for a prolong time.

Do you think saving (重新存入storage) it periodically in 轮训请求 will prolong its life span?

handshaking protocol: synccheck

Following up for the possible reasons for #25

Is the following pushed from Wx server or the wx client actively requested?
image

Such synccheck is happening every 25 seconds:

image

image

image

image

image

Here is its detailed request:

GET https://webpush.wx2.qq.com/cgi-bin/mmwebwx-bin/synccheck?r=1627614927522&skey=%40crypt_a407bcc4_585ada7cff952132e6c320f7b8f0a125&sid=8x%2FVZhcaFHEJSLnF&uin=355967626&deviceid=e609806691702713&synckey=1_721762222%7C2_721762262%7C3_721762082%7C11_721761120%7C19_14974%7C201_1627611121%7C206_103%7C1000_1627600689%7C1001_1627601132&_=1627527016632 HTTP/1.1
Host: webpush.wx2.qq.com
Connection: keep-alive
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) ??/2.0.0 Chrome/59.0.3071.115 Electron/1.8.8 Safari/537.36
Accept: */*
Referer: https://wx2.qq.com/?target=t
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN
Cookie: webwxuvid=b167ead149dff64ee...a638b714c02a4628bf480b; webwx_auth_ticket=CIsBEKW7p8..UYNVNSr+ZOpSqNvSPC9YD+8qAp41CE+G2zJZQ6db8rmxwM=; wxpluginkey=1627600689; wxuin=355967626; wxsid=8x/VZhcaFHEJSLnF; webwx_data_ticket=gS...7r6t/v6...lZ1

The differences between consequent requests are:

image

image

image

image

I.e., the parameter of r, the last _ and even deviceid is changing all the time.

  • If they are pushed from Wx server then it might be OK to ignore them, but
  • if it is the wx client that needs actively requesting it, then 自动掉线 might not be solvable unless such handshaking protocol is carried out by openwechat

无法获取群组中的用户头像

for _,memberItem := range group.MemberList { fmt.Println(memberItem.NickName +" : " + memberItem.HeadImgUrl) memberItem.SaveAvatar(memberItem.UserName + ".png") }
memberItem.HeadImgUrl 没有数据,保存头像的时候也就会报错了

New openwechat org?

Following up on #12, which I'm planning to put your suggestions into real code/project,

What would you say that we create a new openwechat GH organization, put openwechat under it, and collect all different sample/demo projects there as well?

So the next person who comes along, can just pick and choose which sample/demo projects to start with, or know which demo projects to turn to troubleshoot (without the need to hunt for it), like having more insight into the login handshaking.

Comments?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.