Introduction

Telegramis a cloud based mobile and desktop messaging app with a focus on speed and security.

Bots in telegram are used to provide services which makes our life easy and more comfortable. Today, we are going to build one in Elixir using Phoenix framework.

Requirement

— Telegram Bot API Token We need a token of request which is generated by the botfather to make authorized requests to server. Once if you are up with token, we are ready to make uphill battle.

Web-Frameworks

You are suppose to be knowledgeable in one of the Elixir web frameworks available. Some of them are, as follows:

Choose your best. Here I go with Phoenix which is highly recommended by the most of developers because of its channel and plug implementations for socket programming.

Phoenix Project Creation

mix phoenix.new telegrambot --no-ecto --no-brunch

The above command will create a phoenix application with out ecto and brunch which has no use in our application. Hope you know how to work with phoenix. So that, I am not going to explain about phoenix here.

Webhooks Next step we need to have a web hook for matching telegram request to server. Check the Telegram Bot API for more information on Telegram webhooks.

🔥 If you’d like to make sure that the Webhook request comes from Telegram, we recommend using a secret path in the URL, e.g. https://www.example.com/your_token

Since nobody knows your bot’s token, you can be pretty sure of that request is from the Telegram.

On phoenix router, in botkey it can be any parameter, just so that It needs to be identified that its is send by telegram.

defmodule Application.Router do
  use Application.Web, :router
  scope "/", Application do
    post "/#{botkey}",PageController, :index
  end
end

Once route in Phoenix is prepared,

https://api.telegram.org/bot#{botkey}/setWebhook?url="https://example.com/#{botkey}"

A GET request will set the web hook in the telegram server.

Till know we configured that, a bot can communicate to your server, now we will configure so that server can talk back to boot.

Nadia — Telegram API framework GitHub — zhyu/nadia: Telegram Bot API Wrapper written in Elixir

In config/config.ex add your Telegram Bot token like following.

def application do
 [applications: [:nadia]]
end
config :nadia,
 token: “bot token”

In phoenix controller,

defmodule Application.PageController do
 use Application.Web, :controller
 def index(conn, params) do
 %{"from"=> from,"id"=> id,"offset"=>_,"query"=>query}= params["inline_query"]
 application.search(from["id"],id,query)
 conn
 |> json %{ status: true }
 end
end

We have to extract the data from the query, if you are using inline_query, this is the format. For different responses refer to telegram API.

Once query and request id is extracted, its upto to the logic of our application.

Nadia, is a good application that can be used to send responses, well Nadia has full features, you can send any responses. Currently this example is limited to text reply.

defmodule Qwantclient do

  def search(userid, requestId, query) do
    request(query)
    |>Poison.decode!
    |>parser
    |>send_toUser(requestId)
  end

  def request(query) do
    url = "https://api.qwant.com/api/search/web?q=#{query}"
    case HTTPoison.get(url) do
      {:ok, %HTTPoison.Response{status_code: 200, body: body}} ->
        body
      {:error, %HTTPoison.Error{reason: reason}} ->
        IO.puts "reason #{inspect reason}"
        reason

    end
  end

  def parser(data) do
    data["data"]["result"]["items"]                                          
    |> Enum.map(fn (item)->
          article = %Nadia.Model.InlineQueryResult.Article{}                        
          %{article | title: item["title"],                                                       
              thumb_url: "http:"<>item["favicon"],                                                 
              description: item["desc"],                                                  
              url: item["url"],                                                           
              id: item["_id"],                                  
              input_message_content: %Nadia.Model.InputMessageContent.Text{ %Nadia.Model.InputMessageContent.Text{} | message_text: item["title"]<>item["desc"], parse_mode: "HTML" }
            } end)
  end
    def send_toUser(response,requestId) do
      res = Nadia.answer_inline_query(requestId, response)
      IO.inspect res
      IO.puts "nadi"
    end
end

Bot Response

If every thing goes well after pushing your code to heroku and running, you’ll see a response like above image.

Hope this helps you apart.


Join Our Telegram Channel

Blackoders
  Telegram
  Channel

Check out the GitHub repository on Killer Elixir Tips

Blackoders
  Telegram
  Channel Glad if you can contribute with a ★

🎉 Happy Coding :)


author image
WRITTEN BY
Anwesh