294 lines
11 KiB
EmacsLisp
294 lines
11 KiB
EmacsLisp
|
;;; slack-group.el --- slack private group interface -*- lexical-binding: t; -*-
|
||
|
|
||
|
;; Copyright (C) 2015 Yuya Minami
|
||
|
|
||
|
;; Author: Yuya Minami
|
||
|
;; Keywords:
|
||
|
|
||
|
;; This program is free software; you can redistribute it and/or modify
|
||
|
;; it under the terms of the GNU General Public License as published by
|
||
|
;; the Free Software Foundation, either version 3 of the License, or
|
||
|
;; (at your option) any later version.
|
||
|
|
||
|
;; This program is distributed in the hope that it will be useful,
|
||
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
;; GNU General Public License for more details.
|
||
|
|
||
|
;; You should have received a copy of the GNU General Public License
|
||
|
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
|
|
||
|
;;; Commentary:
|
||
|
|
||
|
;;
|
||
|
|
||
|
;;; Code:
|
||
|
|
||
|
(require 'eieio)
|
||
|
(require 'slack-room)
|
||
|
(require 'slack-util)
|
||
|
(require 'slack-buffer)
|
||
|
(require 'slack-request)
|
||
|
|
||
|
(defconst slack-group-history-url "https://slack.com/api/groups.history")
|
||
|
(defconst slack--group-open-url "https://slack.com/api/groups.open")
|
||
|
(defconst slack-group-buffer-name "*Slack - Private Group*")
|
||
|
(defconst slack-group-list-url "https://slack.com/api/groups.list")
|
||
|
(defconst slack-group-update-mark-url "https://slack.com/api/groups.mark")
|
||
|
(defconst slack-create-group-url "https://slack.com/api/groups.create")
|
||
|
(defconst slack-group-rename-url "https://slack.com/api/groups.rename")
|
||
|
(defconst slack-group-invite-url "https://slack.com/api/groups.invite")
|
||
|
(defconst slack-group-leave-url "https://slack.com/api/groups.leave")
|
||
|
(defconst slack-group-archive-url "https://slack.com/api/groups.archive")
|
||
|
(defconst slack-group-unarchive-url "https://slack.com/api/groups.unarchive")
|
||
|
(defconst slack-mpim-close-url "https://slack.com/api/mpim.close")
|
||
|
(defconst slack-mpim-open-url "https://slack.com/api/mpim.open")
|
||
|
(defconst slack-group-info-url "https://slack.com/api/groups.info")
|
||
|
|
||
|
(defvar slack-buffer-function)
|
||
|
|
||
|
(defclass slack-group (slack-room)
|
||
|
((is-group :initarg :is_group :initform nil)
|
||
|
(creator :initarg :creator :initform "")
|
||
|
(is-archived :initarg :is_archived :initform nil)
|
||
|
(is-mpim :initarg :is_mpim :initform nil)
|
||
|
(members :initarg :members :type list :initform '())
|
||
|
(topic :initarg :topic :initform nil)
|
||
|
(purpose :initarg :purpose :initform nil)))
|
||
|
|
||
|
(defmethod slack-merge ((this slack-group) other)
|
||
|
(call-next-method)
|
||
|
(with-slots (is-group creator is-archived is-mpim members topic purpose) this
|
||
|
(setq is-group (oref other is-group))
|
||
|
(setq creator (oref other creator))
|
||
|
(setq is-archived (oref other is-archived))
|
||
|
(setq is-mpim (oref other is-mpim))
|
||
|
(setq members (oref other members))
|
||
|
(setq topic (oref other topic))
|
||
|
(setq purpose (oref other purpose))))
|
||
|
|
||
|
(defun slack-group-names (team &optional filter)
|
||
|
(with-slots (groups) team
|
||
|
(slack-room-names groups filter)))
|
||
|
|
||
|
(defmethod slack-room-subscribedp ((room slack-group) team)
|
||
|
(with-slots (subscribed-channels) team
|
||
|
(let ((name (slack-room-name room)))
|
||
|
(and name
|
||
|
(memq (intern name) subscribed-channels)))))
|
||
|
|
||
|
(defmethod slack-room-buffer-name ((room slack-group))
|
||
|
(concat slack-group-buffer-name
|
||
|
" : "
|
||
|
(slack-room-display-name room)))
|
||
|
|
||
|
(defun slack-group-select ()
|
||
|
(interactive)
|
||
|
(let* ((team (slack-team-select))
|
||
|
(room (slack-room-select
|
||
|
(cl-loop for team in (list team)
|
||
|
for groups = (oref team groups)
|
||
|
nconc groups))))
|
||
|
(slack-room-display room team)))
|
||
|
|
||
|
(defun slack-group-list-update (&optional team after-success)
|
||
|
(interactive)
|
||
|
(let ((team (or team (slack-team-select))))
|
||
|
(cl-labels ((on-list-update
|
||
|
(&key data &allow-other-keys)
|
||
|
(slack-request-handle-error
|
||
|
(data "slack-group-list-update")
|
||
|
(slack-merge-list (oref team groups)
|
||
|
(mapcar #'(lambda (g)
|
||
|
(slack-room-create
|
||
|
g team 'slack-group))
|
||
|
(plist-get data :groups)))
|
||
|
(if after-success
|
||
|
(funcall after-success team))
|
||
|
(mapc #'(lambda (room)
|
||
|
(slack-room-info-request room team))
|
||
|
(oref team groups))
|
||
|
(slack-log "Slack Group List Updated" team :level 'info))))
|
||
|
(slack-room-list-update slack-group-list-url
|
||
|
#'on-list-update
|
||
|
team
|
||
|
:sync nil))))
|
||
|
|
||
|
|
||
|
(defmethod slack-room-update-mark-url ((_room slack-group))
|
||
|
slack-group-update-mark-url)
|
||
|
|
||
|
(defun slack-create-group ()
|
||
|
(interactive)
|
||
|
(let ((team (slack-team-select)))
|
||
|
(cl-labels
|
||
|
((on-create-group (&key data &allow-other-keys)
|
||
|
(slack-request-handle-error
|
||
|
(data "slack-create-group"))))
|
||
|
(slack-create-room slack-create-group-url
|
||
|
team
|
||
|
#'on-create-group))))
|
||
|
|
||
|
(defun slack-group-rename ()
|
||
|
(interactive)
|
||
|
(slack-room-rename slack-group-rename-url
|
||
|
#'slack-group-names))
|
||
|
|
||
|
(defun slack-group-invite ()
|
||
|
(interactive)
|
||
|
(slack-room-invite slack-group-invite-url
|
||
|
#'slack-group-names))
|
||
|
|
||
|
(defun slack-group-leave ()
|
||
|
(interactive)
|
||
|
(let* ((team (slack-team-select))
|
||
|
(group (slack-current-room-or-select
|
||
|
#'(lambda ()
|
||
|
(slack-group-names team)))))
|
||
|
(cl-labels
|
||
|
((on-group-leave
|
||
|
(&key data &allow-other-keys)
|
||
|
(slack-request-handle-error
|
||
|
(data "slack-group-leave")
|
||
|
(with-slots (groups) team
|
||
|
(setq groups
|
||
|
(cl-delete-if #'(lambda (g)
|
||
|
(slack-room-equal-p group g))
|
||
|
groups)))
|
||
|
(message "Left Group: %s"
|
||
|
(slack-room-display-name group)))))
|
||
|
(slack-room-request-with-id slack-group-leave-url
|
||
|
(oref group id)
|
||
|
team
|
||
|
#'on-group-leave))))
|
||
|
|
||
|
(defmethod slack-room-archived-p ((room slack-group))
|
||
|
(oref room is-archived))
|
||
|
|
||
|
(defun slack-group-archive ()
|
||
|
(interactive)
|
||
|
(let* ((team (slack-team-select))
|
||
|
(group (slack-current-room-or-select
|
||
|
#'(lambda ()
|
||
|
(slack-group-names
|
||
|
team
|
||
|
#'(lambda (groups)
|
||
|
(cl-remove-if #'slack-room-archived-p
|
||
|
groups)))))))
|
||
|
(cl-labels
|
||
|
((on-group-archive (&key data &allow-other-keys)
|
||
|
(slack-request-handle-error
|
||
|
(data "slack-group-archive"))))
|
||
|
(slack-room-request-with-id slack-group-archive-url
|
||
|
(oref group id)
|
||
|
team
|
||
|
#'on-group-archive))))
|
||
|
|
||
|
(defun slack-group-unarchive ()
|
||
|
(interactive)
|
||
|
(let* ((team (slack-team-select))
|
||
|
(group (slack-current-room-or-select
|
||
|
#'(lambda ()
|
||
|
(slack-group-names
|
||
|
team
|
||
|
#'(lambda (groups)
|
||
|
(cl-remove-if-not #'slack-room-archived-p
|
||
|
groups)))))))
|
||
|
(cl-labels
|
||
|
((on-group-unarchive (&key _data &allow-other-keys)
|
||
|
(data "slack-group-unarchive")))
|
||
|
(slack-room-request-with-id slack-group-unarchive-url
|
||
|
(oref group id)
|
||
|
team
|
||
|
#'on-group-unarchive))))
|
||
|
|
||
|
|
||
|
(defun slack-group-members-s (group)
|
||
|
(with-slots (members team-id) group
|
||
|
(mapconcat #'(lambda (user) (slack-user-name user
|
||
|
(slack-team-find team-id)))
|
||
|
members ", ")))
|
||
|
|
||
|
|
||
|
(defun slack-group-mpim-open ()
|
||
|
(interactive)
|
||
|
(let* ((team (slack-team-select))
|
||
|
(users (slack-user-names team)))
|
||
|
(cl-labels
|
||
|
((select-users (users acc)
|
||
|
(let ((selected (funcall slack-completing-read-function "Select User: "
|
||
|
users nil t)))
|
||
|
(if (< 0 (length selected))
|
||
|
(select-users users
|
||
|
(push (cdr (cl-assoc selected users :test #'string=)) acc))
|
||
|
acc)))
|
||
|
(on-success
|
||
|
(&key data &allow-other-keys)
|
||
|
(slack-request-handle-error
|
||
|
(data "slack-group-mpim-open")
|
||
|
(if (plist-get data :already_open)
|
||
|
(message "Direct Message Channel with %s Already Open"
|
||
|
(slack-group-members-s (slack-room-find (oref selected id) team)))
|
||
|
(oset team groups
|
||
|
(cons (slack-room-create (plist-get data :group) team 'slack-group)
|
||
|
(oref team groups)))))))
|
||
|
(slack-request
|
||
|
(slack-request-create
|
||
|
slack-mpim-open-url
|
||
|
team
|
||
|
:type "POST"
|
||
|
:params (list (cons "users" (mapconcat (lambda (u) (plist-get u :id)) (select-users users '()) ",")))
|
||
|
:success #'on-success)))))
|
||
|
|
||
|
(defun slack-group-mpim-close ()
|
||
|
(interactive)
|
||
|
(let* ((team (slack-team-select)))
|
||
|
(slack-select-from-list
|
||
|
((slack-group-names team #'(lambda (groups)
|
||
|
(cl-remove-if-not #'slack-mpim-p
|
||
|
groups)))
|
||
|
"Select MPIM: ")
|
||
|
(cl-labels
|
||
|
((on-success
|
||
|
(&key data &allow-other-keys)
|
||
|
(slack-request-handle-error
|
||
|
(data "slack-group-mpim-close")
|
||
|
(let ((group (slack-room-find (oref selected id) team)))
|
||
|
(with-slots (groups) team
|
||
|
(setq groups
|
||
|
(cl-delete-if #'(lambda (g)
|
||
|
(slack-room-equal-p group g))
|
||
|
groups)))
|
||
|
(if (plist-get data :already_closed)
|
||
|
(message "Direct Message Channel with %s Already Closed"
|
||
|
(slack-group-members-s group)))))))
|
||
|
(slack-request
|
||
|
(slack-request-create
|
||
|
slack-mpim-close-url
|
||
|
team
|
||
|
:type "POST"
|
||
|
:params (list (cons "channel" (oref selected id)))
|
||
|
:success #'on-success))))))
|
||
|
|
||
|
|
||
|
(defmethod slack-mpim-p ((room slack-group))
|
||
|
(oref room is-mpim))
|
||
|
|
||
|
(defmethod slack-room-get-info-url ((_room slack-group))
|
||
|
slack-group-info-url)
|
||
|
|
||
|
(defmethod slack-room-update-info ((room slack-group) data team)
|
||
|
(let ((new-room (slack-room-create (plist-get data :group)
|
||
|
team
|
||
|
'slack-group)))
|
||
|
(slack-merge room new-room)))
|
||
|
|
||
|
(defmethod slack-room-history-url ((_room slack-group))
|
||
|
slack-group-history-url)
|
||
|
|
||
|
(defmethod slack-room-replies-url ((_room slack-group))
|
||
|
"https://slack.com/api/groups.replies")
|
||
|
|
||
|
(provide 'slack-group)
|
||
|
;;; slack-group.el ends here
|