This commit is contained in:
eatMoreApple 2021-06-24 08:18:03 +08:00
parent e07ab1059a
commit 5a631356a3
9 changed files with 1395 additions and 514 deletions

1
.gitignore vendored
View File

@ -14,3 +14,4 @@
# Dependency directories (remove the comment below to include it)
# vendor/
.idea
build

20
Makefile Normal file
View File

@ -0,0 +1,20 @@
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = source
BUILDDIR = build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

View File

@ -1,514 +0,0 @@
## openwechat
### 安装
```shell
go get github.com/eatMoreApple/openwechat
```
### 用户登陆
#### 创建Bot对象
登陆之前需要先创建`Bot`对象来登录
```go
bot := openwechat.DefaultBot()
// 注册消息处理函数
bot.MessageHandler = func(msg *openwechat.Message) {
if msg.IsText() {
fmt.Println("你收到了一条新的文本消息")
}
}
// 注册登陆二维码回调
bot.UUIDCallback = openwechat.PrintlnQrcodeUrl
```
#### 普通登陆
每次运行程序需要重新扫码登录
```go
bot.Login()
```
#### 热登陆
单位时间内运行程序不需要重新扫码登录,直到用户主动退出导致凭证信息失效
```go
storage := openwechat.NewJsonFileHotReloadStorage("storage.json")
bot.HotLogin(storage)
```
#### Desktop模式
`Desktop`可突破部分用户的登录限制,如果普通登陆不上,可尝试使用该模式
```go
bot := openwechat.DefaultBot(openwechat.Desktop)
```
### 消息处理
可通过绑定在`Bot`上的消息回调函数来对消息进行定制化处理
```go
bot := openwechat.DefaultBot(openwechat.Desktop)
messageHandle := func(msg *openwechat.Message) {
if msg.IsText() {
fmt.Println("你收到了一条新的文本消息")
}
}
// 注册消息处理函数
bot.MessageHandler = messageHandle
```
#### 回复文本消息
```go
msg.ReplyText("test message")
```
#### 回复图片消息
```go
file, _ := os.Open("test.png")
defer file.Close()
msg.ReplyImage(file)
```
#### 回复文件消息
```go
file, _ := os.Open("your file name")
defer file.Close()
msg.ReplyFile(file)
```
#### 获取消息的发送者
```go
sender, err := msg.Sender()
```
#### 获取消息的接受者
```go
receiver, err := msg.SenderInGroup()
```
#### 判断消息是否由好友发送
```go
msg.IsSendByFriend() // bool
```
#### 判断消息是否由群组发送
```go
msg.IsSendByGroup() // bool
```
#### 判断消息类型
```go
msg.IsText() // 是否为文本消息
msg.IsPicture() // 是否为图片消息
msg.IsVoice() // 是否为语音消息
msg.IsVideo() // 是否为视频消息
msg.IsCard() // 是否为名片消息
msg.IsFriendAdd() // 是否为添加好友消息
msg.IsRecalled() // 是否为撤回消息
msg.IsTransferAccounts() // 判断当前的消息是不是微信转账
msg.IsSendRedPacket() // 是否发出红包
msg.IsReceiveRedPacket() // 判断当前是否收到红包
```
#### 判断消息是否携带文件
```go
msg.HasFile() bool
```
#### 获取消息中的文件
自行读取response处理
```go
resp, err := msg.GetFile() // *http.Response, error
```
#### Card消息
```go
card, err := msg.Card()
if err == nil {
fmt.Println(card.Alias) // 获取名片消息中携带的微信号
}
```
#### 同意好友请求
该方法只在消息类型为`IsFriendAdd``true`的时候生效
```go
msg.Agree()
msg.Agree("我同意了你的好友请求")
```
#### Set
从消息上下文中设置值(协成安全)
```go
msg.Set("hello", "world")
```
#### Get
从消息上下文中获取值(协成安全)
```go
value, exist := msg.Get("hello")
```
#### 消息分发
```go
type MessageDispatcher interface {
Dispatch(msg *Message)
}
func DispatchMessage(dispatcher MessageDispatcher) func(msg *Message) {
return func(msg *Message) { dispatcher.Dispatch(msg) }
}
```
消息分发处理接口跟 DispatchMessage 结合封装成 MessageHandler
##### MessageMatchDispatcher
> MessageMatchDispatcher impl MessageDispatcher interface
###### example
```go
dispatcher := NewMessageMatchDispatcher()
dispatcher.OnText(func(msg *Message){
msg.ReplyText("hello")
})
bot := DefaultBot()
bot.MessageHandler = DispatchMessage(dispatcher)
```
###### 注册消息处理函数
```go
dispatcher.RegisterHandler(matchFunc matchFunc, handlers ...MessageContextHandler)
```
`matchFunc`为匹配函数,返回为`true`代表执行对应的`MessageContextHandler`
###### 注册文本消息处理函数
```go
dispatcher.OnText(handlers ...MessageContextHandler)
```
###### 注册图片消息的处理函数
```go
dispatcher.OnImage(handlers ...MessageContextHandler)
```
###### 注册语音消息的处理函数
```go
dispatcher.OnVoice(handlers ...MessageContextHandler)
```
###### 注册消息类型为`好友添加`的处理函数
```go
dispatcher.OnFriendAdd(handlers ...MessageContextHandler)
```
###### 注册消息类型为`Card`的处理函数
```go
dispatcher.OnCard(handlers ...MessageContextHandler)
```
### 登陆用户
登陆成功后调用
```go
self, err := bot.GetCurrentUser()
```
#### 文件传输助手
```go
fileHelper, err := self.FileHelper()
```
#### 好友列表
```go
friends, err := self.Friends()
```
#### 群组列表
注:群组列表只显示手机端微信:通讯录:群聊里面的群组,若想将别的群组加入通讯录,点击群组,设置为`保存到通讯录`即可(安卓机)
```go
groups, err := self.Groups()
```
#### 公众号列表
```go
mps, err := self.Mps()
```
### 好友对象
好友对象通过调用`self.Friends()`获取
```go
friends, err := self.Friends()
```
#### 搜索好友
根据条件查找好友,返回好友列表
```go
friends.SearchByRemarkName(1, "多吃点苹果") // 根据备注查找, limit 参数为限制查找的数量
friends.SearchByNickName(1, "多吃点苹果") // 根据昵称查找
friends.Search(openwechat.ALL, func(friend *openwechat.Friend) bool {
return friend.Sex == openwechat.MALE
}) // 自定义条件查找(可多个条件)
```
#### 获取第一个好友
返回好友对象
```go
firend := friends.First() // 可能为nil
```
#### 获取最后一个好友
```go
firend := friends.Last() // 可能为nil
```
#### 好友数量统计
```go
count := friends.Count()
```
#### 发送消息
```go
friend := friends.First()
if friend != nil {
friend.SendText("hello")
// SendFile 发送文件
// SendImage 发送图片
}
```
#### 设置备注消息
```go
friend := friends.First()
if friend != nil {
friend.SetRemarkName("remark name")
}
```
#### 拉入群聊
```go
groups, _ := self.Groups()
friend := friends.First() // ensure it won't be bil
friend.AddIntoGroup(groups...)
```
### 群组对象
好友对象通过调用`self.Groups()`获取
```go
groups, err := self.Groups()
```
#### 发送消息
```go
group := groups.First()
if group != nil {
group.SendText("hello")
// SendFile 发送文件
// SendImage 发送图片
}
```
#### 获取群员列表
```go
group := groups.First()
if group != nil {
members, err := group.Members()
}
```
#### 拉好友入群
```go
group := groups.First() // ensure it won't be bil
group.AddFriendsIn(friend1, friend2)
```
### Emoji
emoji表情可当做一个文本消息发送具体见`openwechat.Emoji`
```go
friend.SendText(openwechat.Emoji.Doge) // [旺柴]
```
#### 格式化带emoji表情的昵称
```go
fmt.Println(openchat.FormatEmoji(`多吃点苹果<span class="emoji emoji1f34f"></span>`))
```
**更多功能请在源码中探索**
```go
// TODO ADD MORE SUPPORT
```

35
make.bat Normal file
View File

@ -0,0 +1,35 @@
@ECHO OFF
pushd %~dp0
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=source
set BUILDDIR=build
if "%1" == "" goto help
%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.http://sphinx-doc.org/
exit /b 1
)
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
goto end
:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
:end
popd

268
source/bot.md Normal file
View File

@ -0,0 +1,268 @@
# Bot对象
`Bot`对象负责处理网络请求和消息回调以及登录登出的用户行为,一个`Bot`对应一个登录的微信号。
### 创建Bot对象
在登录微信之前需要创建一个`Bot`对象。
```go
bot := openwechat.DefaultBot()
```
使用默认的构造方法`DefaultBot`来创建一个`Bot`对象。
### 登陆二维码回调
但仅仅是这样我们依然无法登录, 我们平常登录微信都需要用手机扫描二维码登录,所以我们得知道需要扫描哪张二维码,最后还需要为它绑定一个登录二维码的回调函数。
```go
// 注册登陆二维码回调
bot.UUIDCallback = openwechat.PrintlnQrcodeUrl
```
`PrintlnQrcodeUrl`这个函数做的事情很简单,就是将我们需要扫码登录的二维码链接打印打控制台上,这样我们就知道去扫描哪张二维码登录了。
可以自定义`UUIDCallback`来实现自己的逻辑。
如:将登录的二维码打印到控制台。
```go
package main
import (
"fmt"
"github.com/skip2/go-qrcode"
"github.com/eatMoreApple/openwechat"
)
func ConsoleQrCode(uuid string) {
q, _ := qrcode.New("https://login.weixin.qq.com/l/"+uuid, qrcode.Low)
fmt.Println(q.ToString(true))
}
func main() {
bot := openwechat.DefaultBot()
bot.UUIDCallback = ConsoleQrCode
bot.Login()
}
```
虽然最终打印的结果肉眼看上去有点不尽人意,但手机也还能够识别...
### 登录
#### 普通登录
上面的准备工作做完了,下面就可以登录,直接调用`Bot.Login`即可。
```go
bot.Login()
```
登录会返回一个`error`,即登录失败的原因。
#### 热登录
每次执行普通登录都需要扫码,在调试一些功能的时候需要反复编译,这样会很麻烦。
热登录可以只用扫码一次,后面在单位时间内重启程序也不会再要求扫码
```go
// 创建热存储容器对象
reloadStorage := openwechat.NewJsonFileHotReloadStorage("storage.json")
// 执行热登录
bot.HotLogin(reloadStorage)
```
`HotLogin`需要接受一个`热存储容器对象`来调用。`热存储容器`用来保存登录的会话信息,本质是一个接口类型
```go
// 热登陆存储接口
type HotReloadStorage interface {
GetHotReloadStorageItem() HotReloadStorageItem // 获取HotReloadStorageItem
Dump(item HotReloadStorageItem) error // 实现该方法, 将必要信息进行序列化
Load() error // 实现该方法, 将存储媒介的内容反序列化
}
```
`NewJsonFileHotReloadStorage`简单实现了该接口,它采用`JSON`的方式存储会话信息。
实现这个接口,实现你自己的存储方式。
### 扫码回调
在pc端微信上我们打开手机扫码进行登录的时候只扫描二维码但不点击确认微信上也能够显示当前扫码用户的头像并提示用户登录确认。
通过对`bot`对象绑定扫码回调即可实现对应的功能。
```go
bot.ScanCallBack = func(body []byte) { fmt.Println(string(body)) }
```
用户扫码后body里面会携带用户的头像信息。
**注**:绑定扫码回调须在登录前执行。
### 登录回调
`bot`对象绑定登录
```go
bot.LoginCallBack = func(body []byte) {
fmt.Println(string(body))
// to do your business
}
```
登录回调的参数就是当前客户端需要跳转的链接,可以不用关心它。
登录回调函数可以当做一个信号处理,表示当前扫码登录的用户已经确认登录。
### 桌面模式
`DefaultBot`默认是与网页版微信进行交互部分用户的网页版wx可能已经被限制登录了。
这时候可以尝试使用`桌面模式`进行登录。
```go
bot := openwechat.DefaultBot(openwechat.Desktop)
```
别的逻辑不用改直接在创建bot的时候加一个参数就行了。
如果桌面模式还登录不上,请检查你的微信号是不是刚刚申请。
### 消息处理
在用户登录后需要实时接受微信发送过来的消息。
很简单,给`BOT`对象绑定一个消息回调函数就行了。
```go
// 注册消息处理函数
bot.MessageHandler = func(msg *openwechat.Message) {
if msg.IsText() && msg.Content == "ping" {
msg.ReplyText("pong")
}
}
```
所有接受的消息都通过`Bot.MessageHandler`来处理。
基于这个回调函数,可以对消息进行多样化处理
```go
dispatcher := openwechat.NewMessageMatchDispatcher()
// 只处理消息类型为文本类型的消息
dispatcher.OnText(func(msg *Message){
msg.ReplyText("hello")
})
// 注册消息回调函数
bot.MessageHandler = openwechat.DispatchMessage(dispatcher)
```
`openwechat.DispatchMessage`会将消息转发给`dispatcher`对象处理
#### MessageMatchDispatcher
##### 构造方法
```go
openwechat.NewMessageMatchDispatcher()
```
##### 注册消息处理函数
```go
// 注册消息处理函数
func (m *MessageMatchDispatcher) RegisterHandler(matchFunc matchFunc, handlers ...MessageContextHandler)
// 消息匹配函数
type matchFunc func(*Message) bool
// 消息处理函数
type MessageContextHandler func(ctx *MessageContext)
```
`matchFunc`:接受当前收到的消息对象,并返回`bool`值,返回`true`则表示处理当前的消息
`RegisterHandler`:接受一个`matchFunc`和不定长的消息处理函数,如果`matchFunc`返回为`true`,则表示运行对应的处理函数组。
##### OnText
注册处理消息类型为文本类型的消息
```go
func (m *MessageMatchDispatcher) OnText(handlers ...MessageContextHandler)
```
##### OnImage
注册处理消息类型为图片类型的消息
```golang
func (m *MessageMatchDispatcher) OnImage(handlers ...MessageContextHandler)
```
##### OnVoice
注册处理消息类型为语言类型的消息
```go
func (m *MessageMatchDispatcher) OnVoice(handlers ...MessageContextHandler)
```
##### [更多请点击查看源码](https://github.com/eatMoreApple/openwechat/blob/main/message_handle.go)
### 获取登录后的用户
```go
self, err := bot.GetCurrentUser()
```
**注**:该方法在登录成功后调用
[详见`Self`对象](./user.md)
### 阻塞主程序
```go
bot.Block()
```
该方法会一直阻塞,直到用户主动退出或者网络请求发生错误

64
source/conf.py Normal file
View File

@ -0,0 +1,64 @@
# Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
# -- Path setup --------------------------------------------------------------
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
# import os
# import sys
# sys.path.insert(0, os.path.abspath('.'))
# -- Project information -----------------------------------------------------
project = 'openwechat'
copyright = '2021, eatMoreApple'
author = 'eatMoreApple'
# The full version, including alpha/beta/rc tags
release = 'v1'
# -- General configuration ---------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'recommonmark',
'sphinx_markdown_tables'
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = 'zh_CN'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = []
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'sphinx_rtd_theme'
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']

24
source/index.rst Normal file
View File

@ -0,0 +1,24 @@
.. openwechat documentation master file, created by
sphinx-quickstart on Sun Jun 20 09:35:19 2021.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to openwechat's documentation!
======================================
.. toctree::
:maxdepth: 2
bot
user
message
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

365
source/message.md Normal file
View File

@ -0,0 +1,365 @@
# 消息
### 接受消息
被动接受的消息对象,由微信服务器发出
消息对象通过绑定在`bot`上的消息回调函数获取
```go
bot.MessageHandler = func(msg *openwechat.Message) {
if msg.IsText() && msg.Content == "ping" {
msg.ReplyText("pong")
}
}
```
以下简写为`msg`
#### 消息内容
```go
msg.Content // 获取消息内容
```
通过访问`Content`属性可直接获取消息内容
由于消息分为很多种类型,它们都共用`Content`属性。一般当消息类型问文本类型的时候,我们才会去访问`Content`属性。
#### 消息类型判断
下面的判断消息类型的方法均返回`bool`
##### 文本消息
```go
msg.IsText()
```
##### 图片消息
```go
msg.IsPicture()
```
##### 位置消息
```go
msg.IsMap()
```
##### 语音消息
```go
msg.IsVoice()
```
##### 添加好友请求
```go
msg.IsFriendAdd()
```
##### 名片消息
```go
msg.IsCard()
```
##### 视频消息
```go
msg.IsVideo()
```
##### 是否被撤回
```go
msg.IsRecalled()
```
##### 系统消息
```go
msg.IsSystem()
```
##### 收到微信转账
```go
msg.IsTransferAccounts()
```
##### 发出红包(自己发出)
```go
msg.IsSendRedPacket()
```
##### 收到红包
```go
msg.IsReceiveRedPacket()
```
但是不能领取!
#### 获取消息的发送者
```go
sender, err := msg.Sender()
```
如果是群聊消息,该方法返回的是群聊对象(需要自己将`User`转换为`Group`对象)
#### 获取消息的接受者
```go
receiver, err := msg.Receiver()
```
#### 获取消息在群里面的发送者
```go
sender, err := msg.SenderInGroup()
```
获取群聊中具体发消息的用户,前提该消息必须来自群聊。
#### 是否由自己发送
```go
msg.IsSendBySelf()
```
#### 消息是否由好友发出
```go
msg.IsSendByFriend()
```
#### 消息是否由群聊发出
```go
msg.IsSendByGroup()
```
#### 回复文本消息
```go
msg.ReplyText("hello")
```
#### 回复图片消息
```go
img, _ := os.Open("your file path")
defer img.Close()
msg.ReplyImage(img)
```
#### 回复文件消息
```go
file, _ := os.Open("your file path")
defer file.Close()
msg.ReplyFile(file)
```
#### 获取消息里的其他信息
##### 名片消息
```go
card, err := msg. Card()
```
该方法调用的前提为`msg.IsCard()`返回为`true`
名片消息可以获取该名片中的微信号
```go
alias := card.Alias
```
`card`结构
```go
// 名片消息内容
type Card struct {
XMLName xml.Name `xml:"msg"`
ImageStatus int `xml:"imagestatus,attr"`
Scene int `xml:"scene,attr"`
Sex int `xml:"sex,attr"`
Certflag int `xml:"certflag,attr"`
BigHeadImgUrl string `xml:"bigheadimgurl,attr"`
SmallHeadImgUrl string `xml:"smallheadimgurl,attr"`
UserName string `xml:"username,attr"`
NickName string `xml:"nickname,attr"`
ShortPy string `xml:"shortpy,attr"`
Alias string `xml:"alias,attr"` // Note: 这个是名片用户的微信号
Province string `xml:"province,attr"`
City string `xml:"city,attr"`
Sign string `xml:"sign,attr"`
Certinfo string `xml:"certinfo,attr"`
BrandIconUrl string `xml:"brandIconUrl,attr"`
BrandHomeUr string `xml:"brandHomeUr,attr"`
BrandSubscriptConfigUrl string `xml:"brandSubscriptConfigUrl,attr"`
BrandFlags string `xml:"brandFlags,attr"`
RegionCode string `xml:"regionCode,attr"`
}
```
##### 获取已撤回的消息
```go
revokeMsg, err := msg.RevokeMsg()
```
该方法调用成功的前提是`msg.IsRecalled()`返回为`true`
撤回消息的结构
```go
type RevokeMsg struct {
SysMsg xml.Name `xml:"sysmsg"`
Type string `xml:"type,attr"`
RevokeMsg struct {
OldMsgId int64 `xml:"oldmsgid"`
MsgId int64 `xml:"msgid"`
Session string `xml:"session"`
ReplaceMsg string `xml:"replacemsg"`
} `xml:"revokemsg"`
}
```
#### 同意好友请求
```go
msg.Agree()
// msg.Agree("我同意了")
```
该方法调用成功的前提是`msg.IsFriendAdd()`返回为`true`
#### 设置消息的上下文
用于多个消息处理函数之间的通信,并且是协程安全的。
##### 设置值
```go
msg.Set("hello", "world")
```
##### 获取值
```go
value, exist := msg.Get("hello")
```
### 已发送消息
已发送消息指当前用户发送出去的消息
每次调用发送消息的函数都会返回一个`SentMessage`对象
```go
sentMsg, err := msg.ReplyText("hello") // 通过回复消息获取
// sentMsg, err := friend.SendText("hello") // 向好友对象发送消息获取
// and so on
```
#### 撤回消息
撤回刚刚发送的消息撤回消息的有效时间为2分钟超过了这个时间则无法撤回
```go
sentMsg.Revoke()
```
#### 转发给好友
```go
sentMsg.ForwardToFriends(friend1, friend2)
```
将刚发送的消息转发给好友
#### 转发给群聊
```go
sentMsg.ForwardToGroups(group1, group2)
```
将刚发送的消息转发给群聊
### Emoji表情
openwechat提供了微信全套`emoji`表情的支持
`emoji`表情全部维护在`openwechat.Emoji`结构体上
emoji表情可以通过发送`Text`类型的函数发送
```go
firend.SendText(openwechat.Emoji.Doge) // 发送狗头表情
msg.ReplyText(openwechat.Emoji.Awesome) // 发送666的表情
```

618
source/user.md Normal file
View File

@ -0,0 +1,618 @@
# 用户
抽象的用户结构: 好友 群组 公众号
```go
type User struct {
Uin int
HideInputBarFlag int
StarFriend int
Sex int
AppAccountFlag int
VerifyFlag int
ContactFlag int
WebWxPluginSwitch int
HeadImgFlag int
SnsFlag int
IsOwner int
MemberCount int
ChatRoomId int
UniFriend int
OwnerUin int
Statues int
AttrStatus int
Province string
City string
Alias string
DisplayName string
KeyWord string
EncryChatRoomId string
UserName string
NickName string
HeadImgUrl string
RemarkName string
PYInitial string
PYQuanPin string
RemarkPYInitial string
RemarkPYQuanPin string
Signature string
MemberList Members
Self *Self
}
```
`User`结构体的属性,部门信息可以通过它的英文名知道它所描述的意思。
其中要注意的是`UserName`这个属性。
`UserName`是当前会话唯一的身份标识,且仅作用于当前会话。下次登录该属性值则会被改变。
不同用户的`UserName`的值是不一样的,可以通过该字段来区分不同的用户。
#### 获取头像
下载群聊、好友、公众号的头像,具体哪种类型根据当前`User`的抽象类型来判断
```go
func (u *User) SaveAvatar(filename string) error
```
#### 详情
获取制定用户的详细信息, 返回新的用户对象
```go
func (u *User) Detail() (*User, error)
```
#### 判断是否为好友
```go
func (u *User) IsFriend() bool
```
#### 判断是否为群组
```go
func (u *User) IsGroup() bool
```
#### 判断是否为公众号
```go
func (u *User) IsMP() bool
```
## 当前登录用户
当前扫码登录的用户对象
`Self`拥有上面`User`的全部属性和方法
通过调用`bot.GetCurrentUser`来获取
```go
self, err := bot.GetCurrentUser()
```
#### 获取当前用户的所有的好友
```go
firends, err := self.Friends() // self.Friends(true)
```
`Friends`:可接受`bool`值来判断是否获取最新的好友
#### 获取当前用户的所有的群组
```go
groups, err := self.Groups() // self.Groups(true)
```
注:群组列表只显示手机端微信:通讯录:群聊里面的群组,若想将别的群组加入通讯录,点击群组,设置为`保存到通讯录`即可(安卓机)
`Groups`:可接受`bool`值来判断是否获取最新的群组
#### 获取当前用户所有的公众号
```go
mps, err := self.Mps() // self.Mps(true)
```
`Mps`:可接受`bool`值来判断是否获取最新的公众号
#### 获取文件传输助手
```go
fh, err := self.FileHelper()
```
#### 发送文本给好友
```go
func (s *Self) SendTextToFriend(friend *Friend, text string) (*SentMessage, error)
```
```go
firends, err := self.Friends()
if err != nil {
return
}
if friends.Count() > 0 {
self.SendTextToFriend(friends.First(), "hello")
// 或者
// friends.First().SendText("hello")
}
```
返回的`SentMessage`对象可用于消息撤回
#### 发送图片消息给好友
```go
// 确保获取了有效的好友对象
img, _ := os.Open("your file path")
defer img.Close()
self.SendImageToFriend(friend, img)
// 或者
// friend.SendImage(img)
```
#### 发送文件给好友
```go
file, _ := os.Open("your file path")
defer img.Close()
self.SendFileToFriend(friend, file)
// 或者
// friend.SendFile(img)
```
#### 给好友设置备注
```go
self.SetRemarkNameToFriend(friend, "你的备注")
// 或者
// friend.SetRemarkName("你的备注")
```
#### 发送文本消息给群组
```go
self.SendTextToGroup(group, "hello")
// group.SendText("hello")
```
#### 发送图片给群组
```go
img, _ := os.Open("your file path")
defer img.Close()
self.SendImageToGroup(group, img)
// group.SendImage(img)
```
#### 发送文件给群组
```go
file, _ := os.Open("your file path")
defer file.Close()
self.SendFileToGroup(group, file)
// group.SendFile(file)
```
#### 消息撤回
```go
sentMesaage, _ := friend.SendText("hello")
self.RevokeMessage(sentMesaage)
// sentMesaage.Revoke()
```
只要是`openwechat.SentMessage`对象都可以在2分钟之内撤回
#### 消息转发给多个好友
```go
sentMesaage, _ := friend.SendText("hello")
self.ForwardMessageToFriends(sentMesaage, friends1, friends2)
// sentMesaage.ForwardToFriends(friends1, friends2)
```
#### 转发消息给多个群组
```go
sentMesaage, _ := friend.SendText("hello")
self.ForwardMessageToGroups(sentMesaage, group1, group2)
// sentMesaage.ForwardToGroups(friends1, friends2)
```
#### 拉多个好友入群
```go
self.AddFriendsIntoGroup(group, friend1, friend2) // friend1, friend2 为不定长参数
// group.AddFriendsIn(friend1, friend2)
```
最好自己是群主,这样成功率会高一点。
#### 拉单个好友进多个群
```go
self.AddFriendIntoManyGroups(friend, group1, group2) // group1, group2 为不定长参数
// friend.AddIntoGroup(group1, group2)
```
#### 从群聊中移除用户
```go
member, err := group.Members()
self.RemoveMemberFromGroup(group, member[0], member[1])
// group.RemoveMembers(member[:1])
```
注:这个接口已经被微信官方禁用了,现在已经无法使用。
## 好友
### 好友列表
```go
type Friends []*Friend
```
#### 获取当前用户的好友列表
```go
firends, err := self.Friends()
```
注:此时获取到的`friends`为好友组而非好友。好友组是当前wx号所有好友的集合。
#### 统计好友个数
```go
firends.Count() // => int
```
#### 自定义条件查找好友
```go
func (f Friends) Search(limit int, condFuncList ...func(friend *Friend) bool) (results Friends)
```
* `limit`:限制查找的个数
* `condFuncList`:不定长参数,查找的条件,必须全部满足才算匹配上
* `results`:返回的满足条件的好友组
```go
// 例查询昵称为eatmoreapple的1个好友
sult := firends.Search(1, func(friend *openwechat.Friend) bool {return friend.NickName == "eatmoreapple"})
```
#### 根据昵称查找好友
```go
func (f Friends) SearchByNickName(limit int, nickName string) (results Friends)
```
* `limit`:为限制好友查找的个数
* `nickname`:查询指定昵称的好友
* `results`:返回满足条件的好友组
#### 根据备注查找好友
```go
func (f Friends) SearchByRemarkName(limit int, remarkName string) (results Friends)
```
* `limit`:为限制好友查找的个数
* `remarkname`:查询指定备注的好友
* `results`:返回满足条件的好友组
#### 群发文本消息
```go
func (f Friends) SendText(text string, delay ...time.Duration) error
```
* `text`:文本消息的内容
* `delay`每次发送消息的间隔发送消息过快可能会被wx检测到最好加上间隔时间
#### 群发图片
```go
func (f Friends) SendImage(file *os.File, delay ...time.Duration) error
```
* `file``os.file`类型,即发送图片的文件指针
* `delay`每次发送消息的间隔发送消息过快可能会被wx检测到最好加上间隔时间
#### 群发文件
```go
func (f Friends) SendFile(file *os.File, delay ...time.Duration) error
```
* `file``os.file`类型,即发送文件的文件指针
* `delay`每次发送消息的间隔发送消息过快可能会被wx检测到最好加上间隔时间
### 单个好友
#### 获取好友头像
```go
friend.SaveAvatar("avatar.png")
```
#### 发送文本信息
```go
friend.SendText("hello")
```
#### 发送图片信息
```go
img, _ := os.Open("your image path")
defer img.Close()
friend.SendImage(img)
```
#### 发送文件信息
```go
file, _ := os.Open("your file path")
defer file.Close()
friend.SendFile(file)
```
#### 设置备注信息
```go
friend.SetRemarkName("你的备注")
```
#### 拉该好友进群
```go
friend.AddIntoGroup(group)
```
## 群组
### 群组列表
```go
type Groups []*Group
```
#### 获取所有的群聊
```go
groups, err := self.Groups()
```
注:该方法在用户成功登陆之后调用
#### 统计群聊个数
```go
groups.Count() // => int
```
#### 自定义条件查找群聊
```go
func (g Groups) Search(limit int, condFuncList ...func(group *Group) bool) (results Groups)
```
* `limit`:限制查找的个数
* `condFuncList`:不定长参数,查找的条件,必须全部满足才算匹配上
* `results`:返回的满足条件的群聊
#### 根据群名查找群聊
```go
func (g Groups) SearchByNickName(limit int, nickName string) (results Groups)
```
* `limit`:限制查找的个数
* `nickName`:群名称
* `results`:返回的满足条件的群聊
#### 群发文本
```go
func (g Groups) SendText(text string, delay ...time.Duration) error
```
* `text`:文本消息的内容
* `delay`每次发送消息的间隔发送消息过快可能会被wx检测到最好加上间隔时间
#### 群发图片
```go
func (g Groups) SendImage(file *os.File, delay ...time.Duration) error
```
* `file``os.file`类型,即发送文件的文件指针
* `delay`每次发送消息的间隔发送消息过快可能会被wx检测到最好加上间隔时间
#### 群发文件
```go
func (g Groups) SendFile(file *os.File, delay ...time.Duration) error
```
* `file``os.file`类型,即发送文件的文件指针
* `delay`每次发送消息的间隔发送消息过快可能会被wx检测到最好加上间隔时间
### 单个群聊
#### 获取群聊头像
```go
group.SaveAvatar("group.png")
```
#### 获取所有的群员
```go
members, err := group.Members()
```
#### 发送文本信息
```go
group.SendText("hello")
```
#### 发送图片信息
```go
img, _ := os.Open("your image path")
defer img.Close()
group.SendImage(img)
```
#### 发送文件消息
```go
file, _ := os.Open("your file path")
defer file.Close()
group.SendFile(file)
```
#### 拉好友进群
```go
group.AddFriendsIn(friend)
```