defmodule Tgapi do use Tesla, docs: false @moduledoc """ Documentation for `Tgapi`. """ @doc """ you should use this to call Telegram methods. """ adapter(Tesla.Adapter.Hackney, recv_timeout: 63_000) plug(Tesla.Middleware.BaseUrl, "https://api.telegram.org") def client(token) do fn method -> fn parameters -> parameters = Enum.map_join(parameters, "&", fn param -> "#{elem(param, 0)}=#{elem(param, 1)}" end) case get("/bot#{token}/#{method}?#{parameters}") do {:ok, %{body: body}} -> {:ok, data} = JSON.decode(body) case data do %{"ok" => true} -> {:ok, data["result"]} %{"ok" => false} -> {:error, data} end {:error, error} -> {:error, error} end end end end def inline_keyboard(data) do JSON.encode!(%{inline_keyboard: data}) end def keyboard(data) do JSON.encode!(%{keyboard: data}) end def get_updates(token, offset \\ 0) do client(token).(:getUpdates).(offset: offset, timeout: 60) end def handle(token, handler, offset \\ 0) do {:ok, updates} = get_updates(token, offset) Enum.each(updates, &Task.Supervisor.start_child(Tgapi.TaskSupervisor, fn -> handler.(&1) end)) last_update_id = Enum.at(updates, -1, %{"update_id" => -1})["update_id"] handle(token, handler, last_update_id + 1) end def spawn_handle(token, handler, offset \\ 0) do Task.start_link(fn -> handle(token, handler, offset) end) end def start(token, handler) do Supervisor.start_link([ {Task.Supervisor, name: Tgapi.TaskSupervisor}, {Tgapi.Session, Tgapi.BotSession}, Supervisor.child_spec({Task, fn -> handle(token, handler) end}, restart: :permanent) ], [strategy: :one_for_one, name: Tgapi.Supervisor]) end end