2019年7月18日 星期四

使用C#開發LINE Bot(32) – .net core 2.2 WebHook 範例

前面我們談過了如何在 .ner core環境上透過 LineBotSDK發送訊息。我們今天來看如何建立一個WebHook…

我們先看執行結果:

當你跟bot說hello的時候,他會echo你hello,當你說 /show ButtonTempalte的時候,他會reply一個tempalte訊息,當你傳送貼圖的時候,它會回你一個貼圖。

我們來看WebHook的程式碼:

剛才我們說到依照用戶傳來的訊息,回覆相對的訊息的部分,是在27-78行,其中回覆文字訊息的部分是29-57行。你會看到我們在程式碼當中,透過bot物件採用ReplyToken回覆訊息。

回覆多則訊息

比較值得注意的地方是,我們回覆訊息的程式碼其實統一寫在76行,回覆的物件是responseMsgs,這是一個訊息的集合。裡面至多可以放5則訊息。而前面程式碼當中的判斷與回覆,其實只是把準備要回覆的訊息加入這個responseMsgs物件中。這樣的寫法比較理想,因為依照LINE的規格,ReplyToken只能使用一次,如此做法可以在程式碼的單一地方一次性的處理回覆,比較好管理,不容易發生replyToken使用多次的錯誤。

另外,程式碼最上面的5,6兩行,是從json檔案中取得appSetting,這是.net core新的做法,請讀者測是這個範例時,也要記得開啟appsettings.json置換當中的token與admin user ID:

程式碼的18-23行,其實就是取得LINE傳來的http body,並且透過我們的SDK Parsing成為ReceivedMessage物件,其中就包含了用戶跟我們LINE Bot對談傳來的訊息,後面25行LineEvent的操作我覺得我們的讀者應該就不陌生了。

小結

總的來說,使用.net core開發LINE Bot現在已經相對算是成熟很多了,我們的SDK目前也已經全面支援,不管是發送(push)/回覆(reply)文字或template訊息基本上都沒有甚麼問題。

而整段程式碼與過去最大的不同之處,大概只有取得config環境變數的作法稍有不同,完整的程式碼已經在Github上等你,請直接clone或fork下來使用即可,不用客氣。

如果你要測試,無須安裝VS 2019,使用MAC+VS Code開發也是很好的選擇,參考前面介紹過的做法,透過dotnet run指令執行之後,搭配ngrok來運作即可測試使用。

完整的程式碼請參考Github:  https://github.com/isdaviddong/LineBotSdkDotNetCoreWebExample

Hope it helps.

-----------
最新實體課程:http://www.studyhost.tw/NewCourses/LineBot
線上課程:https://www.udemy.com/line-bot/
電子書:http://studyhost.blogspot.tw/2017/12/line-bot.html
LineBotSDK:https://www.nuget.org/packages/LineBotSDK
如果需要即時取得更多相關訊息,可按這裡加入FB專頁。若這篇文章對您有所幫助,請幫我們分享出去,謝謝您的支持。

2019年7月14日 星期日

使用C#開發LINE Bot(31) – .net core 2.2 Web範例

一路上都有不少朋友問過:『LineBotSDK怎麼還不支援 .net core呢?』 我總是回答『手邊事情太多,一直沒時間啊…』不過,老是跟人說:『你永遠有時間做你認為重要的事…』我自己卻拿沒時間當藉口,似乎有點牽強…

該怎麼說呢,總之,我覺得目前看起來, .net core 2.2 似乎是一個挺好的起跑點,所以,我們準備全面開始支援 .net core囉。

SDK

關於LineBotSDK的 .net core套件,前幾天已經跟朋友們介紹過了,我們剛更新了一個 beta3 的版本,幾乎已經可以當作正式版使用了,nuget package 可以參考底下網址:
https://www.nuget.org/packages/LineBotSDK/2.0.0-beta3

這包package可以直接支援 .net framework 與 .net core,所以不管你用哪一種開發技術(只要是 .net)你都只需要直接引用就好。所有的API都在同樣的namespace底下,如果你想把source code從WebForm轉成 .net core,也完全不用改API的用法。

razor page 範例

很久以前我就說過,上了 .net core之後,我自己大部分的專案選擇用razor pages來開發Web專案(少部分用 .net core mvc,箇中原因有機會再慢慢談,不過,.net core的WebAPI依舊是要的),所以,底下這個部分我們會直接介紹一個使用 .net core 2.2 razor pages開發以及透過 .net core WebAPI來做LINE Bot WebHook的範例。

不管你用的是MAC或是PC,不管使用VS 2019或VS Code,你都可以直接在command line底下建立一個資料夾,然後執行底下指令,clone github上的專案…

git clone https://github.com/isdaviddong/LineBotSdkDotNetCoreWebExample.git

當然,別跟我說你沒安裝 Git 和 dotnet SDK

執行後你應該會看到類似底下這樣的輸出:

Cloning into 'LineBotSdkDotNetCoreWebExample'...
remote: Enumerating objects: 29, done.
remote: Counting objects: 100% (29/29), done.
remote: Compressing objects: 100% (25/25), done.
remote: Total 29 (delta 6), reused 22 (delta 3), pack-reused 0
Unpacking objects: 100% (29/29), done.
Checking connectivity... done.

接著,請用底下指令進入到包含 .sln 的資料夾

cd LineBotSdkDotNetCoreWebExample
cd main

然後執行底下指令(請確定您有安裝 .net sdk 2.2)

dotnet build

你應該會看類似底下這樣的回應:

Microsoft (R) Build Engine for .NET Core 15.9.20+g88f5fadfbe 版
Copyright (C) Microsoft Corporation. 著作權所有,並保留一切權利。

  正在還原 D:\test\linebottest\LineBotSdkDotNetCoreWebExample\main\main\main.csproj 的封裝...
  正在安裝 System.Composition.TypedParts 1.0.31。
  正在安裝 System.Composition.Convention 1.0.31。
  正在安裝 System.Composition.Runtime 1.0.31。
  正在安裝 System.Composition.AttributedModel 1.0.31。
  正在安裝 System.Composition.Hosting 1.0.31。
  正在安裝 System.Composition 1.0.31。
  正在安裝 System.Linq.Parallel 4.3.0。
  正在安裝 Microsoft.CodeAnalysis.Workspaces.Common 2.8.0。
  正在安裝 Microsoft.CodeAnalysis.CSharp.Workspaces 2.8.0。
  正在安裝 Microsoft.VisualStudio.Web.CodeGeneration.Design 2.2.3。
  正在安裝 Newtonsoft.Json 12.0.2。
  正在安裝 Microsoft.VisualStudio.Web.CodeGenerators.Mvc 2.2.3。
  正在安裝 NuGet.Frameworks 4.7.0。
  正在安裝 Microsoft.VisualStudio.Web.CodeGeneration 2.2.3。
  正在安裝 Microsoft.VisualStudio.Web.CodeGeneration.Contracts 2.2.3。
  正在安裝 Microsoft.VisualStudio.Web.CodeGeneration.Utils 2.2.3。
  正在安裝 Microsoft.VisualStudio.Web.CodeGeneration.Templating 2.2.3。
  正在安裝 Microsoft.VisualStudio.Web.CodeGeneration.Core 2.2.3。
  正在安裝 Microsoft.VisualStudio.Web.CodeGeneration.EntityFrameworkCore 2.2.3。
  正在安裝 LineBotSDK 2.0.0-beta3。
  正在產生 MSBuild 檔案 D:\test\linebottest\LineBotSdkDotNetCoreWebExample\main\main\obj\main.csproj.nuget.g.props。
  正在產生 MSBuild 檔案 D:\test\linebottest\LineBotSdkDotNetCoreWebExample\main\main\obj\main.csproj.nuget.g.targets。
  D:\test\linebottest\LineBotSdkDotNetCoreWebExample\main\main\main.csproj 的還原於 32.02 sec 完成。
  main -> D:\test\linebottest\LineBotSdkDotNetCoreWebExample\main\main\bin\Debug\netcoreapp2.2\main.dll
  main -> D:\test\linebottest\LineBotSdkDotNetCoreWebExample\main\main\bin\Debug\netcoreapp2.2\main.Views.dll

建置成功。
    0 個警告
    0 個錯誤

經過時間 00:00:47.74

完成後,接著可以用底下指令進入到包含 .csproj 的資料夾

cd main

然後執行

dotnet run

如果沒有意外,你應該會看到底下回應

Hosting environment: Production
Content root path: D:\test\linebottest\LineBotSdkDotNetCoreWebExample\main\main
Now listening on: http://localhost:5000
Now listening on: https://localhost:5001
Application started. Press Ctrl+C to shut down.

這時候你就可以開啟browser,輸入 http://localhost:5000
會看到底下網頁:

只需要在上面輸入你的 channel access token 與 userID,就可以測試發訊息給特定 user囉…

Razor Pages

.net core 的Razor Pages Web專案我們將主程式碼放在 Pages資料夾底下的 index.cshtml與index.cshtml.cs。先來看index.cshtml的部分:

<html>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/css/bootstrap.min.css" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script>
    <script>
    </script>
</head>
<body>
    <h3>LINE Bot - Send Message Test</h3>
    <div class="row" style="margin:10px">
        <div class="col-12">
            <form method="POST">
                @Html.AntiForgeryToken()
                <div class="card">
                    <div class="card-body">
                        <label>LINE Bot Channel Access Token:</label>
                        <textarea class="form-control" name="txbToken" rows="2">@Model.txbToken</textarea>
                        <label>To User ID:</label>
                        <input class="form-control" name="txbUserId" value="@Model.txbUserId" />
                        <div class="row">
                            <div class="col-6">
                                <label>Message:</label>
                                <input class="form-control" name="txbMessage" value="@Model.txbMessage" />
                                <button type="submit" asp-page-handler="SendMessage">Send Message</button>
                            </div>
                            <div class="col-6">
                                <label>sticker:</label>
                                <input class="form-control" name="txbStickerPkgId" value="@Model.txbStickerPkgId" />
                                <input class="form-control" name="txbStickerStkId" value="@Model.txbStickerStkId" />
                                <button type="submit" asp-page-handler="SendSticker">Send Sticker</button>
                            </div>
                            <label>
                                RESULT (JSON) :  @Model.result
                            </label>
                        </div>
                    </div>
                </div>
            </form>
        </div>
    </div>
</body>
</html>

在razor pages裡面,大部分程式碼都是很單純的HTML,無需太多解釋,只有 27 和 33行的兩個Submit Button,我們用到了 .net core razor 的 asp-page-handler 這個attribute。這個attribute它會讓按鈕觸發後端相對應的OnPost_____() 方法,所以你會看到我們後端的程式碼是這樣寫的…

        public void OnPostSendMessage()
        {
            if (string.IsNullOrEmpty(txbToken) ||
                string.IsNullOrEmpty(txbUserId) ||
                string.IsNullOrEmpty(txbMessage))
            {
                this.result = "cannot push message due to missing information...";
            }
            else
            {
                var bot = new isRock.LineBot.Bot(this.txbToken);

                var ret = bot.PushMessage(this.txbUserId, this.txbMessage);
                this.result = ret;
            }
        }
        
        public void OnPostSendSticker()
        {
            if (string.IsNullOrEmpty(txbToken) ||
                    string.IsNullOrEmpty(txbUserId))
            {
                this.result = "missing data...";
            }
            else
            {
                var bot = new isRock.LineBot.Bot(this.txbToken);

                var ret = bot.PushMessage(
                    this.txbUserId,
                    new isRock.LineBot.StickerMessage(this.txbStickerPkgId, this.txbStickerStkId)
                    );
                this.result = ret;
            }
            return;
        }

第1行和第18行的兩個method,分別對應到前端button按下後的功能,你會發現裡面就是很單純的透過LineBotSDK來發送訊息,如此這般,就完成囉…

關於WebHook

這個範例不只支援訊息發送,當然還有訊息的接收,我們先把sample code放在GitHub分享給大家了,下一篇我們再來談談 WebHook 的部分…

-----------
最新實體課程:http://www.studyhost.tw/NewCourses/LineBot
線上課程:https://www.udemy.com/line-bot/
電子書:http://studyhost.blogspot.tw/2017/12/line-bot.html
LineBotSDK:https://www.nuget.org/packages/LineBotSDK
如果需要即時取得更多相關訊息,可按這裡加入FB專頁。若這篇文章對您有所幫助,請幫我們分享出去,謝謝您的支持。

2019年7月4日 星期四

使用PowerShell刪除Azure訂閱中沒有任何資源的資源群組

先前提到,在我棄明投暗開始改用CLI之後,Windows世界裡的PowerShell我當然不可能不去碰。對PowerShell來說,我應該算是新手(資訊界非常有趣,每隔一段時間你就會自動升級為新手,偶而享受一下可以亂做一些蠢事的新手禮遇其實還挺不錯)。

而對新手來說,認識某一種工具或技術的第一件事情,當然就是拿它來弄出一個自己需要的解決方案。PowerShell對我最大的用途當然是控制Azure訂閱,而第一個讓我想幹的解決方案就是,殺光…空著的資源群組。

不知道你有沒有跟我一樣的問題,你知道,Microsoft很大方地給開發人員Azure Free trial帳號、visual studio dev essentials、上課的Azure Pass…等諸多Azure資源。這導致我有非常多的Microsoft Account(MSA)、每個Account底下有非常多的Subscription,每個Subscription底下有一堆常常移動過來移動過去的Resource Group…箇中原由就暫且不表(內行人一定知道)…

當我把Resource Group在subscription之間移來移去的過程中,總是會留下很多空的Resource Group,這很煩、很難看、很難管…

所以我閒暇之餘常常從Azure Portal進去,一個一個Resource Group點進去看看裡面有沒有Resource(這很白癡,對,我知道…)如果是空著的話我就刪除它…很久很久以前我就知道這樣很蠢,根本不是辦法…應該要寫個script去處理它…

但一來沒空二來我內心掙扎不想碰CLI,所以連帶PowerShell也不太動手…好啦,現在我洗心革面棄明投暗之後,第一件解決自己問題的PowerShell巨作,當然就是寫一個刪除empty resource group的script…

寫完之後的結果如下:

由於用到了PowerShell的az Module,如果你要拿去玩耍的話,請記得使用底下指令安Az Module:

Install-Module -Name Az –AllowClobber

相關資訊可以參考: https://docs.microsoft.com/zh-tw/powershell/azure/install-az-ps?view=azps-2.4.0

如果你用PowerShell ISE執行的話,刪起來還蠻過癮的…

要不要拿去試試看? Enjoy it :)

不負責任聲明…

對了,請特別留意,別忘了上面這段code是新手之作,一出手就用 Remove-AzResourceGroup 指令移除整個 resource group,萬一有bug導致發生誤刪resource group的慘案發生,請千萬不要回來找我

Related Posts Plugin for WordPress, Blogger...

熱門文章