|
4 | 4 | [clojure.string :as str]
|
5 | 5 | [co.gaiwan.compass.config :as config]
|
6 | 6 | [hato.client :as hato]
|
7 |
| - [io.pedestal.log :as log])) |
| 7 | + [io.pedestal.log :as log] |
| 8 | + [co.gaiwan.compass.db :as db])) |
8 | 9 |
|
9 | 10 | (def discord-api-endpoint "https://discord.com/api/v10")
|
10 | 11 |
|
|
23 | 24 | :as :auto
|
24 | 25 | :headers (bot-auth-headers)}
|
25 | 26 | body (assoc :content-type :json :form-params body)))]
|
26 |
| - (log/trace :discord/request (:request response) :discord/response (dissoc response :request)) |
| 27 | + (log/trace :discord/request (-> response :request (update :headers dissoc "Authorization")) :discord/response (dissoc response :request)) |
27 | 28 | response)))
|
28 | 29 |
|
29 | 30 | (defn fetch-user-info [token]
|
|
71 | 72 | "late-conference"
|
72 | 73 | "student"} slug)
|
73 | 74 | (conj "regular-ticket")))))
|
| 75 | + |
| 76 | +(defn create-session-thread |
| 77 | + "Create private thread for session in channel configured by `:discord/session-channel-id`." |
| 78 | + [session] |
| 79 | + (let [{:keys [status] thread :body :as response} |
| 80 | + (discord-bot-request |
| 81 | + :post |
| 82 | + (str "/channels/" (config/value :discord/session-channel-id) "/threads") |
| 83 | + {:name (->> session :session/title (take 100) str/join) |
| 84 | + :type 12 ;; PRIVATE_THREAD |
| 85 | + :invitable true})] |
| 86 | + (case status |
| 87 | + 201 |
| 88 | + (do |
| 89 | + (db/transact [[:db/add (:db/id session) :session/thread-id (:id thread)]]) |
| 90 | + thread) |
| 91 | + (log/error :discord/thread-create-failed "Failed to create session thread" |
| 92 | + :session session |
| 93 | + :response (dissoc response :request))))) |
| 94 | + |
| 95 | +(defn get-session-thread |
| 96 | + "Get existing thread for session (or `nil`)." |
| 97 | + [session] |
| 98 | + (let [id (:session/thread-id session) |
| 99 | + {channel :body :keys [status] :as response} (discord-bot-request :get (str "/channels/" id))] |
| 100 | + (case status |
| 101 | + ;; thread already exists |
| 102 | + 200 channel |
| 103 | + ;; thread does not exist |
| 104 | + 404 nil |
| 105 | + ;; something else? |
| 106 | + (log/error |
| 107 | + :discord/thread-fetch-failed (str "Unhandled status code " status " for getting session thread") |
| 108 | + :session session |
| 109 | + :response (dissoc response :request))))) |
| 110 | + |
| 111 | +(defn user-mention |
| 112 | + "Discord ID -> text that pings user" |
| 113 | + [user-id] |
| 114 | + (str "<@" user-id ">")) |
| 115 | + |
| 116 | +(defn send-session-thread-message |
| 117 | + "Send a message to the session thread belonging to `session-id`. |
| 118 | +
|
| 119 | + Returns `nil`. |
| 120 | + A `message` containing @everyone will send a notification to all thread members. |
| 121 | + A `message` mentioning one or more individual users ([[user-mention]]) will notify and add those users to the thread. |
| 122 | + Will fail if there is no session thread (yet) or if the sending the message fails. |
| 123 | + In both cases, an error message is logged." |
| 124 | + [session-id message] |
| 125 | + (if-let [{:keys [id] :as _thread} (get-session-thread (db/entity session-id))] |
| 126 | + (let [{:keys [status] :as response} |
| 127 | + (discord-bot-request |
| 128 | + :post |
| 129 | + (str "/channels/" id "/messages") |
| 130 | + {:content message |
| 131 | + :allowed_mentions {:parse ["users" "everyone"]}})] |
| 132 | + (when-not (= status 200) |
| 133 | + (log/error |
| 134 | + :discord/message-send-fail "Failed to send message to session thread" |
| 135 | + :session (db/entity session-id) |
| 136 | + :response (dissoc response :request)))) |
| 137 | + (log/error :discord/missing-session-thread "Tried to send message to session thread that doesn't exist"))) |
| 138 | + |
| 139 | +(defn add-to-session-thread |
| 140 | + "Add user with `user-id` to session thread of session with `session-id`. |
| 141 | +
|
| 142 | + Returns `nil`. In case of failure, an error message is logged." |
| 143 | + [session-id user-id] |
| 144 | + (let [session (db/entity session-id) |
| 145 | + {:keys [status] :as response} (discord-bot-request :put (str "/channels/" (:session/thread-id session) "/thread-members/" user-id))] |
| 146 | + (when-not (= status 204) |
| 147 | + (log/error |
| 148 | + :discord/thread-member-add-failed "Failed to add member to session thread" |
| 149 | + :session session |
| 150 | + :response (dissoc response :request))))) |
0 commit comments