otann / morse Goto Github PK
View Code? Open in Web Editor NEW๐ก Clojure interface for Telegram Bot API
License: Eclipse Public License 1.0
๐ก Clojure interface for Telegram Bot API
License: Eclipse Public License 1.0
OK, I'm a complete clojure rookie, but I think this is what's happening:
If background process performing long-polling encounters an exception (for example 502 from the api) it shuts down and stops polling updates, which is not nice.
An example exception:
user=> Exception in thread "async-dispatch-32" java.lang.Error: java.io.EOFException: SSL peer shut down incorrectly
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1148)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.io.EOFException: SSL peer shut down incorrectly
at sun.security.ssl.InputRecord.read(InputRecord.java:505)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:973)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
at org.apache.http.conn.ssl.SSLSocketFactory.createLayeredSocket(SSLSocketFactory.java:573)
at org.apache.http.conn.ssl.SSLSocketFactory.createLayeredSocket(SSLSocketFactory.java:447)
at org.apache.http.impl.conn.DefaultClientConnectionOperator.updateSecureConnection(DefaultClientConnectionOperator.java:219)
at org.apache.http.impl.conn.ManagedClientConnectionImpl.layerProtocol(ManagedClientConnectionImpl.java:421)
at org.apache.http.impl.client.DefaultRequestDirector.establishRoute(DefaultRequestDirector.java:815)
at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:616)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:447)
at org.apache.http.impl.client.AbstractHttpClient.doExecute(AbstractHttpClient.java:884)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:107)
at clj_http.core$request.invokeStatic(core.clj:304)
at clj_http.core$request.invoke(core.clj:208)
at clojure.lang.Var.invoke(Var.java:379)
at clj_http.client$wrap_request_timing$fn__11582.invoke(client.clj:835)
at clj_http.headers$wrap_header_map$fn__9803.invoke(headers.clj:143)
at clj_http.client$wrap_query_params$fn__11485.invoke(client.clj:651)
at clj_http.client$wrap_basic_auth$fn__11492.invoke(client.clj:677)
at clj_http.client$wrap_oauth$fn__11496.invoke(client.clj:687)
at clj_http.client$wrap_user_info$fn__11501.invoke(client.clj:700)
at clj_http.client$wrap_url$fn__11568.invoke(client.clj:801)
at clj_http.client$wrap_redirects$fn__11267.invoke(client.clj:267)
at clj_http.client$wrap_decompression$fn__11292.invoke(client.clj:339)
at clj_http.client$wrap_input_coercion$fn__11422.invoke(client.clj:518)
at clj_http.client$wrap_additional_header_parsing$fn__11443.invoke(client.clj:552)
at clj_http.client$wrap_output_coercion$fn__11413.invoke(client.clj:468)
at clj_http.client$wrap_exceptions$fn__11253.invoke(client.clj:219)
at clj_http.client$wrap_accept$fn__11457.invoke(client.clj:595)
at clj_http.client$wrap_accept_encoding$fn__11463.invoke(client.clj:609)
at clj_http.client$wrap_content_type$fn__11452.invoke(client.clj:585)
at clj_http.client$wrap_form_params$fn__11546.invoke(client.clj:765)
at clj_http.client$wrap_nested_params$fn__11563.invoke(client.clj:790)
at clj_http.client$wrap_method$fn__11506.invoke(client.clj:707)
at clj_http.cookies$wrap_cookies$fn__8753.invoke(cookies.clj:124)
at clj_http.links$wrap_links$fn__10040.invoke(links.clj:51)
at clj_http.client$wrap_unknown_host$fn__11572.invoke(client.clj:810)
at clj_http.client$get.invokeStatic(client.clj:913)
at clj_http.client$get.doInvoke(client.clj:909)
at clojure.lang.RestFn.invoke(RestFn.java:423)
at morse.api$get_updates.invokeStatic(api.clj:17)
at morse.api$get_updates.invoke(api.clj:10)
at morse.polling$create_producer$fn__11694$fn__11722$state_machine__6688__auto____11723$fn__11725.invoke(polling.clj:24)
at morse.polling$create_producer$fn__11694$fn__11722$state_machine__6688__auto____11723.invoke(polling.clj:24)
at clojure.core.async.impl.ioc_macros$run_state_machine.invokeStatic(ioc_macros.clj:1011)
at clojure.core.async.impl.ioc_macros$run_state_machine.invoke(ioc_macros.clj:1010)
at clojure.core.async.impl.ioc_macros$run_state_machine_wrapped.invokeStatic(ioc_macros.clj:1015)
at clojure.core.async.impl.ioc_macros$run_state_machine_wrapped.invoke(ioc_macros.clj:1013)
at morse.polling$create_producer$fn__11694$fn__11722.invoke(polling.clj:24)
at clojure.lang.AFn.run(AFn.java:22)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
... 2 more
If this is intentional, then I'd appreciate any hints on how to tackle this on application level :)
We use this code:
(defn -main
[& args]
(println "Bot running!")
(go-loop [ch (p/start token bot-api)]
(<! (timeout 5000))
(if (nil? (<! ch))
(do
(println "Bot restarted")
(recur (p/start token bot-api)))
(recur ch)))
(Thread/sleep Long/MAX_VALUE))
but bot freezes sometimes for unknown reasons ๐ค
When a group where bot is present is upgraded, the following exception appears, and bot thread crashes:
Exception in thread "async-dispatch-23" clojure.lang.ExceptionInfo: clj-http: status 400 {:status 400, :headers {"Server" "nginx/1.12.2", "Date" "Fri, 12 Oct 2018 09:30:18 GMT", "Content-Type" "application/json", "Content-Length" "154", "Connection" "close", "Access-Control-Allow-Origin" "*", "Access-Control-Expose-Headers" "Content-Length,Content-Type,Date,Server,Connection"}, :body "{\"ok\":false,\"error_code\":400,\"description\":\"Bad Request: group chat was upgraded to a supergroup chat\",\"parameters\":{\"migrate_to_chat_id\":-1001158883424}}", :request-time 219, :trace-redirects ["https://api.telegram.org/bot***:*********/sendMessage"], :orig-content-encoding nil}
at slingshot.support$stack_trace.invoke(support.clj:201)
at clj_http.client$wrap_exceptions$fn__10012.invoke(client.clj:196)
at clj_http.client$wrap_accept$fn__10216.invoke(client.clj:565)
at clj_http.client$wrap_accept_encoding$fn__10222.invoke(client.clj:579)
at clj_http.client$wrap_content_type$fn__10211.invoke(client.clj:554)
at clj_http.client$wrap_form_params$fn__10303.invoke(client.clj:722)
at clj_http.client$wrap_nested_params$fn__10317.invoke(client.clj:760)
at clj_http.client$wrap_method$fn__10263.invoke(client.clj:670)
at clj_http.cookies$wrap_cookies$fn__7643.invoke(cookies.clj:124)
at clj_http.links$wrap_links$fn__8927.invoke(links.clj:51)
at clj_http.client$wrap_unknown_host$fn__10326.invoke(client.clj:776)
at clj_http.client$post.invokeStatic(client.clj:891)
at clj_http.client$post.doInvoke(client.clj:887)
at clojure.lang.RestFn.invoke(RestFn.java:423)
at morse.api$send_text.invokeStatic(api.clj:35)
at morse.api$send_text.invoke(api.clj:29)
at morse.api$send_text.invokeStatic(api.clj:31)
at morse.api$send_text.invoke(api.clj:29)
at craplimiter_bot.handler$fn__10722.invokeStatic(handler.clj:23)
at craplimiter_bot.handler$fn__10722.invoke(handler.clj:21)
at morse.handlers$update_fn$fn__10686.invoke(handlers.clj:57)
at morse.handlers$handling$fn__10663.invoke(handlers.clj:9)
at clojure.core$some.invokeStatic(core.clj:2592)
at clojure.core$some.invoke(core.clj:2583)
at morse.handlers$handling.invokeStatic(handlers.clj:9)
at morse.handlers$handling.doInvoke(handlers.clj:6)
at clojure.lang.RestFn.applyTo(RestFn.java:139)
at clojure.core$apply.invokeStatic(core.clj:648)
at clojure.core$apply.invoke(core.clj:641)
at morse.handlers$handlers$fn__10667.invoke(handlers.clj:15)
at morse.polling$create_consumer$fn__10516$state_machine__5526__auto____10517$fn__10519.invoke(polling.clj:42)
at morse.polling$create_consumer$fn__10516$state_machine__5526__auto____10517.invoke(polling.clj:42)
at clojure.core.async.impl.ioc_macros$run_state_machine.invokeStatic(ioc_macros.clj:1011)
at clojure.core.async.impl.ioc_macros$run_state_machine.invoke(ioc_macros.clj:1010)
at clojure.core.async.impl.ioc_macros$run_state_machine_wrapped.invokeStatic(ioc_macros.clj:1015)
at clojure.core.async.impl.ioc_macros$run_state_machine_wrapped.invoke(ioc_macros.clj:1013)
at clojure.core.async.impl.ioc_macros$take_BANG_$fn__5542.invoke(ioc_macros.clj:1024)
at clojure.core.async.impl.channels.ManyToManyChannel$fn__464.invoke(channels.clj:135)
at clojure.lang.AFn.run(AFn.java:22)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Nevertheless, after the bot is restarted, it keeps working fine. But it would be good to not add some kind of trigger to restart bot in such cases :)
.. or maybe have a channel returned directly if no "handler" function is passed.
From the perspective of an application relying on core.async and using morse, the most feasible thing to do in the "handler" function is to push the data to another channel in your application which in the current situation is a bit redundant since the "updates" channel in polling is already serving that purpose.
From the other hand I can understand that it's the matter of taste what is a better interface for the library - to provide the way to pass a callback handler (which can be more universal since not everybody use core.async in their applications) or a channel.
Anyway, I'd be happy to have this ability.
What happened to 908b07b ? (Which is used for https://libraries.io/clojars/hellonico%2Fmorse)
Some features like download-file in api are implemented in hello-nico but not in the supposedly updated morse repo here? :o
I have a problem where my bot no longer receive messages over Telegram, until I restart my application. This usually happens over long-ish period (about 24 hours) and I don't have the best Internet connection.
Reading the code for morse.polling
it appears that morse.polling/start
has no way to signal that it is no longer polling, and so a user will never know to call start
again. create-consumer
returns a channel that will contain exactly one result when the loop exits (as a result of updates
being closed.) If start
returned the result of create-consumer
instead of the running
channel, that will never be closed, it would be possible for user code to restart in the event of the polling loop dying:
(go-loop [ch nil
res nil]
(if res
(recur ch (<! ch))
(recur (polling/start token api) true)))
I'm happy to submit a PR if you don't have time or the inclination to do this yourself, @Otann.
If there are multiple bots in a group, you can disambiguate commands by postfixing the command with bot's @username, e.g. /command@YourBot
. When autocompleting a command (if you have told Telegram about your bot's commands via /setcommands
to BotFather), Telegram does this automatically.
It'd be great if morse.handlers/command
would support this out of the box. If I understand Telegram's FAQ correctly, you won't ever get messages that were meant for other bots in the group, even if your bot is not in the privacy mode. This means morse could just split the received commands on @
and match on the first part - there's no need to know the bot's username.
Currently when I run boot -d morse show -d
I am presented with the following dependency graph:
[morse "0.2.4"]
โโโ [cheshire "5.5.0"]
โ โโโ [com.fasterxml.jackson.core/jackson-core "2.5.3"]
โ โโโ [com.fasterxml.jackson.dataformat/jackson-dataformat-cbor "2.5.3"]
โ โโโ [com.fasterxml.jackson.dataformat/jackson-dataformat-smile "2.5.3"]
โ โโโ [tigris "0.1.1"]
โโโ [clj-http "2.1.0"]
โ โโโ [commons-codec "1.10" :exclusions [[org.clojure/clojure]]]
โ โโโ [commons-io "2.4" :exclusions [[org.clojure/clojure]]]
โ โโโ [org.apache.httpcomponents/httpclient "4.5.1" :exclusions [[org.clojure/clojure]]]
โ โ โโโ [commons-logging "1.2"]
โ โโโ [org.apache.httpcomponents/httpcore "4.4.4" :exclusions [[org.clojure/clojure]]]
โ โโโ [org.apache.httpcomponents/httpmime "4.5.1" :exclusions [[org.clojure/clojure]]]
โ โโโ [potemkin "0.4.3" :exclusions [[org.clojure/clojure]]]
โ โ โโโ [clj-tuple "0.2.2"]
โ โ โโโ [riddley "0.1.12"]
โ โโโ [slingshot "0.12.2" :exclusions [[org.clojure/clojure]]]
โโโ [org.clojure/core.async "0.2.374"]
โ โโโ [org.clojure/tools.analyzer.jvm "0.6.9"]
โ โโโ [org.clojure/core.memoize "0.5.8"]
โ โ โโโ [org.clojure/core.cache "0.6.4"]
โ โ โโโ [org.clojure/data.priority-map "0.0.4"]
โ โโโ [org.clojure/tools.analyzer "0.6.7"]
โ โโโ [org.clojure/tools.reader "1.0.0-alpha1"]
โ โโโ [org.ow2.asm/asm-all "4.2"]
โโโ [org.clojure/tools.macro "0.1.5"]
โ โโโ [org.clojure/clojure "1.4.0"]
โโโ [venantius/ultra "0.4.1"]
โโโ [grimradical/clj-semver "0.3.0" :exclusions [[org.clojure/clojure]]]
โโโ [im.chit/hara.class "2.2.15"]
โ โโโ [im.chit/hara.class.checks "2.2.15"]
โ โโโ [im.chit/hara.class.inheritance "2.2.15"]
โ โโโ [im.chit/hara.namespace.import "2.2.15"]
โโโ [im.chit/hara.reflect "2.2.15"]
โ โโโ [im.chit/hara.common.checks "2.2.15"]
โ โโโ [im.chit/hara.common.string "2.2.15"]
โ โโโ [im.chit/hara.common "2.2.15"]
โ โ โโโ [im.chit/hara.common.error "2.2.15"]
โ โ โโโ [im.chit/hara.common.hash "2.2.15"]
โ โ โโโ [im.chit/hara.common.primitives "2.2.15"]
โ โโโ [im.chit/hara.data.map "2.2.15"]
โ โโโ [im.chit/hara.protocol.string "2.2.15"]
โโโ [io.aviso/pretty "0.1.24"]
โโโ [mvxcvi/puget "1.0.0"]
โ โโโ [fipp "0.6.3"]
โ โ โโโ [org.clojure/core.rrb-vector "0.0.11"]
โ โโโ [mvxcvi/arrangement "1.0.0"]
โโโ [mvxcvi/whidbey "1.3.0"]
โ โโโ [org.clojure/data.codec "0.1.0"]
โโโ [org.clojars.brenton/google-diff-match-patch "0.1"]
โโโ [org.clojure/tools.nrepl "0.2.12"]
โโโ [robert/hooke "1.3.0"]
โโโ [venantius/glow "0.1.3"]
โโโ [clj-antlr "0.2.2"]
โ โโโ [org.antlr/antlr4-runtime "4.2.2"]
โ โ โโโ [org.abego.treelayout/org.abego.treelayout.core "1.0.1"]
โ โ โโโ [org.antlr/antlr4-annotations "4.2.2"]
โ โโโ [org.antlr/antlr4 "4.2.2"]
โ โโโ [org.antlr/ST4 "4.0.8"]
โ โโโ [org.antlr/antlr-runtime "3.5.2"]
โโโ [garden "1.1.7"]
โ โโโ [com.yahoo.platform.yui/yuicompressor "2.4.7"]
โ โโโ [rhino/js "1.6R7"]
โโโ [hiccup "1.0.5"]
โโโ [instaparse "1.4.1"]
Half of this isn't needed during run-time and thus it would be nice to remove it from the list of transitive dependencies.
Long-polling
sample code from README.md
(require '[morse.polling :as p])
(def channel (p/start token handler))
returned
ERROR morse.polling - HTTP request timed out, stopping polling
after switching on 0.3.4 version for handling 502 error i've got an another frustrating bug
ัะตะฒ 23, 2018 10:49:53 AM morse.polling invoke
SEVERE: HTTP request timed out, stopping polling
i've just strarted pooling as
(<!! (p/start token handler))
please help=)
after creating webhook once bot cant revert to polling.
add delete-webhook functionality?
Running a telegram-bot in a long-polling mode I sometimes experienced a complete freeze of the polling process.
According to some issues I had in the past, clj-http doesn't usually handle timeouts in an expected way, probably mainly because of this issue in JDK: https://bugs.openjdk.java.net/browse/JDK-8075484.
Having some external timeout that could inform the user application can be quite useful in such scenarios, but obviously would be good to address this issue to the maintainers of clj-http as well.
I don't see send-video, send-document or send-audio functions in the api namespace, but the telegram API has those methods.
If you're ok with that, I'll be adding those in a pull request.
When i set web hook and start send commands to bot, it goes to infinite loop answering me. As soon as bot answers me for my request, it starts to handle the same request again and again. Any ideas why it happens?
Someone using my bot seemed to have blocked it and is throwing this error whenever I try to restart the server. Is there a way to handle this?
Hi,
I want to use a feature of the api which doesn't have an explicit handler, luckily I can just:
(h/update-fn [:chosen_inline_result]
(fn [{:keys [inline_message_id query]}]
(println "Registering " inline_message_id "\n" query)
(k/assoc-in db [inline_message_id] (register-question query))))
But then I noticed my function still got called on normal messages. I propose therefore a change:
Line 56 in 35ced71
(if-let [data (get-in update path)]
Hopefully you agree, if I have overlooked something let me know.
Sander
I tried sending the message as per the example in the docs
(api/send-text token chat-id "Hello, fellows")
When I run the code using TELEGRAM_TOKEN="..." TELEGRAM_CHAT_ID="..." lein run
, although I receive the message on my telegram, I get the exception (attached below). It seems it's trying to parse a JSON that isn't valid. When I comment the above line of code, everything is working.
{:clojure.main/message
"Syntax error (NullPointerException) compiling at (/private/var/folders/n5/nsp1_zz15_39bkr4d8n97j3c0000gn/T/form-init7703393975619659398.clj:1:125).\nnull\n",
:clojure.main/triage
{:clojure.error/phase :compile-syntax-check,
:clojure.error/line 1,
:clojure.error/column 125,
:clojure.error/source "form-init7703393975619659398.clj",
:clojure.error/path
"/private/var/folders/n5/nsp1_zz15_39bkr4d8n97j3c0000gn/T/form-init7703393975619659398.clj",
:clojure.error/class java.lang.NullPointerException},
:clojure.main/trace
{:via
[{:type clojure.lang.Compiler$CompilerException,
:message
"Syntax error compiling at (/private/var/folders/n5/nsp1_zz15_39bkr4d8n97j3c0000gn/T/form-init7703393975619659398.clj:1:125).",
:data
{:clojure.error/phase :compile-syntax-check,
:clojure.error/line 1,
:clojure.error/column 125,
:clojure.error/source
"/private/var/folders/n5/nsp1_zz15_39bkr4d8n97j3c0000gn/T/form-init7703393975619659398.clj"},
:at [clojure.lang.Compiler load "Compiler.java" 7648]}
{:type java.lang.NullPointerException,
:at [clojure.core$apply invokeStatic "core.clj" 665]}],
:trace
[[clojure.core$apply invokeStatic "core.clj" 665]
[clojure.core$apply invoke "core.clj" 660]
[clj_http.client$json_decode invokeStatic "client.clj" 131]
[clj_http.client$json_decode doInvoke "client.clj" 127]
[clojure.lang.RestFn invoke "RestFn.java" 421]
[clj_http.client$decode_json_body invokeStatic "client.clj" 457]
[clj_http.client$decode_json_body invoke "client.clj" 449]
[clj_http.client$coerce_json_body invokeStatic "client.clj" 465]
[clj_http.client$coerce_json_body doInvoke "client.clj" 460]
[clojure.lang.RestFn invoke "RestFn.java" 445]
[clj_http.client$eval3960$fn__3961 invoke "client.clj" 527]
[clojure.lang.MultiFn invoke "MultiFn.java" 234]
[clj_http.client$output_coercion_response
invokeStatic
"client.clj"
561]
[clj_http.client$output_coercion_response invoke "client.clj" 558]
[clj_http.client$wrap_output_coercion$fn__4004
invoke
"client.clj"
572]
[clj_http.client$wrap_exceptions$fn__3801 invoke "client.clj" 249]
[clj_http.client$wrap_accept$fn__4057 invoke "client.clj" 726]
[clj_http.client$wrap_accept_encoding$fn__4064
invoke
"client.clj"
748]
[clj_http.client$wrap_content_type$fn__4051 invoke "client.clj" 709]
[clj_http.client$wrap_form_params$fn__4160 invoke "client.clj" 950]
[clj_http.client$wrap_nested_params$fn__4181
invoke
"client.clj"
984]
[clj_http.client$wrap_flatten_nested_params$fn__4190
invoke
"client.clj"
1008]
[clj_http.client$wrap_method$fn__4118 invoke "client.clj" 884]
[clj_http.cookies$wrap_cookies$fn__415 invoke "cookies.clj" 131]
[clj_http.links$wrap_links$fn__1929 invoke "links.clj" 63]
[clj_http.client$wrap_unknown_host$fn__4198
invoke
"client.clj"
1037]
[clj_http.client$request_STAR_ invokeStatic "client.clj" 1165]
[clj_http.client$request_STAR_ invoke "client.clj" 1158]
[clj_http.client$post invokeStatic "client.clj" 1183]
[clj_http.client$post doInvoke "client.clj" 1179]
[clojure.lang.RestFn invoke "RestFn.java" 423]
[morse.api$send_text invokeStatic "api.clj" 73]
[morse.api$send_text invoke "api.clj" 67]
[morse.api$send_text invokeStatic "api.clj" 69]
[morse.api$send_text invoke "api.clj" 67]
[github_amazon_bot.core$_main invokeStatic "core.clj" 28]
[github_amazon_bot.core$_main invoke "core.clj" 19]
[clojure.lang.Var invoke "Var.java" 380]
[user$eval140 invokeStatic "form-init7703393975619659398.clj" 1]
[user$eval140 invoke "form-init7703393975619659398.clj" 1]
[clojure.lang.Compiler eval "Compiler.java" 7177]
[clojure.lang.Compiler eval "Compiler.java" 7167]
[clojure.lang.Compiler load "Compiler.java" 7636]
[clojure.lang.Compiler loadFile "Compiler.java" 7574]
[clojure.main$load_script invokeStatic "main.clj" 475]
[clojure.main$init_opt invokeStatic "main.clj" 477]
[clojure.main$init_opt invoke "main.clj" 477]
[clojure.main$initialize invokeStatic "main.clj" 508]
[clojure.main$null_opt invokeStatic "main.clj" 542]
[clojure.main$null_opt invoke "main.clj" 539]
[clojure.main$main invokeStatic "main.clj" 664]
[clojure.main$main doInvoke "main.clj" 616]
[clojure.lang.RestFn applyTo "RestFn.java" 137]
[clojure.lang.Var applyTo "Var.java" 705]
[clojure.main main "main.java" 40]],
:phase :compile-syntax-check}}
My bot did not resume polling after encountering a 502 from Telegram by longpolling.
Exception in thread "async-dispatch-18" clojure.lang.ExceptionInfo: clj-http: status 502 {:cached nil, :request-time 6929, :repeatable? false, :protocol-version {:name "HTTP", :major 1, :minor 1}, :streaming? true, :http-client #object[org.apache.http.impl.client.InternalHttpClient 0x6e992d0a "org.apache.http.impl.client.InternalHttpClient@6e992d0a"], :chunked? false, :type :clj-http.client/unexceptional-status, :reason-phrase "Bad Gateway", :headers {"Server" "nginx/1.12.2", "Date" "Sun, 28 Oct 2018 01:16:34 GMT", "Content-Type" "application/json", "Content-Length" "57", "Connection" "close", "Access-Control-Allow-Origin" "*", "Access-Control-Expose-Headers" "Content-Length,Content-Type,Date,Server,Connection"}, :orig-content-encoding nil, :status 502, :length 57, :body "{\"ok\":false,\"error_code\":502,\"description\":\"Bad Gateway\"}", :trace-redirects []}
at slingshot.support$stack_trace.invoke(support.clj:201)
at clj_http.client$exceptions_response.invokeStatic(client.clj:245)
at clj_http.client$exceptions_response.invoke(client.clj:236)
at clj_http.client$wrap_exceptions$fn__10385.invoke(client.clj:254)
at clj_http.client$wrap_accept$fn__10627.invoke(client.clj:737)
at clj_http.client$wrap_accept_encoding$fn__10634.invoke(client.clj:759)
at clj_http.client$wrap_content_type$fn__10621.invoke(client.clj:720)
at clj_http.client$wrap_form_params$fn__10724.invoke(client.clj:961)
at clj_http.client$wrap_nested_params$fn__10741.invoke(client.clj:995)
at clj_http.client$wrap_flatten_nested_params$fn__10750.invoke(client.clj:1019)
at clj_http.client$wrap_method$fn__10682.invoke(client.clj:895)
at clj_http.cookies$wrap_cookies$fn__7853.invoke(cookies.clj:131)
at clj_http.links$wrap_links$fn__9284.invoke(links.clj:63)
at clj_http.client$wrap_unknown_host$fn__10758.invoke(client.clj:1048)
at clj_http.client$request_STAR_.invokeStatic(client.clj:1176)
at clj_http.client$request_STAR_.invoke(client.clj:1169)
at clj_http.client$get.invokeStatic(client.clj:1182)
at clj_http.client$get.doInvoke(client.clj:1178)
at clojure.lang.RestFn.invoke(RestFn.java:423)
at morse.api$get_updates.invokeStatic(api.clj:17)
at morse.api$get_updates.invoke(api.clj:10)
Would recommend retrying a connection every 10-30 seconds as longpolling sessions may be arbitrarily resumed later
We using morse.pooling
. After telegram returning 502 error:
Oct 29, 2017 9:36:29 PM morse.api invoke
SEVERE: Telegram returned 502 from /getUpdates: <html>
<head><title>502 Bad Gateway</title></head>
<body bgcolor="white">
<center><h1>502 Bad Gateway</h1></center>
<hr><center>nginx/1.10.0</center>
</body>
</html>
bot stops receiving requests. But expected behavior is trying to reconnect.
I started pooling and I set the timeout to 300 and I start communicating with my Bot in Telegram.
but nothing happens.
(morse.handlers/defhandler bot-api
; Each bot has to handle /start and /help commands.
; This could be done in form of a function:
(morse.handlers/command-fn "start" (fn [{{id :id :as chat} :chat}]
(println "Bot joined new chat: " chat)
(morse.api/send-text token id "Welcome!")))
; You can use short syntax for same purposes
; Destructuring works same way as in function above
(morse.handlers/command "help" {{id :id :as chat} :chat}
(println "Help was requested in " chat)
(morse.api/send-text token id "Help is on the way"))
; Handlers will be applied until there are any of those
; returns non-nil result processing update.
; Note that sending stuff to the user returns non-nil
; response from Telegram API.
; So match-all catch-through case would look something like this:
(morse.handlers/message message (println "Intercepted message:" message)))
...
(def channelx (morse.polling/start token bot-api {:timeout 300}))
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.