diff --git a/app/src/main/java/org/yameida/worktool/model/WeworkMessageBean.java b/app/src/main/java/org/yameida/worktool/model/WeworkMessageBean.java
index d2f781a..ad2d7d3 100644
--- a/app/src/main/java/org/yameida/worktool/model/WeworkMessageBean.java
+++ b/app/src/main/java/org/yameida/worktool/model/WeworkMessageBean.java
@@ -38,6 +38,7 @@ public class WeworkMessageBean {
* 打卡 CLOCK_IN
* 切换企业 SWITCH_CORP
* 推送链接 PUSH_LINK
+ * 撤回消息 RECALL_MESSAGE
*
* 非操作类型 300
* 机器人普通日志记录 ROBOT_LOG
@@ -81,6 +82,7 @@ public class WeworkMessageBean {
public static final int CLOCK_IN = 222;
public static final int SWITCH_CORP = 223;
public static final int PUSH_LINK = 224;
+ public static final int RECALL_MESSAGE = 225;
public static final int ROBOT_LOG = 301;
public static final int ROBOT_ERROR_LOG = 302;
diff --git a/app/src/main/java/org/yameida/worktool/service/MyLooper.kt b/app/src/main/java/org/yameida/worktool/service/MyLooper.kt
index a101fef..4d1479a 100644
--- a/app/src/main/java/org/yameida/worktool/service/MyLooper.kt
+++ b/app/src/main/java/org/yameida/worktool/service/MyLooper.kt
@@ -166,6 +166,9 @@ object MyLooper {
WeworkMessageBean.PUSH_LINK -> {
WeworkController.pushLink(message)
}
+ WeworkMessageBean.RECALL_MESSAGE -> {
+ WeworkController.recallMessage(message)
+ }
WeworkMessageBean.DISMISS_GROUP -> {
WeworkController.dismissGroup(message)
}
diff --git a/app/src/main/java/org/yameida/worktool/service/WeworkController.kt b/app/src/main/java/org/yameida/worktool/service/WeworkController.kt
index 77b2cc6..d1079f5 100644
--- a/app/src/main/java/org/yameida/worktool/service/WeworkController.kt
+++ b/app/src/main/java/org/yameida/worktool/service/WeworkController.kt
@@ -363,6 +363,25 @@ object WeworkController {
)
}
+ /**
+ * 撤回消息
+ * @see WeworkMessageBean.RECALL_MESSAGE
+ * @param message#titleList 房间名称
+ * @param message#originalContent 原始消息的内容
+ * @param message#textType 原始消息的消息类型
+ * @see WeworkMessageBean.TEXT_TYPE
+ */
+ @RequestMapping
+ fun recallMessage(message: WeworkMessageBean): Boolean {
+ LogUtils.d("recallMessage(): ${message.titleList} ${message.originalContent} ${message.textType}")
+ return WeworkOperationImpl.recallMessage(
+ message,
+ message.titleList,
+ message.originalContent,
+ message.textType
+ )
+ }
+
/**
* 按手机号添加好友
* @see WeworkMessageBean.ADD_FRIEND_BY_PHONE
diff --git a/app/src/main/java/org/yameida/worktool/service/WeworkOperationImpl.kt b/app/src/main/java/org/yameida/worktool/service/WeworkOperationImpl.kt
index 6f8f0d3..debcaae 100644
--- a/app/src/main/java/org/yameida/worktool/service/WeworkOperationImpl.kt
+++ b/app/src/main/java/org/yameida/worktool/service/WeworkOperationImpl.kt
@@ -764,6 +764,46 @@ object WeworkOperationImpl {
}
}
+ /**
+ * 撤回消息
+ * @see WeworkMessageBean.RECALL_MESSAGE
+ * @param titleList 房间名称
+ * @param originalContent 原始消息的内容
+ * @param textType 原始消息的消息类型
+ * @see WeworkMessageBean.TEXT_TYPE
+ */
+ fun recallMessage(
+ message: WeworkMessageBean,
+ titleList: List,
+ originalContent: String,
+ textType: Int
+ ): Boolean {
+ val startTime = System.currentTimeMillis()
+ for (title in titleList) {
+ if (WeworkRoomUtil.intoRoom(title)) {
+ if (WeworkTextUtil.longClickMyMessageItem(
+ //聊天消息列表 1ListView 0RecycleView xViewGroup
+ AccessibilityUtil.findOneByClazz(getRoot(), Views.ListView),
+ textType,
+ originalContent,
+ "撤回"
+ )
+ ) {
+ LogUtils.d("撤回成功")
+ uploadCommandResult(message, ExecCallbackBean.SUCCESS, "", startTime, titleList, listOf())
+ return true
+ } else {
+ LogUtils.e("撤回失败 未找到目标消息")
+ uploadCommandResult(message, ExecCallbackBean.ERROR_TARGET, "撤回失败 未找到目标消息", startTime, listOf(), titleList)
+ return false
+ }
+ }
+ }
+ LogUtils.e("撤回失败 未找到房间")
+ uploadCommandResult(message, ExecCallbackBean.ERROR_TARGET, "撤回失败 未找到房间", startTime, listOf(), titleList)
+ return false
+ }
+
/**
* 手机号添加好友或修改好友信息
* @see WeworkMessageBean.ADD_FRIEND_BY_PHONE
diff --git a/app/src/main/java/org/yameida/worktool/utils/WeworkTextUtil.kt b/app/src/main/java/org/yameida/worktool/utils/WeworkTextUtil.kt
index 2a925e7..178e159 100644
--- a/app/src/main/java/org/yameida/worktool/utils/WeworkTextUtil.kt
+++ b/app/src/main/java/org/yameida/worktool/utils/WeworkTextUtil.kt
@@ -280,6 +280,15 @@ object WeworkTextUtil {
LogUtils.v("textType: $textType")
return textType
}
+ } else if (Views.ImageView.equals(relativeLayoutItem.getChild(1).className)) {
+ LogUtils.v("头像在右边 本条消息发送者为自己")
+ var textType = WeworkMessageBean.TEXT_TYPE_UNKNOWN
+ val subLayout = relativeLayoutItem.getChild(0)
+ if (subLayout.childCount > 0) {
+ textType = WeworkTextUtil.getTextType(subLayout)
+ LogUtils.v("textType: $textType")
+ return textType
+ }
}
}
return WeworkMessageBean.TEXT_TYPE_UNKNOWN
@@ -326,8 +335,9 @@ object WeworkTextUtil {
}
/**
- * 群聊 长按消息条目
+ * 长按消息条目
* 复制、转发、回复、收藏、置顶、多选、日程、待办、翻译、删除
+ * 适用左侧发言者
* @param node 消息列表节点
* @param replyTextType 带回复消息类型
* @param replyNick 待回复人姓名
@@ -400,6 +410,50 @@ object WeworkTextUtil {
return false
}
+ /**
+ * 长按消息条目
+ * 复制、转发、回复、收藏、置顶、多选、日程、待办、翻译、删除、撤回
+ * 适用自己发言者
+ * @param node 消息列表节点
+ * @param replyTextType 带回复消息类型
+ * @param replyContent 待回复内容
+ * @param key 复制、转发、回复、收藏、多选
+ * @return true 进行了长按 否则 false
+ */
+ fun longClickMyMessageItem(
+ node: AccessibilityNodeInfo?,
+ replyTextType: Int,
+ replyContent: String,
+ key: String
+ ): Boolean {
+ if (node == null) return false
+ for (i in 0 until node.childCount) {
+ val item = node.getChild(node.childCount - 1 - i) ?: continue
+ val frontNode = getMyMessageListNode(item)
+ if (frontNode != null) {
+ val textType = getTextTypeFromItem(item)
+ if (replyTextType == WeworkMessageBean.TEXT_TYPE_UNKNOWN || replyTextType == textType) {
+ if (replyTextType == WeworkMessageBean.TEXT_TYPE_IMAGE) {
+ return longClickMyMessageItem(item, WeworkMessageBean.ROOM_TYPE_INTERNAL_CONTACT, key)
+ }
+ if ((replyTextType == WeworkMessageBean.TEXT_TYPE_FILE || replyTextType == WeworkMessageBean.TEXT_TYPE_VIDEO)
+ && replyContent.contains("###")) {
+ val replyContentList = replyContent.split("###")
+ if (AccessibilityUtil.findOnceByText(frontNode, replyContentList[0]) != null
+ && AccessibilityUtil.findOnceByText(frontNode, replyContentList[1]) != null) {
+ return longClickMyMessageItem(item, WeworkMessageBean.ROOM_TYPE_INTERNAL_GROUP, key)
+ }
+ }
+ val textNode = AccessibilityUtil.findOnceByText(frontNode, replyContent, exact = true)
+ if (textNode != null && replyContent.isNotEmpty()) {
+ return longClickMyMessageItem(item, WeworkMessageBean.ROOM_TYPE_INTERNAL_CONTACT, key)
+ }
+ }
+ }
+ }
+ return false
+ }
+
private fun longClickMessageItem(item: AccessibilityNodeInfo, roomType: Int, key: String): Boolean {
val backNode = getMessageListNode(item, roomType)
AccessibilityUtil.performLongClickWithSon(backNode)
@@ -415,8 +469,26 @@ object WeworkTextUtil {
return false
}
+ private fun longClickMyMessageItem(item: AccessibilityNodeInfo, roomType: Int, key: String): Boolean {
+ val frontNode = getMyMessageListNode(item)
+ AccessibilityUtil.performLongClickWithSon(frontNode)
+ sleep(Constant.POP_WINDOW_INTERVAL)
+ val optionRvList = findAllByClazz(getRoot(), Views.RecyclerView, Views.ViewGroup)
+ for (optionRv in optionRvList) {
+ val keyTv = AccessibilityUtil.findOnceByText(optionRv, key, exact = true)
+ if (keyTv != null) {
+ AccessibilityUtil.performClick(keyTv)
+ if (AccessibilityExtraUtil.loadingPage("CustomDialog", timeout = Constant.POP_WINDOW_INTERVAL)) {
+ AccessibilityUtil.findTextAndClick(getRoot(), "确定", exact = true)
+ }
+ return true
+ }
+ }
+ return false
+ }
+
/**
- * 群聊 提取消息主体框节点(昵称下面的气泡框)
+ * 提取消息主体框节点(昵称下面的气泡框)
* 适用于左侧发言者
* @param item 消息item节点
*/
@@ -434,4 +506,17 @@ object WeworkTextUtil {
}
return null
}
+
+ /**
+ * 提取消息主体框节点(昵称下面的气泡框)
+ * 适用于自己发言者
+ * @param item 消息item节点
+ */
+ private fun getMyMessageListNode(item: AccessibilityNodeInfo): AccessibilityNodeInfo? {
+ val node = AccessibilityUtil.findAllOnceByClazz(item, Views.ImageView).lastOrNull()
+ if (node?.parent?.getChild(0) != node) {
+ return AccessibilityUtil.findFrontNode(node)
+ }
+ return null
+ }
}
\ No newline at end of file