-
Notifications
You must be signed in to change notification settings - Fork 0
/
core.clj
79 lines (71 loc) · 3.37 KB
/
core.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
(ns common-clj.component.telegram.core
(:require [schema.core :as s]
[io.pedestal.interceptor :as interceptor]
[com.stuartsierra.component :as component]
[io.pedestal.interceptor.chain :as chain]
[telegrambot-lib.core :as telegram-bot]
[clostache.parser :as parser]
[medley.core :as medley]
[overtone.at-at :as at-at]
[common-clj.component.telegram.adapters.update :as telegram.adapters.message]
[common-clj.component.telegram.models.consumer :as component.telegram.models.consumer]))
(s/defn send-message!
[message :- s/Str
{:keys [telegram config]}]
(telegram-bot/send-message telegram (-> config :telegram :chat-id) message))
(s/defn commit-update-as-consumed!
[offset :- s/Int
telegram]
(telegram-bot/get-updates telegram {:offset (+ offset 1)}))
(s/defn interceptors-by-consumer
[consumer
{:keys [interceptors]}]
(let [interceptor-groups (group-by :name interceptors)]
(map #(-> (get interceptor-groups %) first) (:consumer/interceptors consumer))))
(s/defn consume-update!
[update
consumers :- component.telegram.models.consumer/Consumers
{:keys [telegram config] :as components}]
(let [{:consumer/keys [handler error-handler type] :as consumer} (telegram.adapters.message/update->consumer update consumers)
update-id (-> update :update_id)
context {:update update
:components components}]
(when (and handler update update-id)
(try
(chain/execute context
(concat (interceptors-by-consumer consumer consumers)
[(interceptor/interceptor {:name :handler-interceptor
:enter handler})]))
(catch Exception e
(if error-handler
(error-handler e components)
(send-message! (parser/render-resource
(format "%s/error_processing_message_command.mustache"
(-> config :telegram :message-template-dir))) components)))))
(when-not handler
(send-message! (parser/render-resource
(format "%s/command_not_found.mustache"
(-> config :telegram :message-template-dir))) components))
(commit-update-as-consumed! update-id telegram)))
(s/defn ^:private consumer-job!
[consumers
{:keys [telegram] :as components}]
(when-let [updates (-> (telegram-bot/get-updates telegram) :result)]
(doseq [update updates] (consume-update! update consumers components))))
(defrecord Telegram [config database consumers]
component/Lifecycle
(start [component]
(let [{{:keys [telegram] :as config-content} :config} config
bot (telegram-bot/create (:token telegram))
components (medley/assoc-some {}
:database (:database database)
:config config-content
:telegram bot)
pool (at-at/mk-pool)]
(at-at/interspaced 100 (partial consumer-job! consumers components) pool)
(merge component {:telegram bot})))
(stop [{:keys [telegram]}]
(telegram-bot/close telegram))) ;TODO: stop at-at pool here
(defn new-telegram
[consumers]
(map->Telegram {:consumers consumers}))