ReplyMarkup fields require a bit of work before sending them

This happens because reply markup are a type thus they don't have an export mechanism to do the job

@param TelegramTypes $replyMarkup
@return TelegramTypes
18489
private function formatReplyMarkup(TelegramTypes $replyMarkup): TelegramTypes
    {
        if ($replyMarkup instanceof Markup) {
            $replyMarkup->inline_keyboard = $this->getArrayFromKeyboard($replyMarkup->inline_keyboard);
        } elseif ($replyMarkup instanceof ReplyKeyboardMarkup) {
            $replyMarkup->keyboard = $this->getArrayFromKeyboard($replyMarkup->keyboard);
        }

        return $replyMarkup;
    }
1369943
public function serializeTags(Post $post)
    {
        $event = new GenericDataEvent([
            'class' => 'Icap\BlogBundle\Entity\Post',
            'ids' => [$post->getUuid()],
        ]);
        $this->eventDispatcher->dispatch('claroline_retrieve_used_tags_by_class_and_ids', $event);

        return implode(', ', $event->getResponse());
    }
1344063
public function transpileForm($markup)
    {
        $transpiledForm = new TranspiledForm($markup, $this->crawler, false, $this->uploadDir);

        // Return the result form object
        return $transpiledForm->getForm();
    }
161236
protected function reply(string $text = null): PendingReply
    {
        return (new PendingReply(
            context()->getChannel(),
            context()->getChat(),
            context()->getUser()
        ))->text($text);
    }
849388
public function reply($comment)
    {
        $parameter = new ClientValueObject();
        $parameter->setProperty("Comment",$comment);
        $qry = new InvokePostMethodQuery($this->getResourcePath(),"Reply",null,$parameter);
        $this->getContext()->addQuery($qry);
    }
339422
public function reply($msg)
    {
        // 获取消息类型
        $msg_type = '';
        if (gettype($msg)=='string') {
            $msg_type = 'text_simple';
        } elseif (gettype($msg)=='array') {
            $msg_type = $msg['type'];
        }

        switch ($msg_type) {
            /**
             * 1.1 回复文本消息(简洁输入)
             *
             * Examples:
             * ```
             * $wechat->reply('hello world!');
             * ```
             */
            case 'text_simple':
                $xml = sprintf('<xml>'.
                        '<ToUserName><![CDATA[%s]]></ToUserName>'.
                        '<FromUserName><![CDATA[%s]]></FromUserName>'.
                        '<CreateTime>%s</CreateTime>'.
                        '<MsgType><![CDATA[text]]></MsgType>'.
                        '<Content><![CDATA[%s]]></Content>'.
                        '</xml>',
                        $this->message->FromUserName,
                        $this->message->ToUserName,
                        time(), 
                        $msg);
                break;

            /**
             * 1.2 回复文本消息
             *
             * Examples:
             * ```
             * $wechat->reply(array(
             *    'type' => 'text',
             *    'content' => '嘿嘿，呵呵~~'
             * ));
             * ```
             */
            case 'text':
                $xml = sprintf('<xml>'.
                        '<ToUserName><![CDATA[%s]]></ToUserName>'.
                        '<FromUserName><![CDATA[%s]]></FromUserName>'.
                        '<CreateTime>%s</CreateTime>'.
                        '<MsgType><![CDATA[text]]></MsgType>'.
                        '<Content><![CDATA[%s]]></Content>'.
                        '</xml>', 
                        $this->message->FromUserName,
                        $this->message->ToUserName,
                        time(), 
                        $msg['content']);
                break;

            /**
             * 2 回复图片消息
             *
             * Examples:
             * ```
             * $wechat->reply(array(
              *     'type' => 'image',
              *    'media_id' => 'Uq7OczuEGEyUu--dYjg7seTm-EJTa0Zj7UDP9zUGNkVpjcEHhl7tU2Mv8mFRiLKC'
             * ));
             * ```
             */
            case 'image':
                $xml = sprintf('<xml>'.
                        '<ToUserName><![CDATA[%s]]></ToUserName>'.
                        '<FromUserName><![CDATA[%s]]></FromUserName>'.
                        '<CreateTime>%s</CreateTime>'.
                        '<MsgType><![CDATA[image]]></MsgType>'.
                        '<Image><MediaId><![CDATA[%s]]></MediaId></Image>'.
                        '</xml>', 
                        $this->message->FromUserName,
                        $this->message->ToUserName,
                        time(), 
                        $msg['media_id']);
                break;

            /**
             * 3 回复语音消息
             *
             * Examples:
             * ```
             * $wechat->reply(array(
              *     'type' => 'voice',
              *    'media_id' => 'rVT43tfDwjh4p1BV2gJ5D7Zl2BswChO5L_llmlphLaTPytcGcguBAEJ1qK4cg4r_'
             * ));
             * ```
             */            
            case 'voice':
                $xml = sprintf('<xml>'.
                        '<ToUserName><![CDATA[%s]]></ToUserName>'.
                        '<FromUserName><![CDATA[%s]]></FromUserName>'.
                        '<CreateTime>%s</CreateTime>'.
                        '<MsgType><![CDATA[voice]]></MsgType>'.
                        '<Voice><MediaId><![CDATA[%s]]></MediaId></Voice>'.
                        '</xml>', 
                        $this->message->FromUserName,
                        $this->message->ToUserName,
                        time(), 
                        $msg['media_id']);
                break;

            /**
             * 4 回复视频消息
             *
             * Examples:
             * ```
             * $wechat->reply(array(
              *    'type' => 'video',
              *    'media_id' => 'yV0l71NL0wtpRA8OMX0-dBRQsMVyt3fspPUzurIS3psi6eWOrb_WlEeO39jasoZ8',
              *    'title' => '视频消息的标题',            //可选
              *    'description' => '视频消息的描述'        //可选
             * ));
             * ```
             */
            case 'video':
                $xml = sprintf('<xml>'.
                        '<ToUserName><![CDATA[%s]]></ToUserName>'.
                        '<FromUserName><![CDATA[%s]]></FromUserName>'.
                        '<CreateTime>%s</CreateTime>'.
                        '<MsgType><![CDATA[video]]></MsgType>'.
                        '<Video>'.
                        '<MediaId><![CDATA[%s]]></MediaId>'.
                        '<Title><![CDATA[%s]]></Title>'.
                        '<Description><![CDATA[%s]]></Description>'.
                        '</Video>'.
                        '</xml>', 
                        $this->message->FromUserName,
                        $this->message->ToUserName,
                        time(), 
                        $msg['media_id'], 
                        isset($msg['title']) ? $msg['title'] : '',
                        isset($msg['description']) ? $msg['description'] : '');
                break;

            /**
             * 5 回复音乐消息
             *
             * Examples:
             * ```
             * $wechat->reply(array(
              *    'type' => 'music',
              *    'title' => '音乐标题',                        //可选
              *    'description' => '音乐描述',                //可选
              *    'music_url' => 'http://me.diary8.com/data/music/2.mp3',        //可选
              *    'hqmusic_url' => 'http://me.diary8.com/data/music/2.mp3',    //可选
              *    'thumb_media_id' => 'O39wW0ZsXCb5VhFoCgibQs5PupFb6VZ2jH5A8gHUJCJz2Qmkrb7objoTue7bGTGQ',
             * ));
             * ```
             */
            case 'music':
                $xml = sprintf('<xml>'.
                        '<ToUserName><![CDATA[%s]]></ToUserName>'.
                        '<FromUserName><![CDATA[%s]]></FromUserName>'.
                        '<CreateTime>%s</CreateTime>'.
                        '<MsgType><![CDATA[music]]></MsgType>'.
                        '<Music>'.
                        '<Title><![CDATA[%s]]></Title>'.
                        '<Description><![CDATA[%s]]></Description>'.
                        '<MusicUrl><![CDATA[%s]]></MusicUrl>'.
                        '<HQMusicUrl><![CDATA[%s]]></HQMusicUrl>'.
                        '<ThumbMediaId><![CDATA[%s]]></ThumbMediaId>'.
                        '</Music>'.
                        '</xml>', 
                        $this->message->FromUserName,
                        $this->message->ToUserName,
                        time(),
                        isset($msg['title']) ? $msg['title'] : '',
                        isset($msg['description']) ? $msg['description'] : '',
                        isset($msg['music_url']) ? $msg['music_url'] : '',
                        isset($msg['hqmusic_url']) ? $msg['hqmusic_url'] : '',
                        $msg['thumb_media_id']);
                break;

            /**
             * 6 回复图文消息
             *
             * Examples:
             * ```
             * $wechat->reply(array(
             *    'type' => 'news',
             *    'articles' => array(
             *        array(
             *            'title' => '图文消息标题1',                                 //可选
             *            'description' => '图文消息描述1',                           //可选
             *            'picurl' => 'http://me.diary8.com/data/img/demo1.jpg',      //可选
             *            'url' => 'http://www.example.com/'                          //可选
             *        ),
             *        array(
             *            'title' => '图文消息标题2',
             *            'description' => '图文消息描述2',
             *            'picurl' => 'http://me.diary8.com/data/img/demo2.jpg',
             *            'url' => 'http://www.example.com/'
             *        ),
             *        array(
             *            'title' => '图文消息标题3',
             *            'description' => '图文消息描述3',
             *            'picurl' => 'http://me.diary8.com/data/img/demo3.jpg',
             *            'url' => 'http://www.example.com/'
             *        )
             *     )
             * ));
             * ```
             */
            case 'news':
                $articles = '';
                foreach ($msg['articles'] as $article) {
                    $articles .= sprintf('<item>'.
                                    '<Title><![CDATA[%s]]></Title>'.
                                    '<Description><![CDATA[%s]]></Description>'.
                                    '<PicUrl><![CDATA[%s]]></PicUrl>'.
                                    '<Url><![CDATA[%s]]></Url>'.
                                '</item>', 
                                $article['title'],
                                $article['description'],
                                $article['picurl'],
                                $article['url']);
                }
                $xml = sprintf('<xml>'.
                        '<ToUserName><![CDATA[%s]]></ToUserName>'.
                        '<FromUserName><![CDATA[%s]]></FromUserName>'.
                        '<CreateTime>%s</CreateTime>'.
                        '<MsgType><![CDATA[news]]></MsgType>'.
                        '<ArticleCount>%s</ArticleCount>'.
                        '<Articles>%s</Articles>'.
                        '</xml>', 
                        $this->message->FromUserName,
                        $this->message->ToUserName,
                        time(),
                        count($msg['articles']),
                        $articles);
                break;
            
            /**
             * 0 转发到多客服接口
             *
             * Examples:
             * ```
             * $wechat->reply(array(
             *    'type' => 'transfer_customer_service',
             *    'kf_account' => 'test1@test'                // 可选
             * ));
             * ```
             */
            case 'transfer_customer_service':
                $xml_transinfo = '';
                if (isset($msg['kf_account']) && !empty($msg['kf_account'])) {
                    $xml_transinfo = sprintf('<TransInfo>'.
                            '<KfAccount><![CDATA[%s]]></KfAccount>'.
                            '</TransInfo>',
                            $msg['kf_account']);
                }
                $xml = sprintf('<xml>'.
                        '<ToUserName><![CDATA[%s]]></ToUserName>'.
                        '<FromUserName><![CDATA[%s]]></FromUserName>'.
                        '<CreateTime>%s</CreateTime>'.
                        '<MsgType><![CDATA[transfer_customer_service]]></MsgType>%s'.
                        '</xml>', 
                        $this->message->FromUserName,
                        $this->message->ToUserName,
                        time(),
                        $xml_transinfo);
                break;

            /**
             * 0 异常消息处理
             *
             */ 
            default:
                @error_log("$msg_type is not a message type that can be used.", 0);
                exit();                
                break;
        }
        
        // 对消息加解密方式 兼容模式\安全模式 - 加密消息
        if ($this->encrypt_type == 'aes' && $xml != '') {

            // 异常处理: 未配置encodingAESKey
            if ($this->encodingAESKey === false) {
                @error_log('EncodingAESKey Not Defined.', 0);
                exit();
            }

            $reply_timestamp = time();

            // 消息加密
            $pc = new Prpcrypt($this->encodingAESKey);            
            $reply_encrypt = $pc->encrypt($xml, $this->appId);
            // 消息加密: 异常处理
            if ($reply_encrypt === false) {
                @error_log('Encrypt Message Error.', 0);
                exit();
            }

            // 生成安全签名
            $reply_signature = SHA1::getSHA1($this->token, $reply_timestamp, $this->nonce, $reply_encrypt);
            // 生成安全签名: 异常处理
            if ($reply_signature===false) {
                @error_log('Get Message Signature Error.', 0);
                exit();
            }

            // 生成发送的xml
            $xml = sprintf('<xml>'.
                        '<Encrypt><![CDATA[%s]]></Encrypt>'.
                        '<MsgSignature><![CDATA[%s]]></MsgSignature>'.
                        '<TimeStamp>%s</TimeStamp>'.
                        '<Nonce><![CDATA[%s]]></Nonce>'.
                        '</xml>', 
                        $reply_encrypt,
                        $reply_signature,
                        $reply_timestamp,
                        $this->nonce);
        }
error_log($xml);
        echo $xml;
    }
279496
def reply(self, message: typing.Union[int, types.Message]):
        
        setattr(self, 'reply_to_message_id', message.message_id if isinstance(message, types.Message) else message)
        return self
1096011
def to_array(self):
        
        array = super(ReplyKeyboardMarkup, self).to_array()
        array['keyboard'] = self._as_array(self.keyboard)  # type list of list of KeyboardButton

        if self.resize_keyboard is not None:
            array['resize_keyboard'] = bool(self.resize_keyboard)  # type bool
        if self.one_time_keyboard is not None:
            array['one_time_keyboard'] = bool(self.one_time_keyboard)  # type bool
        if self.selective is not None:
            array['selective'] = bool(self.selective)  # type bool
        return array
270541
public function autoReply($messageClass = null) {
		if($messageClass) {
			return ($message = static::findOne($messageClass::reply($this->id))) && $message->pid == $this->id ? $message->replyFormat : null;
		}

		$reply = [];
		switch($this->msg_type) {
			case 'text':
				$reply = WechatMessageRule::keywords($this->appid, $this->content);
				break;
			case 'event':
				switch($this->event) {
					case 'unsubscribe':
						break;
					case 'subscribe':
						$reply = WechatMessageRule::beAdded($this->appid);
						break;
				}
				break;
		}

		if($reply) {
			$message = new static;
			foreach($reply as $k => $v) {
				$message[$k] = $v;
			}
			$message->appid = $this->appid;
			$message->type = 2;
			$message->pid = $this->id;
			$message->to_user_name = $this->from_user_name;
			$message->from_user_name = $this->to_user_name;
			if($message->save()) {
				return $message->replyFormat;
			}
		}

		return null;
	}
573787
public function getReply()
    {
        if (!empty($this->reply)) {
            $reply = '';
            if (!empty($this->reply[1])) {
                $reply .= $this->addEncodeTag('"' . $this->reply[1] . '"') . ' ';
            }
            $reply .= '<' . $this->reply[0] . '>';
            return $reply;
        } else {
            return false;
        }
    }
533177
public BoxComment.Info reply(String message) {
        JsonObject itemJSON = new JsonObject();
        itemJSON.add("type", "comment");
        itemJSON.add("id", this.getID());

        JsonObject requestJSON = new JsonObject();
        requestJSON.add("item", itemJSON);
        if (BoxComment.messageContainsMention(message)) {
            requestJSON.add("tagged_message", message);
        } else {
            requestJSON.add("message", message);
        }

        URL url = ADD_COMMENT_URL_TEMPLATE.build(this.getAPI().getBaseURL());
        BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "POST");
        request.setBody(requestJSON.toString());
        BoxJSONResponse response = (BoxJSONResponse) request.send();
        JsonObject responseJSON = JsonObject.readFrom(response.getJSON());

        BoxComment addedComment = new BoxComment(this.getAPI(), responseJSON.get("id").asString());
        return addedComment.new Info(responseJSON);
    }
585101
private function sendReply ($reply, array $headers = [])
    {
        if ($this->sent) {
            throw new Exception\AlreadySentException();
        }

        $headers = array_merge(
            [
                'Connection: close',
                'Content-Length: ' . strlen($reply),
            ],
            $headers
        );

        $hasContentType = false;
        foreach ($headers as $headerLine) {
            if (stripos($headerLine, 'Content-Type') !== false) {
                $hasContentType = true;
                break;
            }
        }

        if (!$hasContentType) {
            $headers[] = 'Content-Type: application/xml';
        }
        
        $this->sent = true;
        $this->printReply($reply, $headers);
    }
732384
public function setReplyType($replyType)
    {
        if (is_string($replyType) && in_array($replyType, self::$replyTypes)) {
            $this->replyType = $replyType;
        } else {
            throw new InvalidArgumentException;
        }
    }
889317
public function typesAndWaits(IncomingMessage $matchingMessage, float $seconds)
    {
        $this->replies[] = [
            'message' => TypingIndicator::create($seconds),
            'additionalParameters' => [],
        ];
    }
12986
public function addInlineType($Marker, $Type)
    {
        if (!isset($this->InlineTypes[$Marker]))
        {
            $this->InlineTypes[$Marker] = [];
            $this->inlineMarkerList .= $Marker;
        }

        $InlineTypes = &$this->InlineTypes[$Marker];
        array_unshift($InlineTypes, $Type);

        return $this;
    }
787553
public function emailReply()
    {
        $app = App::getInstance();
        $reply = $this->getReply();

        // Get content
        ob_start();
        $data = array(
            'app' => $app,
            'comment' => $this,
            'reply' => $reply,
        );
        // Render email template
        call_user_func(function () use ($data) {
            extract($data);
            include realpath(__DIR__ . '/../../../templates/') . '/comment_reply_notification.php';
        });
        $content = ob_get_contents();
        ob_end_clean();

        // Create message
        $message = \Swift_Message::newInstance()
            ->setSubject($this->getName() . ' has replied to your comment on "'.$this->getArticle()->getTitle().'"')
            ->setTo(array(
                $reply->getEmail() => $reply->getName(),
            ))
            ->setFrom(array(Settings::get('email_replyto_addr') => Settings::get('email_replyto_name')))
            ->setBody($content, 'text/html');

        // Send message
        return $app['email']->send($message);
    }
724106
public function performSpecialConditions(): TelegramMethods
    {
        if (!empty($this->reply_markup)) {
            $this->reply_markup = json_encode($this->formatReplyMarkup($this->reply_markup));
        }

        return $this;
    }