Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/.idea
/.elixir_ls
/_build
/config/config.exs
/deps
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ Now Mix will guarantee the `:nadia` application is started before your applicati

## Usage

There is two ways of using this bot:
- `Nadia` - uses default `:nadia` config section and simplifies configration
- `Nadia.Bot` - uses whatever you pass to it as a bot name

### get_me

```elixir
Expand Down
245 changes: 74 additions & 171 deletions lib/nadia.ex

Large diffs are not rendered by default.

119 changes: 6 additions & 113 deletions lib/nadia/api.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,106 +3,7 @@ defmodule Nadia.API do
Provides basic functionalities for Telegram Bot API.
"""

alias Nadia.Model.Error
alias Nadia.Config

defp build_url(method), do: Config.base_url() <> Config.token() <> "/" <> method

defp process_response(response, method) do
case decode_response(response) do
{:ok, true} -> :ok
{:ok, %{ok: false, description: description}} -> {:error, %Error{reason: description}}
{:ok, result} -> {:ok, Nadia.Parser.parse_result(result, method)}
{:error, %HTTPoison.Error{reason: reason}} -> {:error, %Error{reason: reason}}
{:error, error} -> {:error, %Error{reason: error}}
end
end

defp decode_response(response) do
with {:ok, %HTTPoison.Response{body: body}} <- response,
{:ok, %{result: result}} <- Jason.decode(body, keys: :atoms),
do: {:ok, result}
end

defp build_multipart_request(params, file_field) do
{file_path, params} = Keyword.pop(params, file_field)
params = for {k, v} <- params, do: {to_string(k), v}

{:multipart,
params ++
[
{:file, file_path,
{"form-data", [{"name", to_string(file_field)}, {"filename", file_path}]}, []}
]}
end

defp calculate_timeout(options) when is_list(options) do
(Keyword.get(options, :timeout, 0) + Config.recv_timeout()) * 1000
end

defp calculate_timeout(options) when is_map(options) do
(Map.get(options, :timeout, 0) + Config.recv_timeout()) * 1000
end

defp build_request(params, file_field) when is_list(params) do
params
|> Keyword.update(:reply_markup, nil, &Jason.encode!(&1))
|> map_params(file_field)
end

defp build_request(params, file_field) when is_map(params) do
params
|> Map.update(:reply_markup, nil, &Jason.encode!(&1))
|> map_params(file_field)
end

defp map_params(params, file_field) do
params =
params
|> Enum.filter(fn {_, v} -> v end)
|> Enum.map(fn {k, v} -> {k, to_string(v)} end)

if !is_nil(file_field) and File.exists?(params[file_field]) do
build_multipart_request(params, file_field)
else
{:form, params}
end
end

defp build_options(options) do
timeout = calculate_timeout(options)
opts = [recv_timeout: timeout]

opts =
case Config.proxy() do
proxy when byte_size(proxy) > 0 -> Keyword.put(opts, :proxy, proxy)
proxy when is_tuple(proxy) and tuple_size(proxy) == 3 -> Keyword.put(opts, :proxy, proxy)
_ -> opts
end

opts =
case Config.proxy_auth() do
proxy_auth when is_tuple(proxy_auth) and tuple_size(proxy_auth) == 2 ->
Keyword.put(opts, :proxy_auth, proxy_auth)

_ ->
opts
end

opts =
case Config.socks5_user() do
socks5_user when byte_size(socks5_user) > 0 ->
Keyword.put(opts, :socks5_user, socks5_user)

_ ->
opts
end

case Config.socks5_pass() do
socks5_pass when byte_size(socks5_pass) > 0 -> Keyword.put(opts, :socks5_pass, socks5_pass)
_ -> opts
end
end
alias Nadia.Bot.API

@doc """
Generic method to call Telegram Bot API.
Expand All @@ -113,17 +14,11 @@ defmodule Nadia.API do
* `file_field` - specify the key of file_field in `options` when sending files
"""
@spec request(binary, [{atom, any}], atom) :: :ok | {:error, Error.t()} | {:ok, any}
def request(method, options \\ [], file_field \\ nil) do
method
|> build_url
|> HTTPoison.post(build_request(options, file_field), [], build_options(options))
|> process_response(method)
end
def request(method, options \\ [], file_field \\ nil),
do: API.request(:nadia, method, options, file_field)

def request?(method, options \\ [], file_field \\ nil) do
{_, response} = request(method, options, file_field)
response
end
def request?(method, options \\ [], file_field \\ nil),
do: API.request?(:nadia, method, options, file_field)

@doc ~S"""
Use this function to build file url.
Expand All @@ -132,7 +27,5 @@ defmodule Nadia.API do
"https://api.telegram.org/file/bot#{Nadia.Config.token()}/document/file_10"
"""
@spec build_file_url(binary) :: binary
def build_file_url(file_path) do
Config.file_base_url() <> Config.token() <> "/" <> file_path
end
def build_file_url(file_path), do: API.build_file_url(:nadia, file_path)
end
Loading