前言

Just do it.

本文主要描写这两个功能的开发过程中,自己都经历过哪些阶段,以及如何一步步从一开始都不会做MacOS逆向开发,到了解别人的项目,再到实现自己想要的功能。再加上当时正在看的一本书中,描述的内容在这次开发中得到了体现,于是想记录下来,给这段难得的经历留个纪念,也为那些在踏出第一步前迷茫的各位,点亮一盏烛火。Just do it。

插件功能基于WeChatPlugin-MacOS,作者TK。

主要经历

无从下手

在想要实现该功能时,TK已经移除了该项目,然后发现MustangYM在继续维护这个项目。这个时候的我以前翻过两页《Objective-C基础教程》,以及有一些Java和前端开发的相关经验,但是对于MacOS逆向,以及如何写OBJC的代码完全没有头绪,找到MustangYM的时候,我还给他发了一封邮件,询问是否能够提供一些指导方向,那个时候是7月16号。

柳暗花明

在给MustangYM发了邮件一段时间以后,并没有得到回信。有一天跟同事说到了这个东西,在帮他弄的过程中,突然发现了TK的项目文件中有写如何进行编译,然后根据描述试着去跑起来项目,中间在pos install也因为各种情况遇到了一些问题,所幸最后是将项目启动了起来,并且能够进入断点进行调试。

功能开发

在可以进行调试以后,又过去了那么一段时间,这段时间苦于看不懂OBJC的代码,也不会用Xcode,然后我又搁置了一段时间。在给自己开发另外一个项目的时候,需要对接印象笔记,但是JavaScript SDK一直401,在头疼SDK对接不成功的过程中,发现开发文档中有Mac本地API,打开发现使用的是AppleScript脚本。

在使用WeChatPlugin这个插件时,就很好奇为什么他能通过给自己发消息实现远程控制。在这个时候有扒过源码,了解到是通过AppleScript来控制Mac上的应用的,并且使用AppleScript做了一个简单的控制网易云播放和切歌的Workflow,那么看到印象笔记支持AppleScript时,就来了兴趣,于是就写了脚本实现了自己项目的一个功能。

功能完成以后,就开始捣鼓AppleScript,发现微信并没有提供字典,我就尝试着进行了几个测试,看是否能通过特定的键盘操作实现找到好友,并给好友发送消息,接着尝试使用脚本来控制微信发消息,结果是成功的,相关脚本如下。

-- 搜索好友,并发送指定消息

tell application "WeChat" to activate

tell application "System Events"

key code 3 using {command down}

keystroke "会话名称"

delay 1

key code 36

key code 49 using {control down}

delay 2

keystroke "消息"

key code 49

key code 36

end tell

复制代码

联想到远程控制的实现方式,我就想是不是也能通过触发脚本的方式来实现给指定好友发消息的功能,于是就开始了新一轮的折腾。

开发消息转发功能

在一步步查看远程控制的代码的过程中,发现都会经过下面这个方法,然后我看懂了autoReplyWithMsg,通过调试发现接收消息是都会经过消息同步,并且在自动回复中有一个replyWithMsg方法,看作用应该是发送消息用的,于是我就忘记了远程控制,开始了折腾收到消息时,转发给好友里的某个用户。

/**

hook 微信消息同步

*/

- (void)hook_OnSyncBatchAddMsgs:(NSArray *)msgs isFirstSync:(BOOL)arg2 {

// 其他一些代码

[self autoReplyWithMsg:addMsg];

if ([addMsg.fromUserName.string isEqualToString:currentUserName]

&& [addMsg.toUserName.string isEqualToString:currentUserName]) {

[self remoteControlWithMsg:addMsg];

[self replySelfWithMsg:addMsg];

}

}

复制代码

然后分析autoReplyWithMsg这个方法,一眼望过去根本不想去了解每一行都是干嘛的,就觉得“我看不懂啊,这都是什么玩意,My god,救救我吧”。

/**

自动回复

@param addMsg 接收的消息

*/

- (void)autoReplyWithMsg:(AddMsg *)addMsg {

// addMsg.msgType != 49

if (![[TKWeChatPluginConfig sharedConfig] autoReplyEnable]) return;

if (addMsg.msgType != 1 && addMsg.msgType != 3) return;

NSString *userName = addMsg.fromUserName.string;

MMSessionMgr *sessionMgr = [[objc_getClass("MMServiceCenter") defaultCenter] getService:objc_getClass("MMSessionMgr")];

WCContactData *msgContact = [sessionMgr getContact:userName];

if ([msgContact isBrandContact] || [msgContact isSelf]) {

// 该消息为公众号或者本人发送的消息

return;

}

NSArray *autoReplyModels = [[TKWeChatPluginConfig sharedConfig] autoReplyModels];

[autoReplyModels enumerateObjectsUsingBlock:^(TKAutoReplyModel *model, NSUInteger idx, BOOL * _Nonnull stop) {

if (!model.enable) return;

if (!model.replyContent || model.replyContent.length == 0) return;

if (model.enableSpecificReply) {

if ([model.specificContacts containsObject:userName]) {

[self replyWithMsg:addMsg model:model];

}

return;

}

if ([addMsg.fromUserName.string containsString:@"@chatroom"] && !model.enableGroupReply) return;

if (![addMsg.fromUserName.string containsString:@"@chatroom"] && !model.enableSingleReply) return;

[self replyWithMsg:addMsg model:model];

}];

}

复制代码

可是在看消息同步的方法时,留下了一个想法,那就是看不懂某个编程语言时,看if准没错,于是我就去看了最后几行if以及里面的相关代码,不知道model是干嘛的,一番折腾后发现是引入的一个文件,看到下面这些文件里的内容,打开自动回复的设置界面对比了一下,想着“嗯,这应该就是自动回复的相关配置了。”

#import "TKBaseModel.h"

@interface TKAutoReplyModel : TKBaseModel

@property (nonatomic, assign) BOOL enable; /**< 是否开启自动回复 */

@property (nonatomic, copy) NSString *keyword; /**< 自动回复关键字 */

@property (nonatomic, copy) NSString *replyContent; /**< 自动回复的内容 */

@property (nonatomic, assign) BOOL enableGroupReply; /**< 是否开启群聊自动回复 */

@property (nonatomic, assign) BOOL enableSingleReply; /**< 是否开启私聊自动回复 */

@property (nonatomic, assign) BOOL enableRegex; /**< 是否开启正则匹配 */

@property (nonatomic, assign) BOOL enableDelay; /**< 是否开启延迟回复 */

@property (nonatomic, assign) NSInteger delayTime; /**< 延迟时间 */

@property (nonatomic, assign) BOOL enableSpecificReply; /**< 是否开启特定回复 */

@property (nonatomic, strong) NSArray *specificContacts; /**< 特定回复的联系人 */

- (BOOL)hasEmptyKeywordOrReplyContent;

@end

复制代码

明白了作用,再加上代码的自描述,知道这一段应该就是跟特定联系人回复的相关代码,下一步->添加特定联系人,开始测试。(其实我到现在都不记得下面这几行代码写了哪几个字母

java连接微信发送给好友信息,微信消息转发以及给指定好友发送消息相关推荐

  1. asp微信登陆源码,实现asp网站授权微信登录(获取用户信息,微信名头像openid等)

    一个同学的网站想实现asp微信登陆,获取到微信用户资料信息,微信昵称,微信头像,微信openid等信息保存到数据库,我给他了一份asp微信登录授权(获取用户信息)源码,他说不会用,让我帮忙写好入库,并 ...

  2. 将消息转发到客服+php,将消息转发到微信客服

    如果公众号处于开发模式,普通微信用户向公众号发消息时,微信服务器会先将消息POST到开发者填写的url上,如果希望将消息转发到客服系统,则需要开发者在响应包中返回MsgType为transfer_cu ...

  3. 将消息转发到客服 php,将消息转发到微信客服

    如果公众号处于开发模式,普通微信用户向公众号发消息时,微信服务器会先将消息POST到开发者填写的url上,如果希望将消息转发到客服系统,则需要开发者在响应包中返回MsgType为transfer_cu ...

  4. 从微信服务器获取用户信息,微信小程序Ⅴ [获取登陆用户信息,重点openID(详解)]...

    ♩ 背景 其实这篇文章几个月前就写完了,可是这段时间,微信小程序官方文档有了更新,同事在我本身的实际操做过程当中,发现以前写的过于繁杂,因此如今进行简化梳理,欢迎指摘. 语言框架:ThinkPHP3. ...

  5. python微信好友分析源代码_搞事情了 | 教你用Python分析微信好友信息(内附完整代码)...

    本文经授权转载至公众号 Python 知识圈 未经授权 严禁二次转载 阅读文本大概需要 5 分钟 技术群里一位读者微信私聊我,问我能不能统计下微信好友信息并以文件形式保存.其实,以前也写过类似的文章, ...

  6. 搞事情了 | 教你用Python分析微信好友信息(内附完整代码)

    戳上方蓝字 "程序猿杂货铺" 关注我 并 置顶星标! 你的关注意义重大! 本文经授权转载至公众号 Python 知识圈 未经授权 严禁二次转载 阅读文本大概需要 5 分钟 技术群里 ...

  7. java连接rabbitmq_RabbitMQ教程(工作模式篇)

    1 RabbitMQ介绍 1.1 应用场景 ​ MQ全称为Message Queue,即消息队列, RabbitMQ是由erlang语言开发,基于AMQP(Advanced Message Queue ...

  8. Python 好友信息管理系统

    前言 编写程序实现好友信息管理系统的好友添加,查看,修改以及删除功能 一.函数模块 1.菜单 代码如下: def meau():print('----------------------------- ...

  9. QQ空间动态内容,好友信息,点赞爬虫脚本

    一.安装基础的软件包: 1.准备好火狐浏览器,并下载geckodriver,将geckodriver加入到环境变量:下载geckodriver的地址:https://pan.baidu.com/s/1 ...

  10. 不注册微服务号如何使用Java实现每日给女友微信发送早安等信息?

    前言 据说这个功能最近在抖音上很火,我没有抖音,没有看到. 但是我在掘金和CSDN上看了,相关案例确实很多,但是大家都是借助于了微信服务号,在我看来,效果很不佳. 其实我原来的初衷是这样的,每天定时给 ...

最新文章

  1. 无线鼠标接收器对码软件_接收器太小容易丢 这几招记好就不怕
  2. linux7为nginx添加服务,CentOS7添加Nginx为系统服务
  3. mysql中如何计算党龄_党员的党龄如何计算?
  4. 计算机多文件管理,电脑文件管理几条小技巧
  5. awk正则匹配nginx日志【原创】
  6. 利尔达NB-IOT的PSM和eDRX低功耗模式笔记
  7. 洛谷P3676 小清新数据结构题(动态点分治)
  8. maven安装及配置(详细版)
  9. suse 12 sp5安装bug
  10. Windows图片和传真查看器修复办法
  11. 大专生北漂10年,月薪翻20倍,我的人生从不被学历设限
  12. 基于JAVAWeb美食网站设计计算机毕业设计源码+数据库+lw文档+系统+部署
  13. WorldPress 设置固定连接 Apache 服务器无法打开网页(100%解决这个问题)
  14. 桌面内存管理器(dwn.exe)占用内存过高时怎么办?
  15. 和尚挑水 java_java编程:山上有一口缸可以装50升水,现在有15升。老和尚叫小和尚下山挑水,每次挑5升,要挑几次...
  16. 【Unity3d】 制作游戏主菜单 GUI
  17. 解决办法:Call stored procedure using ExecuteSqlCommand (expects parameters which was not supplied)
  18. 举个栗子!Tableau 技巧(95):如何插入漂亮的动图背景
  19. python断网还能用吗_python 断网
  20. stm32接收OpenMv发送的数据,并用oled屏显示

热门文章

  1. AutoCAD2020安装教程
  2. python爬虫,用scrapy爬取天天基金
  3. 20.数据集成、数据整合、数据融合
  4. Frame-Relay基础及配置学习笔记
  5. B. Shashlik Cooking
  6. python查找文件指定内容_python实现在目录中查找指定文件的方法
  7. Python学习第五弹【正则表达式】-kidult
  8. 用python批量发送短信_Python批量发短信
  9. freyja v2版本发布
  10. 腾讯云产品介绍——腾讯云云服务器之运维指南