-
Notifications
You must be signed in to change notification settings - Fork 49
/
handlers.clj
114 lines (81 loc) 路 2.77 KB
/
handlers.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
103
104
105
106
107
108
109
110
111
112
113
114
(ns morse.handlers
[:require [clojure.string :as s]
[clojure.tools.macro :as macro]])
(defn handling
"Apply list of handlers to Telegram update"
[request & handlers]
(some #(% request) handlers))
(defn handlers
"Create handler by combining several into one"
[& handlers]
#(apply handling % handlers))
(defmacro defhandler
"Define a Telegram handler function from a sequence of handlers.
The name may optionally be followed by a doc-string and metadata map."
[name & routes]
(let [[name routes] (macro/name-with-attributes name routes)]
`(def ~name (handlers ~@routes))))
(defn command?
"Checks if message is a command with a name.
/stars and /st are considered different."
[update name]
(some-> update
:message
:text
(s/split #"\s+")
(first)
(s/split #"@")
(first)
(= (str "/" name))))
(defn command-fn
"Generate command handler from an update function"
[name handler]
(fn [update]
(if (command? update name)
(handler (:message update)))))
(defmacro command
"Generate command handler"
[name bindings & body]
`(command-fn ~name (fn [~bindings] ~@body)))
(defn update-fn [path handler-fn]
(fn [update]
(let [data (get-in update path)]
(handler-fn data))))
(defn message-fn [handler-fn]
(update-fn [:message] handler-fn))
(defmacro message
[bindings & body]
`(message-fn (fn [~bindings] ~@body)))
(defn inline-fn [handler-fn]
(update-fn [:inline_query] handler-fn))
(defmacro inline
[bindings & body]
`(inline-fn (fn [~bindings] ~@body)))
(defn callback-fn [handler-fn]
(update-fn [:callback_query] handler-fn))
(defmacro callback
[bindings & body]
`(callback-fn (fn [~bindings] ~@body)))
(comment "Examples of how to use handler definitions"
; creates a handler that will react on "/start" command
(command-fn "start" (fn [{user :from}] (println "Detecte user:" user)))
; There is a macro for a shorthand usage
(command "start" {user :from} (println "Detecte user:" user))
; Which you can use without desctructuring syntax
(command "chroma" message (handle-text message))
(defhandler handler
(handler-fn "start"
(fn [{{id :id :as chat} :chat}]
(println "Bot joined new chat: " chat)))
(command "start" [{{id :id :as chat} :chat}]
(println "Bot joined new chat: " chat)
(t/send-text token id "Welcome!"))
(command "help" {{id :id :as chat} :chat}
(println "Help was requested in " chat)
(t/send-text token id "Help is on the way"))
(message {{id :id} :chat :as message}
(println "Intercepted message: " message)
(t/send-text token id "I don't do a whole lot ... yet.")))
; then run in your repl:
(polling/start token bot-api)
)