Skip to content

Commit

Permalink
Fix getUpdates timeout error (#65)
Browse files Browse the repository at this point in the history
  • Loading branch information
visciang committed Mar 8, 2020
1 parent 548cfb1 commit 5d2db98
Show file tree
Hide file tree
Showing 10 changed files with 84 additions and 53 deletions.
6 changes: 2 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@ language: elixir

matrix:
include:
- otp_release: 20.0
elixir: 1.6
- otp_release: 21.0
elixir: 1.7
- otp_release: 22.2
elixir: 1.10

script:
- mix format --check-formatted
Expand Down
25 changes: 25 additions & 0 deletions DEVELOPMENT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Development

# Build, Lint, Test

```bash
mix format
mix dialyzer
mix coveralls --trace
```

# Docs

```bash
mix docs
```

`doc/readme.html`

# Example bot script

Fill token, username, auth in `example/example.exs`

```bash
mix run example/example.exs
```
2 changes: 1 addition & 1 deletion config/config.exs
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ if Mix.env() == :test do
mock: true,
api_base_url: "http://test:8000",
get_updates_poll_timeout: 1,
on_error_retry_quiet_period: 1
on_error_retry_delay: 1
end
28 changes: 14 additions & 14 deletions lib/api.ex
Original file line number Diff line number Diff line change
Expand Up @@ -132,18 +132,18 @@ defmodule Telegram.Api do
```
"""

@type options :: Keyword.t()
@type parameters :: Keyword.t()
@type request_result :: {:ok, term} | {:error, term} | no_return()

@doc """
Send a Telegram Bot API request.
Reference: [BOT Api](https://core.telegram.org/bots/api)
"""
@spec request(Telegram.Client.token(), Telegram.Client.method(), options) :: request_result
def request(token, method, options \\ []) do
@spec request(Telegram.Client.token(), Telegram.Client.method(), parameters) :: request_result
def request(token, method, parameters \\ []) do
body =
options
parameters
|> do_json_markup()
|> do_body()

Expand Down Expand Up @@ -174,25 +174,25 @@ defmodule Telegram.Api do
Telegram.Client.do_file(token, file_path)
end

defp do_body(options) do
if request_with_file?(options) do
defp do_body(parameters) do
if request_with_file?(parameters) do
# body encoded as "multipart/form-data"
do_multipart_body(options)
do_multipart_body(parameters)
else
# body encoded as "application/json"
Map.new(options)
Map.new(parameters)
end
end

defp request_with_file?(options) do
defp request_with_file?(parameters) do
Enum.any?(
options,
parameters,
&(match?({_name, {:file, _}}, &1) or match?({_name, {:file_content, _, _}}, &1))
)
end

defp do_multipart_body(options) do
Enum.reduce(options, Tesla.Multipart.new(), fn
defp do_multipart_body(parameters) do
Enum.reduce(parameters, Tesla.Multipart.new(), fn
{name, {:file, file}}, multipart ->
Tesla.Multipart.add_file(multipart, file, name: to_string(name))

Expand All @@ -204,8 +204,8 @@ defmodule Telegram.Api do
end)
end

defp do_json_markup(options) do
Enum.map(options, fn
defp do_json_markup(parameters) do
Enum.map(parameters, fn
{name, {:json, value}} ->
{name, Jason.encode!(value)}

Expand Down
6 changes: 3 additions & 3 deletions lib/bot.ex
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ defmodule Telegram.Bot do

# timeout configuration opts unit: seconds
@get_updates_poll_timeout Application.get_env(:telegram, :get_updates_poll_timeout, 30)
@on_error_retry_quiet_period Application.get_env(:telegram, :on_error_retry_quiet_period, 5)
@on_error_retry_delay Application.get_env(:telegram, :on_error_retry_delay, 5)
@purge_after @get_updates_poll_timeout * 2

defmacro __using__(opts) do
Expand Down Expand Up @@ -207,7 +207,7 @@ defmodule Telegram.Bot do

{:error, reason} ->
cooldown(
@on_error_retry_quiet_period,
@on_error_retry_delay,
"Telegram.Api.request 'getMe' error: #{inspect(reason)}"
)

Expand Down Expand Up @@ -242,7 +242,7 @@ defmodule Telegram.Bot do

{:error, reason} ->
cooldown(
@on_error_retry_quiet_period,
@on_error_retry_delay,
"Telegram.Api.request 'getUpdates' error: #{inspect(reason)}"
)

Expand Down
16 changes: 9 additions & 7 deletions lib/client.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,27 @@ defmodule Telegram.Client do
@type token :: String.t()
@type method :: String.t()
@type file_path :: String.t()
@type body :: map() | Tesla.Multipart.t()

@api_base_url Application.get_env(:telegram, :api_base_url, "https://api.telegram.org")
# timeout configuration opts unit: seconds
@recv_timeout Application.get_env(:telegram, :recv_timeout, 60) * 1000
@connect_timeout Application.get_env(:telegram, :connect_timeout, 5) * 1000
@api_base_url Application.compile_env(:telegram, :api_base_url, "https://api.telegram.org")

use Tesla, only: [:get, :post], docs: false

if Application.get_env(:telegram, :mock) == true do
if Application.compile_env(:telegram, :mock) == true do
adapter Tesla.Mock
else
adapter Tesla.Adapter.Hackney
@recv_timeout Application.compile_env(:telegram, :recv_timeout, 60) * 1000
@connect_timeout Application.compile_env(:telegram, :connect_timeout, 5) * 1000

adapter Tesla.Adapter.Gun, timeout: @recv_timeout, connect_timeout: @connect_timeout
end

plug Tesla.Middleware.Opts, recv_timeout: @recv_timeout, connect_timeout: @connect_timeout
plug Tesla.Middleware.BaseUrl, @api_base_url
plug Tesla.Middleware.JSON
plug Tesla.Middleware.Retry

@doc false
@spec do_request(token, method, body) :: {:ok, term} | {:error, term}
def do_request(token, method, body) do
"/bot#{token}/#{method}"
|> post(body)
Expand All @@ -46,6 +47,7 @@ defmodule Telegram.Client do
end

@doc false
@spec do_file(token, file_path) :: {:ok, Tesla.Env.body()} | {:error, term}
def do_file(token, file_path) do
"/file/bot#{token}/#{file_path}"
|> get()
Expand Down
8 changes: 5 additions & 3 deletions mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ defmodule Telegram.Mixfile do
def project do
[
app: :telegram,
version: "0.5.1",
elixir: "~> 1.5",
version: "0.6.0",
elixir: "~> 1.10",
start_permanent: Mix.env() == :prod,
preferred_cli_env: [
coveralls: :test,
Expand All @@ -28,7 +28,9 @@ defmodule Telegram.Mixfile do
defp deps do
[
{:tesla, "~> 1.0"},
{:hackney, "~> 1.9"},
{:gun, "~> 1.3"},
{:idna, "~> 6.0"},
{:castore, "~> 0.1"},
{:jason, "~> 1.0"},
{:excoveralls, "~> 0.8", only: :test},
{:meck, "~> 0.8.9", only: :test},
Expand Down
42 changes: 23 additions & 19 deletions mix.lock
Original file line number Diff line number Diff line change
@@ -1,23 +1,27 @@
%{
"certifi": {:hex, :certifi, "2.4.2", "75424ff0f3baaccfd34b1214184b6ef616d89e420b258bb0a5ea7d7bc628f7f0", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm"},
"dialyxir": {:hex, :dialyxir, "0.5.1", "b331b091720fd93e878137add264bac4f644e1ddae07a70bf7062c7862c4b952", [:mix], [], "hexpm"},
"earmark": {:hex, :earmark, "1.3.1", "73812f447f7a42358d3ba79283cfa3075a7580a3a2ed457616d6517ac3738cb9", [:mix], [], "hexpm"},
"ex_doc": {:hex, :ex_doc, "0.19.2", "6f4081ccd9ed081b6dc0bd5af97a41e87f5554de469e7d76025fba535180565f", [:mix], [{:earmark, "~> 1.2", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.10", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm"},
"excoveralls": {:hex, :excoveralls, "0.10.4", "b86230f0978bbc630c139af5066af7cd74fd16536f71bc047d1037091f9f63a9", [:mix], [{:hackney, "~> 1.13", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"},
"castore": {:hex, :castore, "0.1.5", "591c763a637af2cc468a72f006878584bc6c306f8d111ef8ba1d4c10e0684010", [:mix], [], "hexpm", "6db356b2bc6cc22561e051ff545c20ad064af57647e436650aa24d7d06cd941a"},
"certifi": {:hex, :certifi, "2.5.1", "867ce347f7c7d78563450a18a6a28a8090331e77fa02380b4a21962a65d36ee5", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm", "805abd97539caf89ec6d4732c91e62ba9da0cda51ac462380bbd28ee697a8c42"},
"cowlib": {:hex, :cowlib, "2.6.0", "8aa629f81a0fc189f261dc98a42243fa842625feea3c7ec56c48f4ccdb55490f", [:rebar3], [], "hexpm", "45a1a08e05e4c66f2af665295955e337d52c2d33b1f1cf24d353cadeddf34992"},
"dialyxir": {:hex, :dialyxir, "0.5.1", "b331b091720fd93e878137add264bac4f644e1ddae07a70bf7062c7862c4b952", [:mix], [], "hexpm", "6c32a70ed5d452c6650916555b1f96c79af5fc4bf286997f8b15f213de786f73"},
"earmark": {:hex, :earmark, "1.4.3", "364ca2e9710f6bff494117dbbd53880d84bebb692dafc3a78eb50aa3183f2bfd", [:mix], [], "hexpm", "8cf8a291ebf1c7b9539e3cddb19e9cef066c2441b1640f13c34c1d3cfc825fec"},
"ex_doc": {:hex, :ex_doc, "0.21.3", "857ec876b35a587c5d9148a2512e952e24c24345552259464b98bfbb883c7b42", [:mix], [{:earmark, "~> 1.4", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm", "0db1ee8d1547ab4877c5b5dffc6604ef9454e189928d5ba8967d4a58a801f161"},
"excoveralls": {:hex, :excoveralls, "0.12.2", "a513defac45c59e310ac42fcf2b8ae96f1f85746410f30b1ff2b710a4b6cd44b", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "151c476331d49b45601ffc45f43cb3a8beb396b02a34e3777fea0ad34ae57d89"},
"exjsx": {:hex, :exjsx, "4.0.0", "60548841e0212df401e38e63c0078ec57b33e7ea49b032c796ccad8cde794b5c", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, repo: "hexpm", optional: false]}], "hexpm"},
"hackney": {:hex, :hackney, "1.15.0", "287a5d2304d516f63e56c469511c42b016423bcb167e61b611f6bad47e3ca60e", [:rebar3], [{:certifi, "2.4.2", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "6.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.4", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"},
"idna": {:hex, :idna, "6.0.0", "689c46cbcdf3524c44d5f3dde8001f364cd7608a99556d8fbd8239a5798d4c10", [:rebar3], [{:unicode_util_compat, "0.4.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"},
"jason": {:hex, :jason, "1.1.2", "b03dedea67a99223a2eaf9f1264ce37154564de899fd3d8b9a21b1a6fd64afe7", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"},
"gun": {:hex, :gun, "1.3.2", "542064cbb9f613650b8a8100b3a927505f364fbe198b7a5a112868ff43f3e477", [:rebar3], [{:cowlib, "~> 2.6.0", [hex: :cowlib, repo: "hexpm", optional: false]}], "hexpm", "ba323f0a5fd8abac379a3e1fe6d8ce570c4a12c7fd1c68f4994b53447918e462"},
"hackney": {:hex, :hackney, "1.15.2", "07e33c794f8f8964ee86cebec1a8ed88db5070e52e904b8f12209773c1036085", [:rebar3], [{:certifi, "2.5.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "6.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.5", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm", "e0100f8ef7d1124222c11ad362c857d3df7cb5f4204054f9f0f4a728666591fc"},
"idna": {:hex, :idna, "6.0.0", "689c46cbcdf3524c44d5f3dde8001f364cd7608a99556d8fbd8239a5798d4c10", [:rebar3], [{:unicode_util_compat, "0.4.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "4bdd305eb64e18b0273864920695cb18d7a2021f31a11b9c5fbcd9a253f936e2"},
"jason": {:hex, :jason, "1.1.2", "b03dedea67a99223a2eaf9f1264ce37154564de899fd3d8b9a21b1a6fd64afe7", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fdf843bca858203ae1de16da2ee206f53416bbda5dc8c9e78f43243de4bc3afe"},
"jsx": {:hex, :jsx, "2.8.3", "a05252d381885240744d955fbe3cf810504eb2567164824e19303ea59eef62cf", [:mix, :rebar3], [], "hexpm"},
"makeup": {:hex, :makeup, "0.8.0", "9cf32aea71c7fe0a4b2e9246c2c4978f9070257e5c9ce6d4a28ec450a839b55f", [:mix], [{:nimble_parsec, "~> 0.5.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm"},
"makeup_elixir": {:hex, :makeup_elixir, "0.13.0", "be7a477997dcac2e48a9d695ec730b2d22418292675c75aa2d34ba0909dcdeda", [:mix], [{:makeup, "~> 0.8", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm"},
"meck": {:hex, :meck, "0.8.13", "ffedb39f99b0b99703b8601c6f17c7f76313ee12de6b646e671e3188401f7866", [:rebar3], [], "hexpm"},
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"},
"mime": {:hex, :mime, "1.3.1", "30ce04ab3175b6ad0bdce0035cba77bba68b813d523d1aac73d9781b4d193cf8", [:mix], [], "hexpm"},
"mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], [], "hexpm"},
"nimble_parsec": {:hex, :nimble_parsec, "0.5.0", "90e2eca3d0266e5c53f8fbe0079694740b9c91b6747f2b7e3c5d21966bba8300", [:mix], [], "hexpm"},
"parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm"},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.4", "f0eafff810d2041e93f915ef59899c923f4568f4585904d010387ed74988e77b", [:make, :mix, :rebar3], [], "hexpm"},
"tesla": {:hex, :tesla, "1.2.1", "864783cc27f71dd8c8969163704752476cec0f3a51eb3b06393b3971dc9733ff", [:mix], [{:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: true]}, {:fuse, "~> 2.4", [hex: :fuse, repo: "hexpm", optional: true]}, {:hackney, "~> 1.6", [hex: :hackney, repo: "hexpm", optional: true]}, {:ibrowse, "~> 4.4.0", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:poison, ">= 1.0.0", [hex: :poison, repo: "hexpm", optional: true]}], "hexpm"},
"unicode_util_compat": {:hex, :unicode_util_compat, "0.4.1", "d869e4c68901dd9531385bb0c8c40444ebf624e60b6962d95952775cac5e90cd", [:rebar3], [], "hexpm"},
"makeup": {:hex, :makeup, "1.0.0", "671df94cf5a594b739ce03b0d0316aa64312cee2574b6a44becb83cd90fb05dc", [:mix], [{:nimble_parsec, "~> 0.5.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "a10c6eb62cca416019663129699769f0c2ccf39428b3bb3c0cb38c718a0c186d"},
"makeup_elixir": {:hex, :makeup_elixir, "0.14.0", "cf8b7c66ad1cff4c14679698d532f0b5d45a3968ffbcbfd590339cb57742f1ae", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "d4b316c7222a85bbaa2fd7c6e90e37e953257ad196dc229505137c5e505e9eff"},
"meck": {:hex, :meck, "0.8.13", "ffedb39f99b0b99703b8601c6f17c7f76313ee12de6b646e671e3188401f7866", [:rebar3], [], "hexpm", "d34f013c156db51ad57cc556891b9720e6a1c1df5fe2e15af999c84d6cebeb1a"},
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"},
"mime": {:hex, :mime, "1.3.1", "30ce04ab3175b6ad0bdce0035cba77bba68b813d523d1aac73d9781b4d193cf8", [:mix], [], "hexpm", "6cbe761d6a0ca5a31a0931bf4c63204bceb64538e664a8ecf784a9a6f3b875f1"},
"mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"},
"nimble_parsec": {:hex, :nimble_parsec, "0.5.3", "def21c10a9ed70ce22754fdeea0810dafd53c2db3219a0cd54cf5526377af1c6", [:mix], [], "hexpm", "589b5af56f4afca65217a1f3eb3fee7e79b09c40c742fddc1c312b3ac0b3399f"},
"parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm", "17ef63abde837ad30680ea7f857dd9e7ced9476cdd7b0394432af4bfc241b960"},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.5", "6eaf7ad16cb568bb01753dbbd7a95ff8b91c7979482b95f38443fe2c8852a79b", [:make, :mix, :rebar3], [], "hexpm", "13104d7897e38ed7f044c4de953a6c28597d1c952075eb2e328bc6d6f2bfc496"},
"ssl_verify_hostname": {:hex, :ssl_verify_hostname, "1.0.6", "45866d958d9ae51cfe8fef0050ab8054d25cba23ace43b88046092aa2c714645", [:make], [], "hexpm", "72b2fc8a8e23d77eed4441137fefa491bbf4a6dc52e9c0045f3f8e92e66243b5"},
"tesla": {:hex, :tesla, "1.3.2", "deb92c5c9ce35e747a395ba413ca78593a4f75bf0e1545630ee2e3d34264021e", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: true]}, {:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: true]}, {:fuse, "~> 2.4", [hex: :fuse, repo: "hexpm", optional: true]}, {:gun, "~> 1.3", [hex: :gun, repo: "hexpm", optional: true]}, {:hackney, "~> 1.6", [hex: :hackney, repo: "hexpm", optional: true]}, {:ibrowse, "~> 4.4.0", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.0", [hex: :mint, repo: "hexpm", optional: true]}, {:poison, ">= 1.0.0", [hex: :poison, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.3", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "7567704c4790e21bd9a961b56d0b6a988ff68cc4dacfe6b2106e258da1d5cdda"},
"unicode_util_compat": {:hex, :unicode_util_compat, "0.4.1", "d869e4c68901dd9531385bb0c8c40444ebf624e60b6962d95952775cac5e90cd", [:rebar3], [], "hexpm", "1d1848c40487cdb0b30e8ed975e34e025860c02e419cb615d255849f3427439d"},
}
2 changes: 1 addition & 1 deletion test/bot_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ defmodule Test.Base do
require Logger
require Test.Utils, as: Utils

@after_timeout Application.get_env(:telegram, :on_error_retry_quiet_period) * 1000 + 5000
@after_timeout Application.get_env(:telegram, :on_error_retry_delay) * 1000 + 5000

defmacro test_base(test_name, type, text_field, send_text) do
quote do
Expand Down
2 changes: 1 addition & 1 deletion test/utils.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ defmodule Test.Utils do
@token "123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11"
@method "getFoo"

@retry_wait_period Application.get_env(:telegram, :on_error_retry_quiet_period) * 1000 + 500
@retry_wait_period Application.get_env(:telegram, :on_error_retry_delay) * 1000 + 500

defmacro tg_token do
quote do: unquote(@token)
Expand Down

0 comments on commit 5d2db98

Please sign in to comment.