#18 Executing action X when buddy Y changes status to Z

closed
nobody
None
5
2004-11-21
2004-10-26
No

Today I had an itch, and scratched it. But I scratched
it in a very ugly way...

What I wanted to do was to get some sort of
notification that I did not miss when a certain friend
of mine came online. If he had used Jabber or ICQ I
could have sent him an off-line message but that is not
possible with MSN.

So, I dived into the code and added some hard-coded test in
jabber-presence-echo, like this:

(defun jabber-presence-echo (who oldstatus newstatus
statustext proposed-alert)
"Show a message in the echo area"
(when proposed-alert
(if (string-match "johan" proposed-alert)
(w32-net-send-send "mdahse" proposed-alert))
(message "%s" proposed-alert)))

Now, this is extremely hard coded of course:

- mdahse is my user name at work
- w32-net-send-send is part of my package w32-net-send
- "johan" is hard coded
- it does not matter if Johan comes online or goes offline
- etc ad finitum...

It would be cool if there was a very general way of
executing action X when Y changes status to Z or, for
that matter, doing X when something Y happens. Hmm,
maybe this is too wierd...

The specific problem I had could of course also be
solved by some kind of message queue stored in Emacs
(in memory to start with), for IM systems that does not
support it.

Anyway, I solved my problem for now, but maybe this
will give you hackers some idea of something cool to
add to the next release.

/Mathias

Discussion

  • Magnus Henoch

    Magnus Henoch - 2004-10-26

    Logged In: YES
    user_id=920364

    Another way to do this:

    (defun my-catch-johan (who oldstatus newstatus statustext
    proposed-alert)
    (if (and (string-match "johan" (get who 'name))
    (null oldstatus)
    (not (null newstatus)))
    (w32-net-send-send "mdahse" "Hey, don't miss Johan!")))
    (add-hook 'jabber-alert-presence-hooks 'my-catch-johan)

    But having a more specific hook for "X goes online" sounds
    cool... it wouldn't be hard to expand your example into a
    presence alert hook that just looks up users and actions in
    an alist or something.

    I'm not quite sure how the user interface for that would be.
    Maybe something like (in minibuffer prompts):

    M-x jabber-watch-online
    What user: (standard JID selection goes here)
    What action: (lambda () (ding) (message "look, he's online"))
    Remember forever? n
    How many times? 1

    I think entering a function for the action is the most
    reasonable thing to do, although it requires some lisp skills.

    This is a quite specific example, and I think the answer to
    the general problem of "do X when Y happens" is still "write
    an alert hook". But having a lot of specific features isn't
    wrong either.

    Magnus

     
  • Barman Brakjoller

    Logged In: YES
    user_id=159953

    Thanks for the hint!

    The

    (get who 'name)

    was very informative.

    /Mathias

     
  • Barman Brakjoller

    Logged In: YES
    user_id=159953

    Here is my try:

    ;;;; my-jabber-presence-watch begins here

    (defvar my-jabber-presence-watch-list
    nil
    "List of buddies for which an extra notification should be
    send
    when they come online")

    (defun my-jabber-presence-watch (who oldstatus newstatus
    statustext proposed-alert)
    "Checks if one of your extra-important buddies comes
    online and
    sends a message if that happens. The buddies are stored in
    `my-jabber-presence-watch-list' and are added and removed by
    calling `my-jabber-presence-watch-add-buddy' and
    `my-jabber-presence-watch-remove-buddy.'"
    (if (and (null oldstatus)
    (not (null newstatus)))
    (let ((my-list my-jabber-presence-watch-list)
    current)
    (while my-list
    (setq current (car my-list))
    (if (string= (get who 'name) current)
    ;; Something better than this should be used
    here. Maybe
    ;; we could open a small teenie weenie frame
    like that
    ;; ediff uses?
    (w32-net-send-send "mdahse" (format "%s is
    online now." current)))
    (setq my-list (cdr my-list))))))

    (defun my-jabber-presence-watch-add-buddy (buddy)
    (interactive "sAdd buddy to watch list: ")
    (add-to-list 'my-jabber-presence-watch-list buddy))

    (defun my-jabber-presence-watch-remove-buddy ()
    (interactive)
    (setq my-jabber-presence-watch-list
    (remove (completing-read
    "Buddy to remove from watch list: "
    my-jabber-presence-watch-list nil t)
    my-jabber-presence-watch-list)))

    (add-hook 'jabber-alert-presence-hooks
    'my-jabber-presence-watch)

    ;;;; my-jabber-presence-watch ends here

    My elisp isn't the best so there is probably room for
    improvements, but it should work fairly well.

    /Mathias

     
  • Magnus Henoch

    Magnus Henoch - 2004-10-30

    Logged In: YES
    user_id=920364

    Can message-box be used instead of w32-net-send-send? It is
    noticeable enough for X and Mac, but I can't test w32 right now.

    Magnus

     
  • Barman Brakjoller

    Logged In: YES
    user_id=159953

    Yes, it is probably what I wanted all along but I did not
    know about its existence. Until now... :)

    /Mathias

     
  • Magnus Henoch

    Magnus Henoch - 2004-11-05

    Logged In: YES
    user_id=920364

    There. I've taken your code, hacked it a bit, and put it in
    jabber-watch.el in CVS. jabber-presence-watch is one of the
    default presence hooks now.

    This works for me, though I may have missed something obvious...

    Magnus

     
  • Barman Brakjoller

    Logged In: YES
    user_id=159953

    It does not work for me. I have tried to debug a bit and it
    seems that it is the (memq who jabber-watch-list) that never
    returns true. Maybe you have tested only with jabber
    friends? Here is what I got when I debugged a bit:

    (defun jabber-presence-watch (who oldstatus newstatus
    statustext proposed-alert)
    "Checks if one of your extra-important buddies comes
    online and
    sends a message if that happens. The buddies are stored in
    `jabber-watch-list' and are added and removed by calling
    `jabber-watch-add' and `jabber-watch-remove.'"
    ;; check that buddy was previously offline and now online
    (message "==> Who: %s, oldstatus: %s, newstatus: %s" who
    oldstatus newstatus)
    ...

    The output:

    tho is now Online
    ==> Who: 1234567@icq.jabbernet.dk, oldstatus: nil, newstatus:

    When I do this in the code:

    (setq my-who who)

    and evaluate it, I get:

    1234567@icq\.jabbernet\.dk

    I tried this just to see how memq works:

    (setq my-who-2 '1234567@icq\.jabbernet\.dk)
    (memq my-who-2 jabber-watch-list)

    but memq still returns nil even though my buddy 123... is on
    the list.

    Any ideas?

     
  • Barman Brakjoller

    Logged In: YES
    user_id=159953

    When I tested today it works, hmm...

     
  • Magnus Henoch

    Magnus Henoch - 2004-11-21
    • status: open --> closed
     
  • Magnus Henoch

    Magnus Henoch - 2004-11-21

    Logged In: YES
    user_id=920364

    Seems to work for me too... closing this.

    Magnus

     

Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks