kannix
Poll Telegram API until response
I am currently stuck with an implementation of a function that has to poll the Telegram API periodically and wait for a response from this. I guess there is some async / await magic that will help me to solve this problem in an elegant way. Maybe someone can jump in an give me a hint ![]()
Other suggestions for improvement are also very welcome ![]()
defmodule TelegramHelper do
@moduledoc """
Documentation for TelegramHelper.
"""
import Nadia
@chat_id 123456
@spec get_sms_verification_code() :: any()
def get_sms_verification_code do
# telegram api will return some old messages from time to time
# so we have to check if there are old message and get the update_id to poll later only for newer messages
update_id = 0
{:ok, result} = get_updates
if length(result) > 0 do
update_id = List.last(result).update_id + 1
end
send_message(@chat_id, "Please send the Auth Code")
get_reply(update_id)
end
defp get_reply(update_id) do
Process.sleep(1000)
{:ok, result} = get_updates(%{:update_id => update_id})
if length(result) == 0 do
# this should stop after a timeout of e.g. 5 Minutes
# and is obviously the wrong way of doing it
get_reply(update_id)
end
# this is only for reference on what i want to return if i get back a new message from telegram
List.first(result).message.text
end
end
Most Liked
david_ex
I believe you should be returning a tuple from handle_info/2:
def handle_info(:poll, state) do
case get_updates(last_update_id) do
[] ->
Process.send_after(self(), :poll, 5000)
{:noreply, state}
new_messages ->
state = handle_new_messages(state, new_messages)
{:noreply, state}
end
end
2
Last Post!
idi527
I don’t think you need a looping async functions … I’d do something like
# in Auther
def wait_for_chat(server , chat_id, timeout \\ 5000) do
GenServer.call(server, {:wait_for_chat, chat_id}, timeout)
end
@doc false
def handle_call({:wait_for_chat, chat_id}, from, state) do
# note that `Map.put` would override any previous "subscription" (from)
# if this is a problem, store `from`s in a list
# auth_codes = %{chat_id => [from1, from2, from3, ...]}
{:noreply, %{state | auth_codes: Map.put(state.auth_codes, chat_id, from)}}
end
defp handle_new_messages(state, new_messages) do
# go over new messages and check if there are any auth codes from
# the chat ids in state.auth_codes, if there are, reply to
# the client process in the corresponding to that chat_id's `from`
auth_codes = Enum.reduce(new_messages, state.auth_codes, fn %{"chat" => %{"id" => chat_id}, "text" => message}, auth_codes ->
with true <- auth_code?(message),
{from, auth_codes} when not is_nil(from) <- Map.pop(auth_codes, chat_id) do
GenServer.reply(from, message)
auth_codes
else
_ -> auth_codes
end
end)
%{state | auth_codes: auth_codes}
end
Then in your browser automation program you can do
fill_email_password("mail", "password")
click_auth_button
auth_code = Auther.wait_for_chat(auther_pid, chat_id, :infinity) # or just a large number for timeout
fill_auth_code(code_from_telegram)
state.auth_codes should probably be renamed to state.awaiting_auth_codes or awaiting_chats_auth_code something like that. It was named incorrectly the first time since I misunderstood your problem again, it seems.
0
Popular in Questions
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
Hi everyone!
I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this:
...
New
Hey,
Just curious what are the main benefits of Elixir compared to Clojure?
When is Elixir more useful than Clojure and vice versa?
Th...
New
I’ve got an issue with an app and I’ve no idea of how to troubleshoot it. I’m hoping someone here might have seen something similar.
I p...
New
Other popular topics
Hi,
I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list. ...
New
Hi!
In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir?
Searched the docs for ip address and the web, no good results.
Thanks!
New
Hi there,
I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 records...
New
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
Hello all!
I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #elixirconf-us
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #metaprogramming
- #security
- #hex









