Skip to content

Reply Keyboards

Chris Watson edited this page Sep 9, 2019 · 6 revisions

Intro

Sometimes it might be nice to get user input via predefined options. This is where a reply keyboard comes in handy. Reply keyboards allow you to show a keyboard with a set of buttons that perform different actions. Let's go into what some of those actions are.

Reply Keyboards

Tourmaline comes with a built in class called Model::ReplyKeyboardMarkup. Any message can be sent with a ReplyKeyboardMarkup instance attached to attach a keyboard to the message. Here's a simple example:

REPLY_MARKUP = Tourmaline::Model::ReplyKeyboardMarkup.new([
  [Tourmaline::Model::KeyboardButton.new("/kitty")],
  [Tourmaline::Model::KeyboardButton.new("/kittygif")],
])

@[Command(["start", "help"])]
def help_command(message, params)
  message.chat.send_message("😺 Use commands: /kitty and /kittygif", reply_markup: REPLY_MARKUP)
end

You should end up with a keyboard that looks like this:

kitty reply keyboard

The Markup Module

As you may have noticed, the keyboard creation process is pretty verbose. Luckily there is a module to help you out. The Markup module includes a number of keyboard related convenience methods. Let's modify the previous code block using Markup instead.

REPLY_MARKUP = Markup.keyboard([
  ["/kitty"], ["/kittygif"],
])

@[Command(["start", "help"])]
def help_command(message, params)
  message.chat.send_message("😺 Use commands: /kitty and /kittygif", reply_markup: REPLY_MARKUP)
end

So much better! The Markup.keyboard method returns a ReplyKeyboardMarkup instance, and accepts an Array(Array(String | NamedTuple | Model::KeyboardButton)) as a first argument. If I had wanted to I could have also done REPLY_MARKUP a number of different ways and gotten the same result. For instance:

# This uses the NamedTuples to create a new keyboard button
REPLY_MARKUP = Markup.keyboard([
  [{text: /kitty"}], [{text: "/kittygif"}],
])

# The Markup.button method creates a text button
REPLY_MARKUP = Markup.keyboard([
  [Markup.button("/kitty")], [Markup.button("/kittygif")],
])

You can check out the documentation for the Markup module for more information.

Inline Keyboards

Telegram also allows the creation of inline keyboards. Inline keyboards, as the name states, are displayed inline right below the message they're attached to, rather than being attached below the message area. Let's try to do the same thing as before, but with an inline keyboard.

REPLY_MARKUP = Markup.inline_keyboard([
  [{text: "pic", callback_data: "pic"}, {text: "gif", callback_data: "gif"}],
])

@[Command(["start", "help"])]
def help_command(message, params)
  message.chat.send_message("😺 Choose an option below", reply_markup: REPLY_MARKUP)
end

@[On(:callback_query)]
def kitty_command(update)
  if query = update.callback_query
    if message = query.message
      # The time hack is to get around Telegram's image cache
      api = API_URL + "?time=#{Time.now}&format=src&type="
      cmd = query.data

      message.chat.send_chat_action(:upload_photo)
      if cmd == "pic"
        message.chat.send_photo(api + "jpg")
      else
        message.chat.send_document(api + "gif")
      end
    end
  end
end

With that code you should end up with this:

inline keyboard

Clone this wiki locally