{"componentChunkName":"component---src-templates-blog-detail-tsx","path":"/blog/2020-04-13-Serverless-scf-cos-python","result":{"data":{"currentBlog":{"id":"c62f601c-89a4-5c0b-baa0-c5d2594b3b30","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/2020523/1590214762633-2404.jpg","authors":["乂乂又又"],"categories":["user-stories"],"date":"2020-04-13T00:00:00.000Z","title":"万物皆可 Serverless 之使用 SCF+COS 给未来写封信","description":"这次我带大家一起来使用无服务器云函数 SCF 和对象存储 COS，快速开发一个属于自己的给未来写封信应用。","authorslink":["https://cloud.tencent.com/developer/article/1618588"],"translators":null,"translatorslink":null,"tags":["云函数","对象存储"],"keywords":"Serverless,Serverless云函数,Serverless应用","outdated":null},"wordCount":{"words":218,"sentences":48,"paragraphs":48},"fileAbsolutePath":"/opt/build/repo/content/blog/2020-04-13-Serverless-scf-cos-python.md","fields":{"slug":"/blog/2020-04-13-Serverless-scf-cos-python/","keywords":["java","python","serverless","spa","无服务器","无服务器云函数","云函数","letter","wired","cos"]},"html":"<p>或许你有用过或者听说过《给未来写封信》，这是由全知工坊开发的一款免费应用，你可以在此刻给自己或他人写下一封信，然后选择在未来的某一天寄出，想必那时收到信的人看着这封来自过往的信时一定会十分感动吧。</p>\n<p>这次我就带大家一起来使用无服务器云函数 SCF 和对象存储 COS，快速开发一个属于自己的「给未来写封信」应用。</p>\n<h2 id=\"效果展示\"><a href=\"#%E6%95%88%E6%9E%9C%E5%B1%95%E7%A4%BA\" aria-label=\"效果展示 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>效果展示</h2>\n<p>写下一封信，然后投递：</p>\n<p><img src=\"https://img.serverlesscloud.cn/2020523/1590214762613-2404.jpg\" alt=\"写下一封信，然后投递\"></p>\n<p>一封来自很久以前的信：</p>\n<p><img src=\"https://img.serverlesscloud.cn/2020523/1590214762631-2404.jpg\" alt=\"一封来自很久以前的信\"></p>\n<p>写给未来的自己</p>\n<p><img src=\"https://img.serverlesscloud.cn/2020523/1590214762627-2404.jpg\" alt=\"写给未来的自己\"></p>\n<p>你也可以访问<a href=\"http://letter.idoo.top/letter\">letter.idoo.top/letter</a>来亲自体验一下（仅供测试之用，不保证服务一直可用）</p>\n<h2 id=\"操作步骤\"><a href=\"#%E6%93%8D%E4%BD%9C%E6%AD%A5%E9%AA%A4\" aria-label=\"操作步骤 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>操作步骤</h2>\n<h3 id=\"第一步：新建-python-云函数\"><a href=\"#%E7%AC%AC%E4%B8%80%E6%AD%A5%EF%BC%9A%E6%96%B0%E5%BB%BA-python-%E4%BA%91%E5%87%BD%E6%95%B0\" aria-label=\"第一步：新建 python 云函数 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>第一步：新建 python 云函数</h3>\n<p>参见我之前的系列文章<a href=\"https://serverlesscloud.cn/blog/2020-04-23-serverless-scf-cos/\">《万物皆可 Serverless 之使用 SCF+COS 快速开发全栈应用》</a></p>\n<h3 id=\"第二步：编写云函数\"><a href=\"#%E7%AC%AC%E4%BA%8C%E6%AD%A5%EF%BC%9A%E7%BC%96%E5%86%99%E4%BA%91%E5%87%BD%E6%95%B0\" aria-label=\"第二步：编写云函数 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>第二步：编写云函数</h3>\n<blockquote>\n<p>Life is short, show me the code.</p>\n</blockquote>\n<p>老规矩，直接上代码</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"18215225981258355000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"代码复制成功\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`import json\nimport datetime\nimport random\nfrom email.mime.text import MIMEText\nfrom email.header import Header\nimport smtplib\n\n# 是否开启本地debug模式\ndebug = False\n\n# 腾讯云对象存储依赖\nif debug:\n    from qcloud_cos import CosConfig\n    from qcloud_cos import CosS3Client\n    from qcloud_cos import CosServiceError\n    from qcloud_cos import CosClientError\nelse:\n    from qcloud_cos_v5 import CosConfig\n    from qcloud_cos_v5 import CosS3Client\n    from qcloud_cos_v5 import CosServiceError\n    from qcloud_cos_v5 import CosClientError\n\n# 配置存储桶\nappid = '66666666666'\nsecret_id = 'xxxxxxxxxxxxxxx'\nsecret_key = 'xxxxxxxxxxxxxxx'\nregion = 'ap-chongqing'\nbucket = 'name'+'-'+appid\n\n#配置发件邮箱\nmail_host = &quot;smtp.163.com&quot;\nmail_user = &quot;xxxxxxxxxx@163.com&quot;\nmail_pass = &quot;xxxxxxxxxxxxxx&quot;\nmail_port = 465\n\n# 对象存储实例\nconfig = CosConfig(Secret_id=secret_id, Secret_key=secret_key, Region=region)\nclient = CosS3Client(config)\n\n#smtp邮箱实例\nsmtpObj = smtplib.SMTP_SSL(mail_host, mail_port)\n\n# cos 文件读写\ndef cosRead(key):\n    try:\n        response = client.get_object(Bucket=bucket, Key=key)\n        txtBytes = response['Body'].get_raw_stream()\n        return txtBytes.read().decode()\n    except CosServiceError as e:\n        return &quot;&quot;\n\n\ndef cosWrite(key, txt):\n    try:\n        response = client.put_object(\n            Bucket=bucket,\n            Body=txt.encode(encoding=&quot;utf-8&quot;),\n            Key=key,\n        )\n        return True\n    except CosServiceError as e:\n        return False\n\n#获取所有信件\ndef getletters():\n    letterMap = {}\n    letterTxt = cosRead('letters.txt')  # 读取数据\n    if len(letterTxt) > 0:\n        letterMap = json.loads(letterTxt)\n    return letterMap\n\n#添加信件\ndef addletter(date, email, letter):\n    letterMap = getletters()\n    if len(letterMap) > 0:\n        letterMap[date+'_'+randomKey()] = email+'|'+letter\n    return cosWrite('letters.txt', json.dumps(letterMap, ensure_ascii=False)) if len(letterMap) > 0 else False\n\n#删除信件\ndef delletter(letter):\n    letterMap = getletters()\n    if len(letterMap) > 0:\n        letterMap.pop(letter)\n    return cosWrite('letters.txt', json.dumps(letterMap, ensure_ascii=False)) if len(letterMap) > 0 else False\n\n\n# 获取今日日期\ndef today():\n    return datetime.datetime.now().strftime(&quot;%Y-%m-%d&quot;)\n\n# 判断信件是否到期\ndef checkDate(t):\n    return t[0:10] == today()\n\n# 根据时间生成uuid\ndef randomKey():\n    return ''.join(random.sample('zyxwvutsrqponmlkjihgfedcba0123456789', 6))\n\n# api网关回复消息格式化\ndef apiReply(reply, html=False, code=200):\n    htmlStr = r'''<!DOCTYPE html>\n<html lang=&quot;zh-cn&quot;>\n\n<head>\n    <meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=utf-8&quot; />\n    <meta name=&quot;viewport&quot; content=&quot;width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0&quot;>\n    <title>给未来的自己写封信</title>\n    <style>\n        html,\n        body {\n            padding: 0px;\n            margin: 0px;\n            height: 100vh;\n        }\n\n        .main {\n            display: flex;\n            flex-direction: column;\n            justify-content: center;\n            align-items: center;\n        }\n\n        .main_phone {\n            display: flex;\n            flex-direction: column;\n            justify-content: start;\n            align-items: center;\n        }\n    </style>\n</head>\n\n<body id='body'>\n    <div class=&quot;main&quot; style=&quot;width: 80vw;&quot;>\n        <div style=&quot;height: 5vh;&quot;></div>\n        <div id='letter_top'>\n            <p style=&quot;text-align: center;&quot;>开始写信</p>\n            <wired-textarea id=&quot;letter&quot; style=&quot;height: 320px;width: 300px;&quot; placeholder=&quot;此刻平静地写下一封信,给未来的自己一份温暖...&quot; elevation=&quot;6&quot; rows=&quot;14&quot;></wired-textarea>\n        </div>\n        <div style=&quot;display: flex;align-items: center;justify-content: center;&quot;>\n            <div id='letter_left'>\n                <p style=&quot;text-align: center;&quot;>开始写信</p>\n                <wired-textarea id=&quot;letter&quot; style=&quot;height: 320px;width: 300px;&quot; placeholder=&quot;此刻平静地写下一封信,给未来的自己一份温暖...&quot; elevation=&quot;6&quot; rows=&quot;14&quot;></wired-textarea>\n            </div>\n            <div style=&quot;width: 16px;&quot;></div>\n            <div>\n                <p style=&quot;text-align: center;&quot;>送信日期</p>\n                <wired-calendar id=&quot;calendar&quot;></wired-calendar>\n            </div>\n        </div>\n        <wired-divider style=&quot;margin: 16px 0;&quot;></wired-divider>\n        <p id=&quot;hitokoto&quot;></p>\n        <div>\n            <wired-input id=&quot;email&quot; placeholder=&quot;收件邮箱&quot;></wired-input>\n            <wired-button onclick=&quot;send()&quot;>投递</wired-button>\n        </div>\n        <div style=&quot;height: 5vh;&quot;></div>\n    </div>\n    <script>\n        let datex = '';\n        let myEmail = document.getElementById('email');\n        let myLetter = document.getElementById('letter');\n        let myCalendar = document.getElementById('calendar');\n\n        let width =\n            window.innerWidth ||\n            document.documentElement.clientWidth ||\n            document.body.clientWidth\n\n        let height =\n            window.innerHeight ||\n            document.documentElement.clientHeight ||\n            document.body.clientHeight\n\n        let pc = width >= height\n\n        let today = new Date();\n        let info = today.toString().split(' ');\n        let selected = \\`\\${info[1]} \\${today.getDate()}, \\${today.getFullYear()}\\`;\n\n        document.getElementById('body').classList.add(pc ? 'main' : 'main_phone');\n        document.getElementById('letter_left').style.display = pc ? 'block' : 'none';\n        document.getElementById('letter_top').style.display = pc ? 'none' : 'block';\n        myCalendar.setAttribute(&quot;selected&quot;, selected);\n        myCalendar.addEventListener('selected', () => {\n            let selectedObject = myCalendar.value;\n            let date = new Date(new Date().setDate(selectedObject.date.getDate()));\n            datex = date.toISOString().substr(0, 10);\n        });\n\n        function send() {\n            if (datex.length < 1 || myEmail.value.length < 1 || myLetter.value.length < 1) {\n                alert('信件内容、送信日期或投递邮箱不能为空');\n                return;\n            }\n            fetch(window.location.href, {\n                    method: 'POST',\n                    body: JSON.stringify({\n                        date: datex,\n                        email: myEmail.value,\n                        letter: myLetter.value\n                    })\n                }).then(res => res.json())\n                .catch(error => console.error('Error:', error))\n                .then(response => alert(response.ok ? '添加成功:)' : '添加失败:('));\n        }\n    </script>\n    <script src=&quot;https://v1.hitokoto.cn/?encode=js&select=%23hitokoto&quot; defer></script>\n    <script src=&quot;https://unpkg.com/wired-elements@2.0.5/lib/wired-elements-bundled.js &quot;></script>\n</body>\n\n</html>'''\n    return {\n        &quot;isBase64Encoded&quot;: False,\n        &quot;statusCode&quot;: code,\n        &quot;headers&quot;: {'Content-Type': 'text/html' if html else 'application/json', &quot;Access-Control-Allow-Origin&quot;: &quot;*&quot;},\n        &quot;body&quot;: htmlStr if html else json.dumps(reply, ensure_ascii=False)\n    }\n\n#登陆邮箱\ndef loginEmail():\n    try:\n        smtpObj.login(mail_user, mail_pass)\n        return True\n    except smtplib.SMTPException as e:\n        print(e)\n        return False\n\n#发送邮件\ndef sendEmail(letter):\n    temp=letter.split('|')\n    receivers = [temp[0]]\n    message = MIMEText(temp[1], 'plain', 'utf-8')\n    message['From'] = mail_user\n    message['To'] = temp[0]\n    message['Subject'] = '一封来自很久以前的信'\n    try:\n        smtpObj.sendmail(mail_user, receivers, message.as_string())\n        print(&quot;send email success&quot;)\n        return True\n    except smtplib.SMTPException as e:\n        print(&quot;Error: send email fail&quot;)\n        return False\n\n#每天定时检查需要发送的信件\ndef check_send_letters():\n    loginEmail()\n    letters = getletters()\n    for date in letters.keys():\n        if checkDate(date):\n            sendEmail(letters[date])\n\n\ndef main_handler(event, context):\n    if 'Time' in event.keys():  # 来自定时触发器\n        check_send_letters()\n        return\n    if 'httpMethod' in event.keys():  # 来自api网关触发器\n        if event['httpMethod'] == 'GET':\n            return apiReply('', html=True)  # 返回网页\n        if event['httpMethod'] == 'POST':  # 添加信件\n            body = json.loads(event['body'])\n            flag = addletter(body['date'], body['email'], body['letter'])\n            return apiReply({\n                'ok': True if flag else False,\n                'message': '添加成功' if flag else '添加失败'\n            })\n    return apiReply('', html=True)`, `18215225981258355000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                复制代码<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">import</span> json\n<span class=\"token keyword\">import</span> datetime\n<span class=\"token keyword\">import</span> random\n<span class=\"token keyword\">from</span> email<span class=\"token punctuation\">.</span>mime<span class=\"token punctuation\">.</span>text <span class=\"token keyword\">import</span> MIMEText\n<span class=\"token keyword\">from</span> email<span class=\"token punctuation\">.</span>header <span class=\"token keyword\">import</span> Header\n<span class=\"token keyword\">import</span> smtplib\n\n# 是否开启本地debug模式\ndebug <span class=\"token operator\">=</span> False\n\n# 腾讯云对象存储依赖\n<span class=\"token keyword\">if</span> debug<span class=\"token punctuation\">:</span>\n    <span class=\"token keyword\">from</span> qcloud_cos <span class=\"token keyword\">import</span> CosConfig\n    <span class=\"token keyword\">from</span> qcloud_cos <span class=\"token keyword\">import</span> CosS3Client\n    <span class=\"token keyword\">from</span> qcloud_cos <span class=\"token keyword\">import</span> CosServiceError\n    <span class=\"token keyword\">from</span> qcloud_cos <span class=\"token keyword\">import</span> CosClientError\n<span class=\"token keyword\">else</span><span class=\"token punctuation\">:</span>\n    <span class=\"token keyword\">from</span> qcloud_cos_v5 <span class=\"token keyword\">import</span> CosConfig\n    <span class=\"token keyword\">from</span> qcloud_cos_v5 <span class=\"token keyword\">import</span> CosS3Client\n    <span class=\"token keyword\">from</span> qcloud_cos_v5 <span class=\"token keyword\">import</span> CosServiceError\n    <span class=\"token keyword\">from</span> qcloud_cos_v5 <span class=\"token keyword\">import</span> CosClientError\n\n# 配置存储桶\nappid <span class=\"token operator\">=</span> <span class=\"token string\">'66666666666'</span>\nsecret_id <span class=\"token operator\">=</span> <span class=\"token string\">'xxxxxxxxxxxxxxx'</span>\nsecret_key <span class=\"token operator\">=</span> <span class=\"token string\">'xxxxxxxxxxxxxxx'</span>\nregion <span class=\"token operator\">=</span> <span class=\"token string\">'ap-chongqing'</span>\nbucket <span class=\"token operator\">=</span> <span class=\"token string\">'name'</span><span class=\"token operator\">+</span><span class=\"token string\">'-'</span><span class=\"token operator\">+</span>appid\n\n#配置发件邮箱\nmail_host <span class=\"token operator\">=</span> <span class=\"token string\">\"smtp.163.com\"</span>\nmail_user <span class=\"token operator\">=</span> <span class=\"token string\">\"xxxxxxxxxx@163.com\"</span>\nmail_pass <span class=\"token operator\">=</span> <span class=\"token string\">\"xxxxxxxxxxxxxx\"</span>\nmail_port <span class=\"token operator\">=</span> <span class=\"token number\">465</span>\n\n# 对象存储实例\nconfig <span class=\"token operator\">=</span> <span class=\"token function\">CosConfig</span><span class=\"token punctuation\">(</span>Secret_id<span class=\"token operator\">=</span>secret_id<span class=\"token punctuation\">,</span> Secret_key<span class=\"token operator\">=</span>secret_key<span class=\"token punctuation\">,</span> Region<span class=\"token operator\">=</span>region<span class=\"token punctuation\">)</span>\nclient <span class=\"token operator\">=</span> <span class=\"token function\">CosS3Client</span><span class=\"token punctuation\">(</span>config<span class=\"token punctuation\">)</span>\n\n#smtp邮箱实例\nsmtpObj <span class=\"token operator\">=</span> smtplib<span class=\"token punctuation\">.</span><span class=\"token constant\">SMTP_SSL</span><span class=\"token punctuation\">(</span>mail_host<span class=\"token punctuation\">,</span> mail_port<span class=\"token punctuation\">)</span>\n\n# cos 文件读写\ndef <span class=\"token function\">cosRead</span><span class=\"token punctuation\">(</span>key<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    <span class=\"token keyword\">try</span><span class=\"token punctuation\">:</span>\n        response <span class=\"token operator\">=</span> client<span class=\"token punctuation\">.</span><span class=\"token function\">get_object</span><span class=\"token punctuation\">(</span>Bucket<span class=\"token operator\">=</span>bucket<span class=\"token punctuation\">,</span> Key<span class=\"token operator\">=</span>key<span class=\"token punctuation\">)</span>\n        txtBytes <span class=\"token operator\">=</span> response<span class=\"token punctuation\">[</span><span class=\"token string\">'Body'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">.</span><span class=\"token function\">get_raw_stream</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">return</span> txtBytes<span class=\"token punctuation\">.</span><span class=\"token function\">read</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">decode</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    except CosServiceError <span class=\"token keyword\">as</span> e<span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">return</span> <span class=\"token string\">\"\"</span>\n\n\ndef <span class=\"token function\">cosWrite</span><span class=\"token punctuation\">(</span>key<span class=\"token punctuation\">,</span> txt<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    <span class=\"token keyword\">try</span><span class=\"token punctuation\">:</span>\n        response <span class=\"token operator\">=</span> client<span class=\"token punctuation\">.</span><span class=\"token function\">put_object</span><span class=\"token punctuation\">(</span>\n            Bucket<span class=\"token operator\">=</span>bucket<span class=\"token punctuation\">,</span>\n            Body<span class=\"token operator\">=</span>txt<span class=\"token punctuation\">.</span><span class=\"token function\">encode</span><span class=\"token punctuation\">(</span>encoding<span class=\"token operator\">=</span><span class=\"token string\">\"utf-8\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n            Key<span class=\"token operator\">=</span>key<span class=\"token punctuation\">,</span>\n        <span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">return</span> True\n    except CosServiceError <span class=\"token keyword\">as</span> e<span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">return</span> False\n\n#获取所有信件\ndef <span class=\"token function\">getletters</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    letterMap <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span><span class=\"token punctuation\">}</span>\n    letterTxt <span class=\"token operator\">=</span> <span class=\"token function\">cosRead</span><span class=\"token punctuation\">(</span><span class=\"token string\">'letters.txt'</span><span class=\"token punctuation\">)</span>  # 读取数据\n    <span class=\"token keyword\">if</span> <span class=\"token function\">len</span><span class=\"token punctuation\">(</span>letterTxt<span class=\"token punctuation\">)</span> <span class=\"token operator\">></span> <span class=\"token number\">0</span><span class=\"token punctuation\">:</span>\n        letterMap <span class=\"token operator\">=</span> json<span class=\"token punctuation\">.</span><span class=\"token function\">loads</span><span class=\"token punctuation\">(</span>letterTxt<span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">return</span> letterMap\n\n#添加信件\ndef <span class=\"token function\">addletter</span><span class=\"token punctuation\">(</span>date<span class=\"token punctuation\">,</span> email<span class=\"token punctuation\">,</span> letter<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    letterMap <span class=\"token operator\">=</span> <span class=\"token function\">getletters</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">if</span> <span class=\"token function\">len</span><span class=\"token punctuation\">(</span>letterMap<span class=\"token punctuation\">)</span> <span class=\"token operator\">></span> <span class=\"token number\">0</span><span class=\"token punctuation\">:</span>\n        letterMap<span class=\"token punctuation\">[</span>date<span class=\"token operator\">+</span><span class=\"token string\">'_'</span><span class=\"token operator\">+</span><span class=\"token function\">randomKey</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> email<span class=\"token operator\">+</span><span class=\"token string\">'|'</span><span class=\"token operator\">+</span>letter\n    <span class=\"token keyword\">return</span> <span class=\"token function\">cosWrite</span><span class=\"token punctuation\">(</span><span class=\"token string\">'letters.txt'</span><span class=\"token punctuation\">,</span> json<span class=\"token punctuation\">.</span><span class=\"token function\">dumps</span><span class=\"token punctuation\">(</span>letterMap<span class=\"token punctuation\">,</span> ensure_ascii<span class=\"token operator\">=</span>False<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">if</span> <span class=\"token function\">len</span><span class=\"token punctuation\">(</span>letterMap<span class=\"token punctuation\">)</span> <span class=\"token operator\">></span> <span class=\"token number\">0</span> <span class=\"token keyword\">else</span> False\n\n#删除信件\ndef <span class=\"token function\">delletter</span><span class=\"token punctuation\">(</span>letter<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    letterMap <span class=\"token operator\">=</span> <span class=\"token function\">getletters</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">if</span> <span class=\"token function\">len</span><span class=\"token punctuation\">(</span>letterMap<span class=\"token punctuation\">)</span> <span class=\"token operator\">></span> <span class=\"token number\">0</span><span class=\"token punctuation\">:</span>\n        letterMap<span class=\"token punctuation\">.</span><span class=\"token function\">pop</span><span class=\"token punctuation\">(</span>letter<span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">return</span> <span class=\"token function\">cosWrite</span><span class=\"token punctuation\">(</span><span class=\"token string\">'letters.txt'</span><span class=\"token punctuation\">,</span> json<span class=\"token punctuation\">.</span><span class=\"token function\">dumps</span><span class=\"token punctuation\">(</span>letterMap<span class=\"token punctuation\">,</span> ensure_ascii<span class=\"token operator\">=</span>False<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">if</span> <span class=\"token function\">len</span><span class=\"token punctuation\">(</span>letterMap<span class=\"token punctuation\">)</span> <span class=\"token operator\">></span> <span class=\"token number\">0</span> <span class=\"token keyword\">else</span> False\n\n\n# 获取今日日期\ndef <span class=\"token function\">today</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    <span class=\"token keyword\">return</span> datetime<span class=\"token punctuation\">.</span>datetime<span class=\"token punctuation\">.</span><span class=\"token function\">now</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">strftime</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"%Y-%m-%d\"</span><span class=\"token punctuation\">)</span>\n\n# 判断信件是否到期\ndef <span class=\"token function\">checkDate</span><span class=\"token punctuation\">(</span>t<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    <span class=\"token keyword\">return</span> t<span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">:</span><span class=\"token number\">10</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">==</span> <span class=\"token function\">today</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n\n# 根据时间生成uuid\ndef <span class=\"token function\">randomKey</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    <span class=\"token keyword\">return</span> <span class=\"token string\">''</span><span class=\"token punctuation\">.</span><span class=\"token function\">join</span><span class=\"token punctuation\">(</span>random<span class=\"token punctuation\">.</span><span class=\"token function\">sample</span><span class=\"token punctuation\">(</span><span class=\"token string\">'zyxwvutsrqponmlkjihgfedcba0123456789'</span><span class=\"token punctuation\">,</span> <span class=\"token number\">6</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n\n# api网关回复消息格式化\ndef <span class=\"token function\">apiReply</span><span class=\"token punctuation\">(</span>reply<span class=\"token punctuation\">,</span> html<span class=\"token operator\">=</span>False<span class=\"token punctuation\">,</span> code<span class=\"token operator\">=</span><span class=\"token number\">200</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    htmlStr <span class=\"token operator\">=</span> r<span class=\"token string\">''</span>'<span class=\"token operator\">&lt;</span><span class=\"token operator\">!</span><span class=\"token constant\">DOCTYPE</span> html<span class=\"token operator\">></span>\n<span class=\"token operator\">&lt;</span>html lang<span class=\"token operator\">=</span><span class=\"token string\">\"zh-cn\"</span><span class=\"token operator\">></span>\n\n<span class=\"token operator\">&lt;</span>head<span class=\"token operator\">></span>\n    <span class=\"token operator\">&lt;</span>meta http<span class=\"token operator\">-</span>equiv<span class=\"token operator\">=</span><span class=\"token string\">\"Content-Type\"</span> content<span class=\"token operator\">=</span><span class=\"token string\">\"text/html; charset=utf-8\"</span> <span class=\"token operator\">/</span><span class=\"token operator\">></span>\n    <span class=\"token operator\">&lt;</span>meta name<span class=\"token operator\">=</span><span class=\"token string\">\"viewport\"</span> content<span class=\"token operator\">=</span><span class=\"token string\">\"width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0\"</span><span class=\"token operator\">></span>\n    <span class=\"token operator\">&lt;</span>title<span class=\"token operator\">></span>给未来的自己写封信<span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>title<span class=\"token operator\">></span>\n    <span class=\"token operator\">&lt;</span>style<span class=\"token operator\">></span>\n        html<span class=\"token punctuation\">,</span>\n        body <span class=\"token punctuation\">{</span>\n            padding<span class=\"token punctuation\">:</span> <span class=\"token number\">0</span>px<span class=\"token punctuation\">;</span>\n            margin<span class=\"token punctuation\">:</span> <span class=\"token number\">0</span>px<span class=\"token punctuation\">;</span>\n            height<span class=\"token punctuation\">:</span> <span class=\"token number\">100</span>vh<span class=\"token punctuation\">;</span>\n        <span class=\"token punctuation\">}</span>\n\n        <span class=\"token punctuation\">.</span>main <span class=\"token punctuation\">{</span>\n            display<span class=\"token punctuation\">:</span> flex<span class=\"token punctuation\">;</span>\n            flex<span class=\"token operator\">-</span>direction<span class=\"token punctuation\">:</span> column<span class=\"token punctuation\">;</span>\n            justify<span class=\"token operator\">-</span>content<span class=\"token punctuation\">:</span> center<span class=\"token punctuation\">;</span>\n            align<span class=\"token operator\">-</span>items<span class=\"token punctuation\">:</span> center<span class=\"token punctuation\">;</span>\n        <span class=\"token punctuation\">}</span>\n\n        <span class=\"token punctuation\">.</span>main_phone <span class=\"token punctuation\">{</span>\n            display<span class=\"token punctuation\">:</span> flex<span class=\"token punctuation\">;</span>\n            flex<span class=\"token operator\">-</span>direction<span class=\"token punctuation\">:</span> column<span class=\"token punctuation\">;</span>\n            justify<span class=\"token operator\">-</span>content<span class=\"token punctuation\">:</span> start<span class=\"token punctuation\">;</span>\n            align<span class=\"token operator\">-</span>items<span class=\"token punctuation\">:</span> center<span class=\"token punctuation\">;</span>\n        <span class=\"token punctuation\">}</span>\n    <span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>style<span class=\"token operator\">></span>\n<span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>head<span class=\"token operator\">></span>\n\n<span class=\"token operator\">&lt;</span>body id<span class=\"token operator\">=</span><span class=\"token string\">'body'</span><span class=\"token operator\">></span>\n    <span class=\"token operator\">&lt;</span>div <span class=\"token keyword\">class</span><span class=\"token operator\">=</span><span class=\"token string\">\"main\"</span> style<span class=\"token operator\">=</span><span class=\"token string\">\"width: 80vw;\"</span><span class=\"token operator\">></span>\n        <span class=\"token operator\">&lt;</span>div style<span class=\"token operator\">=</span><span class=\"token string\">\"height: 5vh;\"</span><span class=\"token operator\">></span><span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>div<span class=\"token operator\">></span>\n        <span class=\"token operator\">&lt;</span>div id<span class=\"token operator\">=</span><span class=\"token string\">'letter_top'</span><span class=\"token operator\">></span>\n            <span class=\"token operator\">&lt;</span>p style<span class=\"token operator\">=</span><span class=\"token string\">\"text-align: center;\"</span><span class=\"token operator\">></span>开始写信<span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>p<span class=\"token operator\">></span>\n            <span class=\"token operator\">&lt;</span>wired<span class=\"token operator\">-</span>textarea id<span class=\"token operator\">=</span><span class=\"token string\">\"letter\"</span> style<span class=\"token operator\">=</span><span class=\"token string\">\"height: 320px;width: 300px;\"</span> placeholder<span class=\"token operator\">=</span><span class=\"token string\">\"此刻平静地写下一封信,给未来的自己一份温暖...\"</span> elevation<span class=\"token operator\">=</span><span class=\"token string\">\"6\"</span> rows<span class=\"token operator\">=</span><span class=\"token string\">\"14\"</span><span class=\"token operator\">></span><span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>wired<span class=\"token operator\">-</span>textarea<span class=\"token operator\">></span>\n        <span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>div<span class=\"token operator\">></span>\n        <span class=\"token operator\">&lt;</span>div style<span class=\"token operator\">=</span><span class=\"token string\">\"display: flex;align-items: center;justify-content: center;\"</span><span class=\"token operator\">></span>\n            <span class=\"token operator\">&lt;</span>div id<span class=\"token operator\">=</span><span class=\"token string\">'letter_left'</span><span class=\"token operator\">></span>\n                <span class=\"token operator\">&lt;</span>p style<span class=\"token operator\">=</span><span class=\"token string\">\"text-align: center;\"</span><span class=\"token operator\">></span>开始写信<span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>p<span class=\"token operator\">></span>\n                <span class=\"token operator\">&lt;</span>wired<span class=\"token operator\">-</span>textarea id<span class=\"token operator\">=</span><span class=\"token string\">\"letter\"</span> style<span class=\"token operator\">=</span><span class=\"token string\">\"height: 320px;width: 300px;\"</span> placeholder<span class=\"token operator\">=</span><span class=\"token string\">\"此刻平静地写下一封信,给未来的自己一份温暖...\"</span> elevation<span class=\"token operator\">=</span><span class=\"token string\">\"6\"</span> rows<span class=\"token operator\">=</span><span class=\"token string\">\"14\"</span><span class=\"token operator\">></span><span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>wired<span class=\"token operator\">-</span>textarea<span class=\"token operator\">></span>\n            <span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>div<span class=\"token operator\">></span>\n            <span class=\"token operator\">&lt;</span>div style<span class=\"token operator\">=</span><span class=\"token string\">\"width: 16px;\"</span><span class=\"token operator\">></span><span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>div<span class=\"token operator\">></span>\n            <span class=\"token operator\">&lt;</span>div<span class=\"token operator\">></span>\n                <span class=\"token operator\">&lt;</span>p style<span class=\"token operator\">=</span><span class=\"token string\">\"text-align: center;\"</span><span class=\"token operator\">></span>送信日期<span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>p<span class=\"token operator\">></span>\n                <span class=\"token operator\">&lt;</span>wired<span class=\"token operator\">-</span>calendar id<span class=\"token operator\">=</span><span class=\"token string\">\"calendar\"</span><span class=\"token operator\">></span><span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>wired<span class=\"token operator\">-</span>calendar<span class=\"token operator\">></span>\n            <span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>div<span class=\"token operator\">></span>\n        <span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>div<span class=\"token operator\">></span>\n        <span class=\"token operator\">&lt;</span>wired<span class=\"token operator\">-</span>divider style<span class=\"token operator\">=</span><span class=\"token string\">\"margin: 16px 0;\"</span><span class=\"token operator\">></span><span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>wired<span class=\"token operator\">-</span>divider<span class=\"token operator\">></span>\n        <span class=\"token operator\">&lt;</span>p id<span class=\"token operator\">=</span><span class=\"token string\">\"hitokoto\"</span><span class=\"token operator\">></span><span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>p<span class=\"token operator\">></span>\n        <span class=\"token operator\">&lt;</span>div<span class=\"token operator\">></span>\n            <span class=\"token operator\">&lt;</span>wired<span class=\"token operator\">-</span>input id<span class=\"token operator\">=</span><span class=\"token string\">\"email\"</span> placeholder<span class=\"token operator\">=</span><span class=\"token string\">\"收件邮箱\"</span><span class=\"token operator\">></span><span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>wired<span class=\"token operator\">-</span>input<span class=\"token operator\">></span>\n            <span class=\"token operator\">&lt;</span>wired<span class=\"token operator\">-</span>button onclick<span class=\"token operator\">=</span><span class=\"token string\">\"send()\"</span><span class=\"token operator\">></span>投递<span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>wired<span class=\"token operator\">-</span>button<span class=\"token operator\">></span>\n        <span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>div<span class=\"token operator\">></span>\n        <span class=\"token operator\">&lt;</span>div style<span class=\"token operator\">=</span><span class=\"token string\">\"height: 5vh;\"</span><span class=\"token operator\">></span><span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>div<span class=\"token operator\">></span>\n    <span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>div<span class=\"token operator\">></span>\n    <span class=\"token operator\">&lt;</span>script<span class=\"token operator\">></span>\n        <span class=\"token keyword\">let</span> datex <span class=\"token operator\">=</span> <span class=\"token string\">''</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">let</span> myEmail <span class=\"token operator\">=</span> document<span class=\"token punctuation\">.</span><span class=\"token function\">getElementById</span><span class=\"token punctuation\">(</span><span class=\"token string\">'email'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">let</span> myLetter <span class=\"token operator\">=</span> document<span class=\"token punctuation\">.</span><span class=\"token function\">getElementById</span><span class=\"token punctuation\">(</span><span class=\"token string\">'letter'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">let</span> myCalendar <span class=\"token operator\">=</span> document<span class=\"token punctuation\">.</span><span class=\"token function\">getElementById</span><span class=\"token punctuation\">(</span><span class=\"token string\">'calendar'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n        <span class=\"token keyword\">let</span> width <span class=\"token operator\">=</span>\n            window<span class=\"token punctuation\">.</span>innerWidth <span class=\"token operator\">||</span>\n            document<span class=\"token punctuation\">.</span>documentElement<span class=\"token punctuation\">.</span>clientWidth <span class=\"token operator\">||</span>\n            document<span class=\"token punctuation\">.</span>body<span class=\"token punctuation\">.</span>clientWidth\n\n        <span class=\"token keyword\">let</span> height <span class=\"token operator\">=</span>\n            window<span class=\"token punctuation\">.</span>innerHeight <span class=\"token operator\">||</span>\n            document<span class=\"token punctuation\">.</span>documentElement<span class=\"token punctuation\">.</span>clientHeight <span class=\"token operator\">||</span>\n            document<span class=\"token punctuation\">.</span>body<span class=\"token punctuation\">.</span>clientHeight\n\n        <span class=\"token keyword\">let</span> pc <span class=\"token operator\">=</span> width <span class=\"token operator\">>=</span> height\n\n        <span class=\"token keyword\">let</span> today <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Date</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">let</span> info <span class=\"token operator\">=</span> today<span class=\"token punctuation\">.</span><span class=\"token function\">toString</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">split</span><span class=\"token punctuation\">(</span><span class=\"token string\">' '</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">let</span> selected <span class=\"token operator\">=</span> <span class=\"token template-string\"><span class=\"token template-punctuation string\">`</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span>info<span class=\"token punctuation\">[</span><span class=\"token number\">1</span><span class=\"token punctuation\">]</span><span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token string\"> </span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span>today<span class=\"token punctuation\">.</span><span class=\"token function\">getDate</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token string\">, </span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span>today<span class=\"token punctuation\">.</span><span class=\"token function\">getFullYear</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token template-punctuation string\">`</span></span><span class=\"token punctuation\">;</span>\n\n        document<span class=\"token punctuation\">.</span><span class=\"token function\">getElementById</span><span class=\"token punctuation\">(</span><span class=\"token string\">'body'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>classList<span class=\"token punctuation\">.</span><span class=\"token function\">add</span><span class=\"token punctuation\">(</span>pc <span class=\"token operator\">?</span> <span class=\"token string\">'main'</span> <span class=\"token punctuation\">:</span> <span class=\"token string\">'main_phone'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        document<span class=\"token punctuation\">.</span><span class=\"token function\">getElementById</span><span class=\"token punctuation\">(</span><span class=\"token string\">'letter_left'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>style<span class=\"token punctuation\">.</span>display <span class=\"token operator\">=</span> pc <span class=\"token operator\">?</span> <span class=\"token string\">'block'</span> <span class=\"token punctuation\">:</span> <span class=\"token string\">'none'</span><span class=\"token punctuation\">;</span>\n        document<span class=\"token punctuation\">.</span><span class=\"token function\">getElementById</span><span class=\"token punctuation\">(</span><span class=\"token string\">'letter_top'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>style<span class=\"token punctuation\">.</span>display <span class=\"token operator\">=</span> pc <span class=\"token operator\">?</span> <span class=\"token string\">'none'</span> <span class=\"token punctuation\">:</span> <span class=\"token string\">'block'</span><span class=\"token punctuation\">;</span>\n        myCalendar<span class=\"token punctuation\">.</span><span class=\"token function\">setAttribute</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"selected\"</span><span class=\"token punctuation\">,</span> selected<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        myCalendar<span class=\"token punctuation\">.</span><span class=\"token function\">addEventListener</span><span class=\"token punctuation\">(</span><span class=\"token string\">'selected'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n            <span class=\"token keyword\">let</span> selectedObject <span class=\"token operator\">=</span> myCalendar<span class=\"token punctuation\">.</span>value<span class=\"token punctuation\">;</span>\n            <span class=\"token keyword\">let</span> date <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Date</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">new</span> <span class=\"token class-name\">Date</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">setDate</span><span class=\"token punctuation\">(</span>selectedObject<span class=\"token punctuation\">.</span>date<span class=\"token punctuation\">.</span><span class=\"token function\">getDate</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n            datex <span class=\"token operator\">=</span> date<span class=\"token punctuation\">.</span><span class=\"token function\">toISOString</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">substr</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">,</span> <span class=\"token number\">10</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n        <span class=\"token keyword\">function</span> <span class=\"token function\">send</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n            <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>datex<span class=\"token punctuation\">.</span>length <span class=\"token operator\">&lt;</span> <span class=\"token number\">1</span> <span class=\"token operator\">||</span> myEmail<span class=\"token punctuation\">.</span>value<span class=\"token punctuation\">.</span>length <span class=\"token operator\">&lt;</span> <span class=\"token number\">1</span> <span class=\"token operator\">||</span> myLetter<span class=\"token punctuation\">.</span>value<span class=\"token punctuation\">.</span>length <span class=\"token operator\">&lt;</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n                <span class=\"token function\">alert</span><span class=\"token punctuation\">(</span><span class=\"token string\">'信件内容、送信日期或投递邮箱不能为空'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n                <span class=\"token keyword\">return</span><span class=\"token punctuation\">;</span>\n            <span class=\"token punctuation\">}</span>\n            <span class=\"token function\">fetch</span><span class=\"token punctuation\">(</span>window<span class=\"token punctuation\">.</span>location<span class=\"token punctuation\">.</span>href<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span>\n                    method<span class=\"token punctuation\">:</span> <span class=\"token string\">'POST'</span><span class=\"token punctuation\">,</span>\n                    body<span class=\"token punctuation\">:</span> <span class=\"token constant\">JSON</span><span class=\"token punctuation\">.</span><span class=\"token function\">stringify</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n                        date<span class=\"token punctuation\">:</span> datex<span class=\"token punctuation\">,</span>\n                        email<span class=\"token punctuation\">:</span> myEmail<span class=\"token punctuation\">.</span>value<span class=\"token punctuation\">,</span>\n                        letter<span class=\"token punctuation\">:</span> myLetter<span class=\"token punctuation\">.</span>value\n                    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n                <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">then</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">res</span> <span class=\"token operator\">=></span> res<span class=\"token punctuation\">.</span><span class=\"token function\">json</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n                <span class=\"token punctuation\">.</span><span class=\"token function\">catch</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">error</span> <span class=\"token operator\">=></span> console<span class=\"token punctuation\">.</span><span class=\"token function\">error</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Error:'</span><span class=\"token punctuation\">,</span> error<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n                <span class=\"token punctuation\">.</span><span class=\"token function\">then</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">response</span> <span class=\"token operator\">=></span> <span class=\"token function\">alert</span><span class=\"token punctuation\">(</span>response<span class=\"token punctuation\">.</span>ok <span class=\"token operator\">?</span> <span class=\"token string\">'添加成功:)'</span> <span class=\"token punctuation\">:</span> <span class=\"token string\">'添加失败:('</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token punctuation\">}</span>\n    <span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>script<span class=\"token operator\">></span>\n    <span class=\"token operator\">&lt;</span>script src<span class=\"token operator\">=</span><span class=\"token string\">\"https://v1.hitokoto.cn/?encode=js&amp;select=%23hitokoto\"</span> defer<span class=\"token operator\">></span><span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>script<span class=\"token operator\">></span>\n    <span class=\"token operator\">&lt;</span>script src<span class=\"token operator\">=</span><span class=\"token string\">\"https://unpkg.com/wired-elements@2.0.5/lib/wired-elements-bundled.js \"</span><span class=\"token operator\">></span><span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>script<span class=\"token operator\">></span>\n<span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>body<span class=\"token operator\">></span>\n\n<span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>html<span class=\"token operator\">></span><span class=\"token string\">''</span>'\n    <span class=\"token keyword\">return</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token string\">\"isBase64Encoded\"</span><span class=\"token punctuation\">:</span> False<span class=\"token punctuation\">,</span>\n        <span class=\"token string\">\"statusCode\"</span><span class=\"token punctuation\">:</span> code<span class=\"token punctuation\">,</span>\n        <span class=\"token string\">\"headers\"</span><span class=\"token punctuation\">:</span> <span class=\"token punctuation\">{</span><span class=\"token string\">'Content-Type'</span><span class=\"token punctuation\">:</span> <span class=\"token string\">'text/html'</span> <span class=\"token keyword\">if</span> html <span class=\"token keyword\">else</span> <span class=\"token string\">'application/json'</span><span class=\"token punctuation\">,</span> <span class=\"token string\">\"Access-Control-Allow-Origin\"</span><span class=\"token punctuation\">:</span> <span class=\"token string\">\"*\"</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n        <span class=\"token string\">\"body\"</span><span class=\"token punctuation\">:</span> htmlStr <span class=\"token keyword\">if</span> html <span class=\"token keyword\">else</span> json<span class=\"token punctuation\">.</span><span class=\"token function\">dumps</span><span class=\"token punctuation\">(</span>reply<span class=\"token punctuation\">,</span> ensure_ascii<span class=\"token operator\">=</span>False<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n\n#登陆邮箱\ndef <span class=\"token function\">loginEmail</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    <span class=\"token keyword\">try</span><span class=\"token punctuation\">:</span>\n        smtpObj<span class=\"token punctuation\">.</span><span class=\"token function\">login</span><span class=\"token punctuation\">(</span>mail_user<span class=\"token punctuation\">,</span> mail_pass<span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">return</span> True\n    except smtplib<span class=\"token punctuation\">.</span>SMTPException <span class=\"token keyword\">as</span> e<span class=\"token punctuation\">:</span>\n        <span class=\"token function\">print</span><span class=\"token punctuation\">(</span>e<span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">return</span> False\n\n#发送邮件\ndef <span class=\"token function\">sendEmail</span><span class=\"token punctuation\">(</span>letter<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    temp<span class=\"token operator\">=</span>letter<span class=\"token punctuation\">.</span><span class=\"token function\">split</span><span class=\"token punctuation\">(</span><span class=\"token string\">'|'</span><span class=\"token punctuation\">)</span>\n    receivers <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span>temp<span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">]</span>\n    message <span class=\"token operator\">=</span> <span class=\"token function\">MIMEText</span><span class=\"token punctuation\">(</span>temp<span class=\"token punctuation\">[</span><span class=\"token number\">1</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> <span class=\"token string\">'plain'</span><span class=\"token punctuation\">,</span> <span class=\"token string\">'utf-8'</span><span class=\"token punctuation\">)</span>\n    message<span class=\"token punctuation\">[</span><span class=\"token string\">'From'</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> mail_user\n    message<span class=\"token punctuation\">[</span><span class=\"token string\">'To'</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> temp<span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span>\n    message<span class=\"token punctuation\">[</span><span class=\"token string\">'Subject'</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token string\">'一封来自很久以前的信'</span>\n    <span class=\"token keyword\">try</span><span class=\"token punctuation\">:</span>\n        smtpObj<span class=\"token punctuation\">.</span><span class=\"token function\">sendmail</span><span class=\"token punctuation\">(</span>mail_user<span class=\"token punctuation\">,</span> receivers<span class=\"token punctuation\">,</span> message<span class=\"token punctuation\">.</span><span class=\"token function\">as_string</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n        <span class=\"token function\">print</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"send email success\"</span><span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">return</span> True\n    except smtplib<span class=\"token punctuation\">.</span>SMTPException <span class=\"token keyword\">as</span> e<span class=\"token punctuation\">:</span>\n        <span class=\"token function\">print</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Error: send email fail\"</span><span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">return</span> False\n\n#每天定时检查需要发送的信件\ndef <span class=\"token function\">check_send_letters</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    <span class=\"token function\">loginEmail</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    letters <span class=\"token operator\">=</span> <span class=\"token function\">getletters</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">for</span> date <span class=\"token keyword\">in</span> letters<span class=\"token punctuation\">.</span><span class=\"token function\">keys</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">if</span> <span class=\"token function\">checkDate</span><span class=\"token punctuation\">(</span>date<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n            <span class=\"token function\">sendEmail</span><span class=\"token punctuation\">(</span>letters<span class=\"token punctuation\">[</span>date<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span>\n\n\ndef <span class=\"token function\">main_handler</span><span class=\"token punctuation\">(</span>event<span class=\"token punctuation\">,</span> context<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    <span class=\"token keyword\">if</span> <span class=\"token string\">'Time'</span> <span class=\"token keyword\">in</span> event<span class=\"token punctuation\">.</span><span class=\"token function\">keys</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>  # 来自定时触发器\n        <span class=\"token function\">check_send_letters</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">return</span>\n    <span class=\"token keyword\">if</span> <span class=\"token string\">'httpMethod'</span> <span class=\"token keyword\">in</span> event<span class=\"token punctuation\">.</span><span class=\"token function\">keys</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>  # 来自api网关触发器\n        <span class=\"token keyword\">if</span> event<span class=\"token punctuation\">[</span><span class=\"token string\">'httpMethod'</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">==</span> <span class=\"token string\">'GET'</span><span class=\"token punctuation\">:</span>\n            <span class=\"token keyword\">return</span> <span class=\"token function\">apiReply</span><span class=\"token punctuation\">(</span><span class=\"token string\">''</span><span class=\"token punctuation\">,</span> html<span class=\"token operator\">=</span>True<span class=\"token punctuation\">)</span>  # 返回网页\n        <span class=\"token keyword\">if</span> event<span class=\"token punctuation\">[</span><span class=\"token string\">'httpMethod'</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">==</span> <span class=\"token string\">'POST'</span><span class=\"token punctuation\">:</span>  # 添加信件\n            body <span class=\"token operator\">=</span> json<span class=\"token punctuation\">.</span><span class=\"token function\">loads</span><span class=\"token punctuation\">(</span>event<span class=\"token punctuation\">[</span><span class=\"token string\">'body'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span>\n            flag <span class=\"token operator\">=</span> <span class=\"token function\">addletter</span><span class=\"token punctuation\">(</span>body<span class=\"token punctuation\">[</span><span class=\"token string\">'date'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> body<span class=\"token punctuation\">[</span><span class=\"token string\">'email'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> body<span class=\"token punctuation\">[</span><span class=\"token string\">'letter'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span>\n            <span class=\"token keyword\">return</span> <span class=\"token function\">apiReply</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n                <span class=\"token string\">'ok'</span><span class=\"token punctuation\">:</span> True <span class=\"token keyword\">if</span> flag <span class=\"token keyword\">else</span> False<span class=\"token punctuation\">,</span>\n                <span class=\"token string\">'message'</span><span class=\"token punctuation\">:</span> <span class=\"token string\">'添加成功'</span> <span class=\"token keyword\">if</span> flag <span class=\"token keyword\">else</span> <span class=\"token string\">'添加失败'</span>\n            <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">return</span> <span class=\"token function\">apiReply</span><span class=\"token punctuation\">(</span><span class=\"token string\">''</span><span class=\"token punctuation\">,</span> html<span class=\"token operator\">=</span>True<span class=\"token punctuation\">)</span></code></pre></div>\n<p>没错，这就是前面展示的网页应用的全部源码了，使用云函数 SCF 构建一个完整的前后端的全栈应用就是这么简单。</p>\n<p>代码可能有点长，其实也没多少知识点，下面咱们再一起捋一下这个云函数 ~</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"8864945092382892000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"代码复制成功\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`import json\nimport datetime\nimport random\nfrom email.mime.text import MIMEText\nfrom email.header import Header\nimport smtplib\n\n# 是否开启本地debug模式\ndebug = False\n\n# 腾讯云对象存储依赖\nif debug:\n    from qcloud_cos import CosConfig\n    from qcloud_cos import CosS3Client\n    from qcloud_cos import CosServiceError\n    from qcloud_cos import CosClientError\nelse:\n    from qcloud_cos_v5 import CosConfig\n    from qcloud_cos_v5 import CosS3Client\n    from qcloud_cos_v5 import CosServiceError\n    from qcloud_cos_v5 import CosClientError`, `8864945092382892000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                复制代码<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">import</span> json\n<span class=\"token keyword\">import</span> datetime\n<span class=\"token keyword\">import</span> random\n<span class=\"token keyword\">from</span> email<span class=\"token punctuation\">.</span>mime<span class=\"token punctuation\">.</span>text <span class=\"token keyword\">import</span> MIMEText\n<span class=\"token keyword\">from</span> email<span class=\"token punctuation\">.</span>header <span class=\"token keyword\">import</span> Header\n<span class=\"token keyword\">import</span> smtplib\n\n# 是否开启本地debug模式\ndebug <span class=\"token operator\">=</span> False\n\n# 腾讯云对象存储依赖\n<span class=\"token keyword\">if</span> debug<span class=\"token punctuation\">:</span>\n    <span class=\"token keyword\">from</span> qcloud_cos <span class=\"token keyword\">import</span> CosConfig\n    <span class=\"token keyword\">from</span> qcloud_cos <span class=\"token keyword\">import</span> CosS3Client\n    <span class=\"token keyword\">from</span> qcloud_cos <span class=\"token keyword\">import</span> CosServiceError\n    <span class=\"token keyword\">from</span> qcloud_cos <span class=\"token keyword\">import</span> CosClientError\n<span class=\"token keyword\">else</span><span class=\"token punctuation\">:</span>\n    <span class=\"token keyword\">from</span> qcloud_cos_v5 <span class=\"token keyword\">import</span> CosConfig\n    <span class=\"token keyword\">from</span> qcloud_cos_v5 <span class=\"token keyword\">import</span> CosS3Client\n    <span class=\"token keyword\">from</span> qcloud_cos_v5 <span class=\"token keyword\">import</span> CosServiceError\n    <span class=\"token keyword\">from</span> qcloud_cos_v5 <span class=\"token keyword\">import</span> CosClientError</code></pre></div>\n<p>首先是依赖的导入，这里主要导入了 python 自带的 email 模块和腾讯云对象存储 SDK，来实现信件的发送和后端存储需求。</p>\n<p>这里需要注意一点，在腾讯云的云函数在线运行环境中，已经安装了 <code class=\"language-text\">qcloud\\_cos\\_v5</code> 对象存储 SDK，而我在本地环境安装的对象存储 SDK 是 <code class=\"language-text\">qcloud\\_cos</code>，为了方便本地调试，这里我设置了一个 debug 开关，来动态导入 <code class=\"language-text\">qcloud\\_cos</code> 依赖，这一点我在之前的系列文章<a href=\"https://cloud.tencent.com/developer/article/1612750?from=10680\">《万物皆可Serverless之使用SCF+COS快速开发全栈应用》</a>中有讲到。</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"53775926099228254000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"代码复制成功\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`# 配置存储桶\nappid = '66666666666'\nsecret_id = 'xxxxxxxxxxxxxxx'\nsecret_key = 'xxxxxxxxxxxxxxx'\nregion = 'ap-chongqing'\nbucket = 'name'+'-'+appid\n\n#配置发件邮箱\nmail_host = &quot;smtp.163.com&quot;\nmail_user = &quot;xxxxxxxxxx@163.com&quot;\nmail_pass = &quot;xxxxxxxxxxxxxx&quot;\nmail_port = 465`, `53775926099228254000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                复制代码<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"># 配置存储桶\nappid <span class=\"token operator\">=</span> <span class=\"token string\">'66666666666'</span>\nsecret_id <span class=\"token operator\">=</span> <span class=\"token string\">'xxxxxxxxxxxxxxx'</span>\nsecret_key <span class=\"token operator\">=</span> <span class=\"token string\">'xxxxxxxxxxxxxxx'</span>\nregion <span class=\"token operator\">=</span> <span class=\"token string\">'ap-chongqing'</span>\nbucket <span class=\"token operator\">=</span> <span class=\"token string\">'name'</span><span class=\"token operator\">+</span><span class=\"token string\">'-'</span><span class=\"token operator\">+</span>appid\n\n#配置发件邮箱\nmail_host <span class=\"token operator\">=</span> <span class=\"token string\">\"smtp.163.com\"</span>\nmail_user <span class=\"token operator\">=</span> <span class=\"token string\">\"xxxxxxxxxx@163.com\"</span>\nmail_pass <span class=\"token operator\">=</span> <span class=\"token string\">\"xxxxxxxxxxxxxx\"</span>\nmail_port <span class=\"token operator\">=</span> <span class=\"token number\">465</span></code></pre></div>\n<p>然后配置一下自己的邮箱信息和腾讯云对象存储桶信息</p>\n<p>配置完成之后，我们再来看一下云函数的入口函数 main_handler(event, context)</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"72204128324494524000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"代码复制成功\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`def main_handler(event, context):\n    if 'Time' in event.keys():  # 来自定时触发器\n        check_send_letters()\n        return\n    if 'httpMethod' in event.keys():  # 来自api网关触发器\n        if event['httpMethod'] == 'GET':\n            return apiReply('', html=True)  # 返回网页\n        if event['httpMethod'] == 'POST':  # 添加信件\n            body = json.loads(event['body'])\n            flag = addletter(body['date'], body['email'], body['letter'])\n            return apiReply({\n                'ok': True if flag else False,\n                'message': '添加成功' if flag else '添加失败'\n            })\n    return apiReply('', html=True)`, `72204128324494524000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                复制代码<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\">def <span class=\"token function\">main_handler</span><span class=\"token punctuation\">(</span>event<span class=\"token punctuation\">,</span> context<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    <span class=\"token keyword\">if</span> <span class=\"token string\">'Time'</span> <span class=\"token keyword\">in</span> event<span class=\"token punctuation\">.</span><span class=\"token function\">keys</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>  # 来自定时触发器\n        <span class=\"token function\">check_send_letters</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">return</span>\n    <span class=\"token keyword\">if</span> <span class=\"token string\">'httpMethod'</span> <span class=\"token keyword\">in</span> event<span class=\"token punctuation\">.</span><span class=\"token function\">keys</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>  # 来自api网关触发器\n        <span class=\"token keyword\">if</span> event<span class=\"token punctuation\">[</span><span class=\"token string\">'httpMethod'</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">==</span> <span class=\"token string\">'GET'</span><span class=\"token punctuation\">:</span>\n            <span class=\"token keyword\">return</span> <span class=\"token function\">apiReply</span><span class=\"token punctuation\">(</span><span class=\"token string\">''</span><span class=\"token punctuation\">,</span> html<span class=\"token operator\">=</span>True<span class=\"token punctuation\">)</span>  # 返回网页\n        <span class=\"token keyword\">if</span> event<span class=\"token punctuation\">[</span><span class=\"token string\">'httpMethod'</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">==</span> <span class=\"token string\">'POST'</span><span class=\"token punctuation\">:</span>  # 添加信件\n            body <span class=\"token operator\">=</span> json<span class=\"token punctuation\">.</span><span class=\"token function\">loads</span><span class=\"token punctuation\">(</span>event<span class=\"token punctuation\">[</span><span class=\"token string\">'body'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span>\n            flag <span class=\"token operator\">=</span> <span class=\"token function\">addletter</span><span class=\"token punctuation\">(</span>body<span class=\"token punctuation\">[</span><span class=\"token string\">'date'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> body<span class=\"token punctuation\">[</span><span class=\"token string\">'email'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> body<span class=\"token punctuation\">[</span><span class=\"token string\">'letter'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span>\n            <span class=\"token keyword\">return</span> <span class=\"token function\">apiReply</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n                <span class=\"token string\">'ok'</span><span class=\"token punctuation\">:</span> True <span class=\"token keyword\">if</span> flag <span class=\"token keyword\">else</span> False<span class=\"token punctuation\">,</span>\n                <span class=\"token string\">'message'</span><span class=\"token punctuation\">:</span> <span class=\"token string\">'添加成功'</span> <span class=\"token keyword\">if</span> flag <span class=\"token keyword\">else</span> <span class=\"token string\">'添加失败'</span>\n            <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">return</span> <span class=\"token function\">apiReply</span><span class=\"token punctuation\">(</span><span class=\"token string\">''</span><span class=\"token punctuation\">,</span> html<span class=\"token operator\">=</span>True<span class=\"token punctuation\">)</span></code></pre></div>\n<p>这里我们根据event的keys里有无'Time'来判断云函数是否是通过定时器来触发的，</p>\n<p>这一点我在之前的系列文章<a href=\"https://serverlesscloud.cn/blog/2020-04-23-serverless-scf-cos/\">《万物皆可 Serverless 之使用 SCF+COS 快速开发全栈应用》</a>中有讲到。</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"85777410972264120000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"代码复制成功\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`#每天定时检查需要发送的信件\ndef check_send_letters():\n    loginEmail()\n    letters = getletters()\n    for date in letters.keys():\n        if checkDate(date):\n            sendEmail(letters[date])`, `85777410972264120000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                复制代码<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\">#每天定时检查需要发送的信件\ndef <span class=\"token function\">check_send_letters</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    <span class=\"token function\">loginEmail</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    letters <span class=\"token operator\">=</span> <span class=\"token function\">getletters</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">for</span> date <span class=\"token keyword\">in</span> letters<span class=\"token punctuation\">.</span><span class=\"token function\">keys</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">if</span> <span class=\"token function\">checkDate</span><span class=\"token punctuation\">(</span>date<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n            <span class=\"token function\">sendEmail</span><span class=\"token punctuation\">(</span>letters<span class=\"token punctuation\">[</span>date<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>检查云函数是否是通过定时器触发，是因为在后面我们会给这个云函数添加定时触发器来每天定时检查需要发送的信件。</p>\n<p>这里的 <code class=\"language-text\">check\\_send\\_letters</code> 函数的作用就是登录我们的邮箱并读取在 cos 中的所有信件，然后逐封检查信件的发信日期，如果信件发信日期与当前的日期相符，就会向指定的邮箱发送信件，完成在指定日期投放信件的功能。</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"16664625914965580000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"代码复制成功\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`if event['httpMethod'] == 'GET':\n    return apiReply('', html=True)  # 返回网页\nif event['httpMethod'] == 'POST':  # 添加信件\n    body = json.loads(event['body'])\n    flag = addletter(body['date'], body['email'], body['letter'])\n    return apiReply({\n         'ok': True if flag else False,\n         'message': '添加成功' if flag else '添加失败'\n    })`, `16664625914965580000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                复制代码<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">if</span> event<span class=\"token punctuation\">[</span><span class=\"token string\">'httpMethod'</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">==</span> <span class=\"token string\">'GET'</span><span class=\"token punctuation\">:</span>\n    <span class=\"token keyword\">return</span> <span class=\"token function\">apiReply</span><span class=\"token punctuation\">(</span><span class=\"token string\">''</span><span class=\"token punctuation\">,</span> html<span class=\"token operator\">=</span>True<span class=\"token punctuation\">)</span>  # 返回网页\n<span class=\"token keyword\">if</span> event<span class=\"token punctuation\">[</span><span class=\"token string\">'httpMethod'</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">==</span> <span class=\"token string\">'POST'</span><span class=\"token punctuation\">:</span>  # 添加信件\n    body <span class=\"token operator\">=</span> json<span class=\"token punctuation\">.</span><span class=\"token function\">loads</span><span class=\"token punctuation\">(</span>event<span class=\"token punctuation\">[</span><span class=\"token string\">'body'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span>\n    flag <span class=\"token operator\">=</span> <span class=\"token function\">addletter</span><span class=\"token punctuation\">(</span>body<span class=\"token punctuation\">[</span><span class=\"token string\">'date'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> body<span class=\"token punctuation\">[</span><span class=\"token string\">'email'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> body<span class=\"token punctuation\">[</span><span class=\"token string\">'letter'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">return</span> <span class=\"token function\">apiReply</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n         <span class=\"token string\">'ok'</span><span class=\"token punctuation\">:</span> True <span class=\"token keyword\">if</span> flag <span class=\"token keyword\">else</span> False<span class=\"token punctuation\">,</span>\n         <span class=\"token string\">'message'</span><span class=\"token punctuation\">:</span> <span class=\"token string\">'添加成功'</span> <span class=\"token keyword\">if</span> flag <span class=\"token keyword\">else</span> <span class=\"token string\">'添加失败'</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>如果我们的云函数是通过 api 网关触发的话，就判断一下 http 请求的方法是 GET 还是 POST</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"37878168219919030000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"代码复制成功\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`<!DOCTYPE html>\n<html lang=&quot;zh-cn&quot;>\n\n<head>\n    <meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=utf-8&quot; />\n    <meta name=&quot;viewport&quot; content=&quot;width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0&quot;>\n    <title>给未来的自己写封信</title>\n    <style>\n        html,\n        body {\n            padding: 0px;\n            margin: 0px;\n            height: 100vh;\n        }\n\n        .main {\n            display: flex;\n            flex-direction: column;\n            justify-content: center;\n            align-items: center;\n        }\n\n        .main_phone {\n            display: flex;\n            flex-direction: column;\n            justify-content: start;\n            align-items: center;\n        }\n    </style>\n</head>\n\n<body id='body'>\n    <div class=&quot;main&quot; style=&quot;width: 80vw;&quot;>\n        <div style=&quot;height: 5vh;&quot;></div>\n        <div id='letter_top'>\n            <p style=&quot;text-align: center;&quot;>开始写信</p>\n            <wired-textarea id=&quot;letter&quot; style=&quot;height: 320px;width: 300px;&quot; placeholder=&quot;此刻平静地写下一封信,给未来的自己一份温暖...&quot; elevation=&quot;6&quot; rows=&quot;14&quot;></wired-textarea>\n        </div>\n        <div style=&quot;display: flex;align-items: center;justify-content: center;&quot;>\n            <div id='letter_left'>\n                <p style=&quot;text-align: center;&quot;>开始写信</p>\n                <wired-textarea id=&quot;letter&quot; style=&quot;height: 320px;width: 300px;&quot; placeholder=&quot;此刻平静地写下一封信,给未来的自己一份温暖...&quot; elevation=&quot;6&quot; rows=&quot;14&quot;></wired-textarea>\n            </div>\n            <div style=&quot;width: 16px;&quot;></div>\n            <div>\n                <p style=&quot;text-align: center;&quot;>送信日期</p>\n                <wired-calendar id=&quot;calendar&quot;></wired-calendar>\n            </div>\n        </div>\n        <wired-divider style=&quot;margin: 16px 0;&quot;></wired-divider>\n        <p id=&quot;hitokoto&quot;></p>\n        <div>\n            <wired-input id=&quot;email&quot; placeholder=&quot;收件邮箱&quot;></wired-input>\n            <wired-button onclick=&quot;send()&quot;>投递</wired-button>\n        </div>\n        <div style=&quot;height: 5vh;&quot;></div>\n    </div>\n    <script>\n        let datex = '';\n        let myEmail = document.getElementById('email');\n        let myLetter = document.getElementById('letter');\n        let myCalendar = document.getElementById('calendar');\n\n        let width =\n            window.innerWidth ||\n            document.documentElement.clientWidth ||\n            document.body.clientWidth\n\n        let height =\n            window.innerHeight ||\n            document.documentElement.clientHeight ||\n            document.body.clientHeight\n\n        let pc = width >= height\n\n        let today = new Date();\n        let info = today.toString().split(' ');\n        let selected = \\`\\${info[1]} \\${today.getDate()}, \\${today.getFullYear()}\\`;\n\n        document.getElementById('body').classList.add(pc ? 'main' : 'main_phone');\n        document.getElementById('letter_left').style.display = pc ? 'block' : 'none';\n        document.getElementById('letter_top').style.display = pc ? 'none' : 'block';\n        myCalendar.setAttribute(&quot;selected&quot;, selected);\n        myCalendar.addEventListener('selected', () => {\n            let selectedObject = myCalendar.value;\n            let date = new Date(new Date().setDate(selectedObject.date.getDate()));\n            datex = date.toISOString().substr(0, 10);\n        });\n\n        function send() {\n            if (datex.length < 1 || myEmail.value.length < 1 || myLetter.value.length < 1) {\n                alert('信件内容、送信日期或投递邮箱不能为空');\n                return;\n            }\n            fetch(window.location.href, {\n                    method: 'POST',\n                    body: JSON.stringify({\n                        date: datex,\n                        email: myEmail.value,\n                        letter: myLetter.value\n                    })\n                }).then(res => res.json())\n                .catch(error => console.error('Error:', error))\n                .then(response => alert(response.ok ? '添加成功:)' : '添加失败:('));\n        }\n    </script>\n    <script src=&quot;https://v1.hitokoto.cn/?encode=js&select=%23hitokoto&quot; defer></script>\n    <script src=&quot;https://unpkg.com/wired-elements@2.0.5/lib/wired-elements-bundled.js &quot;></script>\n</body>\n\n</html>`, `37878168219919030000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                复制代码<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token operator\">&lt;</span><span class=\"token operator\">!</span><span class=\"token constant\">DOCTYPE</span> html<span class=\"token operator\">></span>\n<span class=\"token operator\">&lt;</span>html lang<span class=\"token operator\">=</span><span class=\"token string\">\"zh-cn\"</span><span class=\"token operator\">></span>\n\n<span class=\"token operator\">&lt;</span>head<span class=\"token operator\">></span>\n    <span class=\"token operator\">&lt;</span>meta http<span class=\"token operator\">-</span>equiv<span class=\"token operator\">=</span><span class=\"token string\">\"Content-Type\"</span> content<span class=\"token operator\">=</span><span class=\"token string\">\"text/html; charset=utf-8\"</span> <span class=\"token operator\">/</span><span class=\"token operator\">></span>\n    <span class=\"token operator\">&lt;</span>meta name<span class=\"token operator\">=</span><span class=\"token string\">\"viewport\"</span> content<span class=\"token operator\">=</span><span class=\"token string\">\"width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0\"</span><span class=\"token operator\">></span>\n    <span class=\"token operator\">&lt;</span>title<span class=\"token operator\">></span>给未来的自己写封信<span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>title<span class=\"token operator\">></span>\n    <span class=\"token operator\">&lt;</span>style<span class=\"token operator\">></span>\n        html<span class=\"token punctuation\">,</span>\n        body <span class=\"token punctuation\">{</span>\n            padding<span class=\"token punctuation\">:</span> <span class=\"token number\">0</span>px<span class=\"token punctuation\">;</span>\n            margin<span class=\"token punctuation\">:</span> <span class=\"token number\">0</span>px<span class=\"token punctuation\">;</span>\n            height<span class=\"token punctuation\">:</span> <span class=\"token number\">100</span>vh<span class=\"token punctuation\">;</span>\n        <span class=\"token punctuation\">}</span>\n\n        <span class=\"token punctuation\">.</span>main <span class=\"token punctuation\">{</span>\n            display<span class=\"token punctuation\">:</span> flex<span class=\"token punctuation\">;</span>\n            flex<span class=\"token operator\">-</span>direction<span class=\"token punctuation\">:</span> column<span class=\"token punctuation\">;</span>\n            justify<span class=\"token operator\">-</span>content<span class=\"token punctuation\">:</span> center<span class=\"token punctuation\">;</span>\n            align<span class=\"token operator\">-</span>items<span class=\"token punctuation\">:</span> center<span class=\"token punctuation\">;</span>\n        <span class=\"token punctuation\">}</span>\n\n        <span class=\"token punctuation\">.</span>main_phone <span class=\"token punctuation\">{</span>\n            display<span class=\"token punctuation\">:</span> flex<span class=\"token punctuation\">;</span>\n            flex<span class=\"token operator\">-</span>direction<span class=\"token punctuation\">:</span> column<span class=\"token punctuation\">;</span>\n            justify<span class=\"token operator\">-</span>content<span class=\"token punctuation\">:</span> start<span class=\"token punctuation\">;</span>\n            align<span class=\"token operator\">-</span>items<span class=\"token punctuation\">:</span> center<span class=\"token punctuation\">;</span>\n        <span class=\"token punctuation\">}</span>\n    <span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>style<span class=\"token operator\">></span>\n<span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>head<span class=\"token operator\">></span>\n\n<span class=\"token operator\">&lt;</span>body id<span class=\"token operator\">=</span><span class=\"token string\">'body'</span><span class=\"token operator\">></span>\n    <span class=\"token operator\">&lt;</span>div <span class=\"token keyword\">class</span><span class=\"token operator\">=</span><span class=\"token string\">\"main\"</span> style<span class=\"token operator\">=</span><span class=\"token string\">\"width: 80vw;\"</span><span class=\"token operator\">></span>\n        <span class=\"token operator\">&lt;</span>div style<span class=\"token operator\">=</span><span class=\"token string\">\"height: 5vh;\"</span><span class=\"token operator\">></span><span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>div<span class=\"token operator\">></span>\n        <span class=\"token operator\">&lt;</span>div id<span class=\"token operator\">=</span><span class=\"token string\">'letter_top'</span><span class=\"token operator\">></span>\n            <span class=\"token operator\">&lt;</span>p style<span class=\"token operator\">=</span><span class=\"token string\">\"text-align: center;\"</span><span class=\"token operator\">></span>开始写信<span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>p<span class=\"token operator\">></span>\n            <span class=\"token operator\">&lt;</span>wired<span class=\"token operator\">-</span>textarea id<span class=\"token operator\">=</span><span class=\"token string\">\"letter\"</span> style<span class=\"token operator\">=</span><span class=\"token string\">\"height: 320px;width: 300px;\"</span> placeholder<span class=\"token operator\">=</span><span class=\"token string\">\"此刻平静地写下一封信,给未来的自己一份温暖...\"</span> elevation<span class=\"token operator\">=</span><span class=\"token string\">\"6\"</span> rows<span class=\"token operator\">=</span><span class=\"token string\">\"14\"</span><span class=\"token operator\">></span><span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>wired<span class=\"token operator\">-</span>textarea<span class=\"token operator\">></span>\n        <span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>div<span class=\"token operator\">></span>\n        <span class=\"token operator\">&lt;</span>div style<span class=\"token operator\">=</span><span class=\"token string\">\"display: flex;align-items: center;justify-content: center;\"</span><span class=\"token operator\">></span>\n            <span class=\"token operator\">&lt;</span>div id<span class=\"token operator\">=</span><span class=\"token string\">'letter_left'</span><span class=\"token operator\">></span>\n                <span class=\"token operator\">&lt;</span>p style<span class=\"token operator\">=</span><span class=\"token string\">\"text-align: center;\"</span><span class=\"token operator\">></span>开始写信<span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>p<span class=\"token operator\">></span>\n                <span class=\"token operator\">&lt;</span>wired<span class=\"token operator\">-</span>textarea id<span class=\"token operator\">=</span><span class=\"token string\">\"letter\"</span> style<span class=\"token operator\">=</span><span class=\"token string\">\"height: 320px;width: 300px;\"</span> placeholder<span class=\"token operator\">=</span><span class=\"token string\">\"此刻平静地写下一封信,给未来的自己一份温暖...\"</span> elevation<span class=\"token operator\">=</span><span class=\"token string\">\"6\"</span> rows<span class=\"token operator\">=</span><span class=\"token string\">\"14\"</span><span class=\"token operator\">></span><span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>wired<span class=\"token operator\">-</span>textarea<span class=\"token operator\">></span>\n            <span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>div<span class=\"token operator\">></span>\n            <span class=\"token operator\">&lt;</span>div style<span class=\"token operator\">=</span><span class=\"token string\">\"width: 16px;\"</span><span class=\"token operator\">></span><span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>div<span class=\"token operator\">></span>\n            <span class=\"token operator\">&lt;</span>div<span class=\"token operator\">></span>\n                <span class=\"token operator\">&lt;</span>p style<span class=\"token operator\">=</span><span class=\"token string\">\"text-align: center;\"</span><span class=\"token operator\">></span>送信日期<span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>p<span class=\"token operator\">></span>\n                <span class=\"token operator\">&lt;</span>wired<span class=\"token operator\">-</span>calendar id<span class=\"token operator\">=</span><span class=\"token string\">\"calendar\"</span><span class=\"token operator\">></span><span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>wired<span class=\"token operator\">-</span>calendar<span class=\"token operator\">></span>\n            <span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>div<span class=\"token operator\">></span>\n        <span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>div<span class=\"token operator\">></span>\n        <span class=\"token operator\">&lt;</span>wired<span class=\"token operator\">-</span>divider style<span class=\"token operator\">=</span><span class=\"token string\">\"margin: 16px 0;\"</span><span class=\"token operator\">></span><span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>wired<span class=\"token operator\">-</span>divider<span class=\"token operator\">></span>\n        <span class=\"token operator\">&lt;</span>p id<span class=\"token operator\">=</span><span class=\"token string\">\"hitokoto\"</span><span class=\"token operator\">></span><span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>p<span class=\"token operator\">></span>\n        <span class=\"token operator\">&lt;</span>div<span class=\"token operator\">></span>\n            <span class=\"token operator\">&lt;</span>wired<span class=\"token operator\">-</span>input id<span class=\"token operator\">=</span><span class=\"token string\">\"email\"</span> placeholder<span class=\"token operator\">=</span><span class=\"token string\">\"收件邮箱\"</span><span class=\"token operator\">></span><span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>wired<span class=\"token operator\">-</span>input<span class=\"token operator\">></span>\n            <span class=\"token operator\">&lt;</span>wired<span class=\"token operator\">-</span>button onclick<span class=\"token operator\">=</span><span class=\"token string\">\"send()\"</span><span class=\"token operator\">></span>投递<span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>wired<span class=\"token operator\">-</span>button<span class=\"token operator\">></span>\n        <span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>div<span class=\"token operator\">></span>\n        <span class=\"token operator\">&lt;</span>div style<span class=\"token operator\">=</span><span class=\"token string\">\"height: 5vh;\"</span><span class=\"token operator\">></span><span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>div<span class=\"token operator\">></span>\n    <span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>div<span class=\"token operator\">></span>\n    <span class=\"token operator\">&lt;</span>script<span class=\"token operator\">></span>\n        <span class=\"token keyword\">let</span> datex <span class=\"token operator\">=</span> <span class=\"token string\">''</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">let</span> myEmail <span class=\"token operator\">=</span> document<span class=\"token punctuation\">.</span><span class=\"token function\">getElementById</span><span class=\"token punctuation\">(</span><span class=\"token string\">'email'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">let</span> myLetter <span class=\"token operator\">=</span> document<span class=\"token punctuation\">.</span><span class=\"token function\">getElementById</span><span class=\"token punctuation\">(</span><span class=\"token string\">'letter'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">let</span> myCalendar <span class=\"token operator\">=</span> document<span class=\"token punctuation\">.</span><span class=\"token function\">getElementById</span><span class=\"token punctuation\">(</span><span class=\"token string\">'calendar'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n        <span class=\"token keyword\">let</span> width <span class=\"token operator\">=</span>\n            window<span class=\"token punctuation\">.</span>innerWidth <span class=\"token operator\">||</span>\n            document<span class=\"token punctuation\">.</span>documentElement<span class=\"token punctuation\">.</span>clientWidth <span class=\"token operator\">||</span>\n            document<span class=\"token punctuation\">.</span>body<span class=\"token punctuation\">.</span>clientWidth\n\n        <span class=\"token keyword\">let</span> height <span class=\"token operator\">=</span>\n            window<span class=\"token punctuation\">.</span>innerHeight <span class=\"token operator\">||</span>\n            document<span class=\"token punctuation\">.</span>documentElement<span class=\"token punctuation\">.</span>clientHeight <span class=\"token operator\">||</span>\n            document<span class=\"token punctuation\">.</span>body<span class=\"token punctuation\">.</span>clientHeight\n\n        <span class=\"token keyword\">let</span> pc <span class=\"token operator\">=</span> width <span class=\"token operator\">>=</span> height\n\n        <span class=\"token keyword\">let</span> today <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Date</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">let</span> info <span class=\"token operator\">=</span> today<span class=\"token punctuation\">.</span><span class=\"token function\">toString</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">split</span><span class=\"token punctuation\">(</span><span class=\"token string\">' '</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">let</span> selected <span class=\"token operator\">=</span> <span class=\"token template-string\"><span class=\"token template-punctuation string\">`</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span>info<span class=\"token punctuation\">[</span><span class=\"token number\">1</span><span class=\"token punctuation\">]</span><span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token string\"> </span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span>today<span class=\"token punctuation\">.</span><span class=\"token function\">getDate</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token string\">, </span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span>today<span class=\"token punctuation\">.</span><span class=\"token function\">getFullYear</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token template-punctuation string\">`</span></span><span class=\"token punctuation\">;</span>\n\n        document<span class=\"token punctuation\">.</span><span class=\"token function\">getElementById</span><span class=\"token punctuation\">(</span><span class=\"token string\">'body'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>classList<span class=\"token punctuation\">.</span><span class=\"token function\">add</span><span class=\"token punctuation\">(</span>pc <span class=\"token operator\">?</span> <span class=\"token string\">'main'</span> <span class=\"token punctuation\">:</span> <span class=\"token string\">'main_phone'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        document<span class=\"token punctuation\">.</span><span class=\"token function\">getElementById</span><span class=\"token punctuation\">(</span><span class=\"token string\">'letter_left'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>style<span class=\"token punctuation\">.</span>display <span class=\"token operator\">=</span> pc <span class=\"token operator\">?</span> <span class=\"token string\">'block'</span> <span class=\"token punctuation\">:</span> <span class=\"token string\">'none'</span><span class=\"token punctuation\">;</span>\n        document<span class=\"token punctuation\">.</span><span class=\"token function\">getElementById</span><span class=\"token punctuation\">(</span><span class=\"token string\">'letter_top'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>style<span class=\"token punctuation\">.</span>display <span class=\"token operator\">=</span> pc <span class=\"token operator\">?</span> <span class=\"token string\">'none'</span> <span class=\"token punctuation\">:</span> <span class=\"token string\">'block'</span><span class=\"token punctuation\">;</span>\n        myCalendar<span class=\"token punctuation\">.</span><span class=\"token function\">setAttribute</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"selected\"</span><span class=\"token punctuation\">,</span> selected<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        myCalendar<span class=\"token punctuation\">.</span><span class=\"token function\">addEventListener</span><span class=\"token punctuation\">(</span><span class=\"token string\">'selected'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n            <span class=\"token keyword\">let</span> selectedObject <span class=\"token operator\">=</span> myCalendar<span class=\"token punctuation\">.</span>value<span class=\"token punctuation\">;</span>\n            <span class=\"token keyword\">let</span> date <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Date</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">new</span> <span class=\"token class-name\">Date</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">setDate</span><span class=\"token punctuation\">(</span>selectedObject<span class=\"token punctuation\">.</span>date<span class=\"token punctuation\">.</span><span class=\"token function\">getDate</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n            datex <span class=\"token operator\">=</span> date<span class=\"token punctuation\">.</span><span class=\"token function\">toISOString</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">substr</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">,</span> <span class=\"token number\">10</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n        <span class=\"token keyword\">function</span> <span class=\"token function\">send</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n            <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>datex<span class=\"token punctuation\">.</span>length <span class=\"token operator\">&lt;</span> <span class=\"token number\">1</span> <span class=\"token operator\">||</span> myEmail<span class=\"token punctuation\">.</span>value<span class=\"token punctuation\">.</span>length <span class=\"token operator\">&lt;</span> <span class=\"token number\">1</span> <span class=\"token operator\">||</span> myLetter<span class=\"token punctuation\">.</span>value<span class=\"token punctuation\">.</span>length <span class=\"token operator\">&lt;</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n                <span class=\"token function\">alert</span><span class=\"token punctuation\">(</span><span class=\"token string\">'信件内容、送信日期或投递邮箱不能为空'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n                <span class=\"token keyword\">return</span><span class=\"token punctuation\">;</span>\n            <span class=\"token punctuation\">}</span>\n            <span class=\"token function\">fetch</span><span class=\"token punctuation\">(</span>window<span class=\"token punctuation\">.</span>location<span class=\"token punctuation\">.</span>href<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span>\n                    method<span class=\"token punctuation\">:</span> <span class=\"token string\">'POST'</span><span class=\"token punctuation\">,</span>\n                    body<span class=\"token punctuation\">:</span> <span class=\"token constant\">JSON</span><span class=\"token punctuation\">.</span><span class=\"token function\">stringify</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n                        date<span class=\"token punctuation\">:</span> datex<span class=\"token punctuation\">,</span>\n                        email<span class=\"token punctuation\">:</span> myEmail<span class=\"token punctuation\">.</span>value<span class=\"token punctuation\">,</span>\n                        letter<span class=\"token punctuation\">:</span> myLetter<span class=\"token punctuation\">.</span>value\n                    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n                <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">then</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">res</span> <span class=\"token operator\">=></span> res<span class=\"token punctuation\">.</span><span class=\"token function\">json</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n                <span class=\"token punctuation\">.</span><span class=\"token function\">catch</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">error</span> <span class=\"token operator\">=></span> console<span class=\"token punctuation\">.</span><span class=\"token function\">error</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Error:'</span><span class=\"token punctuation\">,</span> error<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n                <span class=\"token punctuation\">.</span><span class=\"token function\">then</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">response</span> <span class=\"token operator\">=></span> <span class=\"token function\">alert</span><span class=\"token punctuation\">(</span>response<span class=\"token punctuation\">.</span>ok <span class=\"token operator\">?</span> <span class=\"token string\">'添加成功:)'</span> <span class=\"token punctuation\">:</span> <span class=\"token string\">'添加失败:('</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token punctuation\">}</span>\n    <span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>script<span class=\"token operator\">></span>\n    <span class=\"token operator\">&lt;</span>script src<span class=\"token operator\">=</span><span class=\"token string\">\"https://v1.hitokoto.cn/?encode=js&amp;select=%23hitokoto\"</span> defer<span class=\"token operator\">></span><span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>script<span class=\"token operator\">></span>\n    <span class=\"token operator\">&lt;</span>script src<span class=\"token operator\">=</span><span class=\"token string\">\"https://unpkg.com/wired-elements@2.0.5/lib/wired-elements-bundled.js \"</span><span class=\"token operator\">></span><span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>script<span class=\"token operator\">></span>\n<span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>body<span class=\"token operator\">></span>\n\n<span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>html<span class=\"token operator\">></span></code></pre></div>\n<p>如果是 GET 请求就返回上面的前端网页，也就是文章开头第一张图，再来瞅一眼</p>\n<p><img src=\"https://img.serverlesscloud.cn/2020523/1590215207162-16200.jpg\" alt=\"云函数返回的前端网页\"></p>\n<p>再来看下前端网页的发信过程</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"30584325188494787000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"代码复制成功\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`function send() {\n    if (datex.length < 1 || myEmail.value.length < 1 || myLetter.value.length < 1) {\n        alert('信件内容、送信日期或投递邮箱不能为空');\n        return;\n    }\n    fetch(window.location.href, {\n            method: 'POST',\n            body: JSON.stringify({\n                date: datex,\n                email: myEmail.value,\n                letter: myLetter.value\n            })\n        }).then(res => res.json())\n        .catch(error => console.error('Error:', error))\n        .then(response => alert(response.ok ? '添加成功:)' : '添加失败:('));\n}`, `30584325188494787000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                复制代码<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">function</span> <span class=\"token function\">send</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>datex<span class=\"token punctuation\">.</span>length <span class=\"token operator\">&lt;</span> <span class=\"token number\">1</span> <span class=\"token operator\">||</span> myEmail<span class=\"token punctuation\">.</span>value<span class=\"token punctuation\">.</span>length <span class=\"token operator\">&lt;</span> <span class=\"token number\">1</span> <span class=\"token operator\">||</span> myLetter<span class=\"token punctuation\">.</span>value<span class=\"token punctuation\">.</span>length <span class=\"token operator\">&lt;</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token function\">alert</span><span class=\"token punctuation\">(</span><span class=\"token string\">'信件内容、送信日期或投递邮箱不能为空'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">return</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n    <span class=\"token function\">fetch</span><span class=\"token punctuation\">(</span>window<span class=\"token punctuation\">.</span>location<span class=\"token punctuation\">.</span>href<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span>\n            method<span class=\"token punctuation\">:</span> <span class=\"token string\">'POST'</span><span class=\"token punctuation\">,</span>\n            body<span class=\"token punctuation\">:</span> <span class=\"token constant\">JSON</span><span class=\"token punctuation\">.</span><span class=\"token function\">stringify</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n                date<span class=\"token punctuation\">:</span> datex<span class=\"token punctuation\">,</span>\n                email<span class=\"token punctuation\">:</span> myEmail<span class=\"token punctuation\">.</span>value<span class=\"token punctuation\">,</span>\n                letter<span class=\"token punctuation\">:</span> myLetter<span class=\"token punctuation\">.</span>value\n            <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">then</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">res</span> <span class=\"token operator\">=></span> res<span class=\"token punctuation\">.</span><span class=\"token function\">json</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">.</span><span class=\"token function\">catch</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">error</span> <span class=\"token operator\">=></span> console<span class=\"token punctuation\">.</span><span class=\"token function\">error</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Error:'</span><span class=\"token punctuation\">,</span> error<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">.</span><span class=\"token function\">then</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">response</span> <span class=\"token operator\">=></span> <span class=\"token function\">alert</span><span class=\"token punctuation\">(</span>response<span class=\"token punctuation\">.</span>ok <span class=\"token operator\">?</span> <span class=\"token string\">'添加成功:)'</span> <span class=\"token punctuation\">:</span> <span class=\"token string\">'添加失败:('</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>这里我们是向当前网页地址，也是云函数的 api 网关地址 POST 了一个包含所有信件信息的 json 字符串</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"88983202475496360000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"代码复制成功\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`if event['httpMethod'] == 'POST':  # 添加信件\n    body = json.loads(event['body'])\n    flag = addletter(body['date'], body['email'], body['letter'])\n    return apiReply({\n         'ok': True if flag else False,\n         'message': '添加成功' if flag else '添加失败'\n    })`, `88983202475496360000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                复制代码<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">if</span> event<span class=\"token punctuation\">[</span><span class=\"token string\">'httpMethod'</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">==</span> <span class=\"token string\">'POST'</span><span class=\"token punctuation\">:</span>  # 添加信件\n    body <span class=\"token operator\">=</span> json<span class=\"token punctuation\">.</span><span class=\"token function\">loads</span><span class=\"token punctuation\">(</span>event<span class=\"token punctuation\">[</span><span class=\"token string\">'body'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span>\n    flag <span class=\"token operator\">=</span> <span class=\"token function\">addletter</span><span class=\"token punctuation\">(</span>body<span class=\"token punctuation\">[</span><span class=\"token string\">'date'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> body<span class=\"token punctuation\">[</span><span class=\"token string\">'email'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> body<span class=\"token punctuation\">[</span><span class=\"token string\">'letter'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">return</span> <span class=\"token function\">apiReply</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n         <span class=\"token string\">'ok'</span><span class=\"token punctuation\">:</span> True <span class=\"token keyword\">if</span> flag <span class=\"token keyword\">else</span> False<span class=\"token punctuation\">,</span>\n         <span class=\"token string\">'message'</span><span class=\"token punctuation\">:</span> <span class=\"token string\">'添加成功'</span> <span class=\"token keyword\">if</span> flag <span class=\"token keyword\">else</span> <span class=\"token string\">'添加失败'</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>回到云函数后端，我们在收到 POST 请求之后，在 event 里拿到 POST 的请求体，并重新将 json 字符串转成 map 对象，之后将 body 传给 addletter 函数，将信件信息保存到 cos 里，然后向网页前端回复信件是否添加成功。</p>\n<p>这样整个应用的前后端只用一个云函数就都实现了，是不是很酸爽呀( •̀ ω •́ )y~</p>\n<h3 id=\"第三步：配置云函数触发器\"><a href=\"#%E7%AC%AC%E4%B8%89%E6%AD%A5%EF%BC%9A%E9%85%8D%E7%BD%AE%E4%BA%91%E5%87%BD%E6%95%B0%E8%A7%A6%E5%8F%91%E5%99%A8\" aria-label=\"第三步：配置云函数触发器 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>第三步：配置云函数触发器</h3>\n<p>找到本地云函数文件夹下面的 <code class=\"language-text\">template.yaml</code> 配置文件</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"62592351698968060000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"代码复制成功\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`Resources:\n  default:\n    Type: 'TencentCloud::Serverless::Namespace'\n    letter:\n      Properties:\n        CodeUri: ./\n        Type: Event\n        Environment:\n          Variables:\n        Description: 给未来写封信云函数\n        Handler: index.main_handler\n        MemorySize: 64\n        Timeout: 3\n        Runtime: Python3.6\n        Events:\n          timer:\n            Type: Timer\n            Properties:\n              CronExpression: '0 0 8 * * * *'\n              Enable: True\n          letter_apigw:\n            Type: APIGW\n            Properties:\n              StageName: release\n              ServiceId:\n              HttpMethod: ANY\n      Type: 'TencentCloud::Serverless::Function'`, `62592351698968060000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                复制代码<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\">Resources<span class=\"token punctuation\">:</span>\n  <span class=\"token keyword\">default</span><span class=\"token punctuation\">:</span>\n    Type<span class=\"token punctuation\">:</span> <span class=\"token string\">'TencentCloud::Serverless::Namespace'</span>\n    letter<span class=\"token punctuation\">:</span>\n      Properties<span class=\"token punctuation\">:</span>\n        CodeUri<span class=\"token punctuation\">:</span> <span class=\"token punctuation\">.</span><span class=\"token operator\">/</span>\n        Type<span class=\"token punctuation\">:</span> Event\n        Environment<span class=\"token punctuation\">:</span>\n          Variables<span class=\"token punctuation\">:</span>\n        Description<span class=\"token punctuation\">:</span> 给未来写封信云函数\n        Handler<span class=\"token punctuation\">:</span> index<span class=\"token punctuation\">.</span>main_handler\n        MemorySize<span class=\"token punctuation\">:</span> <span class=\"token number\">64</span>\n        Timeout<span class=\"token punctuation\">:</span> <span class=\"token number\">3</span>\n        Runtime<span class=\"token punctuation\">:</span> Python3<span class=\"token punctuation\">.</span><span class=\"token number\">6</span>\n        Events<span class=\"token punctuation\">:</span>\n          timer<span class=\"token punctuation\">:</span>\n            Type<span class=\"token punctuation\">:</span> Timer\n            Properties<span class=\"token punctuation\">:</span>\n              CronExpression<span class=\"token punctuation\">:</span> <span class=\"token string\">'0 0 8 * * * *'</span>\n              Enable<span class=\"token punctuation\">:</span> True\n          letter_apigw<span class=\"token punctuation\">:</span>\n            Type<span class=\"token punctuation\">:</span> <span class=\"token constant\">APIGW</span>\n            Properties<span class=\"token punctuation\">:</span>\n              StageName<span class=\"token punctuation\">:</span> release\n              ServiceId<span class=\"token punctuation\">:</span>\n              HttpMethod<span class=\"token punctuation\">:</span> <span class=\"token constant\">ANY</span>\n      Type<span class=\"token punctuation\">:</span> <span class=\"token string\">'TencentCloud::Serverless::Function'</span></code></pre></div>\n<p>这里主要配置了一下云函数的名称，timer 触发器和 api 网关触发器，可以自行设置。</p>\n<h3 id=\"第四步：上线发布云函数，api-网关启用响应集成\"><a href=\"#%E7%AC%AC%E5%9B%9B%E6%AD%A5%EF%BC%9A%E4%B8%8A%E7%BA%BF%E5%8F%91%E5%B8%83%E4%BA%91%E5%87%BD%E6%95%B0%EF%BC%8Capi-%E7%BD%91%E5%85%B3%E5%90%AF%E7%94%A8%E5%93%8D%E5%BA%94%E9%9B%86%E6%88%90\" aria-label=\"第四步：上线发布云函数，api 网关启用响应集成 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>第四步：上线发布云函数，api 网关启用响应集成</h3>\n<p>参见我之前的系列文章<a href=\"https://serverlesscloud.cn/blog/2020-04-23-serverless-scf-cos/\">《万物皆可 Serverless 之使用 SCF+COS 快速开发全栈应用》</a></p>\n<h3 id=\"第五步：绑定备案域名\"><a href=\"#%E7%AC%AC%E4%BA%94%E6%AD%A5%EF%BC%9A%E7%BB%91%E5%AE%9A%E5%A4%87%E6%A1%88%E5%9F%9F%E5%90%8D\" aria-label=\"第五步：绑定备案域名 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>第五步：绑定备案域名</h3>\n<p>如果你有备案域名并且想给 api 网关自定义域名的话，可参考我之前的系列文章<a href=\"https://serverlesscloud.cn/blog/2020-04-23-serverless-cloud-cos/\">《万物皆可Serverless之免费搭建自己的不限速大容量云盘（5TB）》</a></p>\n<h2 id=\"写在最后\"><a href=\"#%E5%86%99%E5%9C%A8%E6%9C%80%E5%90%8E\" aria-label=\"写在最后 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>写在最后</h2>\n<p>OK，没啥问题的话现在你应该已经成功上线了自己的给未来写封信网页应用，或许你也可以趁热打铁，试着静下心来认真的给未来的自己留几句话呢？</p>\n<p>以上，我们可以总结出把一个简单的网页应用前后端都在一个云函数里来实现是完全没有问题的，而且极大缩短了我们应用开发的时间，非常的方便，还省去了购买配置和维护服务器的费用，让开发者可以真正将精力放到业务本身的开发上，这就是 Serverless 最大的魅力！</p>\n<hr>\n<div id='scf-deploy-iframe-or-md'></div>\n<hr>\n<blockquote>\n<p><strong>传送门：</strong></p>\n<ul>\n<li>GitHub: <a href=\"https://github.com/serverless/serverless/blob/master/README_CN.md\">github.com/serverless</a></li>\n<li>官网：<a href=\"https://serverless.com/\">serverless.com</a></li>\n</ul>\n</blockquote>\n<p>欢迎访问：<a href=\"https://serverlesscloud.cn/\">Serverless 中文网</a>，您可以在 <a href=\"https://serverlesscloud.cn/best-practice\">最佳实践</a> 里体验更多关于 Serverless 应用的开发！</p>","tableOfContents":"<ul>\n<li><a href=\"/blog/2020-04-13-Serverless-scf-cos-python/#%E6%95%88%E6%9E%9C%E5%B1%95%E7%A4%BA\">效果展示</a></li>\n<li>\n<p><a href=\"/blog/2020-04-13-Serverless-scf-cos-python/#%E6%93%8D%E4%BD%9C%E6%AD%A5%E9%AA%A4\">操作步骤</a></p>\n<ul>\n<li><a href=\"/blog/2020-04-13-Serverless-scf-cos-python/#%E7%AC%AC%E4%B8%80%E6%AD%A5%EF%BC%9A%E6%96%B0%E5%BB%BA-python-%E4%BA%91%E5%87%BD%E6%95%B0\">第一步：新建 python 云函数</a></li>\n<li><a href=\"/blog/2020-04-13-Serverless-scf-cos-python/#%E7%AC%AC%E4%BA%8C%E6%AD%A5%EF%BC%9A%E7%BC%96%E5%86%99%E4%BA%91%E5%87%BD%E6%95%B0\">第二步：编写云函数</a></li>\n<li><a href=\"/blog/2020-04-13-Serverless-scf-cos-python/#%E7%AC%AC%E4%B8%89%E6%AD%A5%EF%BC%9A%E9%85%8D%E7%BD%AE%E4%BA%91%E5%87%BD%E6%95%B0%E8%A7%A6%E5%8F%91%E5%99%A8\">第三步：配置云函数触发器</a></li>\n<li><a href=\"/blog/2020-04-13-Serverless-scf-cos-python/#%E7%AC%AC%E5%9B%9B%E6%AD%A5%EF%BC%9A%E4%B8%8A%E7%BA%BF%E5%8F%91%E5%B8%83%E4%BA%91%E5%87%BD%E6%95%B0%EF%BC%8Capi-%E7%BD%91%E5%85%B3%E5%90%AF%E7%94%A8%E5%93%8D%E5%BA%94%E9%9B%86%E6%88%90\">第四步：上线发布云函数，api 网关启用响应集成</a></li>\n<li><a href=\"/blog/2020-04-13-Serverless-scf-cos-python/#%E7%AC%AC%E4%BA%94%E6%AD%A5%EF%BC%9A%E7%BB%91%E5%AE%9A%E5%A4%87%E6%A1%88%E5%9F%9F%E5%90%8D\">第五步：绑定备案域名</a></li>\n</ul>\n</li>\n<li><a href=\"/blog/2020-04-13-Serverless-scf-cos-python/#%E5%86%99%E5%9C%A8%E6%9C%80%E5%90%8E\">写在最后</a></li>\n</ul>"},"previousBlog":{"id":"79bc5567-9ccc-59eb-a458-e9739df4471e","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/2020523/1590214222379-%E4%BC%81%E4%B8%9A%E5%BE%AE%E4%BF%A1%E6%88%AA%E5%9B%BE_159021417080.png","authors":["乂乂又又"],"categories":["user-stories"],"date":"2020-04-13T00:00:00.000Z","title":"万物皆可 Serverless 之借助微信公众号简单管理用户激活码","description":"本文尝试带大家使用无服务器云函数和对象存储，快速编写上线自己的用户激活码后端管理云函数，然后把自己的微信公众号后台做为应用前台，简单管理用户激活码。","authorslink":["https://cloud.tencent.com/developer/article/1618586"],"translators":null,"translatorslink":null,"tags":["Serverless","微信公众号"],"keywords":"Serverless,Serverless python,Serverless应用","outdated":null},"wordCount":{"words":102,"sentences":24,"paragraphs":24},"fileAbsolutePath":"/opt/build/repo/content/blog/2020-04-13-serverless-scf-wechat.md","fields":{"slug":"/blog/2020-04-13-serverless-scf-wechat/","keywords":["java","python","serverless","云函数","reply","vipMap","cos","激活码","requestParameters"]}},"nextBlog":{"id":"162777c7-987a-5278-92ac-9887c8dc30a7","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/202049/1586443473383-1586438917%281%29_%E5%89%AF%E6%9C%AC.jpg","authors":["serverless 社区"],"categories":["meetup"],"date":"2020-04-11T00:00:00.000Z","title":"前端基于 Serverless 的开发探索 | 直播课","description":"本次直播将深入讲解 Serverless 给前端带来的变革、前端 Serverless 的发展方向，以及开发者如何基于 Serverless 获得成长，创造收益！","authorslink":["https://serverlesscloud.cn"],"translators":null,"translatorslink":null,"tags":["Serverless","Meetup"],"keywords":"Serverless;Front-end;","outdated":null},"wordCount":{"words":78,"sentences":16,"paragraphs":16},"fileAbsolutePath":"/opt/build/repo/content/blog/2020-04-11-serverless-front-end-development.md","fields":{"slug":"/blog/2020-04-11-serverless-front-end-development/","keywords":["serverless","云函数","Serverless","serverless","腾讯","serverlesscloud"]}},"recommendBlogs":{"edges":[{"node":{"id":"4300b21c-7209-5256-86ff-0d38e3daec9b","frontmatter":{"thumbnail":"https://main.qcloudimg.com/raw/14f1c8eed372e76c1b139703b2f6d0fa.jpg","authors":["KieranMcCarthy"],"categories":["user-stories","engineering-culture"],"date":"2018-01-09T00:00:00.000Z","title":"我是如何在四年时间里，从厨师转行为 Serverless 应用开发者","description":"我是厨师出身，现在成为了一名 Serverless 应用开发者。","authorslink":["https://serverless.com/author/kieranmccarthy/"],"translators":["Aceyclee"],"translatorslink":["https://www.zhihu.com/people/Aceyclee"],"tags":["应用开发","Serverless"],"keywords":"Serverless 应用开发,Serverless 管理,厨师转行为 Serverless 应用开发者","outdated":null},"wordCount":{"words":285,"sentences":38,"paragraphs":36},"fileAbsolutePath":"/opt/build/repo/content/blog/2018-01-09-from-chef-to-serverless-developer-in-4-years.md","fields":{"slug":"/blog/2018-01-09-from-chef-to-serverless-developer-in-4-years/","keywords":["无服务器","无服务器开发","云函数","学习","Serverless","构建","Framework","开发者","服务器","应用","学位","简历"]}}},{"node":{"id":"713a0563-4bf9-5721-bacb-3b4ef609fe4a","frontmatter":{"thumbnail":"https://s3-us-west-2.amazonaws.com/assets.blog.serverless.com/camp-fire/camp-fire-housing-thumb.jpg","authors":["EricWyne"],"categories":["guides-and-tutorials","user-stories"],"date":"2018-12-05T00:00:00.000Z","title":"Serverless Twitter 机器人帮助为坎普山火受灾者安置住房","description":"加利福尼亚州的坎普山火致使数千人流离失所，为此，我构建了一个简单的 Serverless Twitter 机器人来帮助将受灾者安置在临时住房！","authorslink":["https://serverless.com/author/ericwyne/"],"translators":["Aceyclee"],"translatorslink":["zhihu.com/people/Aceyclee"],"tags":null,"keywords":null,"outdated":null},"wordCount":{"words":157,"sentences":26,"paragraphs":26},"fileAbsolutePath":"/opt/build/repo/content/blog/2018-12-05-serverless-twitter-camp-fire.md","fields":{"slug":"/blog/2018-12-05-serverless-twitter-camp-fire/","keywords":["serverless","无服务器","云函数","Serverless","org","住房","Twitter","函数","受灾","机器人","山火"]}}},{"node":{"id":"98602143-b837-5f50-a24f-3b1ec76044d7","frontmatter":{"thumbnail":"https://s3-us-west-2.amazonaws.com/assets.blog.serverless.com/sqquid/sqquid-serverless-thumb.jpg","authors":["RonPeled"],"categories":["user-stories"],"date":"2018-12-17T00:00:00.000Z","title":"SQQUID：100% 无服务器初创公司","description":"SQQUID 将 AWS Lambda 和无服务器框架用于其核心产品和营销网站。我们来看看一个完全无服务器的初创公司是怎样的。","authorslink":null,"translators":null,"translatorslink":null,"tags":null,"keywords":null,"outdated":null},"wordCount":{"words":266,"sentences":42,"paragraphs":42},"fileAbsolutePath":"/opt/build/repo/content/blog/2018-12-17-sqquid-one-hundred-percent-serverless.md","fields":{"slug":"/blog/2018-12-17-sqquid-one-hundred-percent-serverless/","keywords":["go","serverless","无服务器","无服务器架构","服务器","架构","Lambda","集成","FaaS","串行","系统"]}}},{"node":{"id":"29dc2e58-d2ba-56f9-aee1-d21b0bc62e0e","frontmatter":{"thumbnail":"https://s3-us-west-2.amazonaws.com/assets.blog.serverless.com/ao-com-story/ao-serverless-thumbnail.png","authors":["NickGottlieb"],"categories":["user-stories"],"date":"2019-04-24T00:00:00.000Z","title":"AO.com：逐渐转向无服务器优先","description":"AO.com 的 SCV 团队率先尝试无服务器服务。折服于无服务器框架的快速周转时间和低维护成本，整个团队逐渐转向无服务器优先。","authorslink":null,"translators":null,"translatorslink":null,"tags":null,"keywords":null,"outdated":null},"wordCount":{"words":236,"sentences":42,"paragraphs":35},"fileAbsolutePath":"/opt/build/repo/content/blog/2019-04-24-ao-serverless-first.md","fields":{"slug":"/blog/2019-04-24-ao-serverless-first/","keywords":["serverless","无服务器","服务器","团队","Lambda","功能","构建"]}}},{"node":{"id":"752d08d1-387a-5bde-acf3-98141baab294","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/2020414/1586871710979-%E5%85%AC%E5%85%B1%E7%94%A8.png","authors":["Anycodes"],"categories":["user-stories"],"date":"2019-06-20T00:00:00.000Z","title":"如何用 Serverless 为 Python 云函数打包依赖","description":"在使用无服务器云函数SCF时通常会遇到导入第三方库的问题，很多小伙伴比较头疼是：应该如何打包进去？这里，推荐几个不错的方法。","authorslink":["https://zhuanlan.zhihu.com/ServerlessGo"],"translators":null,"translatorslink":null,"tags":["云函数","Serverless"],"keywords":"Serverless,Serverless应用,无服务器云函数","outdated":null},"wordCount":{"words":81,"sentences":43,"paragraphs":43},"fileAbsolutePath":"/opt/build/repo/content/blog/2019-06-20-for-python-cloud-functions.md","fields":{"slug":"/blog/2019-06-20-for-python-cloud-functions/","keywords":["java","serverless","无服务器","无服务器云函数","云函数","serverlesscloud","安装","serverless","pillowtest"]}}},{"node":{"id":"2dc78814-9d77-555b-a1bb-ad202c8ec2d1","frontmatter":{"thumbnail":"https://s3-us-west-2.amazonaws.com/assets.blog.serverless.com/cloudforecast/thumbnail.png","authors":["FrancoisLagier"],"categories":["user-stories"],"date":"2019-08-07T00:00:00.000Z","title":"Serverless：初创企业的理想选择？（CloudForecast 案例分析）","description":"CloudForecast 是 2018 年成立的一家独立初创企业，本文将介绍他们决定选择 Serverless 的原因。","authorslink":["https://serverless.com/author/francoislagier/"],"translators":["Aceyclee"],"translatorslink":["zhihu.com/people/Aceyclee"],"tags":null,"keywords":null,"outdated":null},"wordCount":{"words":211,"sentences":29,"paragraphs":29},"fileAbsolutePath":"/opt/build/repo/content/blog/2019-08-07-serverless-for-startups.md","fields":{"slug":"/blog/2019-08-07-serverless-for-startups/","keywords":["serverless","云函数","serverless","函数","Serverless","utm","Framework","blog","CloudForecast","cloudforecast"]}}},{"node":{"id":"97450b07-658b-5207-8216-1c7b9b51b115","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/2020114/1578988490344-v2-8b2cd2c5275aa2c5a3c5083a148a7a9f_1200x500.jpg","authors":["Anycodes"],"categories":["user-stories"],"date":"2019-09-01T00:00:00.000Z","title":"如何通过 Serverless 与自然语言处理，让搜索引擎「看」到你的博客","description":"Serverless 与自然语言处理结合的一个小应用","authorslink":["https://www.zhihu.com/people/liuyu-43-97"],"translators":null,"translatorslink":null,"tags":["个人博客","serverless"],"keywords":"Serverless 自然语言处理","outdated":null},"wordCount":{"words":106,"sentences":34,"paragraphs":34},"fileAbsolutePath":"/opt/build/repo/content/blog/2019-09-01-search-engine-blog.md","fields":{"slug":"/blog/2019-09-01-search-engine-blog/","keywords":["serverless","云函数","keywords","serverlesscloud","summary"]}}},{"node":{"id":"ae4fd2f8-515c-5aec-b584-38427ef33f7e","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/2020114/1578989800047-part-00492-780.jpg","authors":["Anycodes"],"categories":["guides-and-tutorials","user-stories"],"date":"2019-09-16T00:00:00.000Z","title":"突破传统 OJ 瓶颈，「判题姬」接入云函数","description":"通过 Serverless 实现在线编程","authorslink":["https://www.zhihu.com/people/liuyu-43-97"],"translators":null,"translatorslink":null,"tags":["在线编程","云函数"],"keywords":"Serverless 在线编程,Serverless OJ","outdated":null},"wordCount":{"words":169,"sentences":30,"paragraphs":30},"fileAbsolutePath":"/opt/build/repo/content/blog/2019-09-16-online-Judge.md","fields":{"slug":"/blog/2019-09-16-online-Judge/","keywords":["python","serverless","云函数","代码","函数","serverless"]}}}],"totalCount":64}},"pageContext":{"isCreatedByStatefulCreatePages":false,"blogId":"c62f601c-89a4-5c0b-baa0-c5d2594b3b30","previousBlogId":"79bc5567-9ccc-59eb-a458-e9739df4471e","nextBlogId":"162777c7-987a-5278-92ac-9887c8dc30a7","categories":["user-stories"]}}}