<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:media="http://search.yahoo.com/mrss/">
  <channel>
    <title>OpenAI ChatGPT｜林鼎淵 Dean Lin</title>
    <link>https://deanlin.net/tags/openai-chatgpt/</link>
    <image><url>https://deanlin.net/images/author_hu_aa256fc934e9a932.jpg</url><title>OpenAI ChatGPT｜林鼎淵 Dean Lin</title><link>https://deanlin.net/tags/openai-chatgpt/</link><width>144</width><height>144</height></image>
    <description>林鼎淵（Dean Lin）的部落格：生成式 AI 企業內訓講師、外商資安公司軟體專家、7 本書作者。400 多篇文章用白話分享生成式 AI 實戰、Claude Code 與 Vibe Coding 教學、團隊合作與職場成長。</description>
    <generator>Hugo</generator>
    <language>zh-tw</language>
    <copyright>© 2020–2026 林鼎淵 Dean Lin</copyright>
    <lastBuildDate>Tue, 25 Apr 2023 21:13:35 +0800</lastBuildDate>
    <atom:link href="https://deanlin.net/tags/openai-chatgpt/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>ChatGPT plugins 新功能搶先看（網頁瀏覽、外掛產圖&amp;發文、程式直譯）</title>
      <link>https://deanlin.net/blog/202304/chatgpt-plugins-preview/</link>
      <pubDate>Tue, 25 Apr 2023 21:13:35 +0800</pubDate>
      <guid>https://deanlin.net/blog/202304/chatgpt-plugins-preview/</guid>
      <dc:creator>林鼎淵</dc:creator>
      <category>AI 實戰</category>
      <description>OpenAI 聯合創辦人Greg Brockman 在 4 月 TED 演講時，向大家分享 ChatGPT 將推出的新功能（Browsing、Code Interpreter、Plugins）。這篇文章將會向大家展示用ChatGPT產圖、線上購物、發送twitter貼文…</description>
      <media:content url="https://deanlin.net/blog/202304/chatgpt-plugins-preview/images/chatgpt-plugins-preview-og_hu_5ddc904159cd5941.jpg" medium="image" type="image/jpeg" width="1200" height="675" />
      <content:encoded><![CDATA[<p><a href="https://www.youtube.com/watch?v=C_78DM8fG6E">OpenAI 聯合創辦人Greg Brockman 在 4 月 TED 演講時</a>，向大家分享了 ChatGPT 即將推出的新功能。</p>
<blockquote>
<p>筆者撰文時，這些功能尚未完全開放；目前預計開放時會先讓付費用戶體驗（ChatGPT PLUS），在文末有附上加入等候清單的官網連結。</p>
</blockquote>
<figure class="figure"><img src="https://deanlin.net/blog/202304/chatgpt-plugins-preview/images/chatgpt-plugins-preview-01.webp" width="1301" height="556" alt="ChatGPT付費版新功能" fetchpriority="high" decoding="async">
  <figcaption>ChatGPT付費版新功能</figcaption>
</figure>

<p>從展示的下拉選單中，我們可以看到多出了「Browsing、Code Interpreter、Plugins」他們各自能完成什麼任務呢？讓我們看下去！</p>
<p><img src="https://deanlin.net/blog/202304/chatgpt-plugins-preview/images/chatgpt-plugins-preview-02.webp" width="1288" height="718" alt="ChatGPT plugins 新功能搶先看（網頁瀏覽、外掛產圖&amp;發文、程式直譯）（圖 2）" loading="lazy" decoding="async"></p>
<pre tabindex="0"><code>大綱

▋ 在ChatGPT產圖、線上購物、發送twitter貼文
▋ 連到網路驗證自己的內容是否正確
▋ 分析Excel內容，產出驚人圖表
▋ 結語：如果想用 AI 做產品請三思
</code></pre><h2 id="在-chatgpt-產圖線上購物發送-twitter-貼文">在 ChatGPT 產圖、線上購物、發送 twitter 貼文<a class="h-anchor" href="#%e5%9c%a8-chatgpt-%e7%94%a2%e5%9c%96%e7%b7%9a%e4%b8%8a%e8%b3%bc%e7%89%a9%e7%99%bc%e9%80%81-twitter-%e8%b2%bc%e6%96%87" aria-label="這個段落的連結"></a></h2>
<p>這邊用到的是「Plugins」中「DALL.E APP」的功能。</p>
<p><img src="https://deanlin.net/blog/202304/chatgpt-plugins-preview/images/chatgpt-plugins-preview-03.webp" width="1298" height="733" alt="在 ChatGPT 產圖、線上購物、發送 twitter 貼文（圖 3）" loading="lazy" decoding="async"></p>
<p>上圖講者輸入「Suggest a nice post-TED meal, and draw a picture（推薦一頓TED演講後的餐點，並將他畫出來）」後，ChatGPT 先用文字建議。</p>
<p><img src="https://deanlin.net/blog/202304/chatgpt-plugins-preview/images/chatgpt-plugins-preview-04.webp" width="1298" height="733" alt="在 ChatGPT 產圖、線上購物、發送 twitter 貼文（圖 4）" loading="lazy" decoding="async"></p>
<p>最後直接產生一幅美味晚餐的圖片</p>
<p><img src="https://deanlin.net/blog/202304/chatgpt-plugins-preview/images/chatgpt-plugins-preview-05.webp" width="1298" height="733" alt="在 ChatGPT 產圖、線上購物、發送 twitter 貼文（圖 5）" loading="lazy" decoding="async"></p>
<p>如果你想知道這個美麗晚餐的背後是什麼 Prompt，ChatGPT 也可以直接秀出 DALL.E 的 Prompt。</p>
<p><img src="https://deanlin.net/blog/202304/chatgpt-plugins-preview/images/chatgpt-plugins-preview-06.webp" width="1298" height="638" alt="在 ChatGPT 產圖、線上購物、發送 twitter 貼文（圖 6）" loading="lazy" decoding="async"></p>
<p>上面的功能已經很驚人了對吧？接下來的這個更猛！</p>
<p>講者選用了「Instacart（美國電商）、Zapier（連結各式應用的自動化工具）」這兩個 Plugins，然後要求 ChatGPT 將他之前建議好吃的東西列一個購物清單，然後在推特上發布給所有 TED 觀眾。</p>
<p><strong>STEP 1</strong>：ChatGPT 先做檢索</p>
<p><img src="https://deanlin.net/blog/202304/chatgpt-plugins-preview/images/chatgpt-plugins-preview-07.webp" width="1399" height="556" alt="在 ChatGPT 產圖、線上購物、發送 twitter 貼文（圖 7）" loading="lazy" decoding="async"></p>
<p><strong>STEP 2</strong>：然後產生對應的購物連結</p>
<p><img src="https://deanlin.net/blog/202304/chatgpt-plugins-preview/images/chatgpt-plugins-preview-08.webp" width="1399" height="556" alt="在 ChatGPT 產圖、線上購物、發送 twitter 貼文（圖 8）" loading="lazy" decoding="async"></p>
<p><strong>STEP 3</strong>：進入網站後是已經選好物品的購物車</p>
<p><img src="https://deanlin.net/blog/202304/chatgpt-plugins-preview/images/chatgpt-plugins-preview-09.webp" width="1298" height="727" alt="在 ChatGPT 產圖、線上購物、發送 twitter 貼文（圖 9）" loading="lazy" decoding="async"></p>
<p><strong>STEP 4</strong>：隨後透過 Zapier 這個外掛導向到tweet發文前的畫面</p>
<p><img src="https://deanlin.net/blog/202304/chatgpt-plugins-preview/images/chatgpt-plugins-preview-10.webp" width="1399" height="553" alt="在 ChatGPT 產圖、線上購物、發送 twitter 貼文（圖 10）" loading="lazy" decoding="async"></p>
<p><strong>STEP 5</strong>：然後就真的發文成功了！</p>
<p><img src="https://deanlin.net/blog/202304/chatgpt-plugins-preview/images/chatgpt-plugins-preview-11.webp" width="1298" height="725" alt="在 ChatGPT 產圖、線上購物、發送 twitter 貼文（圖 11）" loading="lazy" decoding="async"></p>
<p>在上面這段演示中，我們看到了「產生圖片、購買商品、發布貼文」等操作都幾乎靠<strong>自動化</strong>實現了！</p>
<hr>
<h2 id="連到網路驗證自己的內容是否正確">連到網路驗證自己的內容是否正確<a class="h-anchor" href="#%e9%80%a3%e5%88%b0%e7%b6%b2%e8%b7%af%e9%a9%97%e8%ad%89%e8%87%aa%e5%b7%b1%e7%9a%84%e5%85%a7%e5%ae%b9%e6%98%af%e5%90%a6%e6%ad%a3%e7%a2%ba" aria-label="這個段落的連結"></a></h2>
<p>過去 ChatGPT 最為人詬病的問題之一就是會胡說八道，針對這個問題，講者也用「詢問兩篇部落格時間的間隔」直接示範給大家看。</p>
<p><img src="https://deanlin.net/blog/202304/chatgpt-plugins-preview/images/chatgpt-plugins-preview-12.webp" width="1298" height="521" alt="連到網路驗證自己的內容是否正確（圖 12）" loading="lazy" decoding="async"></p>
<p>針對這個問題，ChatGPT 回答前者於 2017 / 04 / 24 發佈，而後者在 2017 / 06 / 27 發佈，因此兩者大約相隔兩個月。</p>
<p>不過這真的是事實嗎？講者將 Model切換到「Browsing」，然後把一樣的問題丟給ChatGPT。</p>
<p><img src="https://deanlin.net/blog/202304/chatgpt-plugins-preview/images/chatgpt-plugins-preview-13.webp" width="1298" height="558" alt="連到網路驗證自己的內容是否正確（圖 13）" loading="lazy" decoding="async"></p>
<p>這個模式下的 ChatGPT 沒有直接回應，而是一步步說明自己在做的事情（跟 New Bing有點像）。</p>
<p><strong>STEP 1</strong>：上網搜尋</p>
<p><img src="https://deanlin.net/blog/202304/chatgpt-plugins-preview/images/chatgpt-plugins-preview-14.webp" width="1298" height="562" alt="連到網路驗證自己的內容是否正確（圖 14）" loading="lazy" decoding="async"></p>
<p><strong>STEP 2</strong>：依序告訴你他執行的順序</p>
<p><img src="https://deanlin.net/blog/202304/chatgpt-plugins-preview/images/chatgpt-plugins-preview-15.webp" width="1298" height="506" alt="連到網路驗證自己的內容是否正確（圖 15）" loading="lazy" decoding="async"></p>
<p><strong>STEP 3</strong>：最終將搜尋到的內容整合出答案</p>
<p><img src="https://deanlin.net/blog/202304/chatgpt-plugins-preview/images/chatgpt-plugins-preview-16.webp" width="1298" height="506" alt="連到網路驗證自己的內容是否正確（圖 16）" loading="lazy" decoding="async"></p>
<p>在遇到事實性的問題時，原本的ChatGPT 容易給出錯誤的答案；但加上「Browsing」後，他就能給出前者於 2017 / 04 / 6 發佈，而後者在 2017 / 06 / 13 發佈，因此兩者相隔兩個月又ㄧ週的正確結論。</p>
<p>儘管驗證事實這塊人類也能做，但真的沒有任何生產力且繁複，ChatGPT能幫我們完成這個任務真的幫到很大的忙。</p>
<hr>
<h2 id="分析-excel-內容產出驚人圖表">分析 Excel 內容，產出驚人圖表<a class="h-anchor" href="#%e5%88%86%e6%9e%90-excel-%e5%85%a7%e5%ae%b9%e7%94%a2%e5%87%ba%e9%a9%9a%e4%ba%ba%e5%9c%96%e8%a1%a8" aria-label="這個段落的連結"></a></h2>
<p>講者秀出了一個彙過去 30 年人工智慧論文的 Excel 表（約 16.7萬篇），然後告訴我們 ChatGPT 如何分析這些數據。</p>
<figure class="figure"><img src="https://deanlin.net/blog/202304/chatgpt-plugins-preview/images/chatgpt-plugins-preview-17.webp" width="1293" height="723" alt="人工智慧論文的 Excel 表" loading="lazy" decoding="async">
  <figcaption>人工智慧論文的 Excel 表</figcaption>
</figure>

<p>這次他選用「Code Interpreter（程式直譯）」的 Model，並上傳剛剛的 Excel 表。</p>
<p><img src="https://deanlin.net/blog/202304/chatgpt-plugins-preview/images/chatgpt-plugins-preview-18.webp" width="1298" height="728" alt="分析 Excel 內容，產出驚人圖表（圖 18）" loading="lazy" decoding="async"></p>
<p>然後 ChatGPT 就能夠很神的分析出這個 Excel 每個欄位所代表的意義，然後詢問使用者要對數據做分析或是視覺化。</p>
<p><img src="https://deanlin.net/blog/202304/chatgpt-plugins-preview/images/chatgpt-plugins-preview-19.webp" width="1298" height="510" alt="分析 Excel 內容，產出驚人圖表（圖 19）" loading="lazy" decoding="async"></p>
<p>這時講者要求ChatGPT給一些「探索性的圖（exploratory graph）」，面對這種模糊的需求，聰明的ChatGPT 給他3種呈現方式：</p>
<p>1. <strong>直方圖</strong>：顯示每篇論文的作者數量，讓我們了解AI研究的典型團隊規模。</p>
<p>2. <strong>折線圖</strong>：顯示每年論文發表的總數，以此展示AI研究的趨勢。</p>
<p>3. <strong>論文標題的單字雲</strong>：顯示AI研究標題中最常出現的單字。</p>
<p><img src="https://deanlin.net/blog/202304/chatgpt-plugins-preview/images/chatgpt-plugins-preview-20.webp" width="1298" height="598" alt="分析 Excel 內容，產出驚人圖表（圖 20）" loading="lazy" decoding="async"></p>
<figure class="figure"><img src="https://deanlin.net/blog/202304/chatgpt-plugins-preview/images/chatgpt-plugins-preview-21.webp" width="1298" height="643" alt="直方圖" loading="lazy" decoding="async">
  <figcaption><strong>直方圖</strong></figcaption>
</figure>

<figure class="figure"><img src="https://deanlin.net/blog/202304/chatgpt-plugins-preview/images/chatgpt-plugins-preview-22.webp" width="1298" height="643" alt="折線圖" loading="lazy" decoding="async">
  <figcaption><strong>折線圖</strong></figcaption>
</figure>

<figure class="figure"><img src="https://deanlin.net/blog/202304/chatgpt-plugins-preview/images/chatgpt-plugins-preview-23.webp" width="1298" height="648" alt="論文標題的單字雲" loading="lazy" decoding="async">
  <figcaption><strong>論文標題的單字雲</strong></figcaption>
</figure>

<p>此時講者發現折線圖中 2023 年的數據有問題，AI 應該指數成長卻被腰斬；所以向 ChatGPT 說明2023年尚未過完，可以重新做一個公平的預測嗎？</p>
<p><img src="https://deanlin.net/blog/202304/chatgpt-plugins-preview/images/chatgpt-plugins-preview-24.webp" width="1298" height="526" alt="分析 Excel 內容，產出驚人圖表（圖 24）" loading="lazy" decoding="async"></p>
<p>最後 ChatGPT 也不負眾望的向大家展示了新的繪製成果，並且在圖片上標明2023 年的論文發表總數是預測的。</p>
<p><img src="https://deanlin.net/blog/202304/chatgpt-plugins-preview/images/chatgpt-plugins-preview-25.webp" width="1298" height="636" alt="分析 Excel 內容，產出驚人圖表（圖 25）" loading="lazy" decoding="async"></p>
<p>如果你有興趣，也可以看 ChatGPT 是如何用 Python 將這些數據分析、繪製出來的。</p>
<p><img src="https://deanlin.net/blog/202304/chatgpt-plugins-preview/images/chatgpt-plugins-preview-26.webp" width="1351" height="617" alt="分析 Excel 內容，產出驚人圖表（圖 26）" loading="lazy" decoding="async"></p>
<p>想搶先體驗新功能的朋友可以加入等候清單喔：<a href="https://l.facebook.com/l.php?u=https%3A%2F%2Fopenai.com%2Fwaitlist%2Fplugins%3Ffbclid%3DIwAR3gPvnT_gF2d2yZSE5q1TPvncoQBLAo1E4Lun0B5fqxZMGC8cvwj7CzPKA&amp;h=AT1IewtX1_-ZtWx-qgby-OuRwajSY2TOh8i-ovuMXld9ZN0NKjxlpH3RBUPfldFjZ95-BHas7YT-g4eUE4VH5DoPKtJrxJm0Uyk6spCI-ILgx5N6dqC4SufUFuCJQemK47ef_QxePA&amp;__tn__=R]-R&amp;c[0]=AT2CJjwCgax8N6srJJ3zsNkCY2ElNuahARS_wV5Z4K_q5YgL2LCjenQ4_gLu4WTMuTYC0BF6NDlesfnBhxZkwtImnqQU0T89zDAX99lZ4WS0Q583TfxjxSpnPItJ2sa1te0FqaEzDd0R0DtelOn4QCzko6wbKYt3lmxNohSnPV43TJT85k06fUbcOGPTvi42bLYMllbnt-UTvQkj1Ffolgg">https://openai.com/waitlist/plugins</a></p>
<p><img src="https://deanlin.net/blog/202304/chatgpt-plugins-preview/images/chatgpt-plugins-preview-27.webp" width="1400" height="581" alt="分析 Excel 內容，產出驚人圖表（圖 27）" loading="lazy" decoding="async"></p>
<hr>
<h2 id="結語如果想用-ai-做產品請三思">結語：如果想用 AI 做產品請三思<a class="h-anchor" href="#%e7%b5%90%e8%aa%9e%e5%a6%82%e6%9e%9c%e6%83%b3%e7%94%a8-ai-%e5%81%9a%e7%94%a2%e5%93%81%e8%ab%8b%e4%b8%89%e6%80%9d" aria-label="這個段落的連結"></a></h2>
<p>從 Demo 中可以看到這次 ChatGPT 的改版是非常有感的，跟過去只能文字輸入/輸出的型態相比，他多了非常多應用的可能性。</p>
<p>現在市面上有許多新興的產品是依附在 OpenAI 的 API 上面的，但如果哪天OpenAI 突然跑出來自己做，那對產品無疑是一個毀滅性打擊。</p>
<p>如果是針對 OpenAI 缺點做的產品就更危險了，你都能補足這個缺點了，OpenAI 官方會沒想到嗎？只是看他想不想去優化而已。</p>
<p>門檻越低的產品越容易被淘汰，在 AI 工具急速發展的年代更是如此！</p>
<hr>
<a class="linkcard" href="https://deanlin.net/categories/ai/">
  <span class="lc-body">
    <span class="lc-title">AI 實戰</span>
    <span class="lc-desc">實測生成式 AI 工具、Vibe Coding 與自動化流程的第一手心得，把 AI 變成每天都用得上的即戰力。</span>
    <span class="lc-site"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M5 12h14M13 6l6 6-6 6"/></svg>林鼎淵 Dean Lin</span>
  </span>
</a>

<p><strong>想將 AI 導入自己的職場與生活嗎？歡迎<a href="https://www.books.com.tw/products/0011004216">購買筆者出版的新書</a></strong>，幫助您<strong>在 AI 的浪潮中站穩腳步，並在未來的職場競爭中佔據優勢！</strong></p>
<figure class="figure"><img src="https://deanlin.net/blog/202304/chatgpt-plugins-preview/images/chatgpt-plugins-preview-28.webp" width="1400" height="319" alt="林鼎淵著作《ChatGPT 與 AI 繪圖效率大師（新增 Copilot、Gamma、Runway、Suno）》" loading="lazy" decoding="async">
  <figcaption><a href="https://www.books.com.tw/products/0011004216">https://www.books.com.tw/products/0011004216</a></figcaption>
</figure>

]]></content:encoded>
    </item>
    <item>
      <title>靠問 ChatGPT 寫程式，能完成 OpenAI &amp; Linebot 的 Side Project 嗎？（下）</title>
      <link>https://deanlin.net/blog/202301/chatgpt-line-bot-side-project-part-2/</link>
      <pubDate>Wed, 25 Jan 2023 15:24:33 +0800</pubDate>
      <guid>https://deanlin.net/blog/202301/chatgpt-line-bot-side-project-part-2/</guid>
      <dc:creator>林鼎淵</dc:creator>
      <category>AI 實戰</category>
      <description>在這篇文章中，我們要來設定 Line 的 webhook，並測試 ChatGPT 寫的程式是否可以正確執行；並告訴讀者遇到問題時，我們可以從哪些面向來思考、解決；最後於文末給想用 ChatGPT 寫程式、學程式的朋友一些建議。</description>
      <media:content url="https://deanlin.net/blog/202301/chatgpt-line-bot-side-project-part-2/images/chatgpt-line-bot-side-project-part-2-og_hu_b00ae86497f1183.jpg" medium="image" type="image/jpeg" width="1200" height="675" />
      <content:encoded><![CDATA[<p>在<a href="https://deanlin.net/blog/202301/chatgpt-line-bot-side-project-part-1/">上一篇文章</a>中，我們好不容易請 ChatGPT 完成 OpenAI-Linebot 的專案，並順利啟動。</p>
<p>在這篇文章中，我們要來設定 Line 的 webhook，並測試 ChatGPT 寫的程式是否可以正確執行；並告訴讀者遇到問題時，我們可以從哪些面向來思考、解決；最後於文末給想用 ChatGPT 寫程式、學程式的朋友一些建議。</p>
<p><img src="https://deanlin.net/blog/202301/chatgpt-line-bot-side-project-part-2/images/chatgpt-line-bot-side-project-part-2-01.webp" width="1260" height="689" alt="靠問 ChatGPT 寫程式，能完成 OpenAI &amp; Linebot 的 Side Project 嗎？（下）（圖 1）" fetchpriority="high" decoding="async"></p>
<pre tabindex="0"><code>大綱

▋ 在 local 建立一個可以讓 Line 訪問的 HTTP server（ngrok）
▋ 設定 Line 的 webhook
▋ 測試功能＆痛苦的 Debug 之路
▋ 結論：給想用 ChatGPT 寫程式、學程式的朋友一些建議
</code></pre><h2 id="在-local-建立一個可以讓-line-訪問的-http-serverngrok">在 local 建立一個可以讓 Line 訪問的 HTTP server（ngrok）<a class="h-anchor" href="#%e5%9c%a8-local-%e5%bb%ba%e7%ab%8b%e4%b8%80%e5%80%8b%e5%8f%af%e4%bb%a5%e8%ae%93-line-%e8%a8%aa%e5%95%8f%e7%9a%84-http-serverngrok" aria-label="這個段落的連結"></a></h2>
<p>上一篇文章中，專案是在本地啟動的，因此他的網址是 <a href="http://localhost:3000">http://localhost:3000</a> ，而 Line 的 webhook 是無法接受本地網址的。</p>
<p>為了方便 Debug，我這邊選擇在 local 建立一個可以讓 Line 訪問的 HTTP server，具體的方案我們來詢問一下 ChatGPT。</p>
<p><img src="https://deanlin.net/blog/202301/chatgpt-line-bot-side-project-part-2/images/chatgpt-line-bot-side-project-part-2-02.webp" width="1077" height="537" alt="在 local 建立一個可以讓 Line 訪問的 HTTP server（ngrok）（圖 2）" loading="lazy" decoding="async"></p>
<p>這邊我選用「ngrok」的方案，並在指定「作業系統」的狀態下，請 ChatGPT 告訴我接下來該怎麼做。</p>
<p><img src="https://deanlin.net/blog/202301/chatgpt-line-bot-side-project-part-2/images/chatgpt-line-bot-side-project-part-2-03.webp" width="1086" height="705" alt="在 local 建立一個可以讓 Line 訪問的 HTTP server（ngrok）（圖 3）" loading="lazy" decoding="async"></p>
<p>接下來我們就按造建議的步驟來實作看看。</p>
<p><strong>SETP 1</strong>：先到 ngrok 的官網下載 ngrok 的 Mac 版本： <a href="https://ngrok.com/download">https://ngrok.com/download</a> 。</p>
<p><img src="https://deanlin.net/blog/202301/chatgpt-line-bot-side-project-part-2/images/chatgpt-line-bot-side-project-part-2-04.webp" width="1400" height="1296" alt="在 local 建立一個可以讓 Line 訪問的 HTTP server（ngrok）（圖 4）" loading="lazy" decoding="async"></p>
<blockquote>
<p>提醒讀者，要先確認自己 mac 的處理器是 Intel 還是 Apple Silicon 喔！</p>
</blockquote>
<p><strong>SETP 2</strong>：解壓縮下載的檔案，並將 ngrok 放入您的 PATH 中 (例如: /usr/local/bin)</p>
<p>解壓縮檔案後，你會得到一個 ngrok 的值行檔，其實你就算放在 download 的資料夾也能執行，不過放到 bin 的資料夾下可以在任何位置執行。</p>
<p>下面說明一下 mac 進入 bin 資料夾的步驟：「到 mac 桌面」or「點擊 Finder」➝ 「前往」➝ 「前往資料夾」➝ 輸入「/usr/local/bin」➝ 把「ngrok 值行檔」丟進去。</p>
<p><img src="https://deanlin.net/blog/202301/chatgpt-line-bot-side-project-part-2/images/chatgpt-line-bot-side-project-part-2-05.webp" width="1108" height="892" alt="在 local 建立一個可以讓 Line 訪問的 HTTP server（ngrok）（圖 5）" loading="lazy" decoding="async"></p>
<p><img src="https://deanlin.net/blog/202301/chatgpt-line-bot-side-project-part-2/images/chatgpt-line-bot-side-project-part-2-06.webp" width="956" height="456" alt="在 local 建立一個可以讓 Line 訪問的 HTTP server（ngrok）（圖 6）" loading="lazy" decoding="async"></p>
<p><img src="https://deanlin.net/blog/202301/chatgpt-line-bot-side-project-part-2/images/chatgpt-line-bot-side-project-part-2-07.webp" width="1400" height="670" alt="在 local 建立一個可以讓 Line 訪問的 HTTP server（ngrok）（圖 7）" loading="lazy" decoding="async"></p>
<p><strong>SETP 3</strong>：打開終端機，輸入 <code>ngrok http 3000</code> (3000 是您的本地環境的 HTTP Server 的通訊埠)，啟動 ngrok。</p>
<p><img src="https://deanlin.net/blog/202301/chatgpt-line-bot-side-project-part-2/images/chatgpt-line-bot-side-project-part-2-08.webp" width="1400" height="486" alt="在 local 建立一個可以讓 Line 訪問的 HTTP server（ngrok）（圖 8）" loading="lazy" decoding="async"></p>
<p><strong>SETP 4</strong>：ngrok 將會顯示一個可供外部訪問的 URL（上圖紅框處 <code>https://xxxx.ngrok.io</code>），您可以在 LINE 的 Developer Console 中設定 webhook 的 URL。</p>
<blockquote>
<p><strong>小提醒</strong>：Session 2 小時後會過期，到時再重新執行一次 <code>ngrok http 3000</code> 就好了，然後別忘記把新的 URL 設定到 Line 的 webhook。</p>
</blockquote>
<hr>
<h2 id="-設定-line-的-webhook">設定 Line 的 webhook<a class="h-anchor" href="#-%e8%a8%ad%e5%ae%9a-line-%e7%9a%84-webhook" aria-label="這個段落的連結"></a></h2>
<p>因為設定步驟很簡單，我就不特別問 ChatGPT 了。</p>
<p><strong>SETP 1</strong>：在 Messaging API 的 WebhookURL 貼上剛剛的的網址，並於後面加上 <code>/webhook</code>（那是我們程式設定的 API 路徑）。</p>
<p><img src="https://deanlin.net/blog/202301/chatgpt-line-bot-side-project-part-2/images/chatgpt-line-bot-side-project-part-2-09.webp" width="1077" height="563" alt="設定 Line 的 webhook（圖 9）" loading="lazy" decoding="async"></p>
<p><strong>SETP 2</strong>：按下「Verify」後得到 Success 就代表有成功聯通嚕！</p>
<p><img src="https://deanlin.net/blog/202301/chatgpt-line-bot-side-project-part-2/images/chatgpt-line-bot-side-project-part-2-10.webp" width="1000" height="397" alt="設定 Line 的 webhook（圖 10）" loading="lazy" decoding="async"></p>
<p><strong>SETP 3</strong>：在 Messaging API 取得 Linebot 的 LineID，並把他加入好友。</p>
<p><img src="https://deanlin.net/blog/202301/chatgpt-line-bot-side-project-part-2/images/chatgpt-line-bot-side-project-part-2-11.webp" width="739" height="332" alt="設定 Line 的 webhook（圖 11）" loading="lazy" decoding="async"></p>
<p>加入好友後，他會跟你打招呼。</p>
<p>但當你很興奮的傳訊息給他時，他的回覆語氣一點都不像是 ChatGPT。</p>
<p><img src="https://deanlin.net/blog/202301/chatgpt-line-bot-side-project-part-2/images/chatgpt-line-bot-side-project-part-2-12.webp" width="1382" height="1006" alt="設定 Line 的 webhook（圖 12）" loading="lazy" decoding="async"></p>
<p>雖然到這裡我們已經知道出事了，但還是先把下面的步驟做完吧。</p>
<p><strong>SETP 4</strong>：在 Messaging API 關閉自動回覆（Auto-reply messages）與打招呼（Greeting messages）。</p>
<p><img src="https://deanlin.net/blog/202301/chatgpt-line-bot-side-project-part-2/images/chatgpt-line-bot-side-project-part-2-13.webp" width="1300" height="588" alt="設定 Line 的 webhook（圖 13）" loading="lazy" decoding="async"></p>
<blockquote>
<p>因為自動回覆（Auto-reply messages）會干擾 Debug 所以建議關閉，至於打招呼（Greeting messages）要不要關閉就看你自己。</p>
</blockquote>
<hr>
<h2 id="測試功能痛苦的-debug-之路">測試功能＆痛苦的 Debug 之路<a class="h-anchor" href="#%e6%b8%ac%e8%a9%a6%e5%8a%9f%e8%83%bd%e7%97%9b%e8%8b%a6%e7%9a%84-debug-%e4%b9%8b%e8%b7%af" aria-label="這個段落的連結"></a></h2>
<p>上面 Webhook URL 的 Verify 得到 200 只是證明這條路有打通，如果把畫面切到 ngrok，會發現許多 500 的錯誤訊息。</p>
<p><img src="https://deanlin.net/blog/202301/chatgpt-line-bot-side-project-part-2/images/chatgpt-line-bot-side-project-part-2-14.webp" width="1400" height="708" alt="測試功能＆痛苦的 Debug 之路（圖 14）" loading="lazy" decoding="async"></p>
<h3 id="-上一篇-chatgpt-給的程式有哪些錯誤">上一篇 ChatGPT 給的程式有哪些錯誤？<a class="h-anchor" href="#-%e4%b8%8a%e4%b8%80%e7%af%87-chatgpt-%e7%b5%a6%e7%9a%84%e7%a8%8b%e5%bc%8f%e6%9c%89%e5%93%aa%e4%ba%9b%e9%8c%af%e8%aa%a4" aria-label="這個段落的連結"></a></h3>
<p>回到程式，你會發現有「TypeError: Cannot read properties of undefined (reading ‘events’)」的錯誤。</p>
<p><img src="https://deanlin.net/blog/202301/chatgpt-line-bot-side-project-part-2/images/chatgpt-line-bot-side-project-part-2-15.webp" width="1400" height="384" alt="上一篇 ChatGPT 給的程式有哪些錯誤？（圖 15）" loading="lazy" decoding="async"></p>
<p>如果你把這個問題拿去詢問 ChatGPT，會收到一大堆鬼打牆的回覆。</p>
<p><img src="https://deanlin.net/blog/202301/chatgpt-line-bot-side-project-part-2/images/chatgpt-line-bot-side-project-part-2-16.webp" width="1067" height="728" alt="上一篇 ChatGPT 給的程式有哪些錯誤？（圖 16）" loading="lazy" decoding="async"></p>
<p>這邊筆者就直接告訴大家為什麼會有各式各樣的錯誤：</p>
<ul>
<li>「@line/bot-sdk」套件使用方式錯誤</li>
<li>「openai」套件使用方式錯誤</li>
</ul>
<p>你沒看錯，要實作的兩個套件，ChatGPT 的使用方式都是有問題的。</p>
<h3 id="-讓-chatgpt-擔任程式專家改用英文詢問">讓 ChatGPT 擔任程式專家，改用英文詢問<a class="h-anchor" href="#-%e8%ae%93-chatgpt-%e6%93%94%e4%bb%bb%e7%a8%8b%e5%bc%8f%e5%b0%88%e5%ae%b6%e6%94%b9%e7%94%a8%e8%8b%b1%e6%96%87%e8%a9%a2%e5%95%8f" aria-label="這個段落的連結"></a></h3>
<p>為了避免冤枉好人，我這次改成用英文詢問，並讓 ChatGPT 擔任程式專家來撰寫，這是他給出的新回覆：</p>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-javascript" data-lang="javascript"><span style="display:flex;"><span><span style="color:#ff7b72">const</span> line <span style="color:#ff7b72;font-weight:bold">=</span> require(<span style="color:#a5d6ff">&#39;@line/bot-sdk&#39;</span>);
</span></span><span style="display:flex;"><span><span style="color:#ff7b72">const</span> express <span style="color:#ff7b72;font-weight:bold">=</span> require(<span style="color:#a5d6ff">&#39;express&#39;</span>);
</span></span><span style="display:flex;"><span><span style="color:#ff7b72">const</span> openai <span style="color:#ff7b72;font-weight:bold">=</span> require(<span style="color:#a5d6ff">&#39;openai&#39;</span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>openai.apiKey <span style="color:#ff7b72;font-weight:bold">=</span> <span style="color:#a5d6ff">&#34;YOUR_API_KEY&#34;</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ff7b72">const</span> config <span style="color:#ff7b72;font-weight:bold">=</span> {
</span></span><span style="display:flex;"><span>  channelAccessToken<span style="color:#ff7b72;font-weight:bold">:</span> <span style="color:#a5d6ff">&#39;YOUR_CHANNEL_ACCESS_TOKEN&#39;</span>,
</span></span><span style="display:flex;"><span>  channelSecret<span style="color:#ff7b72;font-weight:bold">:</span> <span style="color:#a5d6ff">&#39;YOUR_CHANNEL_SECRET&#39;</span>
</span></span><span style="display:flex;"><span>};
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ff7b72">const</span> client <span style="color:#ff7b72;font-weight:bold">=</span> <span style="color:#ff7b72">new</span> line.Client(config);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ff7b72">const</span> app <span style="color:#ff7b72;font-weight:bold">=</span> express();
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>app.post(<span style="color:#a5d6ff">&#39;/webhook&#39;</span>, line.middleware(config), (req, res) =&gt; {
</span></span><span style="display:flex;"><span>  Promise
</span></span><span style="display:flex;"><span>    .all(req.body.events.map(handleEvent))
</span></span><span style="display:flex;"><span>    .then((result) =&gt; res.json(result))
</span></span><span style="display:flex;"><span>    .<span style="color:#ff7b72">catch</span>((err) =&gt; {
</span></span><span style="display:flex;"><span>      console.error(err);
</span></span><span style="display:flex;"><span>      res.status(<span style="color:#a5d6ff">500</span>).end();
</span></span><span style="display:flex;"><span>    });
</span></span><span style="display:flex;"><span>});
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ff7b72">function</span> handleEvent (event) {
</span></span><span style="display:flex;"><span>  <span style="color:#ff7b72">if</span> (event.type <span style="color:#ff7b72;font-weight:bold">!==</span> <span style="color:#a5d6ff">&#39;message&#39;</span> <span style="color:#ff7b72;font-weight:bold">||</span> event.message.type <span style="color:#ff7b72;font-weight:bold">!==</span> <span style="color:#a5d6ff">&#39;text&#39;</span>) {
</span></span><span style="display:flex;"><span>    <span style="color:#ff7b72">return</span> Promise.resolve(<span style="color:#79c0ff">null</span>);
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#ff7b72">return</span> openai
</span></span><span style="display:flex;"><span>    .engines
</span></span><span style="display:flex;"><span>    .completions
</span></span><span style="display:flex;"><span>    .create({
</span></span><span style="display:flex;"><span>      prompt<span style="color:#ff7b72;font-weight:bold">:</span> event.message.text,
</span></span><span style="display:flex;"><span>      engine<span style="color:#ff7b72;font-weight:bold">:</span> <span style="color:#a5d6ff">&#34;text-davinci-002&#34;</span>,
</span></span><span style="display:flex;"><span>      maxTokens<span style="color:#ff7b72;font-weight:bold">:</span> <span style="color:#a5d6ff">100</span>
</span></span><span style="display:flex;"><span>    })
</span></span><span style="display:flex;"><span>    .then((completions) =&gt; {
</span></span><span style="display:flex;"><span>      <span style="color:#ff7b72">const</span> message <span style="color:#ff7b72;font-weight:bold">=</span> completions.choices[<span style="color:#a5d6ff">0</span>].text;
</span></span><span style="display:flex;"><span>      <span style="color:#ff7b72">return</span> client.replyMessage(event.replyToken, {
</span></span><span style="display:flex;"><span>        type<span style="color:#ff7b72;font-weight:bold">:</span> <span style="color:#a5d6ff">&#39;text&#39;</span>,
</span></span><span style="display:flex;"><span>        text<span style="color:#ff7b72;font-weight:bold">:</span> message
</span></span><span style="display:flex;"><span>      });
</span></span><span style="display:flex;"><span>    });
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>app.listen(<span style="color:#a5d6ff">3000</span>);
</span></span><span style="display:flex;"><span>console.log(<span style="color:#a5d6ff">&#39;Linebot is running on 3000 port&#39;</span>);
</span></span></code></pre></div><p>果然專家就是比較厲害，錯誤訊息變得不一樣了！</p>
<p><img src="https://deanlin.net/blog/202301/chatgpt-line-bot-side-project-part-2/images/chatgpt-line-bot-side-project-part-2-17.webp" width="1400" height="292" alt="讓 ChatGPT 擔任程式專家，改用英文詢問（圖 17）" loading="lazy" decoding="async"></p>
<p>但這個錯誤並沒有辦法靠詢問 ChatGPT 解決（他會再次鬼打牆）。</p>
<p><img src="https://deanlin.net/blog/202301/chatgpt-line-bot-side-project-part-2/images/chatgpt-line-bot-side-project-part-2-18.webp" width="1083" height="665" alt="讓 ChatGPT 擔任程式專家，改用英文詢問（圖 18）" loading="lazy" decoding="async"></p>
<h3 id="-好吧最後還是得靠自己處理">好吧…最後還是得靠自己處理<a class="h-anchor" href="#-%e5%a5%bd%e5%90%a7%e6%9c%80%e5%be%8c%e9%82%84%e6%98%af%e5%be%97%e9%9d%a0%e8%87%aa%e5%b7%b1%e8%99%95%e7%90%86" aria-label="這個段落的連結"></a></h3>
<p>因為我看錯誤的源頭出在 openai 套件，所以我就去官網研究了一下：<a href="https://www.npmjs.com/package/openai">https://www.npmjs.com/package/openai</a></p>
<p>先給大家看一下官網給的範例程式：</p>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-javascript" data-lang="javascript"><span style="display:flex;"><span><span style="color:#ff7b72">const</span> { Configuration, OpenAIApi } <span style="color:#ff7b72;font-weight:bold">=</span> require(<span style="color:#a5d6ff">&#34;openai&#34;</span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ff7b72">const</span> configuration <span style="color:#ff7b72;font-weight:bold">=</span> <span style="color:#ff7b72">new</span> Configuration({
</span></span><span style="display:flex;"><span>  apiKey<span style="color:#ff7b72;font-weight:bold">:</span> process.env.OPENAI_API_KEY,
</span></span><span style="display:flex;"><span>});
</span></span><span style="display:flex;"><span><span style="color:#ff7b72">const</span> openai <span style="color:#ff7b72;font-weight:bold">=</span> <span style="color:#ff7b72">new</span> OpenAIApi(configuration);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ff7b72">const</span> completion <span style="color:#ff7b72;font-weight:bold">=</span> <span style="color:#ff7b72">await</span> openai.createCompletion({
</span></span><span style="display:flex;"><span>  model<span style="color:#ff7b72;font-weight:bold">:</span> <span style="color:#a5d6ff">&#34;text-davinci-002&#34;</span>,
</span></span><span style="display:flex;"><span>  prompt<span style="color:#ff7b72;font-weight:bold">:</span> <span style="color:#a5d6ff">&#34;Hello world&#34;</span>,
</span></span><span style="display:flex;"><span>});
</span></span><span style="display:flex;"><span>console.log(completion.data.choices[<span style="color:#a5d6ff">0</span>].text);
</span></span></code></pre></div><p><strong>如果把他跟 ChatGPT 給的程式做比對，會發現 ChatGPT 的使用方式根本是錯的</strong>，下面筆者就直接把修改好的程式放上來，調整過的部分有在旁邊用註解說明：</p>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-javascript" data-lang="javascript"><span style="display:flex;"><span>require(<span style="color:#a5d6ff">&#39;dotenv&#39;</span>).config(); <span style="color:#8b949e;font-style:italic">// 皆採用 .env 讀取
</span></span></span><span style="display:flex;"><span><span style="color:#ff7b72">const</span> line <span style="color:#ff7b72;font-weight:bold">=</span> require(<span style="color:#a5d6ff">&#39;@line/bot-sdk&#39;</span>);
</span></span><span style="display:flex;"><span><span style="color:#ff7b72">const</span> express <span style="color:#ff7b72;font-weight:bold">=</span> require(<span style="color:#a5d6ff">&#39;express&#39;</span>);
</span></span><span style="display:flex;"><span><span style="color:#ff7b72">const</span> { Configuration, OpenAIApi } <span style="color:#ff7b72;font-weight:bold">=</span> require(<span style="color:#a5d6ff">&#34;openai&#34;</span>); <span style="color:#8b949e;font-style:italic">// 他套件使用方式錯誤，我直接改掉
</span></span></span><span style="display:flex;"><span><span style="color:#ff7b72">const</span> configuration <span style="color:#ff7b72;font-weight:bold">=</span> <span style="color:#ff7b72">new</span> Configuration({
</span></span><span style="display:flex;"><span>  apiKey<span style="color:#ff7b72;font-weight:bold">:</span> process.env.OPENAI_API_KEY,
</span></span><span style="display:flex;"><span>});
</span></span><span style="display:flex;"><span><span style="color:#ff7b72">const</span> openai <span style="color:#ff7b72;font-weight:bold">=</span> <span style="color:#ff7b72">new</span> OpenAIApi(configuration);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ff7b72">const</span> config <span style="color:#ff7b72;font-weight:bold">=</span> {
</span></span><span style="display:flex;"><span>  channelAccessToken<span style="color:#ff7b72;font-weight:bold">:</span> process.env.CHANNEL_ACCESS_TOKEN,
</span></span><span style="display:flex;"><span>  channelSecret<span style="color:#ff7b72;font-weight:bold">:</span> process.env.CHANNEL_SECRET,
</span></span><span style="display:flex;"><span>};
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ff7b72">const</span> client <span style="color:#ff7b72;font-weight:bold">=</span> <span style="color:#ff7b72">new</span> line.Client(config);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ff7b72">const</span> app <span style="color:#ff7b72;font-weight:bold">=</span> express();
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>app.post(<span style="color:#a5d6ff">&#39;/webhook&#39;</span>, line.middleware(config), (req, res) =&gt; {
</span></span><span style="display:flex;"><span>  Promise
</span></span><span style="display:flex;"><span>    .all(req.body.events.map(handleEvent))
</span></span><span style="display:flex;"><span>    .then((result) =&gt; res.json(result))
</span></span><span style="display:flex;"><span>    .<span style="color:#ff7b72">catch</span>((err) =&gt; {
</span></span><span style="display:flex;"><span>      console.error(err);
</span></span><span style="display:flex;"><span>      res.status(<span style="color:#a5d6ff">500</span>).end();
</span></span><span style="display:flex;"><span>    });
</span></span><span style="display:flex;"><span>});
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ff7b72">function</span> handleEvent (event) {
</span></span><span style="display:flex;"><span>  <span style="color:#ff7b72">if</span> (event.type <span style="color:#ff7b72;font-weight:bold">!==</span> <span style="color:#a5d6ff">&#39;message&#39;</span> <span style="color:#ff7b72;font-weight:bold">||</span> event.message.type <span style="color:#ff7b72;font-weight:bold">!==</span> <span style="color:#a5d6ff">&#39;text&#39;</span>) {
</span></span><span style="display:flex;"><span>    <span style="color:#ff7b72">return</span> Promise.resolve(<span style="color:#79c0ff">null</span>);
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#ff7b72">return</span> openai.createCompletion({ <span style="color:#8b949e;font-style:italic">// 方法用錯修正
</span></span></span><span style="display:flex;"><span>    prompt<span style="color:#ff7b72;font-weight:bold">:</span> event.message.text,
</span></span><span style="display:flex;"><span>    model<span style="color:#ff7b72;font-weight:bold">:</span> <span style="color:#a5d6ff">&#34;text-davinci-003&#34;</span>, <span style="color:#8b949e;font-style:italic">// 使用 model 而非 engine
</span></span></span><span style="display:flex;"><span>    max_tokens<span style="color:#ff7b72;font-weight:bold">:</span> <span style="color:#a5d6ff">1000</span> <span style="color:#8b949e;font-style:italic">// 應用 max_tokens 而非 maxTokens
</span></span></span><span style="display:flex;"><span>  }).then((completions) =&gt; {
</span></span><span style="display:flex;"><span>    <span style="color:#8b949e;font-style:italic">// 少了 data 這層結構，並要加上 trim() 去除空白
</span></span></span><span style="display:flex;"><span>    <span style="color:#ff7b72">const</span> message <span style="color:#ff7b72;font-weight:bold">=</span> completions.data.choices[<span style="color:#a5d6ff">0</span>].text.trim();
</span></span><span style="display:flex;"><span>    <span style="color:#ff7b72">return</span> client.replyMessage(event.replyToken, {
</span></span><span style="display:flex;"><span>      type<span style="color:#ff7b72;font-weight:bold">:</span> <span style="color:#a5d6ff">&#39;text&#39;</span>,
</span></span><span style="display:flex;"><span>      text<span style="color:#ff7b72;font-weight:bold">:</span> message
</span></span><span style="display:flex;"><span>    });
</span></span><span style="display:flex;"><span>  });
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>app.listen(<span style="color:#a5d6ff">3000</span>);
</span></span><span style="display:flex;"><span>console.log(<span style="color:#a5d6ff">&#39;Linebot is running on 3000 port&#39;</span>);
</span></span></code></pre></div><p>最後再給大家看看順利溝通時的畫面：</p>
<div class="gallery-row cols-2">

<figure class="figure"><img src="https://deanlin.net/blog/202301/chatgpt-line-bot-side-project-part-2/images/chatgpt-line-bot-side-project-part-2-19.webp" width="744" height="970" alt="好吧…最後還是得靠自己處理（圖 19）" loading="lazy" decoding="async">
</figure>

<figure class="figure"><img src="https://deanlin.net/blog/202301/chatgpt-line-bot-side-project-part-2/images/chatgpt-line-bot-side-project-part-2-20.webp" width="742" height="972" alt="好吧…最後還是得靠自己處理（圖 20）" loading="lazy" decoding="async">
</figure>


</div>

<p>看到成功溝通的畫面時，筆者真的感動到快哭了，這是個能與你溝通的 AI 機器人喔！</p>
<blockquote>
<p>不過操作下來我覺得回答穩定度沒有比 ChatGPT 高，有時會出現一些奇怪的程式碼，讀者有興趣可以再做優化，本篇文章僅為參考範例。</p>
</blockquote>
<hr>
<h2 id="結論給想用-chatgpt-寫程式學程式的朋友一些建議">結論：給想用 ChatGPT 寫程式、學程式的朋友一些建議<a class="h-anchor" href="#%e7%b5%90%e8%ab%96%e7%b5%a6%e6%83%b3%e7%94%a8-chatgpt-%e5%af%ab%e7%a8%8b%e5%bc%8f%e5%ad%b8%e7%a8%8b%e5%bc%8f%e7%9a%84%e6%9c%8b%e5%8f%8b%e4%b8%80%e4%ba%9b%e5%bb%ba%e8%ad%b0" aria-label="這個段落的連結"></a></h2>
<p>可能是我運氣比較好，剛好測試到 ChatGPT 的許多 Bug，下面筆者彙整了一些遇到的「坑」給讀者參考：</p>
<ol>
<li><strong>ChatGPT 沒有最新資料</strong>：筆者在使用 ChatGPT 時，他的資料是在 2021 年截止的，也就是說他不認識新推出的套件，當套件有更新時他也無法第一時間知道。</li>
<li><strong>有些問題 ChatGPT 真的回答不出來</strong>：如果是程式邏輯問題，ChatGPT 有機會給出解答，但如果是套件相關問題，可能真的給不出解答；你一直問他也只是鬼打牆。</li>
<li><strong>似是而非的答案最可怕</strong>：ChatGPT 在上一篇（中文）跟這一篇（英文）給的答案，如果只看「邏輯」，那是正確的；但實際跑起來卻有一堆問題，不去看官方網站查證真的無法解決。</li>
</ol>
<p>會有上述問題，我覺得是因為 ChatGPT 還在學習、以及資料不夠即時；相信在未來推出新版時，能給出更正確的解答。</p>
<p>至於如何透過 ChatGPT 學程式，我的建議如下：</p>
<ol>
<li>要學習的<strong>程式語言、工具要有一定的年紀</strong>。</li>
<li>使用套件遇到錯誤時，<strong>先去官網看說明文件</strong>。</li>
<li>如果完全沒基礎，<strong>強烈建議先從書籍、課程開始學習</strong>。</li>
</ol>
<p>目前筆者把 ChatGPT 的定位放在「輔助」，適合給你方向、關鍵字、優化的建議；像是這次使用下來，雖然程式有些許錯誤，但是在「步驟、關鍵字、指令」方面的建議都是很不錯的。</p>
<p>未來筆者會出一系列使用 ChatGPT、openAI 的文章，如果你對這個議題感興趣，可以持續關注我的文章！</p>
<a class="linkcard" href="https://deanlin.net/categories/ai/">
  <span class="lc-body">
    <span class="lc-title">AI 實戰</span>
    <span class="lc-desc">實測生成式 AI 工具、Vibe Coding 與自動化流程的第一手心得，把 AI 變成每天都用得上的即戰力。</span>
    <span class="lc-site"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M5 12h14M13 6l6 6-6 6"/></svg>林鼎淵 Dean Lin</span>
  </span>
</a>

<p><strong>想將 AI 導入自己的職場與生活嗎？歡迎<a href="https://www.books.com.tw/products/0011004216">購買筆者出版的新書</a></strong>，幫助您<strong>在 AI 的浪潮中站穩腳步，並在未來的職場競爭中佔據優勢！</strong></p>
<figure class="figure"><img src="https://deanlin.net/blog/202301/chatgpt-line-bot-side-project-part-2/images/chatgpt-line-bot-side-project-part-2-21.webp" width="1400" height="319" alt="林鼎淵著作《ChatGPT 與 AI 繪圖效率大師（新增 Copilot、Gamma、Runway、Suno）》" loading="lazy" decoding="async">
  <figcaption><a href="https://www.books.com.tw/products/0011004216">https://www.books.com.tw/products/0011004216</a></figcaption>
</figure>

<p><strong>參考資料</strong>：</p>
<ol>
<li>用英文溝通 ChatGPT 得到的回覆：<a href="https://github.com/dean9703111/linebot-openai-chatgpt/blob/master/bug2-index.js">Github</a></li>
<li>筆者自己優化得到的解答：<a href="https://github.com/dean9703111/linebot-openai-chatgpt/blob/master/index.js">Github</a></li>
</ol>
]]></content:encoded>
    </item>
    <item>
      <title>靠問 ChatGPT 寫程式，能完成 OpenAI &amp; Linebot 的 Side Project 嗎？（上）</title>
      <link>https://deanlin.net/blog/202301/chatgpt-line-bot-side-project-part-1/</link>
      <pubDate>Wed, 25 Jan 2023 14:35:08 +0800</pubDate>
      <guid>https://deanlin.net/blog/202301/chatgpt-line-bot-side-project-part-1/</guid>
      <dc:creator>林鼎淵</dc:creator>
      <category>AI 實戰</category>
      <description>許多網紅都說 ChatGPT 寫程式的能力超強，不但可以解 LeeCode 還能幫你優化程式，甚至寫點小專案都不是問題，但事實真的是如此嗎？就讓筆者透過一個 Side Project 來測試看看。</description>
      <media:content url="https://deanlin.net/blog/202301/chatgpt-line-bot-side-project-part-1/images/chatgpt-line-bot-side-project-part-1-og_hu_517affb4376a2a91.jpg" medium="image" type="image/jpeg" width="1200" height="675" />
      <content:encoded><![CDATA[<p>許多網紅都說 ChatGPT 寫程式的能力超強，不但可以解 LeeCode 還能幫你優化程式，甚至寫點小專案都不是問題，但事實真的是如此嗎？就讓筆者透過一個 Side Project 來測試看看。</p>
<p><img src="https://deanlin.net/blog/202301/chatgpt-line-bot-side-project-part-1/images/chatgpt-line-bot-side-project-part-1-01.webp" width="1260" height="689" alt="靠問 ChatGPT 寫程式，能完成 OpenAI &amp; Linebot 的 Side Project 嗎？（上）（圖 1）" fetchpriority="high" decoding="async"></p>
<pre tabindex="0"><code>大綱

▋ 詢問 ChatGPT 實作的步驟
▋ 前置作業 1：申請 OpenAI API key
▋ 前置作業 2：取得 Line 的 Channel access token 和 Channel secret
▋ 建立 OpenAI-Linebot 的 Node.js 專案
▋ 小結：他還還努力學習中
</code></pre><h2 id="-詢問-chatgpt-實作的步驟">詢問 ChatGPT 實作的步驟<a class="h-anchor" href="#-%e8%a9%a2%e5%95%8f-chatgpt-%e5%af%a6%e4%bd%9c%e7%9a%84%e6%ad%a5%e9%a9%9f" aria-label="這個段落的連結"></a></h2>
<p>目前看起來，ChatGPT 回應給我的實作步驟可行性很高，而且每個重點都提示到了。</p>
<p><img src="https://deanlin.net/blog/202301/chatgpt-line-bot-side-project-part-1/images/chatgpt-line-bot-side-project-part-1-02.webp" width="1074" height="738" alt="詢問 ChatGPT 實作的步驟（圖 2）" loading="lazy" decoding="async"></p>
<hr>
<h2 id="前置作業-1申請-openai-api-key">前置作業 1：申請 OpenAI API key<a class="h-anchor" href="#%e5%89%8d%e7%bd%ae%e4%bd%9c%e6%a5%ad-1%e7%94%b3%e8%ab%8b-openai-api-key" aria-label="這個段落的連結"></a></h2>
<p><strong>SETP 1</strong>：進入 OpenAI 官網：<a href="https://beta.openai.com/">https://beta.openai.com/</a></p>
<p><strong>SETP 2</strong>：註冊 &amp; 登入 OpenAI 帳號，進入首頁。</p>
<p><img src="https://deanlin.net/blog/202301/chatgpt-line-bot-side-project-part-1/images/chatgpt-line-bot-side-project-part-1-03.webp" width="1400" height="729" alt="前置作業 1：申請 OpenAI API key（圖 3）" loading="lazy" decoding="async"></p>
<p><strong>SETP 3</strong>：點擊右上角圖像，選擇「View API keys」。</p>
<p><img src="https://deanlin.net/blog/202301/chatgpt-line-bot-side-project-part-1/images/chatgpt-line-bot-side-project-part-1-04.webp" width="722" height="476" alt="前置作業 1：申請 OpenAI API key（圖 4）" loading="lazy" decoding="async"></p>
<p><strong>SETP 4</strong>：點擊「Create new secret key」。</p>
<p><img src="https://deanlin.net/blog/202301/chatgpt-line-bot-side-project-part-1/images/chatgpt-line-bot-side-project-part-1-05.webp" width="1400" height="631" alt="前置作業 1：申請 OpenAI API key（圖 5）" loading="lazy" decoding="async"></p>
<p><strong>SETP 5</strong>：產生出來的 API Key 請保存好，之後你都不會再看到他了。</p>
<p><img src="https://deanlin.net/blog/202301/chatgpt-line-bot-side-project-part-1/images/chatgpt-line-bot-side-project-part-1-06.webp" width="1400" height="584" alt="前置作業 1：申請 OpenAI API key（圖 6）" loading="lazy" decoding="async"></p>
<hr>
<h2 id="前置作業-2取得-line-的-channel-access-token-和-channel-secret">前置作業 2：取得 Line 的 Channel access token 和 Channel secret<a class="h-anchor" href="#%e5%89%8d%e7%bd%ae%e4%bd%9c%e6%a5%ad-2%e5%8f%96%e5%be%97-line-%e7%9a%84-channel-access-token-%e5%92%8c-channel-secret" aria-label="這個段落的連結"></a></h2>
<p>因為步驟比較複雜，所以我有詢問一下 ChatGPT ：</p>
<p><img src="https://deanlin.net/blog/202301/chatgpt-line-bot-side-project-part-1/images/chatgpt-line-bot-side-project-part-1-07.webp" width="1085" height="656" alt="前置作業 2：取得 Line 的 Channel access token 和 Channel secret（圖 7）" loading="lazy" decoding="async"></p>
<p><strong>SETP 1</strong>：登入開發者平台，網址：<a href="https://developers.line.biz/zh-hant/">https://developers.line.biz/zh-hant/</a> 。</p>
<p><strong>SETP 2</strong>：建立一個 provider，名字自取。</p>
<p><img src="https://deanlin.net/blog/202301/chatgpt-line-bot-side-project-part-1/images/chatgpt-line-bot-side-project-part-1-08.webp" width="1400" height="730" alt="前置作業 2：取得 Line 的 Channel access token 和 Channel secret（圖 8）" loading="lazy" decoding="async"></p>
<p><img src="https://deanlin.net/blog/202301/chatgpt-line-bot-side-project-part-1/images/chatgpt-line-bot-side-project-part-1-09.webp" width="878" height="489" alt="前置作業 2：取得 Line 的 Channel access token 和 Channel secret（圖 9）" loading="lazy" decoding="async"></p>
<p><strong>SETP 3</strong>：選擇「Create a Message API channel」，我們要做一個聊天機器人。</p>
<p><img src="https://deanlin.net/blog/202301/chatgpt-line-bot-side-project-part-1/images/chatgpt-line-bot-side-project-part-1-10.webp" width="1400" height="668" alt="前置作業 2：取得 Line 的 Channel access token 和 Channel secret（圖 10）" loading="lazy" decoding="async"></p>
<p>接下來填寫一些必填資訊：</p>
<ul>
<li><strong>Company or owner&rsquo;s country or region</strong>：Taiwan</li>
<li><strong>Channel name</strong>：ChatGPT bot（自由填寫）</li>
<li><strong>Channel description</strong>：ChatGPT bot（自由填寫）</li>
<li><strong>Category</strong>：公眾人物、專業人士（自由填寫）</li>
<li><strong>Subcategory</strong>：IT、電腦（自由填寫）</li>
</ul>
<p><strong>SETP 4</strong>：最下面兩個同意事項要打勾才能按下「Create」按鈕。</p>
<p><img src="https://deanlin.net/blog/202301/chatgpt-line-bot-side-project-part-1/images/chatgpt-line-bot-side-project-part-1-11.webp" width="869" height="289" alt="前置作業 2：取得 Line 的 Channel access token 和 Channel secret（圖 11）" loading="lazy" decoding="async"></p>
<p>最後會讓你確認一下填寫的細節，還有一些規則提醒。</p>
<p><img src="https://deanlin.net/blog/202301/chatgpt-line-bot-side-project-part-1/images/chatgpt-line-bot-side-project-part-1-12.webp" width="901" height="548" alt="前置作業 2：取得 Line 的 Channel access token 和 Channel secret（圖 12）" loading="lazy" decoding="async"></p>
<p><strong>SETP 5</strong>：在 Basic settings 取得 Channel secret（這邊 ChatGPT 說錯成 General settings，不過大體意思能理解）。</p>
<p><img src="https://deanlin.net/blog/202301/chatgpt-line-bot-side-project-part-1/images/chatgpt-line-bot-side-project-part-1-13.webp" width="1332" height="543" alt="前置作業 2：取得 Line 的 Channel access token 和 Channel secret（圖 13）" loading="lazy" decoding="async"></p>
<p><strong>SETP 6</strong>：在 Messaging API 取得 Channel access token。</p>
<p><img src="https://deanlin.net/blog/202301/chatgpt-line-bot-side-project-part-1/images/chatgpt-line-bot-side-project-part-1-14.webp" width="1301" height="641" alt="前置作業 2：取得 Line 的 Channel access token 和 Channel secret（圖 14）" loading="lazy" decoding="async"></p>
<blockquote>
<p><strong>注意</strong>：<br>Channel access token 是用來驗證和保護機器人與 LINE Platform 之間的通訊，因此請勿將它公開給任何人。<br>Channel secret 則是用來驗證 Webhook 事件的簽章。</p>
</blockquote>
<hr>
<h2 id="建立-openai-linebot-的-nodejs-專案">建立 OpenAI-Linebot 的 Node.js 專案<a class="h-anchor" href="#%e5%bb%ba%e7%ab%8b-openai-linebot-%e7%9a%84-nodejs-%e5%b0%88%e6%a1%88" aria-label="這個段落的連結"></a></h2>
<p>下面的步驟，我是透過詢問 ChatGPT 所得到的：「接下來要如何建立一個 Node.js 專案，並安裝&quot;openai&quot; 和 &ldquo;@line/bot-sdk&rdquo; 等套件呢？有相關指令與程式範例嗎？」</p>
<p><strong>SETP 1</strong>：建立一個新的專案目錄，並在終端機中進入該目錄。</p>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>mkdir myproject
</span></span><span style="display:flex;"><span>cd myproject
</span></span></code></pre></div><p><strong>SETP 2</strong>：建立一個 package.json 檔案，並設定專案的相關資訊。</p>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>npm init
</span></span></code></pre></div><p><strong>SETP 3</strong>：安裝 &ldquo;openai&rdquo;、&quot;@line/bot-sdk&quot;、&ldquo;express&quot;套件（這邊原本是建議裝 line-bot-sdk 這個套件，但因為無法使用，所以請 ChatGPT 重選了一次）。</p>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>npm install openai @line/bot-sdk express
</span></span></code></pre></div><blockquote>
<p>注意！在使用上面的指令前，需要先安裝 Node.js 和 npm。</p>
</blockquote>
<p><strong>SETP 4</strong>：建立一個新的檔案放程式碼。</p>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>touch index.js
</span></span></code></pre></div><p><strong>SETP 5</strong>：在 index.js 中引用所需的套件，並設定 OpenAI 的 API key、Linebot 的 channelAccessToken、channelSecret。</p>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-javascript" data-lang="javascript"><span style="display:flex;"><span><span style="color:#ff7b72">const</span> openai <span style="color:#ff7b72;font-weight:bold">=</span> require(<span style="color:#a5d6ff">&#39;openai&#39;</span>);
</span></span><span style="display:flex;"><span><span style="color:#ff7b72">const</span> line <span style="color:#ff7b72;font-weight:bold">=</span> require(<span style="color:#a5d6ff">&#39;@line/bot-sdk&#39;</span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>openai.apiKey <span style="color:#ff7b72;font-weight:bold">=</span> <span style="color:#a5d6ff">&#34;YOUR_OPENAI_API_KEY&#34;</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ff7b72">const</span> config <span style="color:#ff7b72;font-weight:bold">=</span> {
</span></span><span style="display:flex;"><span>  channelAccessToken<span style="color:#ff7b72;font-weight:bold">:</span> <span style="color:#a5d6ff">&#39;YOUR_CHANNEL_ACCESS_TOKEN&#39;</span>,
</span></span><span style="display:flex;"><span>  channelSecret<span style="color:#ff7b72;font-weight:bold">:</span> <span style="color:#a5d6ff">&#39;YOUR_CHANNEL_SECRET&#39;</span>
</span></span><span style="display:flex;"><span>};
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ff7b72">const</span> client <span style="color:#ff7b72;font-weight:bold">=</span> <span style="color:#ff7b72">new</span> line.Client(config);
</span></span></code></pre></div><p><strong>SETP 6</strong>：在 index.js 中建立一個 HTTP server 並設定 line 的 webhook。</p>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-javascript" data-lang="javascript"><span style="display:flex;"><span><span style="color:#ff7b72">const</span> express <span style="color:#ff7b72;font-weight:bold">=</span> require(<span style="color:#a5d6ff">&#39;express&#39;</span>);
</span></span><span style="display:flex;"><span><span style="color:#ff7b72">const</span> app <span style="color:#ff7b72;font-weight:bold">=</span> express();
</span></span><span style="display:flex;"><span><span style="color:#ff7b72">const</span> port <span style="color:#ff7b72;font-weight:bold">=</span> <span style="color:#a5d6ff">3000</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>app.post(<span style="color:#a5d6ff">&#39;/webhook&#39;</span>, line.middleware(config), (req, res) =&gt; {
</span></span><span style="display:flex;"><span>  Promise
</span></span><span style="display:flex;"><span>    .all(req.body.events.map(handleEvent))
</span></span><span style="display:flex;"><span>    .then((result) =&gt; res.json(result))
</span></span><span style="display:flex;"><span>    .<span style="color:#ff7b72">catch</span>((err) =&gt; {
</span></span><span style="display:flex;"><span>      console.error(err);
</span></span><span style="display:flex;"><span>      res.status(<span style="color:#a5d6ff">500</span>).end();
</span></span><span style="display:flex;"><span>    });
</span></span><span style="display:flex;"><span>});
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>app.listen(port, () =&gt; {
</span></span><span style="display:flex;"><span>  console.log(<span style="color:#a5d6ff">`app is running on port </span><span style="color:#a5d6ff">${</span>port<span style="color:#a5d6ff">}</span><span style="color:#a5d6ff">`</span>);
</span></span><span style="display:flex;"><span>})
</span></span></code></pre></div><p><strong>SETP 7</strong>：在 index.js 中建立一個事件處理函式，當使用者發送訊息時，使用 OpenAI API 將訊息傳到指定的語言模型處理，並將回應的結果傳回給使用者。</p>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-javascript" data-lang="javascript"><span style="display:flex;"><span><span style="color:#ff7b72">function</span> handleEvent (event) {
</span></span><span style="display:flex;"><span>  <span style="color:#ff7b72">if</span> (event.type <span style="color:#ff7b72;font-weight:bold">!==</span> <span style="color:#a5d6ff">&#39;message&#39;</span> <span style="color:#ff7b72;font-weight:bold">||</span> event.message.type <span style="color:#ff7b72;font-weight:bold">!==</span> <span style="color:#a5d6ff">&#39;text&#39;</span>) {
</span></span><span style="display:flex;"><span>    <span style="color:#ff7b72">return</span> Promise.resolve(<span style="color:#79c0ff">null</span>);
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>  <span style="color:#ff7b72">return</span> openai.Completion.create({
</span></span><span style="display:flex;"><span>    engine<span style="color:#ff7b72;font-weight:bold">:</span> <span style="color:#a5d6ff">&#34;text-davinci-002&#34;</span>,
</span></span><span style="display:flex;"><span>    prompt<span style="color:#ff7b72;font-weight:bold">:</span> event.message.text,
</span></span><span style="display:flex;"><span>  }).then(response =&gt; {
</span></span><span style="display:flex;"><span>    <span style="color:#ff7b72">return</span> client.replyMessage(event.replyToken, {
</span></span><span style="display:flex;"><span>      type<span style="color:#ff7b72;font-weight:bold">:</span> <span style="color:#a5d6ff">&#39;text&#39;</span>,
</span></span><span style="display:flex;"><span>      text<span style="color:#ff7b72;font-weight:bold">:</span> response.choices[<span style="color:#a5d6ff">0</span>].text
</span></span><span style="display:flex;"><span>    });
</span></span><span style="display:flex;"><span>  });
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p><strong>SETP 8</strong>：最後啟動伺服器 <code>node index.js</code></p>
<p><img src="https://deanlin.net/blog/202301/chatgpt-line-bot-side-project-part-1/images/chatgpt-line-bot-side-project-part-1-15.webp" width="1270" height="202" alt="建立 OpenAI-Linebot 的 Node.js 專案（圖 15）" loading="lazy" decoding="async"></p>
<p>喔喔喔！居然沒有報錯！！！<br>之後可以請 ChatGPT 幫我完成 Side Project 了嗎？</p>
<blockquote>
<p><strong>小提醒</strong>：程式能啟動跟能順利執行是兩件事。</p>
</blockquote>
<hr>
<h2 id="小結他還在努力學習中">小結：他還在努力學習中<a class="h-anchor" href="#%e5%b0%8f%e7%b5%90%e4%bb%96%e9%82%84%e5%9c%a8%e5%8a%aa%e5%8a%9b%e5%ad%b8%e7%bf%92%e4%b8%ad" aria-label="這個段落的連結"></a></h2>
<p>其實過程並沒有想像中順利，上面放的步驟已經是多次優化後得到的答案，下面筆者放幾個請 ChatGPT 優化的片段。</p>
<p><strong>錯誤 1</strong>： 我按造步驟執行後，會噴錯誤：「TypeError: line.Client is not a constructor」</p>
<p><img src="https://deanlin.net/blog/202301/chatgpt-line-bot-side-project-part-1/images/chatgpt-line-bot-side-project-part-1-16.webp" width="1088" height="749" alt="小結：他還在努力學習中（圖 16）" loading="lazy" decoding="async"></p>
<p><strong>錯誤 2</strong>：我調整後，會噴錯誤：「TypeError: Cannot read properties of undefined (reading &lsquo;validateSignature&rsquo;)」</p>
<p><img src="https://deanlin.net/blog/202301/chatgpt-line-bot-side-project-part-1/images/chatgpt-line-bot-side-project-part-1-17.webp" width="1091" height="682" alt="小結：他還在努力學習中（圖 17）" loading="lazy" decoding="async"></p>
<p>其實還有其他錯誤，只是這兩個最嚴重，所以筆者單獨拿出來說一下。</p>
<p>對初學者而言而言，他們可能會覺得是程式哪裡寫錯了，只要修改一下就好；但實際上，真正的問題是<strong> ChatGPT 一開始推薦安裝的套件「line-bot-sdk」就是有問題的</strong>。</p>
<p>這邊放個截圖給大家看一下，<strong>這款套件已經有 7 年多沒有更新，而且幾乎沒有下載量！</strong>如果是缺乏經驗的開發者，應該會在這裡卡很久。</p>
<p><img src="https://deanlin.net/blog/202301/chatgpt-line-bot-side-project-part-1/images/chatgpt-line-bot-side-project-part-1-18.webp" width="1400" height="707" alt="小結：他還在努力學習中（圖 18）" loading="lazy" decoding="async"></p>
<p>後來我請他重新推薦，ChatGPT 才給了比較合理的套件，最後我請他改用「@line/bot-sdk」重寫一遍才得到上面的結果。</p>
<p><img src="https://deanlin.net/blog/202301/chatgpt-line-bot-side-project-part-1/images/chatgpt-line-bot-side-project-part-1-19.webp" width="1075" height="519" alt="小結：他還在努力學習中（圖 19）" loading="lazy" decoding="async"></p>
<p>不知道這篇文章會不會勸退一些使用者？</p>
<p>其實 ChatGPT 的問題並不只這些，<a href="https://deanlin.net/blog/202301/chatgpt-line-bot-side-project-part-2/">下一篇文章</a>我會帶大家把後面「啟動 server 並在 Line 開發者平台設定 webhook 的網址、測試機器人是否能正確回應使用者的訊息」等步驟走完，希望筆者踩過的坑能讓讀者日後使用時少走點彎路。</p>
<blockquote>
<p>本次 ChatGPT 回應的完整程式請參考筆者的 <a href="https://github.com/dean9703111/linebot-openai-chatgpt/blob/master/bug-index.js">Github</a></p>
</blockquote>
<p>未來筆者會出一系列使用 ChatGPT、openAI 的文章，如果你對這個議題感興趣，可以持續關注我的文章！</p>
<a class="linkcard" href="https://deanlin.net/categories/ai/">
  <span class="lc-body">
    <span class="lc-title">AI 實戰</span>
    <span class="lc-desc">實測生成式 AI 工具、Vibe Coding 與自動化流程的第一手心得，把 AI 變成每天都用得上的即戰力。</span>
    <span class="lc-site"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M5 12h14M13 6l6 6-6 6"/></svg>林鼎淵 Dean Lin</span>
  </span>
</a>

<p><strong>想將 AI 導入自己的職場與生活嗎？歡迎<a href="https://www.books.com.tw/products/0011004216">購買筆者出版的新書</a></strong>，幫助您<strong>在 AI 的浪潮中站穩腳步，並在未來的職場競爭中佔據優勢！</strong></p>
<figure class="figure"><img src="https://deanlin.net/blog/202301/chatgpt-line-bot-side-project-part-1/images/chatgpt-line-bot-side-project-part-1-20.webp" width="1400" height="319" alt="林鼎淵著作《ChatGPT 與 AI 繪圖效率大師（新增 Copilot、Gamma、Runway、Suno）》" loading="lazy" decoding="async">
  <figcaption><a href="https://www.books.com.tw/products/0011004216">https://www.books.com.tw/products/0011004216</a></figcaption>
</figure>

]]></content:encoded>
    </item>
  </channel>
</rss>
