Skip to content

Commit 8be96ba

Browse files
authored
Merge branch 'master' into fix-api-accumulator-barf
2 parents d3df624 + f0bbb61 commit 8be96ba

4 files changed

Lines changed: 84 additions & 11 deletions

File tree

src/yetibot/core/adapters/discord.clj

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,8 @@
108108
(guild-channels)))
109109

110110
(defn- generated-image-info [msg]
111-
(when-let [[_ id ext] (re-matches #".*/generated-images/([^.]+)\.(png|gif|mp4)$" (str/trim msg))]
112-
{:id id :ext ext}))
111+
(when-let [[url id ext] (re-find #"https?://\S+?/generated-images/([^./\s]+)\.(png|gif|mp4)" msg)]
112+
{:url url :id id :ext ext}))
113113

114114
(def discord-max-message-length 2000)
115115

@@ -119,13 +119,23 @@
119119

120120
(defn- send-msg [{:keys [conn]} msg]
121121
(try
122-
(if-let [{:keys [id ext]} (generated-image-info msg)]
123-
(when-let [{:keys [data]} (get @images/image-store id)]
122+
(if-let [{:keys [url id ext]} (generated-image-info msg)]
123+
(if-let [{:keys [data]} (get @images/image-store id)]
124124
(let [bytes (.decode (Base64/getDecoder) ^String data)
125-
stream (java.io.ByteArrayInputStream. bytes)]
126-
@(messaging/create-message!
127-
(:rest @conn) chat/*target*
128-
:stream {:content stream :filename (str id "." ext)})))
125+
stream (java.io.ByteArrayInputStream. bytes)
126+
clean-msg (str/replace msg url "")]
127+
(if (str/blank? clean-msg)
128+
@(messaging/create-message!
129+
(:rest @conn) chat/*target*
130+
:stream {:content stream :filename (str id "." ext)})
131+
@(messaging/create-message!
132+
(:rest @conn) chat/*target*
133+
:content clean-msg
134+
:stream {:content stream :filename (str id "." ext)})))
135+
(if (> (count msg) discord-max-message-length)
136+
(doseq [chunk (chunk-message msg)]
137+
@(messaging/create-message! (:rest @conn) chat/*target* :content chunk))
138+
@(messaging/create-message! (:rest @conn) chat/*target* :content msg)))
129139
(if (> (count msg) discord-max-message-length)
130140
(doseq [chunk (chunk-message msg)]
131141
@(messaging/create-message! (:rest @conn) chat/*target* :content chunk))

src/yetibot/core/util/image_input.clj

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@
77
#"(https?://\S+\.(?:jpg|jpeg|png|gif|webp)(?:[?\#]\S*)?|https?://(?:cdn\.discordapp\.com|media\.discordapp\.net|i\.imgur\.com)/\S+)")
88

99
(defn- discord-avatar-url [{:keys [id avatar]}]
10-
(when (and id avatar)
11-
(let [ext (if (str/starts-with? avatar "a_") "gif" "png")]
12-
(format "https://cdn.discordapp.com/avatars/%s/%s.%s?size=256" id avatar ext))))
10+
(cond
11+
(= id "269292446041636866") "https://i.imgflip.com/4/9omh8s.jpg"
12+
(and id avatar) (let [ext (if (str/starts-with? avatar "a_") "gif" "png")]
13+
(format "https://cdn.discordapp.com/avatars/%s/%s.%s?size=256" id avatar ext))
14+
:else nil))
1315

1416
(defn- replace-mentions [prompt mentions]
1517
(reduce (fn [p {:keys [id username]}]

test/yetibot/core/test/adapters/discord.clj

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
[yetibot.core.handler :as handler]
55
[yetibot.core.models.users :as users]
66
[yetibot.core.chat :as chat]
7+
[yetibot.core.webapp.routes.images :as images]
78
[midje.sweet :refer [fact facts anything => provided]]))
89

910
(facts
@@ -62,4 +63,44 @@
6263
(provided (users/create-user "fake" {:id 999 :username "fake"}) => {:username "fake"}
6364
(chat/chat-source 456) => {:channel-id 456 :room "fake"}
6465
(handler/handle-raw anything anything anything anything anything) => "called handle-raw")))
66+
67+
(facts
68+
"about generated-image-info"
69+
(fact
70+
"returns nil for messages without generated image URLs"
71+
(#'discord/generated-image-info "hello there!") => nil)
72+
(fact
73+
"extracts ID and extension when only URL is present"
74+
(#'discord/generated-image-info "http://localhost:3003/generated-images/fc62974c-0c61-4be6-8241-d1f79cd1eac0.png")
75+
=> {:url "http://localhost:3003/generated-images/fc62974c-0c61-4be6-8241-d1f79cd1eac0.png"
76+
:id "fc62974c-0c61-4be6-8241-d1f79cd1eac0"
77+
:ext "png"})
78+
(fact
79+
"extracts ID and extension when URL is embedded in text"
80+
(#'discord/generated-image-info "Check out the celebration: http://localhost:3003/generated-images/fc62974c-0c61-4be6-8241-d1f79cd1eac0.png ! Very cool!")
81+
=> {:url "http://localhost:3003/generated-images/fc62974c-0c61-4be6-8241-d1f79cd1eac0.png"
82+
:id "fc62974c-0c61-4be6-8241-d1f79cd1eac0"
83+
:ext "png"}))
84+
85+
(facts
86+
"about send-msg with generated images"
87+
(fact
88+
"sends message with attachment stream on discord and strips url"
89+
(with-redefs [images/image-store (atom {"fc62974c-0c61-4be6-8241-d1f79cd1eac0" {:data "SGVsbG8gd29ybGQ="}})]
90+
(binding [chat/*target* 456]
91+
(#'discord/send-msg {:conn (atom {:rest :fake-rest})}
92+
"Check out the celebration: http://localhost:3003/generated-images/fc62974c-0c61-4be6-8241-d1f79cd1eac0.png ! Very cool!")))
93+
=> "created-message-result"
94+
(provided (messaging/create-message! :fake-rest 456
95+
:content "Check out the celebration: ! Very cool!"
96+
:stream anything) => (future "created-message-result")))
97+
(fact
98+
"sends message with attachment stream without content if text is blank"
99+
(with-redefs [images/image-store (atom {"fc62974c-0c61-4be6-8241-d1f79cd1eac0" {:data "SGVsbG8gd29ybGQ="}})]
100+
(binding [chat/*target* 456]
101+
(#'discord/send-msg {:conn (atom {:rest :fake-rest})}
102+
"http://localhost:3003/generated-images/fc62974c-0c61-4be6-8241-d1f79cd1eac0.png")))
103+
=> "created-message-result"
104+
(provided (messaging/create-message! :fake-rest 456
105+
:stream anything) => (future "created-message-result"))))
65106

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
(ns yetibot.core.test.util.image-input
2+
(:require
3+
[midje.sweet :refer [fact facts =>]]
4+
[yetibot.core.util.image-input :as img-input]))
5+
6+
(facts
7+
"about extracting user mentions with custom avatar mapping"
8+
(fact
9+
"a regular user mention extracts their discord avatar"
10+
(img-input/extract-images
11+
"<@123456789>"
12+
{:raw-event {:mentions [{:id "123456789" :avatar "avatar123" :username "alice"}]}})
13+
=> {:prompt "@alice" :image-urls ["https://cdn.discordapp.com/avatars/123456789/avatar123.png?size=256"]})
14+
15+
(fact
16+
"a hardcoded user mention extracts the custom mario death meme avatar"
17+
(img-input/extract-images
18+
"<@269292446041636866>"
19+
{:raw-event {:mentions [{:id "269292446041636866" :avatar "someavatar" :username "bob"}]}})
20+
=> {:prompt "@bob" :image-urls ["https://i.imgflip.com/4/9omh8s.jpg"]}))

0 commit comments

Comments
 (0)