鐵人賽完賽整理&開源 (30)

第12 屆iT邦幫忙鐵人賽系列文章 (Day30) 終於走到這一天了,每次都覺得鐵人賽過程都生不如死,但寫完30天候總有一種成就感,技術跟文章不難,難的是30天養成一個固定的習慣阿! 回到第一天文章所講的:所用到的技術預計採用 .NET Core 3.1、Html/CSS/JavaScript、Line API 、Azure的一些服務…等等 (但寫這篇文章時完全還沒實作XD…只能說待訂) 這次寫完30天也收穫良多,主要也是挑一些之前比較少碰的東西順便玩玩看 把 Line 的 Api 文件又完整K了一遍,並一個一個寫成 .NET Core 的版本, 之前比較沒碰過的是 Line Pay/Line Beacon 寫得過程中看到 vue 海賊王版本推出 (vue 3.0),起了專案實踐了一些功能,來看看它的架構 用了 Razor Page,讓我回到 ASP.NET WebForm 的復古感 玩了一些 Azure 服務,Azure Storage、QnA Maker,其中 Azure SignalR Service 是之前比較沒玩過的 把之前自己婚禮用的 chatbot 改一版,順便要給接下來結婚的朋友用 XD 真實的把所做的Side Project給用上 邊看文件邊寫SDK出來,並開源出來 本篇就來講講最後一哩路,怎麼發佈到 NuGet 上吧! 我將這次系列邊走邊看得的程式稍作整理,建立一個 .NET Core 的函示庫專案 在 VS 按右鍵套件 或者可以使用CLI : dotnet pack 編輯套件的資訊 release 編譯後,可以看到 bin\release 有 nupkg 檔案...

2020-11-30 · 1 min · Kyle

製作婚禮現場即時留言版- Azure SignalR Service II (29)

第12 屆iT邦幫忙鐵人賽系列文章 (Day29) 在上一篇我們用 Console App 發送訊息到 Api 的 Server Hub,並呈現在HTML上,今天這篇我們要來結合 chatbot,其實就是在chatbot當成SignalR的client而已,實際效果如下(本篇不會介紹CSS部分): 新增一個 MessageBoard class 來處理留言板發送,這部分可以看這篇 而透過 Line 的 User Id ,我們能取得使用者的大頭照.姓名…等等資訊 public async Task ReplyAsync(string replyToken) { var profile = await lineProfileUtility.GetUserProfile(userId); var hubClient = new ClientSignalR(); await hubClient.Initialize("http://localhost:12733/message"); await hubClient.SendHubMessage("SendMessage", profile.pictureUrl, profile.displayName, message); await lineMessageUtility.ReplyMessageAsync(replyToken, "謝謝您,我們已收到留言"); } GetUserProfile public async Task<UserProfile> GetUserProfile(string userId) { using (var httpClient = new HttpClient()) { using (var request = new HttpRequestMessage(new HttpMethod("GET"), $"{lineMessageApiBaseUrl}/{userId}")) { request....

2020-11-29 · 2 min · Kyle

製作婚禮現場即時留言版- Azure SignalR Service I (28)

第12 屆iT邦幫忙鐵人賽系列文章 (Day28) SignalR是實現即時通訊的框架,如下圖,在Server Hub宣告要給client端呼叫的方法,能傳送即時訊息給已連線的使用者 https://www.pubnub.com/learn/glossary/what-is-signalr/ 而透過Azure SignalR 服務,大大簡化使用門檻,很簡單就能建立一個服務,且享有雲端帶來的高拓展性,這篇文章會step by step 實作以下內容 建立 Azure SignalR 服務 建立 SignalR Server Hub 建立 HTML Client 即時呈現訊息 建立 .NET Console App 來發送訊息 建立 Azure SignalR 服務 登入Azure,進入https://portal.azure.com/#create/Microsoft.SignalRGalleryPackage 新增服務 建完後,到key的選單,我們等等需要這個 Connection String 建立 SignalR Server Hub 打開 Web Api 專案的 .csproj,加入以下程式碼 <ItemGroup> <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0" /> <DotNetCliToolReference Include="Microsoft.Extensions.SecretManager.Tools" Version="2.0.0" /> </ItemGroup> 用 Nuget 安裝 Microsoft.Azure.SignalR 在 Web Api 專案案右鍵,建立管理使用者密碼, 建立 Azure:SignalR:ConnectionString ,把剛剛的連線字串貼上 Web Api 專案 Startup....

2020-11-28 · 2 min · Kyle

收集婚禮現場照片- 將圖片用C#傳到 Imgur 服務 (27)

第12 屆iT邦幫忙鐵人賽系列文章 (Day27) 婚禮現場一定會有各種親朋好友視角的照片,以往都要一個一個傳在社群媒體之類的,本次來實作 chatbot 來廣收各種朋友拍的照片.. XD 上傳到 Imgur Imgur是個圖床服務,如果是非商業使用,是完全免費的,串接起來也很容易,首先先到 https://api.imgur.com/oauth2/addclient 註冊一個 OAuth 服務 會得到 client id 和 client secret 回到 LineBotApp.cs,我們可以針對圖片類型的訊息做處理 GetContentBytesAsync public async Task<Stream> GetContentBytesAsync(string messageId) { using (var httpClient = new HttpClient()) { using (var request = new HttpRequestMessage(new HttpMethod("GET"), $"https://api-data.line.me/v2/bot/message/{messageId}/content")) { request.Headers.TryAddWithoutValidation("Authorization", $"Bearer {accessToken}"); var response = await httpClient.SendAsync(request); var results = await response.Content.ReadAsStreamAsync(); return results; } } } UploadToImgurAsync 可以透過 Nuget 安裝 Imgur.API public async Task<string> UploadToImgurAsync(Stream stream) { var apiClient = new ApiClient("<Your Imgur ClientId>"); var httpClient = new HttpClient(); var imageEndpoint = new ImageEndpoint(apiClient, httpClient); var imageUpload = await imageEndpoint....

2020-11-27 · 1 min · Kyle

婚禮禮金用Line Pay II (26)

第12 屆iT邦幫忙鐵人賽系列文章 (Day26) 以下是 Line 官方文件的流程,今天會依據這個圖的流程來實作 Line Pay 付款 https://pay.line.me/jp/developers/apis/onlineApis?locale=zh_TW Checkout 流程 官方API文件可以從這裡看到 Request Body 的 C# Class public class LinePayRequest { public int amount { get; set; } public string currency { get; set; } public string orderId { get; set; } public List<Package> packages { get; set; } public Options options { get; set; } public Redirecturls redirectUrls { get; set; } } public class Package { public string id { get; set; } public int amount { get; set; } public string name { get; set; } public List<Product> products { get; set; } } public class Product { public string id { get; set; } public string name { get; set; } public string imageUrl { get; set; } public int quantity { get; set; } public int price { get; set; } } public class Options { public Payment payment { get; set; } } public class Payment { public bool capture { get; set; } } public class Redirecturls { public string confirmUrl { get; set; } public string cancelUrl { get; set; } } 整個 Post 的 Body 可以這樣組成,channelId和channelSecret可以在前一篇申請sandbox時候取得...

2020-11-26 · 2 min · Kyle