partial method with [CallbackButton] attributes and the generator emits the implementation. Both produce standard Telegram.Bot markup types.
- Fluent builders
- Generated keyboards
Fluent builders accumulate buttons linearly and then shape them into rows with
Flat methods cover every button kind — callback, URL (
Build() (one button per row) or Adjust(rowSizes) (explicit row widths, last size repeated for remaining buttons).InlineKeyboardBuilder
Flat methods cover every button kind — callback, URL (string or Uri), copy-text, Web App, switch-inline-query variants, login, and pay — plus Add(...) for pre-built InlineKeyboardButtons. Row(...) composes an explicit row (via a nested InlineKeyboardRowBuilder or pre-built buttons); composed rows precede the flat buttons in Build().Adjust(...) chunks only the flat buttons; composed rows are included by Build().ReplyKeyboardBuilder
ReplyKeyboardBuilder mirrors the inline builder and always sets ResizeKeyboard = true on the produced markup. Beyond plain text buttons it covers the request-style buttons: contact, location, poll, users, chat, managed business bot, and Web App.Adjust row-sizing rules
Adjust(params int[] rowSizes) chunks the flat button list into rows using the given widths in order. When the button list is longer than the specified sizes, the last size is repeated for all remaining buttons.
{parameter} placeholders in generated keyboards
Placeholders in CallbackData strings reference the declaring method’s parameters by name and are interpolated in the generated code at call time. Placeholders that don’t match any parameter name produce warning CUR017.
Partial properties have no parameters, so
{parameter} placeholders only work on methods.Requirements for generated keyboards
- The containing type must be
partial. - The method or property return type must be
InlineKeyboardMarkup; any other type is a compile-time error (CUR018). - Non-
partialmembers and generic methods produce warningCUR019and are skipped.
Diagnostics reference
CUR017 – Unknown placeholder in CallbackData
CUR017 – Unknown placeholder in CallbackData
Severity: WarningA
{name} placeholder in a [CallbackButton] attribute’s CallbackData does not match any parameter of the declaring method. The placeholder will be emitted as a literal string at runtime.CUR018 – Non-InlineKeyboardMarkup return type
CUR018 – Non-InlineKeyboardMarkup return type
Severity: ErrorA
[CallbackButton]-annotated method or property does not return InlineKeyboardMarkup. The generator skips the member.CUR019 – Non-partial or generic member
CUR019 – Non-partial or generic member
Severity: WarningA
[CallbackButton]-annotated member is not declared partial, or the method itself is generic. The generator cannot emit an implementation and skips the member.CUR050 – callback_data literal is invalid
CUR050 – callback_data literal is invalid
Severity: ErrorA constant
callback_data string passed to InlineKeyboardButton.WithCallbackData(...), InlineKeyboardBuilder.CallbackButton(...), or an InlineKeyboardButton object initializer is empty or longer than 64 bytes. The Bot API requires 1–64 bytes, so the button fails at runtime.CUR055 – callback_data built by string interpolation
CUR055 – callback_data built by string interpolation
Severity: InfoA
callback_data argument (same call sites as CUR050) is an interpolated string ($"item:{id}"). Consider a [CallbackButton]-generated keyboard with placeholders, or [Pattern] routing with CallbackPatternMatcher for typed, length-checked parsing.