src.handlers package

Submodules

src.handlers.base module

src.handlers.base.inline_control_buttons(back: bool = True, skip: bool = True, cancel: bool = True) → List[aiogram.types.inline_keyboard.InlineKeyboardButton][source]

Create inline button row with translated labels to control current state.

src.handlers.base.orders_list(cursor: pymongo.cursor.Cursor, chat_id: int, start: int, quantity: int, buttons_data: str, user_id: Optional[int] = None, message_id: Optional[int] = None, invert: Optional[bool] = None) → None[source]

Send list of orders.

Parameters:
  • cursor – Cursor of MongoDB query to orders.
  • chat_id – Telegram ID of current chat.
  • start – Start index.
  • quantity – Quantity of orders in cursor.
  • buttons_data – Beginning of callback data of left/right buttons.
  • user_id – Telegram ID of current user if cursor is not user-specific.
  • message_id – Telegram ID of message to edit.
  • invert – Invert all prices.
src.handlers.base.show_order(order: Mapping[str, Any], chat_id: int, user_id: int, message_id: Optional[int] = None, location_message_id: Optional[int] = None, show_id: bool = False, invert: Optional[bool] = None, edit: bool = False, locale: Optional[str] = None)[source]

Send detailed order.

Parameters:
  • order – Order document.
  • chat_id – Telegram ID of chat to send message to.
  • user_id – Telegram user ID of message receiver.
  • message_id – Telegram ID of message to edit.
  • location_message_id – Telegram ID of message with location object. It is deleted when Hide inline button is pressed.
  • show_id – Add ID of order to the top.
  • invert – Invert price.
  • edit – Enter edit mode.
  • locale – Locale of message receiver.
src.handlers.base.start_keyboard() → aiogram.types.reply_keyboard.ReplyKeyboardMarkup[source]

Create reply keyboard with main menu.

src.handlers.creation module

Handlers for order creation.

Handlers decorated with state_handler are called by change_state when user skips (where it is possible) or goes back to corresponding step using back/skip inline buttons. Handlers decorated with private_handler are called when user sends value.

src.handlers.creation.cancel_button(call: aiogram.types.callback_query.CallbackQuery, state: aiogram.dispatcher.storage.FSMContext)[source]

React to cancel button.

src.handlers.creation.cancel_order_creation(user_id: int, chat_id: int)[source]

Cancel order creation.

src.handlers.creation.change_state(call: aiogram.types.callback_query.CallbackQuery, state: aiogram.dispatcher.storage.FSMContext)[source]

React to back/skip button query.

src.handlers.creation.choose_buy(message: aiogram.types.message.Message, state: aiogram.dispatcher.storage.FSMContext)[source]

Set currency user wants to buy and ask for one they want to sell.

src.handlers.creation.choose_buy_gateway(message: aiogram.types.message.Message, state: aiogram.dispatcher.storage.FSMContext)[source]

Set gateway of buy currency and ask for sell currency.

src.handlers.creation.choose_comments(message: aiogram.types.message.Message, state: aiogram.dispatcher.storage.FSMContext)[source]

Set comments and finish order creation.

src.handlers.creation.choose_comments_handler(call: aiogram.types.callback_query.CallbackQuery)[source]

Finish order creation.

src.handlers.creation.choose_duration(message: aiogram.types.message.Message, state: aiogram.dispatcher.storage.FSMContext)[source]

Set duration and ask for comments.

src.handlers.creation.choose_location(message: aiogram.types.message.Message, state: aiogram.dispatcher.storage.FSMContext)[source]

Set location from Telegram object and ask for duration.

src.handlers.creation.choose_payment_system(message: aiogram.types.message.Message, state: aiogram.dispatcher.storage.FSMContext)[source]

Set payment system and ask for location.

src.handlers.creation.choose_price(message: aiogram.types.message.Message, state: aiogram.dispatcher.storage.FSMContext)[source]

Set price and ask for sum currency.

src.handlers.creation.choose_sell(message: aiogram.types.message.Message, state: aiogram.dispatcher.storage.FSMContext)[source]

Set currency user wants to sell and ask for price.

src.handlers.creation.choose_sell_gateway(message: aiogram.types.message.Message, state: aiogram.dispatcher.storage.FSMContext)[source]

Set gateway of sell currency and ask for price.

src.handlers.creation.choose_sum(message: aiogram.types.message.Message, state: aiogram.dispatcher.storage.FSMContext)[source]

Set sum.

If price and sum in another currency were not specified, ask for sum in another currency. Otherwise calculate it if price was specified, and, finally, ask for cashless payment system.

src.handlers.creation.choose_sum_currency(call: aiogram.types.callback_query.CallbackQuery)[source]

Set sum currency and ask for sum in that currency.

src.handlers.creation.comment_handler(call: aiogram.types.callback_query.CallbackQuery)[source]

Ask for comments.

src.handlers.creation.duration_handler(call: aiogram.types.callback_query.CallbackQuery)[source]

Ask for duration.

src.handlers.creation.geocoded_location(call: aiogram.types.callback_query.CallbackQuery)[source]

Choose location from list of options and ask for duration.

src.handlers.creation.get_currency_with_gateway(currency_type: str, message: aiogram.types.message.Message)[source]

Try to append gateway from message text to currency.

src.handlers.creation.invert_price(call: aiogram.types.callback_query.CallbackQuery)[source]

Change currency of price.

src.handlers.creation.location_handler(call: aiogram.types.callback_query.CallbackQuery)[source]

Ask for location.

src.handlers.creation.match_currency(currency_type: str, message: aiogram.types.message.Message)[source]

Match message text with currency pattern.

src.handlers.creation.payment_system_handler(call: aiogram.types.callback_query.CallbackQuery)[source]

Ask for cashless payment system.

src.handlers.creation.price_ask(call: aiogram.types.callback_query.CallbackQuery, order: Mapping[str, Any], price_currency: str)[source]

Edit currency of price in message to price_currency field value.

src.handlers.creation.price_handler(call: aiogram.types.callback_query.CallbackQuery)[source]

Ask for price.

src.handlers.creation.set_order(order: MutableMapping[str, Any], chat_id: int)[source]

Set missing values and finish order creation.

src.handlers.creation.set_price_state(message: aiogram.types.message.Message, order: Mapping[str, Any])[source]

Ask for price.

src.handlers.creation.sum_handler(call: aiogram.types.callback_query.CallbackQuery)[source]

Ask for sum currency.

src.handlers.creation.text_location(message: aiogram.types.message.Message, state: aiogram.dispatcher.storage.FSMContext)[source]

Find location by name.

If there is only one option, set it and ask for duration. Otherwise send a list of these options for user to choose.

src.handlers.creation.whitelisting_request(call: aiogram.types.callback_query.CallbackQuery)[source]

Send whitelisting request to support or increment requests count.

src.handlers.escrow module

Handlers for escrow exchange.

src.handlers.escrow.accept_insurance(call: aiogram.types.callback_query.CallbackQuery, offer: src.escrow.escrow_offer.EscrowOffer)[source]

Ask for fee payment agreement after accepting partial insurance.

src.handlers.escrow.accept_offer(call: aiogram.types.callback_query.CallbackQuery, offer: src.escrow.escrow_offer.EscrowOffer)[source]

React to counteragent accepting offer by asking for fee payment agreement.

src.handlers.escrow.add_cashback(currency, amount, sum_fee_up, sum_fee_down, sender_user, recipient_user)[source]

Create cashback documents from escrow exchange.

src.handlers.escrow.ask_credentials(call: aiogram.types.callback_query.CallbackQuery, offer: src.escrow.escrow_offer.EscrowOffer)[source]

Update offer with update_dict and start asking transfer information.

Ask to choose bank if user is initiator and there is a fiat currency. Otherwise ask receive address.

src.handlers.escrow.ask_fee(user_id: int, chat_id: int, offer: src.escrow.escrow_offer.EscrowOffer)[source]

Ask fee of any party.

src.handlers.escrow.call_later(delay: float, callback: Callable, *args, **kwargs)[source]

Call callback(*args, **kwargs) asynchronously after delay seconds.

src.handlers.escrow.cancel_offer(call: aiogram.types.callback_query.CallbackQuery, offer: src.escrow.escrow_offer.EscrowOffer)[source]

React to offer cancellation.

While first party is transferring, second party can’t cancel offer, because we can’t be sure that first party hasn’t already completed transfer before confirming.

src.handlers.escrow.check_transaction(call: aiogram.types.callback_query.CallbackQuery, offer: src.escrow.escrow_offer.EscrowOffer)[source]

Start transaction check.

src.handlers.escrow.choose_bank(call: aiogram.types.callback_query.CallbackQuery, offer: src.escrow.escrow_offer.EscrowOffer)[source]

Set chosen bank and continue.

Because bank is chosen by initiator, ask for receive address if they receive escrow asset.

src.handlers.escrow.complete_offer(call: aiogram.types.callback_query.CallbackQuery, offer: src.escrow.escrow_offer.EscrowOffer)[source]

Release escrow asset and finish exchange.

src.handlers.escrow.create_memo(offer: src.escrow.escrow_offer.EscrowOffer, *, transfer: bool, counter_send_address: Optional[str] = None)[source]

Create memo for transfer.

src.handlers.escrow.decline_fee(call: aiogram.types.callback_query.CallbackQuery, offer: src.escrow.escrow_offer.EscrowOffer)[source]

Decline fee and start asking transfer information.

src.handlers.escrow.decline_offer(call: aiogram.types.callback_query.CallbackQuery, offer: src.escrow.escrow_offer.EscrowOffer)[source]

React to counteragent declining offer.

src.handlers.escrow.edit_keyboard(offer_id: bson.objectid.ObjectId, chat_id: int, message_id: int, keyboard: aiogram.types.inline_keyboard.InlineKeyboardMarkup)[source]

Edit inline keyboard markup of message.

Parameters:
  • offer_id – Primary key value of offer document connected with message.
  • chat_id – Telegram chat ID of message.
  • message_id – Telegram ID of message.
  • keyboard – New inline keyboard markup.
src.handlers.escrow.escrow_callback_handler(*args, state=<State '*'>, **kwargs)[source]

Simplify handling callback queries during escrow exchange.

Add offer of EscrowOffer to arguments of decorated callback query handler.

src.handlers.escrow.escrow_message_handler(*args, **kwargs)[source]

Simplify handling messages during escrow exchange.

Add offer of EscrowOffer to arguments of decorated private message handler.

src.handlers.escrow.final_offer_confirmation(call: aiogram.types.callback_query.CallbackQuery, offer: src.escrow.escrow_offer.EscrowOffer)[source]

Ask not escrow asset receiver to confirm transfer.

src.handlers.escrow.full_card_number_message(message: aiogram.types.message.Message, offer: src.escrow.escrow_offer.EscrowOffer)[source]

React to sent message while sending full card number to fiat sender.

src.handlers.escrow.full_card_number_request(chat_id: int, offer: src.escrow.escrow_offer.EscrowOffer)[source]

Ask to send full card number.

src.handlers.escrow.full_card_number_sent(call: aiogram.types.callback_query.CallbackQuery, offer: src.escrow.escrow_offer.EscrowOffer)[source]

Confirm that full card number is sent and ask for first and last 4 digits.

src.handlers.escrow.get_card_number(text: str, chat_id: int) → Optional[Tuple[str, str]][source]

Parse first and last 4 digits from card number in text.

If parsing is unsuccessful, send warning to chat_id and return None. Otherwise return tuple of first and last 4 digits of card number.

src.handlers.escrow.get_insurance(offer: src.escrow.escrow_offer.EscrowOffer) → decimal.Decimal[source]

Get insurance of escrow asset in offer taking limits into account.

src.handlers.escrow.init_cancel(call: aiogram.types.callback_query.CallbackQuery, offer: src.escrow.escrow_offer.EscrowOffer)[source]

Cancel offer on initiator’s request.

src.handlers.escrow.pay_fee(call: aiogram.types.callback_query.CallbackQuery, offer: src.escrow.escrow_offer.EscrowOffer)[source]

Accept fee and start asking transfer information.

src.handlers.escrow.set_counter_send_address(address: str, message: aiogram.types.message.Message, offer: src.escrow.escrow_offer.EscrowOffer)[source]

Set address as sender’s address of counteragent.

Ask for escrow asset transfer.

src.handlers.escrow.set_escrow_sum(message: aiogram.types.message.Message, offer: src.escrow.escrow_offer.EscrowOffer)[source]

Set sum and ask for fee payment agreement.

src.handlers.escrow.set_init_send_address(address: str, message: aiogram.types.message.Message, offer: src.escrow.escrow_offer.EscrowOffer)[source]

Set address as sender’s address of initiator.

Send offer to counteragent.

src.handlers.escrow.set_name(message: aiogram.types.message.Message, offer: src.escrow.escrow_offer.EscrowOffer)[source]

Set fiat sender’s name on card and ask for first and last 4 digits.

src.handlers.escrow.set_receive_address(message: aiogram.types.message.Message, offer: src.escrow.escrow_offer.EscrowOffer)[source]

Set escrow asset receiver’s address and ask for sender’s information.

If there is a fiat currency, which is indicated by existing bank field, and user is a fiat sender, ask their name on card. Otherwise ask escrow asset sender’s address.

src.handlers.escrow.set_receive_card_number(message: aiogram.types.message.Message, offer: src.escrow.escrow_offer.EscrowOffer)[source]

Create address from first and last 4 digits of card number and ask send address.

First and last 4 digits of card number are sent by fiat receiver, so their send address is escrow asset address.

src.handlers.escrow.set_send_address(message: aiogram.types.message.Message, offer: src.escrow.escrow_offer.EscrowOffer)[source]

Set send address of any party.

src.handlers.escrow.set_send_card_number(message: aiogram.types.message.Message, offer: src.escrow.escrow_offer.EscrowOffer)[source]

Set first and last 4 digits of any party.

src.handlers.escrow.validate_offer(call: aiogram.types.callback_query.CallbackQuery, offer: src.escrow.escrow_offer.EscrowOffer)[source]

Ask support for manual verification of exchange.

src.handlers.order module

Handlers for showing orders and reacting to query buttons attached to them.

src.handlers.order.aggregate_orders(buy: str, sell: str) → Tuple[motor.core.AgnosticBaseCursor, int][source]

Aggregate and query orders with specified currency pair.

Return cursor with unexpired orders sorted by price and creation time and quantity of documents in it.

src.handlers.order.archive_button(call: aiogram.types.callback_query.CallbackQuery, order: Mapping[str, Any])[source]

React to “Archive” or “Unarchive” button by flipping archived flag.

src.handlers.order.confirm_delete_button(call: aiogram.types.callback_query.CallbackQuery)[source]

Delete order after confirmation button query.

src.handlers.order.default_duration(call: aiogram.types.callback_query.CallbackQuery, state: aiogram.dispatcher.storage.FSMContext)[source]

Repeat default duration.

src.handlers.order.delete_button(call: aiogram.types.callback_query.CallbackQuery, order: Mapping[str, Any])[source]

React to “Delete” button by asking user to confirm deletion.

src.handlers.order.edit_button(call: aiogram.types.callback_query.CallbackQuery)[source]

React to “Edit” button by entering edit mode on order.

src.handlers.order.edit_field(message: aiogram.types.message.Message, state: aiogram.dispatcher.storage.FSMContext)[source]

Ask new value of chosen order’s field during editing.

src.handlers.order.escrow_button(call: aiogram.types.callback_query.CallbackQuery, order: Mapping[str, Any])[source]

React to “Escrow” button by starting escrow exchange.

src.handlers.order.finish_edit(user, update_dict)[source]

Update and show order after editing.

src.handlers.order.get_order_button(call: aiogram.types.callback_query.CallbackQuery, order: Mapping[str, Any])[source]

Choose order from order book.

src.handlers.order.get_order_command(message: aiogram.types.message.Message)[source]

Get order from ID.

Order ID is indicated after /id or ID: in message text.

src.handlers.order.hide_button(call: aiogram.types.callback_query.CallbackQuery)[source]

React to “Hide” button by deleting messages with location object and order.

src.handlers.order.invert_button(call: aiogram.types.callback_query.CallbackQuery, order: Mapping[str, Any])[source]

React to invert button query.

src.handlers.order.match_button(call: aiogram.types.callback_query.CallbackQuery, order: Mapping[str, Any])[source]

React to “Match” button by sending list of matched orders.

Matched orders are ones that have the inverted currency pair.

src.handlers.order.matched_orders_button(call: aiogram.types.callback_query.CallbackQuery)[source]

React to left/right button query in list of orders matched by currency pair.

src.handlers.order.my_orders_button(call: aiogram.types.callback_query.CallbackQuery)[source]

React to left/right button query in list of user’s orders.

src.handlers.order.order_handler(handler: Callable[[aiogram.types.callback_query.CallbackQuery, Mapping[str, Any]], Any])[source]

Simplify handling callback queries attached to order.

Add order of OrderType to arguments of handler.

src.handlers.order.orders_button(call: aiogram.types.callback_query.CallbackQuery)[source]

React to left/right button query in order book.

src.handlers.order.show_orders(call: aiogram.types.callback_query.CallbackQuery, cursor: motor.core.AgnosticBaseCursor, start: int, quantity: int, buttons_data: str, invert: bool, user_id: Optional[int] = None)[source]

Send list of orders.

Parameters:
  • cursor – Cursor of MongoDB query to orders.
  • chat_id – Telegram chat ID.
  • start – Start index.
  • quantity – Quantity of orders in cursor.
  • buttons_data – Beginning of callback data of left/right buttons.
  • user_id – If cursor is user-specific, Telegram ID of user who created all orders in cursor.
  • invert – Invert all prices.
src.handlers.order.similar_button(call: aiogram.types.callback_query.CallbackQuery, order: Mapping[str, Any])[source]

React to “Similar” button by sending list of similar orders.

Similar orders are ones that have the same currency pair.

src.handlers.order.unset_button(call: aiogram.types.callback_query.CallbackQuery, state: aiogram.dispatcher.storage.FSMContext)[source]

React to “Unset” button by unsetting the edit field.

src.handlers.start_menu module

Handlers for start menu.

src.handlers.start_menu.choose_locale(message: aiogram.types.message.Message)[source]

Show list of languages.

src.handlers.start_menu.claim_cashback(message: aiogram.types.message.Message, state: aiogram.dispatcher.storage.FSMContext)[source]

Start cashback claiming process by asking currency.

Send user’s referral link and generate if it doesn’t exist.

src.handlers.start_menu.handle_book(message: aiogram.types.message.Message, state: aiogram.dispatcher.storage.FSMContext, command: Optional[aiogram.dispatcher.filters.builtin.Command.CommandObj] = None)[source]

Show order book with specified currency pair.

Currency pair is indicated with one or two space separated arguments after /book in message text. If two arguments are sent, then first is the currency order’s creator wants to sell and second is the currency order’s creator wants to buy. If one argument is sent, then it’s any of the currencies in a pair.

Any argument can be replaced with *, which results in searching pairs with any currency in place of the wildcard.

Examples:
Command Description
/book BTC USD Show orders that sell BTC and buy USD (BTC → USD)
/book BTC * Show orders that sell BTC and buy any currency
/book * USD Show orders that sell any currency and buy USD
/book BTC Show orders that sell or buy BTC
/book * * Equivalent to /book
src.handlers.start_menu.handle_create(message: aiogram.types.message.Message, state: aiogram.dispatcher.storage.FSMContext)[source]

Start order creation by asking user for currency they want to buy.

src.handlers.start_menu.handle_my_orders(message: aiogram.types.message.Message, state: aiogram.dispatcher.storage.FSMContext)[source]

Show user’s orders.

src.handlers.start_menu.handle_start_command(message: aiogram.types.message.Message, state: aiogram.dispatcher.storage.FSMContext)[source]

Handle /start.

Ask for language if user is new or show menu.

src.handlers.start_menu.help_command(message: aiogram.types.message.Message)[source]

Handle request to support.

src.handlers.start_menu.locale_button(call: aiogram.types.callback_query.CallbackQuery)[source]

Choose language from list.

src.handlers.start_menu.locale_keyboard()[source]

Get inline keyboard markup with available locales.

src.handlers.start_menu.search_by_creator(message: aiogram.types.message.Message, state: aiogram.dispatcher.storage.FSMContext)[source]

Search orders by creator.

Creator is indicated with username (with or without @) or user ID after /creator or /c in message text.

In contrast to usernames and user IDs, names aren’t unique and therefore not supported.

src.handlers.start_menu.subcribe_to_pair(message: aiogram.types.message.Message, state: aiogram.dispatcher.storage.FSMContext, command: aiogram.dispatcher.filters.builtin.Command.CommandObj)[source]

Manage subscription to pairs.

Currency pair is indicated with two space separated arguments after /subscribe or /unsubscribe in message text. First argument is the currency order’s creator wants to sell and second is the currency order’s creator wants to buy.

Similarly to /book, any argument can be replaced with *, which results in subscribing to pairs with any currency in place of the wildcard.

Without arguments commands show list of user’s subscriptions.

src.handlers.support module

Handlers for interacting with support.

src.handlers.support.answer_support_ticket(message: aiogram.types.message.Message)[source]

Answer support ticket.

Speech balloon emoji at the beginning is the mark of support’s reply to ticket.

src.handlers.support.contact_support(message: aiogram.types.message.Message, state: aiogram.dispatcher.storage.FSMContext)[source]

Send message to support after request in start manu.

src.handlers.support.handle_reply(message: aiogram.types.message.Message)[source]

Answer support’s reply to ticket.

src.handlers.support.send_message_to_support(message: aiogram.types.message.Message)[source]

Format message and send it to support.

Envelope emoji at the beginning is the mark of support ticket.

src.handlers.support.toggle_escrow(message: aiogram.types.message.Message)[source]

Toggle escrow availability.

This command makes creation of new escrow offers unavailable if escrow is enabled, and makes it available if it’s disabled.

src.handlers.support.unhelp_button(call: aiogram.types.callback_query.CallbackQuery, state: aiogram.dispatcher.storage.FSMContext)[source]

Cancel request to support.

Module contents

Handler modules with default and fallback handlers.

src.handlers.default_callback_query(call: aiogram.types.callback_query.CallbackQuery)[source]

React to query which has not passed any previous conditions.

If callback query is not answered, button will stuck in loading as if the bot stopped working until it times out. So unknown buttons are better be answered accordingly.

src.handlers.default_message(message: aiogram.types.message.Message)[source]

React to message which has not passed any previous conditions.

src.handlers.errors_handler(update: aiogram.types.update.Update, exception: Exception)[source]

Handle exceptions when calling handlers.

Send error notification to special chat and warn user about the error.