Packages
ex_gram
0.50.1
0.67.0
0.66.0
0.65.0
0.64.0
0.63.0
0.62.0
0.61.0
0.60.0
0.58.0
0.57.0
0.56.1
0.56.0
0.55.1
0.55.0
0.54.0
0.53.0
0.52.2
0.52.1
0.52.0
0.51.1
0.51.0
0.50.2
0.50.1
0.50.0
0.41.0
0.40.0
0.34.0
0.33.0
0.32.0
0.31.0
0.30.0
0.29.0
0.28.0
0.27.0
0.26.0
0.25.0
0.24.1
0.24.0
0.23.0
0.22.0
0.21.0
0.20.0
0.15.0
0.14.0
0.13.0
0.12.0
0.11.0
0.10.0
0.9.0
0.8.1
0.8.0
0.7.1
0.7.0
0.6.2
0.6.1
0.6.0
0.5.0
0.5.0-rc6
0.5.0-rc5
0.5.0-rc4
0.5.0-rc3
0.5.0-rc2
Telegram Bot API low level and framework
Current section
Files
Jump to
Current section
Files
lib/ex_gram/updates/polling.ex
defmodule ExGram.Updates.Polling do
@moduledoc """
Updates implementation that uses polling method
"""
use GenServer
require Logger
@polling_timeout 100
def start_link({:bot, pid, :token, token}) do
# Logger.debug "START WORKER"
GenServer.start_link(__MODULE__, {:ok, pid, token})
end
def init({:ok, pid, token}) do
# Clean webhook
ExGram.delete_webhook(token: token)
Process.send_after(self(), {:fetch, :update_id}, @polling_timeout)
{:ok, {pid, token, -1}}
end
def handle_cast({:fetch, :update_id} = m, state), do: handle_info(m, state)
def handle_info(:timeout, state), do: handle_info({:fetch, :update_id}, state)
def handle_info({:fetch, :update_id}, {pid, token, uid}) do
updates = get_updates(token, uid)
send_updates(updates, pid)
nid = next_pid(uid, updates)
{:noreply, {pid, token, nid}, @polling_timeout}
end
def handle_info(unknown_message, state) do
Logger.debug("Polling updates received an unknown message #{inspect(unknown_message)}")
{:noreply, state, @polling_timeout}
end
@default_opts [limit: 100, timeout: 50]
defp get_updates(token, uid, opts \\ []) do
opts =
@default_opts
|> Keyword.merge(opts)
|> Keyword.put(:offset, uid)
|> Keyword.put(:token, token)
try do
ExGram.get_updates!(opts)
rescue
ExGram.Error -> []
end
end
defp send_updates(updates, pid) do
Enum.map(updates, &GenServer.call(pid, {:update, &1}))
end
defp next_pid(actual, []), do: actual
defp next_pid(actual, updates) do
updates
|> Stream.map(&(&1.update_id + 1))
|> Enum.reduce(actual, &max(&1, &2))
end
end