Skip to content

Instantly share code, notes, and snippets.

@egh
Last active January 3, 2018 18:08
Show Gist options
  • Save egh/5f46b5d6d2061f305b46 to your computer and use it in GitHub Desktop.
Save egh/5f46b5d6d2061f305b46 to your computer and use it in GitHub Desktop.
jabber.el hipchat setup
(require 's)
(require 'request)
(require 'seq)
(require 'jabber)
(defvar hipchat--user-info-for-completion nil)
(defcustom hipchat-nickname "Full name" "Hipchat real name (see see https://hipchat.com/account/xmpp)."
:type '(string)
:group 'hipchat)
(defcustom hipchat-autojoin nil "List of rooms to autojoin."
:type '(repeat string)
:group 'hipchat)
(defcustom hipchat-api-key nil "API key for hipchat.
Used for @ mention autocompletion. Get via hipchat.com / Account
settings / API access. Must have view_group scope."
:type '(string)
:group 'hipchat)
(defun hipchat-get-jid ()
"Return the JID of the users hipchat account."
(car (seq-elt (seq-filter (lambda (acct)
(s-match "chat.hipchat.com" (car acct)))
jabber-account-list) 0)))
(defun hipchat-get-connection ()
"Return the hipchat jabber connetion."
(jabber-find-connection (hipchat-get-jid)))
(defun hipchat-list ()
"Open a list of all hipchat rooms."
(interactive)
(jabber-get-disco-items (hipchat-get-connection) "conf.hipchat.com" nil))
(defun hipchat-join-raw (groupid)
"Join the hipchat group GROUPID."
(jabber-muc-join (hipchat-get-connection) groupid hipchat-nickname t))
(defun hipchat-join ()
"Prompt for hipchat group and join it."
(interactive)
(jabber-disco-get-items
(hipchat-get-connection) "conf.hipchat.com" nil
(lambda (jc data items)
(let* ((groups (mapcar (lambda (item)
(cons (elt item 0) (elt item 1))) items))
(groupname (completing-read "Room name: " groups))
(groupid (cdr (assoc groupname groups))))
(if (y-or-n-p (format "Autojoin %s in the future? " groupname))
(customize-push-and-save 'hipchat-autojoin (list groupid)))
(hipchat-join-raw groupid)))
nil))
(defun hipchat-load-user-info ()
"Load user information from hipchat API for autocompletion."
(request
"https://api.hipchat.com/v2/user"
:params `(("auth_token" . ,hipchat-api-key)
("max-results" . "500"))
:parser 'json-read
:success (function*
(lambda (&key data &allow-other-keys)
(setq hipchat--user-info-for-completion nil)
(seq-map (lambda (user)
(push (cons (format "@%s" (cdr (assq 'mention_name user)))
(cdr (assq 'name user)))
hipchat--user-info-for-completion))
(cdr (assq 'items data)))
(setq hipchat--user-info-for-completion
(completion-table-case-fold hipchat--user-info-for-completion))))))
(defun hipchat-setup-hook (jc)
"Hook to run to setup hipchat. Add to `jabber-post-connect-hooks'."
(when (eq jc (hipchat-get-connection))
(hipchat-load-user-info)
(mapcar (lambda (id)
(hipchat-join-raw id))
hipchat-autojoin)))
(defun hipchat-setup-completion ()
"Setup hipchat @ mention completion. Add to `jabber-chat-mode-hook'."
(define-key jabber-chat-mode-map [?\t] 'completion-at-point)
(add-to-list 'completion-at-point-functions #'hipchat-complete-mention-function))
(defun hipchat-complete-mention-function (&optional start)
"Completion at point function for hipchat @ mention completion."
(let* ((end (point))
(start
(or start
(save-excursion
(re-search-backward "@")
(point)))))
(list start end hipchat--user-info-for-completion)))
(add-hook 'jabber-post-connect-hooks #'hipchat-setup-hook)
(add-hook 'jabber-chat-mode-hook #'hipchat-setup-completion)
;; use this if you don't like all those notices about people joining/leaving
(defadvice jabber-muc-process-presence
(after jabber-muc-process-presence-clear-notices)
"Remove all muc notices."
(let* ((from (jabber-xml-get-attribute presence 'from))
(group (jabber-jid-user from))
(buffer (get-buffer (jabber-muc-get-buffer group))))
(if buffer
(with-current-buffer buffer
(ewoc-filter jabber-chat-ewoc (lambda (elt) (not (eq (car elt) :muc-notice))))))))
(ad-activate #'jabber-muc-process-presence)
;; Render HTML. Especially useful for notifications.
(when (functionp #'shr-insert-document)
(defun jabber-chat-html-body (xml-data who mode)
"Render HTML content in jabber buffer."
(if (string-equal "html" (nth 2 (assq 'message_format (cdr (assq 'x (cdr xml-data))))))
(if (eq mode :printp)
t
(let ((parsed (with-temp-buffer
(insert (nth 1 (cdr (assq 'body (cdr xml-data)))))
(libxml-parse-html-region (point-min) (point-max)))))
(shr-insert-document parsed)
t))
nil))
(add-to-list 'jabber-body-printers #'jabber-chat-html-body))
@agzam
Copy link

agzam commented Oct 24, 2015

really nice. do you guys know how to retrieve messages from server? Someone sends you a message while you're not connected. You connect and still won't see missed messages. In hipchat's client they'd appear though. Also is it possible at all to have inline images to show up right there in Emacs?

@egh
Copy link
Author

egh commented Oct 30, 2015

@ispyinternet Sorry for the late response. You might try setting your jabber-account-list using M-x customize-variable. (You will need to delete the setting in your .emacs.) This will ensure you have the right format for the variable.

@egh
Copy link
Author

egh commented Oct 30, 2015

@agzam When I login hipchat dumps a bunch of history into my channels. But I don't think there is a way to get the history further back. You can use jabber.el history, though.

@egh
Copy link
Author

egh commented Nov 3, 2015

Now with support for HTML rendering and stripping out all those presence notifications.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment