Skip to content

Commit

Permalink
'#1923: Handle UI elements table and message types (45, 46, 49).
Browse files Browse the repository at this point in the history
  • Loading branch information
wladimirleite committed Jan 3, 2024
1 parent addc56f commit 3f80ac8
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
import static iped.parsers.whatsapp.Message.MessageType.TEMPLATE_MESSAGE;
import static iped.parsers.whatsapp.Message.MessageType.TEMPLATE_QUOTE;
import static iped.parsers.whatsapp.Message.MessageType.TEXT_MESSAGE;
import static iped.parsers.whatsapp.Message.MessageType.UI_ELEMENTS;
import static iped.parsers.whatsapp.Message.MessageType.UI_ELEMENTS_QUOTE;
import static iped.parsers.whatsapp.Message.MessageType.UNAVAILABLE_VIDEO_CALL;
import static iped.parsers.whatsapp.Message.MessageType.UNAVAILABLE_VOICE_CALL;
import static iped.parsers.whatsapp.Message.MessageType.UNBLOCKED_CONTACT;
Expand Down Expand Up @@ -393,6 +395,7 @@ private void extractMessages(Connection conn, Map<Long, Chat> idToChat) throws S
m.setUuid(rs.getString("uuid"));
m.setGroupInviteName(rs.getString("groupInviteName"));
m.setSortId(rs.getLong("sortId"));
m.setUiElements(rs.getString("uiElem"));

if (hasTemplateTables && m.getMessageType() == TEMPLATE_MESSAGE) {
extractTemplateInfo(conn, m);
Expand Down Expand Up @@ -700,6 +703,13 @@ protected Message.MessageType decodeMessageType(int messageType, int status, Int
case 43:
result = VIEW_ONCE_VIDEO_MESSAGE;
break;
case 45:
result = UI_ELEMENTS;
break;
case 46:
case 49:
result = UI_ELEMENTS_QUOTE;
break;
case 64:
if (status == 0) {
result = DELETED_BY_ADMIN;
Expand Down Expand Up @@ -774,6 +784,13 @@ private static String getSelectMessagesQuery(Connection conn) throws SQLExceptio
grpInvTableJoin = " left join message_group_invite mgi on m._id=mgi.message_row_id";
}

String uiElemCol = "null";
String uiElemTableJoin = "";
if (SQLite3DBParser.containsTable("message_ui_elements", conn)) {
uiElemCol = "mue.element_content";
uiElemTableJoin = " left join message_ui_elements mue on m._id=mue.message_row_id";
}

return "select m._id AS id,m.chat_row_id as chatId, chatJid.raw_string as remoteId,"
+ " jid.raw_string as remoteResource, status, mv.vcard, m.text_data,"
+ " m.from_me as fromMe, m.timestamp as timestamp, message_url as mediaUrl,"
Expand All @@ -785,7 +802,8 @@ private static String getSelectMessagesQuery(Connection conn) throws SQLExceptio
+ " " + mhtCol + " as thumbData2,"
+ " " + bizStateCol + " as bizStateId,"
+ " " + grpInvCol + " as groupInviteName,"
+ " " + sortCol + " as sortId"
+ " " + sortCol + " as sortId,"
+ " " + uiElemCol + " as uiElem"
+ " from message m"
+ " left join chat on m.chat_row_id=chat._id"
+ " left join jid chatJid on chatJid._id=chat.jid_row_id"
Expand All @@ -797,6 +815,7 @@ private static String getSelectMessagesQuery(Connection conn) throws SQLExceptio
+ mhtTableJoin
+ bizStateTableJoin
+ grpInvTableJoin
+ uiElemTableJoin
+ " left join message_thumbnail mt on m._id=mt.message_row_id where status!=-1";
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ public class Message implements Comparable<Message> {
private long sortId;
private List<PollOption> pollOptions;
private List<String> usersGroupAction;
private String uiElements;

static {
try {
Expand Down Expand Up @@ -560,8 +561,16 @@ public void setSortId(long sortId) {
this.sortId = sortId;
}

public String getUiElements() {
return uiElements;
}

public void setUiElements(String uiElements) {
this.uiElements = uiElements;
}

public static enum MessageType {
TEXT_MESSAGE, IMAGE_MESSAGE, AUDIO_MESSAGE, VIDEO_MESSAGE, UNKNOWN_MEDIA_MESSAGE, CONTACT_MESSAGE, LOCATION_MESSAGE, SHARE_LOCATION_MESSAGE, VOICE_CALL, VIDEO_CALL, APP_MESSAGE, GIF_MESSAGE, BLOCKED_CONTACT, UNBLOCKED_CONTACT, BUSINESS_CHAT, BUSINESS_TO_STANDARD, MESSAGES_ENCRYPTED, MESSAGES_NOW_ENCRYPTED, ENCRYPTION_KEY_CHANGED, MISSED_VOICE_CALL, MISSED_VIDEO_CALL, DELETED_MESSAGE, DELETED_BY_ADMIN, DELETED_BY_SENDER, GROUP_CREATED, USER_JOINED_GROUP, USER_JOINED_GROUP_FROM_LINK, USERS_JOINED_GROUP, USER_LEFT_GROUP, USER_REMOVED_FROM_GROUP, URL_MESSAGE, GROUP_ICON_CHANGED, GROUP_ICON_DELETED, GROUP_DESCRIPTION_CHANGED, SUBJECT_CHANGED, YOU_ADMIN, WAITING_MESSAGE, STICKER_MESSAGE, REFUSED_VIDEO_CALL, REFUSED_VOICE_CALL, UNAVAILABLE_VIDEO_CALL, UNAVAILABLE_VOICE_CALL, UNKNOWN_VOICE_CALL, UNKNOWN_VIDEO_CALL, VIEW_ONCE_IMAGE_MESSAGE, VIEW_ONCE_VIDEO_MESSAGE, CALL_MESSAGE, BUSINESS_META_SECURE_SERVICE, GROUP_INVITE, TEMPLATE_MESSAGE, TEMPLATE_QUOTE, POLL_MESSAGE, EPHEMERAL_DURATION_CHANGED, EPHEMERAL_ENABLED, EPHEMERAL_SAVE, GROUP_CHANGED_ONLY_ADMINS_CAN_SEND, GROUP_CHANGED_ALL_MEMBERS_CAN_SEND, GROUP_ONLY_ADMINS_CAN_SEND, CHANGED_NUMBER, STANDARD_CHAT, SENDER_IN_CONTACTS, BUSINESS_OFFICIAL, GROUP_ADDED_TO_COMMUNITY, COMMUNITY_MANAGEMENT_ACTION, UNKNOWN_MESSAGE
TEXT_MESSAGE, IMAGE_MESSAGE, AUDIO_MESSAGE, VIDEO_MESSAGE, UNKNOWN_MEDIA_MESSAGE, CONTACT_MESSAGE, LOCATION_MESSAGE, SHARE_LOCATION_MESSAGE, VOICE_CALL, VIDEO_CALL, APP_MESSAGE, GIF_MESSAGE, BLOCKED_CONTACT, UNBLOCKED_CONTACT, BUSINESS_CHAT, BUSINESS_TO_STANDARD, MESSAGES_ENCRYPTED, MESSAGES_NOW_ENCRYPTED, ENCRYPTION_KEY_CHANGED, MISSED_VOICE_CALL, MISSED_VIDEO_CALL, DELETED_MESSAGE, DELETED_BY_ADMIN, DELETED_BY_SENDER, GROUP_CREATED, USER_JOINED_GROUP, USER_JOINED_GROUP_FROM_LINK, USERS_JOINED_GROUP, USER_LEFT_GROUP, USER_REMOVED_FROM_GROUP, URL_MESSAGE, GROUP_ICON_CHANGED, GROUP_ICON_DELETED, GROUP_DESCRIPTION_CHANGED, SUBJECT_CHANGED, YOU_ADMIN, WAITING_MESSAGE, STICKER_MESSAGE, REFUSED_VIDEO_CALL, REFUSED_VOICE_CALL, UNAVAILABLE_VIDEO_CALL, UNAVAILABLE_VOICE_CALL, UNKNOWN_VOICE_CALL, UNKNOWN_VIDEO_CALL, VIEW_ONCE_IMAGE_MESSAGE, VIEW_ONCE_VIDEO_MESSAGE, CALL_MESSAGE, BUSINESS_META_SECURE_SERVICE, GROUP_INVITE, TEMPLATE_MESSAGE, TEMPLATE_QUOTE, POLL_MESSAGE, EPHEMERAL_DURATION_CHANGED, EPHEMERAL_ENABLED, EPHEMERAL_SAVE, GROUP_CHANGED_ONLY_ADMINS_CAN_SEND, GROUP_CHANGED_ALL_MEMBERS_CAN_SEND, GROUP_ONLY_ADMINS_CAN_SEND, CHANGED_NUMBER, STANDARD_CHAT, SENDER_IN_CONTACTS, BUSINESS_OFFICIAL, GROUP_ADDED_TO_COMMUNITY, COMMUNITY_MANAGEMENT_ACTION, UI_ELEMENTS, UI_ELEMENTS_QUOTE, UNKNOWN_MESSAGE
}

public static enum MessageStatus {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -659,8 +659,16 @@ private synchronized void printMessage(PrintWriter out, Message message, boolean
+ "</span></div>");
break;
default:
out.print("<div class=\""+quoteClass+"\" "+quoteClick+"><div style=\"display:table-cell;\"><span class=\"quote_user\">"+quoteUser+
"</span><br><span class=\"quote_msg\">"+ format(dataQuote) + "</span></div>");
out.print("<div class=\"" + quoteClass + "\" " + quoteClick
+ "><div style=\"display:table-cell;\"><span class=\"quote_user\">" + quoteUser
+ "</span><br><span class=\"quote_msg\">" + format(dataQuote));
if (messageQuote.getUiElements() != null && !messageQuote.getUiElements().isBlank()) {
if (dataQuote != null && !dataQuote.isBlank()) {
out.println("<br>");
}
out.print(formatUiElements(messageQuote.getUiElements()));
}
out.println("</span></div>");
break;
}
if (messageQuote.isDeleted()) {
Expand All @@ -679,11 +687,16 @@ private synchronized void printMessage(PrintWriter out, Message message, boolean
switch (message.getMessageType()) {
case TEXT_MESSAGE:
case TEMPLATE_QUOTE:
case UI_ELEMENTS_QUOTE:
case UI_ELEMENTS:
// Some textual messages may have thumbs
printThumb(out, message);
if (message.getData() != null && !message.getData().isBlank()) {
out.print(format(message.getData()) + "<br>"); //$NON-NLS-1$
}
// Some textual messages may have thumbs
printThumb(out, message);
if (message.getUiElements() != null && !message.getUiElements().isBlank()) {
out.print(formatUiElements(message.getUiElements()));
}
break;
case UNKNOWN_MEDIA_MESSAGE:
if (message.getMediaCaption() != null) {
Expand Down Expand Up @@ -1041,6 +1054,63 @@ private void printThumb(PrintWriter out, Message message) {
}
}

private static String formatUiElements(String s) {
StringBuilder sb = new StringBuilder();
String[] keys = { "title", "content", "description", "footerText", "footer" };
for (String key : keys) {
key = '"' + key + '"';
int p1 = s.indexOf(key);
if (p1 >= 0) {
p1 += key.length();
p1 = s.indexOf("\"", p1);
if (p1 >= 0) {
p1++;
int p2 = s.indexOf("\"", p1);
if (p2 > 0 && p2 > p1 + 1) {
if (sb.length() > 0) {
sb.append("<br>\n");
}
sb.append(format(s.substring(p1, p2).replaceAll("\\\\n", "\n")));
}
}
}
}
keys = new String[] { "displayText", "title", "description" };
int p0 = s.indexOf("\"id\"");
while (p0 > 0 && p0 < s.length()) {
StringBuilder opt = new StringBuilder();
int p3 = p0;
for (String key : keys) {
key = '"' + key + '"';
int p1 = s.indexOf(key, p0);
if (p1 >= 0) {
p1 += key.length();
p1 = s.indexOf("\"", p1);
if (p1 >= 0) {
p1++;
int p2 = s.indexOf("\"", p1);
if (p2 > 0 && p2 > p1 + 1) {
if (opt.length() > 0) {
opt.append(" - ");
}
opt.append(format(s.substring(p1, p2).replaceAll("\\\\n", "\n")));
p3 = Math.max(p3, p2 + 1);
}
}
}
}
if (opt.length() == 0) {
break;
}
if (sb.length() > 0) {
sb.append("<br>\n");
}
sb.append("[<b>").append(opt).append("</b>]");
p0 = p3 + 1;
}
return sb.toString();
}

private String formatTemplate(Message message) {
StringBuilder sb = new StringBuilder();
if (message.getData() != null && !message.getData().isBlank()) {
Expand Down

0 comments on commit 3f80ac8

Please sign in to comment.