我的公眾號(hào)開(kāi)發(fā)(第一步)簡(jiǎn)單功能實(shí)現(xiàn)

作者:JiawuZhang
出品:JiawuLab(ID:jiawulab)

實(shí)驗(yàn)記錄系列是JiawuLab原創(chuàng)欄目集嵌,通過(guò)真實(shí)項(xiàng)目的操作,記錄整個(gè)實(shí)驗(yàn)過(guò)程酱讶。
旨在通過(guò)一步步過(guò)程衬衬,無(wú)基礎(chǔ)的朋友都能直接上手。

大家好询筏,我是JiawuZhang,本次實(shí)驗(yàn)記錄的項(xiàng)目是--微信公眾號(hào)開(kāi)發(fā)竖慧。

選擇這個(gè)項(xiàng)目的原因有二:
1嫌套、微信公眾號(hào)還是大部分人(包括我自己)獲取信息的一個(gè)重要渠道;
2圾旨、正好我手上有個(gè)公眾號(hào)踱讨;

好了,閑話不多說(shuō)砍的,直接進(jìn)入主題痹筛。

效果演示

先放出實(shí)驗(yàn)過(guò)程中效果圖,閃耀登場(chǎng):

消息回復(fù)演示
關(guān)注回復(fù)演示
關(guān)鍵字回復(fù)演示

這么有個(gè)性的回復(fù)是不是很好玩,不再是固定的幾個(gè)回復(fù)帚稠,具體的實(shí)現(xiàn)方法請(qǐng)往下看谣旁。

您也可以關(guān)注公眾號(hào):JiawuLab,來(lái)體驗(yàn)更多功能滋早。

前期準(zhǔn)備工作

一榄审、準(zhǔn)備一個(gè)微信公眾號(hào),我的是個(gè)人訂閱號(hào)杆麸,未認(rèn)證搁进。(ps:個(gè)人公眾號(hào),不能認(rèn)證)

認(rèn)不認(rèn)證都不要緊昔头,只是接口權(quán)限多少的問(wèn)題饼问,未認(rèn)證的接口已經(jīng)能滿足這次實(shí)驗(yàn)?zāi)康摹?/p>

(具體權(quán)限可見(jiàn)-公眾號(hào)后臺(tái)-開(kāi)發(fā)-接口權(quán)限)

紅框內(nèi)是已獲得的接口權(quán)限

二、準(zhǔn)備一臺(tái)服務(wù)器减细,現(xiàn)在提供云服務(wù)器的廠家很多,大家可自行準(zhǔn)備赢笨。

建議選擇獨(dú)立ip的服務(wù)器未蝌,(共享ip會(huì)便宜些,但是不推薦茧妒,具體原因后面會(huì)說(shuō)到萧吠。)

我選擇的是某廠的1核2G1M(1核cpu,2G內(nèi)存桐筏,1M帶寬)的獨(dú)立ip服務(wù)器纸型,具體品牌就不說(shuō)了,怕有廣告嫌疑梅忌。

這個(gè)配置應(yīng)付常規(guī)公眾號(hào)足夠了狰腌,但是如果你的公眾號(hào)的流量特別大,需要根據(jù)自己的情況增加配置牧氮。

三琼腔、服務(wù)器上安裝python環(huán)境,我的環(huán)境是python3.7.4踱葛, Centos7.5丹莲。

如果你不清楚怎么安裝,可關(guān)注公眾號(hào):JiawuLab尸诽,給我留言甥材,這里不展開(kāi)。

開(kāi)發(fā)方向

微信公眾號(hào)開(kāi)發(fā)性含,官方的技術(shù)文檔洲赵,寫(xiě)的很詳細(xì),也有范例參照。

另外板鬓,github上獲得3000多星的WeRoBot悲敷,也是一個(gè)很受歡迎的微信公眾號(hào)開(kāi)發(fā)框架,有興趣的朋友可自行了解俭令。

上面提到的相關(guān)資源鏈接后德,請(qǐng)到文末獲取

我們這次以官方開(kāi)發(fā)文檔來(lái)進(jìn)行實(shí)驗(yàn)抄腔。

實(shí)驗(yàn)開(kāi)始

首先瓢湃,進(jìn)入官方開(kāi)發(fā)文檔-入門(mén)指引,如下圖:

我們只用關(guān)注紅框中的內(nèi)容赫蛇,這里是python2.7版本绵患,服務(wù)器上是python3.7.4版本。

所以后面需要對(duì)該指引所提到的內(nèi)容進(jìn)行版本轉(zhuǎn)化悟耘,我會(huì)在后面提到如何轉(zhuǎn)落蝙,不用擔(dān)心。

然后需要安裝web.py暂幼,這是一個(gè)python的輕型web開(kāi)發(fā)框架筏勒,我們只來(lái)用,不用特別學(xué)習(xí)旺嬉,如需自行百度管行。

現(xiàn)在,在服務(wù)器中進(jìn)行安裝web.py邪媳,很簡(jiǎn)單捐顷,直接用pip安裝就好

# 安裝web.py
pip(3) install web.py

這里需要注意兩點(diǎn):
1、centos自帶python2.7雨效,如果安裝python3版本沒(méi)有改軟鏈接迅涮,需要用pip3,檢查方式徽龟,直接輸入python -V逗柴,看版本
2、web.py版本顿肺,pip安裝的直接是0.40正式版戏溺,支持python3,不用像網(wǎng)上說(shuō)的那種指定版本

安裝完好屠尊,我們測(cè)試一下旷祸,拷貝下面的代碼,保存為main.py文件

# -*- coding: utf-8 -*-
# filename: main.py
import web

urls = (
    '/wx', 'Handle',
)

class Handle(object):
    def GET(self):
        return "pika pika pikaqiu!"

if __name__ == '__main__':
    app = web.application(urls, globals())
    app.run()

然后找到當(dāng)前文件所在目錄輸入python(3) main.py 80讼昆,服務(wù)器啟動(dòng)成功托享,本地打開(kāi)網(wǎng)頁(yè),輸入http://外網(wǎng)ip:80/wx,顯示如下

說(shuō)明配置沒(méi)有問(wèn)題闰围,這里記得一定要服務(wù)器將80端口放行赃绊。到這里,我們就可以正式進(jìn)行公眾號(hào)的配置及操作了羡榴。

微信公眾號(hào)配置

打開(kāi)微信公眾號(hào)后臺(tái)碧查,找到-開(kāi)發(fā)-基本配置-服務(wù)器配置,進(jìn)行如下配置:

ps:這里先按照明文模式進(jìn)行校仑,后面會(huì)改成安全模式忠售,過(guò)程都會(huì)涉及的。點(diǎn)擊提交迄沫,出現(xiàn)報(bào)錯(cuò)稻扬,說(shuō)Token驗(yàn)證失敗,果然和文檔中說(shuō)的一樣羊瘩,出現(xiàn)錯(cuò)誤泰佳,先不管它。

繼續(xù)看文檔后面的內(nèi)容尘吗,原來(lái)是服務(wù)器沒(méi)有進(jìn)行配置逝她,所以報(bào)錯(cuò),我們按照文檔后面的來(lái)摇予。

先將之前的main.py文件改成如下:(注意備注)

# -*- coding: utf-8 -*-
# filename: main.py
import web
from handle import Handle  # 將Handle類放進(jìn)handle.py文件中汽绢,再導(dǎo)入進(jìn)來(lái)

urls = (
    '/wx', 'Handle',
)

if __name__ == '__main__':
    app = web.application(urls, globals())
    app.run()

然后新建handle.py文件吗跋,里面寫(xiě)入:(注意備注)

# -*- coding: utf-8 -*-
# filename: handle.py

import hashlib
import web

class Handle(object):
    def GET(self):
        try:
            data = web.input()
            if len(data) == 0:
                return "pika pika pikaqiu!"
            signature = data.signature
            timestamp = data.timestamp
            nonce = data.nonce
            echostr = data.echostr
            token = "xxxx" #請(qǐng)按照公眾平臺(tái)官網(wǎng)\基本配置中信息填寫(xiě)

            list = [token, timestamp, nonce]
            list.sort()
            sha1 = hashlib.sha1()
            # map函數(shù)在python2和3的功能不同侧戴,需要轉(zhuǎn)化
            # map(sha1.update, list)
            sha1.update(list[0].encode('utf-8'))
            sha1.update(list[1].encode('utf-8'))
            sha1.update(list[2].encode('utf-8'))
            hashcode = sha1.hexdigest()
            # 這里print轉(zhuǎn)為python3
            print("handle/GET func: hashcode, signature: ", hashcode, signature)
            if hashcode == signature:
                return echostr
            else:
                return ""
        except Exception as Argument:  # 這里加as 轉(zhuǎn)為python3
            return Argument

備注中已提到python3轉(zhuǎn)化的位置, 然后在token中填入微信公眾號(hào)中對(duì)應(yīng)的token跌宛。

保存后輸入python(3) main.py 80酗宋,服務(wù)器啟動(dòng)。

再次回到微信公眾號(hào)的配置疆拘,點(diǎn)擊提交蜕猫,配置成功,顯示如下:


現(xiàn)在微信公眾號(hào)就配置好了哎迄,打通服務(wù)器與微信公眾號(hào)這一步很關(guān)鍵回右,所有后續(xù)功能都是在此基礎(chǔ)上開(kāi)發(fā)的。

回復(fù)功能實(shí)現(xiàn)

到這里漱挚,指引列出兩個(gè)示例翔烁,分別是你說(shuō)我學(xué)、圖尚往來(lái)旨涝,展示文字回復(fù)和圖片回復(fù)功能蹬屹。

另外還展示了獲取accessToken、獲取臨時(shí)素材、獲取永久素材慨默、自定義菜單等四個(gè)功能演示贩耐。

現(xiàn)在根據(jù)自己的需求,以及獲得接口權(quán)限來(lái)決定選擇哪些功能厦取,比如我沒(méi)有自定義菜單權(quán)限潮太,就不用理它。

而圖片回復(fù)需要用到臨時(shí)素材或是永久素材功能蒜胖,來(lái)調(diào)用不同圖片消别,這些都可根據(jù)實(shí)際需求來(lái)選用。

我需要用到的是文字回復(fù)台谢,所以這里實(shí)現(xiàn)文字回復(fù)演示寻狂。

官方文檔中關(guān)于文字回復(fù)的機(jī)制,以及注意事項(xiàng)很詳細(xì)朋沮,大家先仔細(xì)研究一下蛇券,比如消息體收到和回復(fù)的區(qū)別,消息回復(fù)流程等樊拓。

這里只做一個(gè)關(guān)鍵點(diǎn)的提醒纠亚,就是回復(fù)success問(wèn)題
1、假如服務(wù)器無(wú)法保證在五秒內(nèi)處理回復(fù)筋夏,則必須回復(fù)“success”或者“”(空串)蒂胞,否則微信后臺(tái)會(huì)發(fā)起三次重試。
2条篷、三次重試后骗随,依舊沒(méi)有及時(shí)回復(fù)任何內(nèi)容,系統(tǒng)自動(dòng)在粉絲會(huì)話界面出現(xiàn)錯(cuò)誤提示“該公眾號(hào)暫時(shí)無(wú)法提供服務(wù)赴叹,請(qǐng)稍后再試”鸿染。

這是什么意思呢?是指需要保證你的功能代碼乞巧,在服務(wù)器收到消息后涨椒,5秒內(nèi)做出反應(yīng),這也是為什么我不推薦共享IP服務(wù)器的緣故绽媒。

在功能代碼中蚕冬,我們可能需要做一些遞歸運(yùn)算,數(shù)據(jù)庫(kù)的查詢等花時(shí)間的事情是辕,而共享IP服務(wù)器會(huì)受到其他網(wǎng)站的很大影響囤热。

到時(shí)可能你寫(xiě)了很厲害的功能,因?yàn)闊o(wú)法在5秒內(nèi)實(shí)現(xiàn)免糕,最后給讀者的展示赢乓,就是無(wú)盡的“該公眾號(hào)暫時(shí)無(wú)法提供服務(wù)忧侧,請(qǐng)稍后再試”

好了,碼代碼的時(shí)間到了牌芋,這里直接將示例中的三段代碼保存即可蚓炬。

分別是接受消息代碼、回復(fù)消息代碼躺屁、handle類的改寫(xiě)肯夏,如下:

接受消息代碼,保存為receive.py
# -*- coding: utf-8 -*-
# filename: receive.py

import xml.etree.ElementTree as ET


def parse_xml(web_data):
    if len(web_data) == 0:
        return None
    xmlData = ET.fromstring(web_data)
    msg_type = xmlData.find('MsgType').text
    if msg_type == 'text':
        return TextMsg(xmlData)
    elif msg_type == 'image':
        return ImageMsg(xmlData)


class Msg(object):
    def __init__(self, xmlData):
        self.ToUserName = xmlData.find('ToUserName').text
        self.FromUserName = xmlData.find('FromUserName').text
        self.CreateTime = xmlData.find('CreateTime').text
        self.MsgType = xmlData.find('MsgType').text
        self.MsgId = xmlData.find('MsgId').text


class TextMsg(Msg):
    def __init__(self, xmlData):
        Msg.__init__(self, xmlData)
        self.Content = xmlData.find('Content').text.encode("utf-8")


class ImageMsg(Msg):
    def __init__(self, xmlData):
        Msg.__init__(self, xmlData)
        self.PicUrl = xmlData.find('PicUrl').text
        self.MediaId = xmlData.find('MediaId').text
回復(fù)消息代碼犀暑,保存為reply.py
# -*- coding: utf-8 -*-
# filename: reply.py

import time


class Msg(object):
    def __init__(self):
        pass

    def send(self):
        return "success"


class TextMsg(Msg):
    def __init__(self, toUserName, fromUserName, content):
        self.__dict = dict()
        self.__dict['ToUserName'] = toUserName
        self.__dict['FromUserName'] = fromUserName
        self.__dict['CreateTime'] = int(time.time())
        self.__dict['Content'] = content

    def send(self):
        XmlForm = """
        <xml>
        <ToUserName><![CDATA[{ToUserName}]]></ToUserName>
        <FromUserName><![CDATA[{FromUserName}]]></FromUserName>
        <CreateTime>{CreateTime}</CreateTime>
        <MsgType><![CDATA[text]]></MsgType>
        <Content><![CDATA[{Content}]]></Content>
        </xml>
        """
        return XmlForm.format(**self.__dict)


class ImageMsg(Msg):
    def __init__(self, toUserName, fromUserName, mediaId):
        self.__dict = dict()
        self.__dict['ToUserName'] = toUserName
        self.__dict['FromUserName'] = fromUserName
        self.__dict['CreateTime'] = int(time.time())
        self.__dict['MediaId'] = mediaId

    def send(self):
        XmlForm = """
        <xml>
        <ToUserName><![CDATA[{ToUserName}]]></ToUserName>
        <FromUserName><![CDATA[{FromUserName}]]></FromUserName>
        <CreateTime>{CreateTime}</CreateTime>
        <MsgType><![CDATA[image]]></MsgType>
        <Image>
        <MediaId><![CDATA[{MediaId}]]></MediaId>
        </Image>
        </xml>
        """
        return XmlForm.format(**self.__dict)

上面兩個(gè)文件只用保存就可以驯击,不過(guò)細(xì)心的你會(huì)發(fā)現(xiàn),里面除了文字耐亏,還有圖片功能徊都,這個(gè)后面再說(shuō)。

有了接受和回復(fù)文件后广辰,我們就要在handle.py文件中對(duì)Handle類進(jìn)行改寫(xiě)暇矫,如下:

# filename: handle.py

import hashlib
import reply    # 導(dǎo)入回復(fù)文件
import receive  # 導(dǎo)入接收文件
import web


class Handle(object):
    def GET(self):
        try:
            data = web.input()
            if len(data) == 0:
                return "pika pika pikaqu!"
            signature = data.signature
            timestamp = data.timestamp
            nonce = data.nonce
            echostr = data.echostr
            token = 'XXXX'  # 請(qǐng)按照公眾平臺(tái)官網(wǎng)\基本配置中信息填寫(xiě)

            list = [token, timestamp, nonce]
            list.sort()
            sha1 = hashlib.sha1()
            sha1.update(list[0].encode('utf-8'))
            sha1.update(list[1].encode('utf-8'))
            sha1.update(list[2].encode('utf-8'))
            hashcode = sha1.hexdigest()
            print("handle/GET func: hashcode, signature: ", hashcode, signature)
            if hashcode == signature:
                return echostr
            else:
                return ""
        except Exception as Argument:
            return Argument

    def POST(self):    # 新增加的POST函數(shù)
        try:
            webData = web.data()
            print("Handle Post webdata is ", webData)
            # 后臺(tái)打日志
            recMsg = receive.parse_xml(webData)
            if isinstance(recMsg, receive.Msg) and recMsg.MsgType == 'text':
                toUser = recMsg.FromUserName
                fromUser = recMsg.ToUserName
                content = "test"  # 這里是回復(fù)內(nèi)容
                replyMsg = reply.TextMsg(toUser, fromUser, content)
                return replyMsg.send()
            else:
                print("暫且不處理")
                return "success"
        except Exception as Argment:
            return Argment

現(xiàn)在代碼都寫(xiě)好了,保存后輸入python(3) main.py 80择吊,服務(wù)器啟動(dòng)李根。然后就可以進(jìn)行測(cè)試了。

正好在測(cè)試期間有讀者回復(fù)几睛,下面是截圖:

小編與一位讀者聊天的后臺(tái)截圖

初步test成功房轿,不過(guò)還沒(méi)有達(dá)到我們的要求。現(xiàn)在簡(jiǎn)單的消息回復(fù)功能就實(shí)現(xiàn)了所森。

下一步預(yù)告

經(jīng)過(guò)一番摸索囱持,我們打通了服務(wù)器與微信公眾號(hào),也簡(jiǎn)單實(shí)現(xiàn)了消息回復(fù)功能必峰,盡管還不是那么理想洪唐。

另外在測(cè)試中發(fā)現(xiàn)钻蹬,原來(lái)設(shè)置的自定義菜單不見(jiàn)了吼蚁,關(guān)注也沒(méi)有回復(fù)了回復(fù)語(yǔ)音達(dá)不到效果问欠。肝匆。。

下一步顺献,我們將進(jìn)行如下實(shí)驗(yàn)旗国,對(duì)接智能機(jī)器人,讓回復(fù)更有個(gè)性注整;關(guān)注與關(guān)鍵字回復(fù)能曾;語(yǔ)音也能很好的回復(fù)度硝;自定義菜單又出現(xiàn)了等功能。

本期實(shí)驗(yàn)記錄到此結(jié)束寿冕,感謝您的閱讀蕊程。如果您喜歡這期文章,請(qǐng)點(diǎn)贊驼唱,支持一下藻茂。

您可以關(guān)注公眾號(hào):JiawuLab,提前體驗(yàn)更多功能玫恳,或者給我留言辨赐,說(shuō)說(shuō)你遇到的問(wèn)題,我們一起探討京办。

文中資源:

1掀序、微信公眾號(hào)官方文檔地址:
https://developers.weixin.qq.com/doc/offiaccount/Getting_Started/Overview.html
2、WeRoBot github地址:
https://github.com/offu/WeRoBot/tree/master/werobot
3惭婿、WeRoBot文檔地址:
https://werobot.readthedocs.io/zh_CN/latest/

▼▼▼▼▼▼

長(zhǎng)按掃碼關(guān)注我
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末森枪,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子审孽,更是在濱河造成了極大的恐慌县袱,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,104評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件佑力,死亡現(xiàn)場(chǎng)離奇詭異式散,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)打颤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)暴拄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人编饺,你說(shuō)我怎么就攤上這事乖篷。” “怎么了透且?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,697評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵撕蔼,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我秽誊,道長(zhǎng)鲸沮,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,836評(píng)論 1 298
  • 正文 為了忘掉前任锅论,我火速辦了婚禮讼溺,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘最易。我一直安慰自己怒坯,他們只是感情好炫狱,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,851評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著剔猿,像睡著了一般毕荐。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上艳馒,一...
    開(kāi)封第一講書(shū)人閱讀 52,441評(píng)論 1 310
  • 那天憎亚,我揣著相機(jī)與錄音,去河邊找鬼弄慰。 笑死第美,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的陆爽。 我是一名探鬼主播什往,決...
    沈念sama閱讀 40,992評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼慌闭!你這毒婦竟也來(lái)了别威?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,899評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤驴剔,失蹤者是張志新(化名)和其女友劉穎省古,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體丧失,經(jīng)...
    沈念sama閱讀 46,457評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡豺妓,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,529評(píng)論 3 341
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了布讹。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片琳拭。...
    茶點(diǎn)故事閱讀 40,664評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖描验,靈堂內(nèi)的尸體忽然破棺而出白嘁,到底是詐尸還是另有隱情,我是刑警寧澤膘流,帶...
    沈念sama閱讀 36,346評(píng)論 5 350
  • 正文 年R本政府宣布絮缅,位于F島的核電站,受9級(jí)特大地震影響睡扬,放射性物質(zhì)發(fā)生泄漏盟蚣。R本人自食惡果不足惜黍析,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,025評(píng)論 3 334
  • 文/蒙蒙 一卖怜、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧阐枣,春花似錦马靠、人聲如沸奄抽。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,511評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)逞度。三九已至,卻和暖如春妙啃,著一層夾襖步出監(jiān)牢的瞬間档泽,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,611評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工揖赴, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留馆匿,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,081評(píng)論 3 377
  • 正文 我出身青樓燥滑,卻偏偏與公主長(zhǎng)得像渐北,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子铭拧,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,675評(píng)論 2 359