-
Notifications
You must be signed in to change notification settings - Fork 14
/
embeds.clj
102 lines (88 loc) · 4.03 KB
/
embeds.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
(ns discord.embeds
(:require [clj-time.format :as f]
[clj-time.coerce :as c]))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Embedded Fields
;;;
;;; An embed in a message can contain a number of things, each of which has optional properties
;;; that can be present of missing. Below is a series of records that captures these.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defrecord EmbedFooter [text icon_url proxy_icon_url])
(defrecord EmbedField [name value inline])
(defrecord EmbedVideo [url height width])
(defrecord EmbedImage [url proxy_url height width])
(defrecord EmbedProvider [name url])
(defrecord EmbedAuthor [name url icon_url proxy_icon_url])
(defrecord EmbedThumbnail [url proxy_url height width])
(defrecord Embed [title type description url timestamp color footer image thumbnail video
provider author fields])
(defn- get-iso-timestamp []
(let [iso-formatter (f/formatters :date-hour-minute-second-ms)]
(->> (System/currentTimeMillis)
(c/from-long)
(f/unparse iso-formatter))))
(defn create-embed
"Creates an Discord embed object that can be included in a message. These are built by
successively applying modifier functions."
[& {:keys [title description url color] :as embed-options}]
(let [timestamp (get-iso-timestamp)]
(map->Embed
{:title title
:type "rich"
:description description
:url url
:color color
:timestamp timestamp})))
(defn +footer
"Sets the footer in the supplied message embed."
[embed text & {:keys [icon-url proxy-icon-url]}]
(assoc embed :footer (EmbedFooter. text icon-url proxy-icon-url)))
(defn +field
"Adds a field to the supplied message embed."
[embed name value & {:keys [inline] :or {inline false}}]
(update embed :fields conj (EmbedField. name value inline)))
(defn +video
"Sets the footer in the supplied message embed."
[embed & {:keys [url height width]}]
(assoc embed :video (EmbedVideo. url height width)))
(defn +image
"Sets the footer in the supplied message embed."
[embed & {:keys [url proxy-url height width]}]
(assoc embed :image (EmbedImage. url proxy-url height width)))
(defn +provider
"Sets the footer in the supplied message embed."
[embed & {:keys [name url]}]
(assoc embed :provider (EmbedProvider. name url)))
(defn +author
"Sets the footer in the supplied message embed."
[embed & {:keys [name url icon-url proxy-icon-url]}]
(assoc embed :author (EmbedAuthor. name url icon-url proxy-icon-url)))
(defn +thumbnail
"Sets the footer in the supplied message embed."
[embed & {:keys [url proxy-url height width]}]
(assoc embed :thumbnail (EmbedThumbnail. url proxy-url height width)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Converting Embeds into maps for the Discord API
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defn- prune-into-map
"Removes keys from a map that have nil valules."
[m]
(->> m
(into {})
(remove (comp nil? second))
(into {})))
(defn embed->map
"Converts the Embed record into a map with no nil valued fields."
[embed]
(as-> embed embed
(if (:image embed) (assoc embed :image (prune-into-map (:image embed))) embed)
(if (:author embed) (assoc embed :author (prune-into-map (:author embed))) embed)
(if (:video embed) (assoc embed :video (prune-into-map (:video embed))) embed)
(if (:provider embed) (assoc embed :provider (prune-into-map (:provider embed))) embed)
(if (:thumbnail embed) (assoc embed :thumbnail (prune-into-map (:thumbnail embed))) embed)
(if (:fields embed) (assoc embed :fields (map prune-into-map (:fields embed))) embed)
(prune-into-map embed)))
(defn embed?
"Returns whether or not 'maybe-embed' is an Embed record."
[maybe-embed]
(instance? Embed maybe-embed))