From 5ba2ea763b40418f054a4597bf3b502d018fdedc Mon Sep 17 00:00:00 2001 From: eta Date: Fri, 28 May 2021 16:55:24 +0100 Subject: [PATCH] Invite users to chats they're not in when messages are sent in those chats (untested!) --- message.lisp | 6 ++++++ stuff.lisp | 37 ++++++++++++++++++++++--------------- 2 files changed, 28 insertions(+), 15 deletions(-) diff --git a/message.lisp b/message.lisp index 9bf31f7..52fbcc5 100644 --- a/message.lisp +++ b/message.lisp @@ -159,6 +159,12 @@ FIXME: the above behaviour is a bit meh." (from (if one-to-one-p (concatenate 'string (from msg) "@" component-host "/whatsapp") (concatenate 'string (conversation msg) "@" component-host "/" (from msg))))) + (when (and (not one-to-one-p) + (eql (length destinations) 0)) + (warn "User ~A not in groupchat ~A; inviting due to new message" + jid (conversation msg)) + (handle-wa-chat-invitation comp nil jid (uid msg) (conversation msg) + :use-join-count t)) (loop for to in destinations do (with-message (comp to diff --git a/stuff.lisp b/stuff.lisp index 2f3b5eb..5dd09a7 100644 --- a/stuff.lisp +++ b/stuff.lisp @@ -578,34 +578,41 @@ Returns three values: avatar data (as two values), and a generalized boolean spe (lambda (conn meta) (wa-handle-group-metadata comp conn jid wx-localpart meta)))) -(defun handle-wa-chat-invitation (comp conn jid uid localpart &key noretry) - "Checks to see whether the group chat LOCALPART has any metadata; if not, requests some. If it does, and the user hasn't been invited to that group chat yet, send them an invitation." +(defun handle-wa-chat-invitation (comp conn jid uid localpart &key noretry use-join-count) + "Checks to see whether the group chat LOCALPART has any metadata; if not, requests some. If it does, and the user hasn't been invited to that group chat yet, send them an invitation. +If USE-JOIN-COUNT is set, checks whether the user is in the groupchat and invites them if they aren't, instead of checking whether the bridge has invited them previously." (unless (uiop:string-prefix-p "g" localpart) (return-from handle-wa-chat-invitation)) (with-prepared-statements ((get-stmt "SELECT id, invitation_state FROM user_chats WHERE user_id = ? AND wa_jid = ?") (count-stmt "SELECT COUNT(*) FROM user_chat_members WHERE chat_id = ?") + (count-joined-stmt "SELECT COUNT(*) FROM user_chat_joined WHERE chat_id = ?") (update-stmt "UPDATE user_chats SET invitation_state = ? WHERE id = ?")) (bind-parameters get-stmt uid localpart) (assert (sqlite:step-statement get-stmt) () "Chat ~A doesn't exist in database!" localpart) (with-bound-columns (chat-id invitation-state) get-stmt (bind-parameters count-stmt chat-id) + (bind-parameters count-joined-stmt chat-id) (assert (sqlite:step-statement count-stmt)) + (assert (sqlite:step-statement count-joined-stmt)) (with-bound-columns (n-members) count-stmt - (if (> n-members 0) - (when (equal invitation-state "none") - (with-message (comp jid) - (cxml:with-element "x" - (cxml:attribute "xmlns" +muc-invite-ns+) - (cxml:attribute "jid" (concatenate 'string - localpart - "@" - (component-name comp))))) - (bind-parameters update-stmt "invited" chat-id) - (sqlite:step-statement update-stmt)) - (unless noretry - (request-wa-chat-metadata comp conn jid localpart))))))) + (with-bound-columns (n-joined) count-joined-stmt + (if (> n-members 0) + (when (or + (and use-join-count (eql n-joined 0)) + (equal invitation-state "none")) + (with-message (comp jid) + (cxml:with-element "x" + (cxml:attribute "xmlns" +muc-invite-ns+) + (cxml:attribute "jid" (concatenate 'string + localpart + "@" + (component-name comp))))) + (bind-parameters update-stmt "invited" chat-id) + (sqlite:step-statement update-stmt)) + (unless noretry + (request-wa-chat-metadata comp conn jid localpart)))))))) (defun add-wa-chat (comp conn jid ct-jid) "Adds the JID CT-JID to the list of the user's groupchats, if it is a groupchat. If it's a user JID, sends a presence subscription request if necessary."