JabberEl

jabber.el aims to be a minimal Jabber client.

Screenshots

Roster:

JabberElScreenshotRosterActionMenu

A chat can also be started using the keyboard:

 M-x jabber-chat-with

If you want to, you can configure special-display-regexps to open chats in their own frame:

 (setq 
  special-display-regexps 
  '(("jabber-chat" 
      (width . 80)
     (scroll-bar-width . 16)
     (height . 15)
     (tool-bar-lines . 0)
     (menu-bar-lines 0)
     (font . "-GURSoutline-Courier New-normal-r-normal-normal-11-82-96-96-c-70-iso8859-1")
     (left . 80))))

Looking like this:

JabberElScreenshotRosterAndChatWindow

Customizations

Nifty keybindings

I have this function in my .emacs that I run after I have started emacs. It logs on and defines some nifty keybindings:

(defun jabber ()
  (interactive)
  (require 'jabber)
  (define-key jabber-chat-mode-map [escape] 
    'my-jabber-chat-delete-or-bury)

  (define-key mode-specific-map "jr"
    (lambda () 
      (interactive) 
      (switch-to-buffer "*-jabber-*")))
  
  (define-key mode-specific-map "jc"
    '(lambda () 
       (interactive) 
       (call-interactively 'jabber-connect)))

  (define-key mode-specific-map "jd"
    '(lambda () 
       (interactive) 
       (call-interactively 'jabber-disconnect)))

  (define-key mode-specific-map "jj"
    '(lambda () 
       (interactive) 
       (call-interactively 'jabber-chat-with)))

  (define-key mode-specific-map "ja"
    '(lambda () 
       (interactive) 
       (jabber-send-presence "away" "" 10)))
  
  (define-key mode-specific-map "jo"
    '(lambda () 
       (interactive) 
       (jabber-send-presence "" "" 10)))

  (define-key mode-specific-map "jx"
    '(lambda () 
       (interactive) 
       (jabber-send-presence "xa" "" 10)))
  
  (jabber-connect))


Here is the function my-jabber-chat-delete-or-bury used above:

(defun my-jabber-chat-delete-or-bury ()
  (interactive)
  (if (eq 'jabber-chat-mode major-mode)
      (condition-case e 
          (delete-frame)
        (error 
         (if (string= "Attempt to delete the sole visible or iconified frame" 
                      (cadr e))
            (bury-buffer))))))

Some useful settings

Control message history (which stored in ~/.emacs-jabber dir):

(setq
  jabber-history-enabled t
  jabber-use-global-history nil
  jabber-backlog-number 40
  jabber-backlog-days 30
 )

Don’t disturb me if someone chage presence status (usually remote clients make this automatically):

(setq jabber-alert-presence-message-function (lambda (who oldstatus newstatus statustext) nil))

The above didn’t work for me, and has unbalenced parenthesis in any case… M-x customise-variable jabber-alert-presence-hooks should give you the defcustom offered by the package (jabber-presence-echo is the one)

Redefine standard binding for sending message form RET to C-RET:

(define-key jabber-chat-mode-map (kbd "RET") 'newline)
(define-key jabber-chat-mode-map [C-return] 'jabber-chat-buffer-send)

Change prompt format:

(setq my-chat-prompt "[%t] %n>\n")
(when (featurep 'jabber)
  (setq
   jabber-chat-foreign-prompt-format my-chat-prompt
   jabber-chat-local-prompt-format my-chat-prompt
   jabber-groupchat-prompt-format my-chat-prompt
   jabber-muc-private-foreign-prompt-format "[%t] %g/%n>\n"
   )
  )

Show your status in the header

This snippet will show your buddy’s resource in the HeaderLine, and also show your status if you’re not "online":

    (setq jabber-chat-header-line-format
          '(" " (:eval (jabber-jid-displayname jabber-chatting-with))
    	" " (:eval (jabber-jid-resource jabber-chatting-with)) "\t";
    	(:eval (let ((buddy (jabber-jid-symbol jabber-chatting-with)))
    		 (propertize
    		  (or
    		   (cdr (assoc (get buddy 'show) jabber-presence-strings))
    		   (get buddy 'show))
    		  'face
    		  (or (cdr (assoc (get buddy 'show) jabber-presence-faces))
    		      'jabber-roster-user-online))))
    	"\t" (:eval (get (jabber-jid-symbol jabber-chatting-with) 'status))
    	(:eval (unless (equal "" *jabber-current-show*)
    		 (concat "\t You're " *jabber-current-show*
    			 " (" *jabber-current-status* ")")))))

AutoSmiley mode

Get smileys automatically in jabber chat windows:

    (require 'autosmiley)
    (add-hook 'jabber-chat-mode-hook 'autosmiley-mode)

(Needs Lisp:autosmiley.el (AutoSmiley)

Announcing about new message

Using Xmessage

To configure emacs-jabber to alert you throw incoming message throw Xmessage you can include this into your config file:

(add-hook 'jabber-alert-message-hooks 'jabber-message-xmessage) 

Using xosd

This code will alert about incoming message through xosd. Obviously, it requires xosd (package xosd-bin on debian-like distros)

(setq jabber-xosd-display-time 5)

(defun jabber-xosd-display-message (message)
  "Displays MESSAGE through the xosd"
  (let ((process-connection-type nil))
    (start-process "jabber-xosd" nil "osd_cat" "-p" "bottom" "-A" "center" "-f" "-*-courier-*-*-*-*-30" "-d" (number-to-string jabber-xosd-display-time))
    (process-send-string "jabber-xosd" message)
    (process-send-eof "jabber-xosd")))

(defun jabber-message-xosd (from buffer text propsed-alert)
  (jabber-xosd-display-message "New message."))

(add-to-list 'jabber-alert-message-hooks 'jabber-message-xosd)

; Try this line rather than the add-to-list above 
; if you experience problem on init
;(add-hook 'jabber-alert-message-hooks 'jabber-message-xosd) 

Using notifiy.el (cross platform)

Original code was for libnotify1 and libnotify-bin, but I modified it to use notify.el - http://www.emacswiki.org/emacs/notify.el , which is cross-platform (I tested it on linux and mac).

(require 'notify)

(defun notify-jabber-notify (from buf text proposed-alert)
  "(jabber.el hook) Notify of new Jabber chat messages via notify.el"
  (when (or jabber-message-alert-same-buffer
            (not (memq (selected-window) (get-buffer-window-list buf))))
    (if (jabber-muc-sender-p from)
        (notify (format "(PM) %s"
                       (jabber-jid-displayname (jabber-jid-user from)))
               (format "%s: %s" (jabber-jid-resource from) text)))
      (notify (format "%s" (jabber-jid-displayname from))
             text)))

(add-hook 'jabber-alert-message-hooks 'notify-jabber-notify)

Using xmonad/xmobar

If you want display new message notification like other clients does (notify when there is new message and remove the notification when the messages are read). Xmobar can comunicate with a file, here a simple file on .xmonad directory, but you may want it in /dev/shm

in xmobarrc, add a this :

   	 Run Com "cat" [".xmonad/jabber_notify"] "jabber" 1000

dont forget to put a %jabber% in the template string

in your jabber.el configuration :


(defun send-message-xmobar (msg)
  (if *jabber-connected*
      (call-process-shell-command (format "echo \"%s\" > ~/.xmonad/jabber_notify" msg))))

(defun jabber-notify-xmobar ()
  (if (equal "0" jabber-activity-count-string)
      (send-message-xmobar "")
    (send-message-xmobar (format "<fc=red,black>%s new messages</fc>" jabber-activity-count-string))))

(add-hook 'jabber-activity-update-hook 'jabber-notify-xmobar)

Setting several alerts at a time

If you want to configure several alert systems at a time when a new message arrive, you can include them inside jabber-alert-message-hooks. For example, to receive an Xmessage notification and a system bell beep:

(add-hook 'jabber-alert-message-hooks 'jabber-message-xmessage jabber-message-beep)

Preventing messages in the echo area from clobbering the mini buffer

I found that redefining define-jabber-alert as follows prevents messages arriving while I am using the mini buffer from stealing my focus.

;; Message alert hooks
(define-jabber-alert echo "Show a message in the echo area"
  (lambda (msg)
    (unless (minibuffer-prompt)
      (message "%s" msg))))

Viewing histories

To open a new chat-like buffer in view mode that visits a contact’s history file:

(defun jabber-visit-history (jid)
  "Visit jabber history with JID in a new buffer.

Performs well only for small files.  Expect to wait a few seconds
for large histories.  Adapted from `jabber-chat-create-buffer'."
  (interactive (list (jabber-read-jid-completing "JID: ")))
  (let ((buffer (generate-new-buffer (format "*-jabber-history-%s-*"
                                             (jabber-jid-displayname jid)))))
    (switch-to-buffer buffer)
    (make-local-variable 'jabber-chat-ewoc)
    (setq jabber-chat-ewoc (ewoc-create #'jabber-chat-pp))
    (mapc 'jabber-chat-insert-backlog-entry
          (nreverse (jabber-history-query nil nil t t "."
                                          (jabber-history-filename jid))))
    (view-mode)))

Some ideas for improvement:

   1 Make it work for global history.
   1 Improve performance.
   1 Add searching capabilities (e.g., keyword).

Connecting to Google talk

There is an article related about jabber.el’s issues with Google Talk for connecting and chatting: Read GoogleTalk article.

starttls, gnutls-cli and related issues

If you have problems to connect to a secure jabber server using gnutls-cli (starttls mode), you can try this config:

(setq starttls-use-gnutls t
      starttls-gnutls-program "gnutls-cli"
      starttls-extra-arguments '("--starttls" "--insecure"))

This workaround try to connect to a server when there is a problem with its certificate. The problem usually appears when starttls package is not included in your distro and the server you try to connect has some problem with its certificate.

WARNING!!! as gnutls-cli parameter points to, this configuration could result in an insecure connection. Try to find out which kind of trouble is with server certificate before adding --insecure option.

You can find more information about Debian decision to remove starttls package and other related questions in:

http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=499774

Success-stories :)

I’m using this as my primary jabber client now and have no need for the extra jabber client (I primarily used JAJC on Windows and GAIM on Linux before) and it works really good. The nice thing is of course that you can hack it, customize key bindings etc, something that is much harder to do in most other clients. Among other things I use it as a "agent" to do stuff remotely. Read more about this in the forum on the SourceForge page. – MathiasDahl

I am also using it for two days now. It is a good substitute to the BitlBee/ERC couple. I use it when I do not want to shoot a whole IRC session. Works pretty good. – XavierMaillard

I am using it now, works pretty well under EmacsForWindows with cygwin (for the SSL part). I have to find a way thought to have under linux to show me an icon in my status bar when i get messages. (i guess some kind of python + dbus client server for it). Good work. – chmouel

A note on the above - dbus support is in GNU Emacs in CVS now --GeoffreyTeale

Jabber.el is my XMPP client for last year. Before I used gaim, tkabber, but I not found happiness in it. Jabber.el makes me happy… – Zert

With emacs-jabber-0.7.92 or emacs-jabber-0.8.0 put

;; For debug purpose.
;; (setq jabber-debug-log-xml t)
;; (setq jabber-debug-keep-process-buffers t)

(add-to-list 'load-path "/home/user/usr/share/emacs/site-lisp/emacs-jabber-0.7.92")
(require 'jabber)

(setq jabber-account-list '(
                            ("your-name@gmail.com"
                            ;;   (:password . nil) or (:password . "your-pass")
                              (:network-server . "talk.google.com")
                              (:port . 443)
                              (:connection-type . ssl))
                            ))

in your .emacs in order to connect to gtalk. And press “C-x C-j C-c”!

I have issue with jabber on Windows - 100% CPU load or roster not appear, with openssl it not work in all case. I post to list 100% cpu load with GNUTLS on Windows and finally found solution - Emacs 23.1 + gnutls-cli form Cygwin! – gavenkoa

Setting urgency hint for Emacs frame (only for X Window System).

Function x-urgency-hint allows you to enable or disable urgency hint for the frame FRAME. Set ARG to non-nil to enable urgency hint, nil to disable.

You may, for example, enable urgency hint when the activity list is updated and disable it when the list becomes empty. In this case your WM will start blinking by taskbar button or by window’s header or perform other actions to attract the user’s attention (the appearance depends on WM). Tested with emacs-jabber v0.7.91 and IceWM 1.2.35.

(defun jabber-activity-set-urgency (from buffer text proposed-alert)
  (x-urgency-hint (selected-frame) t))

(defun jabber-activity-update-urgency ()
  (if (zerop (length jabber-activity-jids))
      (x-urgency-hint (selected-frame) nil)))

(add-hook 'jabber-message-hooks 'jabber-activity-set-urgency)
(add-hook 'jabber-activity-update-hook 'jabber-activity-update-urgency)

(defun x-urgency-hint (frame arg &optional source)
  (let* ((wm-hints (append (x-window-property 
			    "WM_HINTS" frame "WM_HINTS" source nil t) nil))
	 (flags (car wm-hints)))
    (setcar wm-hints
	    (if arg
		(logior flags #x100)
	      (logand flags (lognot #x100))))
    (x-change-window-property "WM_HINTS" wm-hints frame "WM_HINTS" 32 t)))

--EvgenyZubok

I’ve been using jabber.el as my primary chat client for a few months now on Windows with great success.

I’ve been using a command line toast notification program (there is a few out there with simple interfaces) to display notifications for chat messages that currently don’t have a window. Which is a nice way to only show notifications when you wouldn’t otherwise see the message:

;; simple toast wrapper, M-x: toast <ret> "Hello, World!" <ret> is fun
(defun toast (message)
  "Display a toast notification."
  (interactive "sMessage: ")
  (if (processp (ignore-errors
		  (start-process "toast-proc" "*toast-notifications*" "toast" (format "%s" message))))
      message
    (warn "Could not create toast notification, is toast installed?")))

;; toast alert hook function
(defun jorbi-jabber/toast-notification (from buffer text title)
  "Show a toast notification if chat buffer not visible."
  (unless (get-buffer-window buffer)
    (toast (format "%s\n%s" title text))))

;; add it to alert hook
(add-hook 'jabber-alert-message-hooks
				  'jorbi-jabber/toast-notification)
				  

I also have a smtp mail system set up so that If I get a chat message and I’ve been idle for 5 minutes, it sends me an email with the message which I will get on my phone.

(defun jorbi/mail-it (subject body)
	"Send an email to yourself with SUBJECT and BODY."
  (require 'smtpmail)
  (let ((mail-interactive nil))
    (with-temp-buffer
      (insert "From:  <placeholder@nothing>\nTo: \nSubject: \n--text follows this line--\n")
      (mail-to) (insert "your-email-address@website.foo")
      (mail-subject) (insert subject)
      (mail-text) (insert body)
      (mail-send))))


(defvar jorbi-jabber/send-mail-idle-time 300
  "Emacs must be idle for this many seconds in order to send mail for jabber messages.")

;; I had problems with sending mail in a hook, the blocking mail process would always
;; fail so I postpone the mail until the other hooks are done running by
;; performing the mail send on an idle timer that is started by a default
;; 2 second timer. Kind of hacky but it works for what I need and doesn't
;; kill the other hooks.
(defun jorbi-jabber/send-mail-notification (from buffer text title)
  "Set up an idle task to send an email to myself with the message if I've \
been idle for a little bit when the message comes in."
  (when (> (time-to-seconds (or (current-idle-time) (seconds-to-time 0)))
	   (or jorbi-jabber/send-mail-idle-time 300))
    (run-with-timer
     2 nil
     (lambda (from buffer text title)
       (run-with-idle-timer
        2 nil
        (lambda (from buffer text title)
          (jorbi/mail-it (format "JABBERNOT: (%s)" title)
		   (format "AUTOMATIC NOTIFICATION FROM JABBERNOT-BOT 9000\n\n[%s]: %s"
			   from text)))
        from buffer text title))
     from buffer text title)))

;; add it to alert hook
(add-hook 'jabber-alert-message-hooks
				  'jorbi-jabber/send-mail-notification)

JordonBiondo

Page discussion

Are there any catches in using JabberEl to connect to two different jabber services at the same time? (i.e. google talk and an ordinary jabber…) How does one go about that? --MartinJ

This is currently only possible in the CVS version. You can set up all your accounts in jabber-account-list (e.g. by using Customize), or just connect them manually with M-x jabber-connect-one. (C-x C-j C-c will connect to all accounts in jabber-account-list, or if that is empty, ask you for an account to connect to) --MagnusHenoch

Note that this was recently released as 0.8.0. See http://emacs-jabber.sourceforge.net/list-of-releases.html for more info. --JuneTateGans

I had a problem recently with the 0.8.0 version. The file jabber-muc-nick-completion.el defines a function modify-alist, which, according to grep, is used only in that file. However, I had loaded apel, which also defines modify-alist, and not in a compatible way. Therefore, I simply changed the name of jabber’s version to jabber-modify-alist. Maybe this is already done in CVS, but I thought I’d mention it in case it’s not. --JosephGay

I had to use @googlemail.com rather than @gmail.com to get gtalk to work.

I finally got emacs-jabber up and running on my Debian Lenny machine. It refused to work for a really long time, it always stopped with a ssl error, saying that the server name does not match the certificate. Installation of the starttls package, which was not installed before, fixed the problem for me. I hope that this hint can save someone else from some headache. Update: It refuses to work again, no apparent reason.

I seem to have problems if I, by reflex, close the *-jabber-* buffer. That seems to just totally hose me. Even if I do a jabber-disconnect, jabber-connect, although the buffer comes back and says I’m online, I can’t see anyone and can’t even do a version query on myself. --PaulGoins

Painfully, jabber.el doesn’t support PGP, meaning that messages can’t be encrypted between receiving clients. If you consider that a privacy concern, consider using Gajim, Psi, or a similar Jabber client.

Is there a plan to save history for groupchat too? --DanielDehennin

Is it possible to dynamically turn on and off the alerts for specific chats? --Chet

Recently I found the emacs jabber client no longer working properly. it is version 8.0. the problem is no contact shown in the buffer *-jabber-roster-* after login, but jabber says me online. the jabber seems never go ahead when it shows “Authentication succeeded” in the minibuffer. but previously it would continue to show “….. is online” messages and load all contacts in the roster buffer. --Cesc

Are you connecting to Google Talk by any chance? Those symptoms sounds very much like a problem that’s solved in the recent 0.8.90 release. (Google Talk recently started using namespace prefixes, which jabber.el was rather ill-prepared for.) --MagnusHenoch

Yes, it is Google Talk. And I have checked out the git version for namespace prefixes after I saw the information in the mail list. It works now. --Cesc

Hi, I just write a simple extension to upload image or other files using HTTP file upload extension(XEP-0363).

https://github.com/yuchangyuan/jabber-http-file-upload


CategoryChatClient