diff --git a/Telegram/SourceFiles/dropdown.cpp b/Telegram/SourceFiles/dropdown.cpp
index aa5a38aa3..72588abf2 100644
--- a/Telegram/SourceFiles/dropdown.cpp
+++ b/Telegram/SourceFiles/dropdown.cpp
@@ -1215,6 +1215,7 @@ StickerPanInner::StickerPanInner() : TWidget()
 , _top(0)
 , _showingSavedGifs(cShowingSavedGifs())
 , _showingInlineItems(_showingSavedGifs)
+, _setGifCommand(false)
 , _lastScrolled(0)
 , _inlineWithThumb(false)
 , _selected(-1)
@@ -1609,19 +1610,25 @@ void StickerPanInner::clearSelection(bool fast) {
 	}
 }
 
-void StickerPanInner::hideFinish() {
-	clearInlineRows(false);
-	for (GifLayouts::const_iterator i = _gifLayouts.cbegin(), e = _gifLayouts.cend(); i != e; ++i) {
-		i.value()->document()->forget();
-	}
-	for (InlineLayouts::const_iterator i = _inlineLayouts.cbegin(), e = _inlineLayouts.cend(); i != e; ++i) {
-		if (i.value()->result()->doc) {
-			i.value()->result()->doc->forget();
+void StickerPanInner::hideFinish(bool completely) {
+	if (completely) {
+		clearInlineRows(false);
+		for (GifLayouts::const_iterator i = _gifLayouts.cbegin(), e = _gifLayouts.cend(); i != e; ++i) {
+			i.value()->document()->forget();
 		}
-		if (i.value()->result()->photo) {
-			i.value()->result()->photo->forget();
+		for (InlineLayouts::const_iterator i = _inlineLayouts.cbegin(), e = _inlineLayouts.cend(); i != e; ++i) {
+			if (i.value()->result()->doc) {
+				i.value()->result()->doc->forget();
+			}
+			if (i.value()->result()->photo) {
+				i.value()->result()->photo->forget();
+			}
 		}
 	}
+	if (_setGifCommand && _showingSavedGifs) {
+		App::insertBotCommand(qsl(""), true);
+	}
+	_setGifCommand = false;
 }
 
 void StickerPanInner::refreshStickers() {
@@ -1713,6 +1720,7 @@ void StickerPanInner::refreshSavedGifs() {
 }
 
 void StickerPanInner::inlineBotChanged() {
+	_setGifCommand = false;
 	refreshInlineRows(0, InlineResults(), true);
 	deleteUnusedInlineLayouts();
 }
@@ -2351,11 +2359,16 @@ void StickerPanInner::showStickerSet(uint64 setId) {
 		refreshSavedGifs();
 		emit scrollToY(0);
 		emit scrollUpdated();
-		_setGifCommand = App::insertBotCommand(qsl("@gif"));
+		showFinish();
 		return;
 	}
 
 	if (_showingInlineItems) {
+		if (_setGifCommand && _showingSavedGifs) {
+			App::insertBotCommand(qsl(""), true);
+		}
+		_setGifCommand = false;
+
 		_showingInlineItems = false;
 		cSetShowingSavedGifs(false);
 		emit saveConfigDelayed(SaveRecentEmojisTimeout);
@@ -2381,6 +2394,12 @@ void StickerPanInner::showStickerSet(uint64 setId) {
 	update();
 }
 
+void StickerPanInner::showFinish() {
+	if (_showingInlineItems && _showingSavedGifs) {
+		_setGifCommand = App::insertBotCommand((cTestMode() ? qstr("@contextbot") : qstr("@gif")), true);
+	}
+}
+
 EmojiPanel::EmojiPanel(QWidget *parent, const QString &text, uint64 setId, bool special, int32 wantedY) : TWidget(parent)
 , _wantedY(wantedY)
 , _setId(setId)
@@ -3151,7 +3170,7 @@ void EmojiPan::hideAnimated() {
 void EmojiPan::hideFinish() {
 	hide();
 	e_inner.hideFinish();
-	s_inner.hideFinish();
+	s_inner.hideFinish(true);
 	_cache = _toCache = _fromCache = QPixmap();
 	_a_slide.stop();
 	_horizontal = false;
@@ -3419,6 +3438,9 @@ void EmojiPan::onSwitch() {
 		} else if (!cShowingSavedGifs() && !cSavedGifs().isEmpty() && cStickerSets().isEmpty()) {
 			s_inner.showStickerSet(NoneStickerSetId);
 		}
+		if (cShowingSavedGifs()) {
+			s_inner.showFinish();
+		}
 		validateSelectedIcon();
 		setMaxHeight(_maxHeight);
 	}
@@ -3436,6 +3458,8 @@ void EmojiPan::onSwitch() {
 
 	if (_stickersShown) {
 		e_inner.hideFinish();
+	} else {
+		s_inner.hideFinish(false);
 	}
 
 	a_toCoord = (_stickersShown != rtl()) ? anim::ivalue(st::emojiPanWidth, 0) : anim::ivalue(-st::emojiPanWidth, 0);
diff --git a/Telegram/SourceFiles/dropdown.h b/Telegram/SourceFiles/dropdown.h
index 6c186b3b6..72254b9b4 100644
--- a/Telegram/SourceFiles/dropdown.h
+++ b/Telegram/SourceFiles/dropdown.h
@@ -333,7 +333,8 @@ public:
 
 	void step_selected(uint64 ms, bool timer);
 
-	void hideFinish();
+	void hideFinish(bool completely);
+	void showFinish();
 	void showStickerSet(uint64 setId);
 
 	bool showSectionIcons() const;
@@ -427,6 +428,7 @@ private:
 	QList<bool> _custom;
 
 	bool _showingSavedGifs, _showingInlineItems;
+	bool _setGifCommand;
 	UserData *_inlineBot;
 	QString _inlineBotTitle;
 	uint64 _lastScrolled;
diff --git a/Telegram/SourceFiles/facades.cpp b/Telegram/SourceFiles/facades.cpp
index 99bbba7cf..0fb84b15b 100644
--- a/Telegram/SourceFiles/facades.cpp
+++ b/Telegram/SourceFiles/facades.cpp
@@ -31,8 +31,9 @@ namespace App {
 		if (MainWidget *m = main()) m->sendBotCommand(cmd, replyTo);
 	}
 
-	void insertBotCommand(const QString &cmd) {
-		if (MainWidget *m = main()) m->insertBotCommand(cmd);
+	bool insertBotCommand(const QString &cmd, bool specialGif) {
+		if (MainWidget *m = main()) return m->insertBotCommand(cmd, specialGif);
+		return false;
 	}
 
 	void searchByHashtag(const QString &tag, PeerData *inPeer) {
diff --git a/Telegram/SourceFiles/facades.h b/Telegram/SourceFiles/facades.h
index d4a0890bf..21db659b6 100644
--- a/Telegram/SourceFiles/facades.h
+++ b/Telegram/SourceFiles/facades.h
@@ -25,7 +25,7 @@ class LayeredWidget;
 namespace App {
 
 	void sendBotCommand(const QString &cmd, MsgId replyTo = 0);
-	void insertBotCommand(const QString &cmd);
+	bool insertBotCommand(const QString &cmd, bool specialGif = false);
 	void searchByHashtag(const QString &tag, PeerData *inPeer);
 	void openPeerByName(const QString &username, bool toProfile = false, const QString &startToken = QString());
 	void joinGroupByHash(const QString &hash);
diff --git a/Telegram/SourceFiles/gui/flattextarea.cpp b/Telegram/SourceFiles/gui/flattextarea.cpp
index c204ed684..ae09ce169 100644
--- a/Telegram/SourceFiles/gui/flattextarea.cpp
+++ b/Telegram/SourceFiles/gui/flattextarea.cpp
@@ -313,7 +313,7 @@ void FlatTextarea::getMentionHashtagBotCommandStart(QString &start, UserData *&i
 			inlineUsernameLength = 0;
 		}
 	}
-	if (!inlineUsernameLength) {
+	if (inlineUsernameLength < 3) {
 		inlineBot = 0;
 		inlineBotUsername = QString();
 	}
diff --git a/Telegram/SourceFiles/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp
index 570db8287..cdb995846 100644
--- a/Telegram/SourceFiles/historywidget.cpp
+++ b/Telegram/SourceFiles/historywidget.cpp
@@ -4829,8 +4829,8 @@ void HistoryWidget::sendBotCommand(const QString &cmd, MsgId replyTo) { // reply
 	_field.setFocus();
 }
 
-void HistoryWidget::insertBotCommand(const QString &cmd) {
-	if (!_history) return;
+bool HistoryWidget::insertBotCommand(const QString &cmd, bool specialGif) {
+	if (!_history) return false;
 
 	QString toInsert = cmd;
 	PeerData *bot = _peer->isUser() ? _peer : (App::hoveredLinkItem() ? (App::hoveredLinkItem()->toHistoryForwarded() ? App::hoveredLinkItem()->toHistoryForwarded()->fromForwarded() : App::hoveredLinkItem()->from()) : 0);
@@ -4844,20 +4844,31 @@ void HistoryWidget::insertBotCommand(const QString &cmd) {
 
 	if (toInsert.at(0) != '@') {
 		QString text = _field.getLastText();
-		QRegularExpressionMatch m = QRegularExpression(qsl("^/[A-Za-z_0-9]{0,64}(@[A-Za-z_0-9]{0,32})?(\\s|$)")).match(text);
-		if (m.hasMatch()) {
-			text = toInsert + text.mid(m.capturedLength());
+		if (specialGif) {
+			if (text.trimmed() == (cTestMode() ? qstr("@contextbot") : qstr("@gif")) && text.at(0) == '@') {
+				_field.setTextFast(QString(), true);
+			}
 		} else {
-			text = toInsert + text;
-		}
-		_field.setTextFast(text);
+			QRegularExpressionMatch m = QRegularExpression(qsl("^/[A-Za-z_0-9]{0,64}(@[A-Za-z_0-9]{0,32})?(\\s|$)")).match(text);
+			if (m.hasMatch()) {
+				text = toInsert + text.mid(m.capturedLength());
+			} else {
+				text = toInsert + text;
+			}
+			_field.setTextFast(text);
 
-		QTextCursor cur(_field.textCursor());
-		cur.movePosition(QTextCursor::End);
-		_field.setTextCursor(cur);
+			QTextCursor cur(_field.textCursor());
+			cur.movePosition(QTextCursor::End);
+			_field.setTextCursor(cur);
+		}
 	} else {
-		_field.setTextFast(toInsert, true);
+		if (!specialGif || _field.getLastText().isEmpty()) {
+			_field.setTextFast(toInsert, true);
+			_field.setFocus();
+			return true;
+		}
 	}
+	return false;
 }
 
 bool HistoryWidget::eventFilter(QObject *obj, QEvent *e) {
@@ -5333,7 +5344,11 @@ void HistoryWidget::onCheckMentionDropdown() {
 		if (_inlineBot != bot) {
 			updateFieldPlaceholder();
 		}
-		_emojiPan.queryInlineBot(_inlineBot, start);
+		if (_inlineBot->username == (cTestMode() ? qstr("contextbot") : qstr("gif")) && start.isEmpty()) {
+			_emojiPan.clearInlineBot();
+		} else {
+			_emojiPan.queryInlineBot(_inlineBot, start);
+		}
 		if (!_attachMention.isHidden()) {
 			_attachMention.hideStart();
 		}
diff --git a/Telegram/SourceFiles/historywidget.h b/Telegram/SourceFiles/historywidget.h
index bc3ece421..f3f7acb31 100644
--- a/Telegram/SourceFiles/historywidget.h
+++ b/Telegram/SourceFiles/historywidget.h
@@ -518,7 +518,7 @@ public:
 	void onListEscapePressed();
 
 	void sendBotCommand(const QString &cmd, MsgId replyTo);
-	void insertBotCommand(const QString &cmd);
+	bool insertBotCommand(const QString &cmd, bool specialGif);
 
 	bool eventFilter(QObject *obj, QEvent *e);
 	void updateBotKeyboard(History *h = 0);
diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp
index d9fc79a60..8624a27d3 100644
--- a/Telegram/SourceFiles/mainwidget.cpp
+++ b/Telegram/SourceFiles/mainwidget.cpp
@@ -1390,8 +1390,8 @@ void MainWidget::sendBotCommand(const QString &cmd, MsgId replyTo) {
 	history.sendBotCommand(cmd, replyTo);
 }
 
-void MainWidget::insertBotCommand(const QString &cmd) {
-	history.insertBotCommand(cmd);
+bool MainWidget::insertBotCommand(const QString &cmd, bool specialGif) {
+	return history.insertBotCommand(cmd, specialGif);
 }
 
 void MainWidget::searchMessages(const QString &query, PeerData *inPeer) {
diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h
index edff1b96d..03c30ccda 100644
--- a/Telegram/SourceFiles/mainwidget.h
+++ b/Telegram/SourceFiles/mainwidget.h
@@ -327,7 +327,7 @@ public:
 	void stopAnimActive();
 
 	void sendBotCommand(const QString &cmd, MsgId msgId);
-	void insertBotCommand(const QString &cmd);
+	bool insertBotCommand(const QString &cmd, bool specialGif);
 
 	void searchMessages(const QString &query, PeerData *inPeer);
 	bool preloadOverview(PeerData *peer, MediaOverviewType type);
diff --git a/Telegram/SourceFiles/mtproto/mtpScheme.cpp b/Telegram/SourceFiles/mtproto/mtpScheme.cpp
index a2fee6ab3..6693765ba 100644
--- a/Telegram/SourceFiles/mtproto/mtpScheme.cpp
+++ b/Telegram/SourceFiles/mtproto/mtpScheme.cpp
@@ -3161,7 +3161,7 @@ void _serialize_updateShortMessage(MTPStringLogger &to, int32 stage, int32 lev,
 	case 10: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
 	case 11: to.add("  fwd_from_id: "); ++stages.back(); if (flag & MTPDupdateShortMessage::flag_fwd_from_id) { types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break;
 	case 12: to.add("  fwd_date: "); ++stages.back(); if (flag & MTPDupdateShortMessage::flag_fwd_date) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break;
-	case 13: to.add("  via_bot_id: "); ++stages.back(); if (flag & MTPDupdateShortMessage::flag_via_bot_id) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 8 IN FIELD flags ]"); } break;
+	case 13: to.add("  via_bot_id: "); ++stages.back(); if (flag & MTPDupdateShortMessage::flag_via_bot_id) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 11 IN FIELD flags ]"); } break;
 	case 14: to.add("  reply_to_msg_id: "); ++stages.back(); if (flag & MTPDupdateShortMessage::flag_reply_to_msg_id) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 3 IN FIELD flags ]"); } break;
 	case 15: to.add("  entities: "); ++stages.back(); if (flag & MTPDupdateShortMessage::flag_entities) { types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 7 IN FIELD flags ]"); } break;
 	default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
@@ -3190,7 +3190,7 @@ void _serialize_updateShortChatMessage(MTPStringLogger &to, int32 stage, int32 l
 	case 11: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
 	case 12: to.add("  fwd_from_id: "); ++stages.back(); if (flag & MTPDupdateShortChatMessage::flag_fwd_from_id) { types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break;
 	case 13: to.add("  fwd_date: "); ++stages.back(); if (flag & MTPDupdateShortChatMessage::flag_fwd_date) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break;
-	case 14: to.add("  via_bot_id: "); ++stages.back(); if (flag & MTPDupdateShortChatMessage::flag_via_bot_id) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 8 IN FIELD flags ]"); } break;
+	case 14: to.add("  via_bot_id: "); ++stages.back(); if (flag & MTPDupdateShortChatMessage::flag_via_bot_id) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 11 IN FIELD flags ]"); } break;
 	case 15: to.add("  reply_to_msg_id: "); ++stages.back(); if (flag & MTPDupdateShortChatMessage::flag_reply_to_msg_id) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 3 IN FIELD flags ]"); } break;
 	case 16: to.add("  entities: "); ++stages.back(); if (flag & MTPDupdateShortChatMessage::flag_entities) { types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 7 IN FIELD flags ]"); } break;
 	default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
diff --git a/Telegram/SourceFiles/mtproto/mtpScheme.h b/Telegram/SourceFiles/mtproto/mtpScheme.h
index d726efe15..bb52437c2 100644
--- a/Telegram/SourceFiles/mtproto/mtpScheme.h
+++ b/Telegram/SourceFiles/mtproto/mtpScheme.h
@@ -288,8 +288,8 @@ enum {
 	mtpc_updates_difference = 0xf49ca0,
 	mtpc_updates_differenceSlice = 0xa8fb1981,
 	mtpc_updatesTooLong = 0xe317af7e,
-	mtpc_updateShortMessage = 0x63bd23d,
-	mtpc_updateShortChatMessage = 0xb024ead6,
+	mtpc_updateShortMessage = 0x13e4deaa,
+	mtpc_updateShortChatMessage = 0x248afa62,
 	mtpc_updateShort = 0x78d4dec1,
 	mtpc_updatesCombined = 0x725b04c3,
 	mtpc_updates = 0x74ae4240,
@@ -11802,7 +11802,7 @@ public:
 		flag_media_unread = (1 << 5),
 		flag_fwd_from_id = (1 << 2),
 		flag_fwd_date = (1 << 2),
-		flag_via_bot_id = (1 << 8),
+		flag_via_bot_id = (1 << 11),
 		flag_reply_to_msg_id = (1 << 3),
 		flag_entities = (1 << 7),
 	};
@@ -11846,7 +11846,7 @@ public:
 		flag_media_unread = (1 << 5),
 		flag_fwd_from_id = (1 << 2),
 		flag_fwd_date = (1 << 2),
-		flag_via_bot_id = (1 << 8),
+		flag_via_bot_id = (1 << 11),
 		flag_reply_to_msg_id = (1 << 3),
 		flag_entities = (1 << 7),
 	};
diff --git a/Telegram/SourceFiles/mtproto/scheme.tl b/Telegram/SourceFiles/mtproto/scheme.tl
index 61d4889dc..64bfa2eaa 100644
--- a/Telegram/SourceFiles/mtproto/scheme.tl
+++ b/Telegram/SourceFiles/mtproto/scheme.tl
@@ -409,8 +409,8 @@ updates.difference#f49ca0 new_messages:Vector<Message> new_encrypted_messages:Ve
 updates.differenceSlice#a8fb1981 new_messages:Vector<Message> new_encrypted_messages:Vector<EncryptedMessage> other_updates:Vector<Update> chats:Vector<Chat> users:Vector<User> intermediate_state:updates.State = updates.Difference;
 
 updatesTooLong#e317af7e = Updates;
-updateShortMessage#63bd23d flags:# unread:flags.0?true out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true id:int user_id:int message:string pts:int pts_count:int date:int fwd_from_id:flags.2?Peer fwd_date:flags.2?int via_bot_id:flags.8?int reply_to_msg_id:flags.3?int entities:flags.7?Vector<MessageEntity> = Updates;
-updateShortChatMessage#b024ead6 flags:# unread:flags.0?true out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true id:int from_id:int chat_id:int message:string pts:int pts_count:int date:int fwd_from_id:flags.2?Peer fwd_date:flags.2?int via_bot_id:flags.8?int reply_to_msg_id:flags.3?int entities:flags.7?Vector<MessageEntity> = Updates;
+updateShortMessage#13e4deaa flags:# unread:flags.0?true out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true id:int user_id:int message:string pts:int pts_count:int date:int fwd_from_id:flags.2?Peer fwd_date:flags.2?int via_bot_id:flags.11?int reply_to_msg_id:flags.3?int entities:flags.7?Vector<MessageEntity> = Updates;
+updateShortChatMessage#248afa62 flags:# unread:flags.0?true out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true id:int from_id:int chat_id:int message:string pts:int pts_count:int date:int fwd_from_id:flags.2?Peer fwd_date:flags.2?int via_bot_id:flags.11?int reply_to_msg_id:flags.3?int entities:flags.7?Vector<MessageEntity> = Updates;
 updateShort#78d4dec1 update:Update date:int = Updates;
 updatesCombined#725b04c3 updates:Vector<Update> users:Vector<User> chats:Vector<Chat> date:int seq_start:int seq:int = Updates;
 updates#74ae4240 updates:Vector<Update> users:Vector<User> chats:Vector<Chat> date:int seq:int = Updates;