2017年12月17日 星期日

使用C#開發LineBot(15) – 當Linebot與我們同在一起, 談群組(聊天室)處理

2017年下旬,Line更新了相關的API,終於讓Linebot可以抓取到群組中的用戶的資訊,這一點看似不起眼,但其實沒有這個功能的話,相當程度的限制了Linebot在群組中的可能性。

也因此,雖著Line開發相關API,我們的LineBotSDK當然也跟著支援了,請將專案中的LineBotSDK更新到v0.6.1-beta即可享有此功能:

更新後你會發現有幾個跟群組聊天有關係的API,分別是

  • LeaveRoom
  • LeaveGroup
  • GetRoomMemberProfile
  • GetGroupMemberProfile

在開始之前,你需要知道一些基本概念:

  1. Line裡面的群組聊天有兩種,分別是room與group
  2. 你隨意地邀請幾個人加入聊天,那一種叫做room
  3. 你透過選單所建立的群組,叫做group
  4. 一個群組裡面只能加入一隻bot
  5. 你的bot無法知道是誰把自己加進來的
  6. 但你的bot可以知道群組中當前說話的人是誰(意味著,可以取得他的個人資料,包含頭像、顯示名稱…等),即便你的bot沒有跟發話者成為好友。
  7. 你的bot只能被某人加入群組,無法主動加入群組,但可以主動離開群組。

好了,有了這些基本概念之後,我們可以開始來玩玩看,請先大致瀏覽一下底下這段code,這是WebHook的片段程式碼(完整程式碼位於github https://github.com/isdaviddong/LinebotInTheGroup)  :


接著我們看運行的結果,當我們在兩人對話的狀況下,可以透過邀請好友的方式,把一隻bot加入對談:

注意上面testlinebot2018這支bot,請觀察他回復的訊息,你會發現,他是知道自己是被加入room還是group中的(這資訊很重要,可以透過source.type取得)。

同時,當你對照上面的code也可以知道,當bot被加入群組(room/group)時,WebHook會收到一個join的event(位於第12行)。

接著,你可以試試看在群組中說話:

你會發現,當bot收到你的訊息時,WebHook會收到一個message event(第18行),其中可以取得說話者的userId(36行),透過UserId你可以取得該人的個人資訊(35行, GetRoomMemberProfile),最後回應給群組中所有人(一樣透過Reply即可, 45行)。

如果要讓bot離開群組,只需要針對呼叫LeaveRoom/LeaveGroup即可(25,27行),例如:

當你對bot說bye,你會發現bot在說完bye-bye之後,就離開聊天室了,對應到上面的程式碼就是第行,呼叫LeaveRoom或是LeaveGroup API即可,請留意,一但bot主動離開,bot是無法自己重新加回群組或聊天室的,必須『被加入』才行。

其實用起來並不難,但有這幾個功能之後,你的bot可以做的事情就非常多了,改天我們再來談談一些具體的應用實例。

------------------
相關課程: http://www.studyhost.tw/NewCourses/LineBot
LineBotSDK : https://www.nuget.org/packages/LineBotSDK
如果需要即時取得更多相關訊息,可按這裡加入FB專頁。若這篇文章對您有所幫助,請幫我們分享出去,謝謝您的支持。

2017年12月11日 星期一

MS Teams - 透過Incoming WebHook將通知傳入Channel

如果你開始使用MS Teams,Incoming WebHook是個不用可惜的簡單機制。

需求是這樣,我們常常在工作上想要在某些事件發生時(例如失火,系統崩潰、訂單爆量…)發生的時候,可以透過手機推播訊息的方式告知大家,而MS Teams中的Channel,本身就有手機App可以接收推送訊息,如果企業有使用免費的MS Teams(只要你有Office 365),那沒什麼道理不安裝這個App(因為平時跟同事的溝通、群組討論…都在用才對)…

因此,當事件發生時,把訊息送到Channel中是再合理不過的了。

怎麼實現呢?簡單到不行,首先,請先建立一個連接器(看你要在哪一個channel收到通知,就在哪一個channel裡面建):

在出現的連接器清單中,找到『Incoming WebHook(傳入WebHook,嘖嘖…翻譯的真好)』:

點選設定後,在接下來出現的畫面中,逐一填入:

最後按下建立,完成後會出現底下這一組URL:

請務必複製該URL,未來你只需要對該URL送出Post訊息,即可把訊息發到該channel,有訂閱該channel的用戶,自然可以在手機App上收到該通知。

例如,當你對WebHook URL送出底下訊息:

用戶會收到:

手機上也會收到通知:


很簡單吧… :)

2017年11月30日 星期四

關於bot framework (7) - 快速建立並測試MS Teams bot

MS最近推Teams推得很兇,但不知道有多少台灣企業開始使用MS Teams?

如果你也開始用,應該會知道裡面有一個T-Bot,也就是MS teams的bot,它可以擔任一些基礎的引導工作,但也僅此而已。不過,類似Slack一樣,你可以自己開發一個chat bot,掛在MS Teams裡面,做一些日常的查詢功能,例如查詢分機、檢索資料位置、一般員工 Q & A、教育訓練索引、或是更進一步的與ERP整合,來查詢訂單、庫存…等。

而且開發方式極其簡單,只需要透過MS bot framework就可以了,也就是說,IT人員可以透過bot framework,幾乎不用寫什麼code就完成一個可以運行在MS Teams裡面的T-Bot。

你可以先從透過azure建立一個bot開始:

在azure站台中,你可以透過搜尋 bot service找到(上圖),點選後,請選下圖中的建立:

接著填妥底下的資料,最後按下建立:

完成後,portal會自動跳到底下這樣的設定畫面,請依照您的需要選擇,如果您熟悉C#,您可以不勾選任何項目,以預設的值進行配置:

選擇Next之後,會出現底下畫面:

由於bot framework會需要您建立一個Microsoft App,因此azure portal會透過上圖的畫面引導你建立一個App,最終我們需要得到App Name, AppID與Password這三組資訊,請點選上圖中的Create…,接著,會自動跳出底下這樣的畫面:

系統已經自動為您產生同樣名稱的App,以及所需要的App ID,你只需點選上圖中的藍色按鈕『Generate…』,在接下來出現的畫面中,牢記你的Password(因為只會出現一次):

記好password之後,按下『Finish…』鈕回到原本的畫面,這時,你要填入剛才記得的密碼即可:

所有的設定完成之後,就會看到底下這個畫面,這表示你的bot已經被自動建立完成,到目前為止我們還沒寫任何一行程式碼:

當你點選上圖物中的這個『→test』鈕,azure portal會出現一個web的測試UI,讓你可以直接跟chat bot對話,當然,目前這個chat bot只會echo,但已經很不錯了。

如果你希望調整chat bot的功能,讓它多做一些事情,你可以點選上圖中的Download zip file下載source code,以VS2017開啟修改,你會發現其實就是一個很標準的bot framework框架所建立的Web API:

你可以修改程式碼後,將該Web Site Deploy到剛才建立的這個bot所關聯的Azure Web App站台即可。

好,上面是透過Azure建立chat bot的過程,回到我們的T-bot。

你可能不知道,這樣建立好的chat bot其實已經可以支援MS Teams了,只需要點選channels,選擇底下的Teams圖示:

按下 Done 就可以啦:

就只需要這樣,這個透過bot framework所建立的Chat bot已經支援MS Teams了,如果你想要測試,只需要進入到MS Teams的一對一聊天畫面,在『搜尋區塊』放大鏡的右邊,點選該圖示,然後在『收件人』欄位上,填入剛才建立好的這個chat bot的App ID,即可找到該chat bot:

這樣就可以在Teams中與他對談囉:

果然是我們這個只會echo的chat bot沒錯…

完全不用寫任何一行Code,MS Teams bot就搞定啦。

咦? 不記得剛才的App ID? 不要緊,在azure portal中bot的Settings頁面中,可以找到當時你建立的App ID:

一切都很輕鬆容易吧…

--------------------

相關課程: http://www.studyhost.tw/NewCourses

如果需要即時取得更多相關訊息,可按這裡加入FB專頁。若這篇文章對您有所幫助,請幫我們分享出去,謝謝您的支持。

2017年11月29日 星期三

關於LineBot(14) – 新版建立Line Bot流程(2017年底)

2017年底,Line又改了一些東西,比較重要的影響是建立Line bot的入口,過去我們習慣從Line@ Manager那邊進去,現在建立Line Bot建議讀者可以從底下位置:
https://developers.line.me

進入後請點選:

如果你還沒登入Line,會跳出一個登入畫面讓你先登入:

登入後就會到選取Provider的畫面:

這個Provider是什麼呢? 你可以建立『公司』或『個人』,這是便於你日後管理Line bot使用,如果只是測試,你可以隨意建立一個。

點選了上圖的Next Page之後,會出現底下畫面:

說明如下:

A>你的line bot的Icon
B>你的Line bot的名稱
C>說明文字
D>方案,如果你要測試,請選擇Developer Trial,因為這個方案才有Push API,否則Free方案只能回覆訊息,無法主動發送訊息。但Developer Trial方案有50個好友的限制。(但如果你要申請正式帳號,則需要先申請Free,然後再付費升級它成為正式帳號,即可享有Push API的功能)
E>帳號類型,依照你的用途選擇即可。
F>管理者Email

完成後按下 Confirm 鈕,接著會出現讓你非同意不可的條款,請乖乖打勾:

然後按下Create,就建立完成啦:

你點選上面這個頭像後,依舊可以看到熟悉的管理後台,包含建立Channel Access Token的位置,設定WebHook的位置,都在:

基本上,這是個沒甚麼真正改變的改變,大致上申請流程都完全相同,除了再次體驗到Line這家公司在Web Site UI/UX Design上的能力真的普普之外,沒什麼特別感想。

------------------
相關課程: http://www.studyhost.tw/NewCourses/LineBot
LineBotSDK : https://www.nuget.org/packages/LineBotSDK
如果需要即時取得更多相關訊息,可按這裡加入FB專頁。若這篇文章對您有所幫助,請幫我們分享出去,謝謝您的支持。

2017年11月28日 星期二

MS Enterprise Library 6.0 (六) - 透過Attribute處理Exception

上一篇我們談過了AOP的概念以及如何透過attribute來實作類AOP的機制之後,你一定會想,要說Infrastructure Logic最容易跟Business夾雜在一起的情境,莫過於try…catch了,任何Business Logic中夾雜著try…catch,都很容易造成程式碼的過度相依,我們是否可以透過前面學習到的概念,利用Attribute來處理Exception呢?

我們看底下這段Code:

上面這段程式碼和上一篇我們介紹時的一樣,唯一的差別是第13行我們多加了一個ExceptionNotify的Attribute,這個Attribute會讓Calculate()這個Method發生Exception之後,自動將Ecception的狀態寫入LogFileName指定的log.txt檔。而無須把這樣寫log的程式碼用try…catch的方式寫在Calculate()這個Method當中…怎麼實現的呢?

我們看ExceptionNotify這個Attribute:

我們只需要繼承PolicyInjectionAttributeBase,建立一個自己的ExceptionNotify,並且override OnException(sender,e)這個Method,在其中進行我們想做的錯誤處理即可。

如此一來,當掛上該Attribute的Method發生Exception時,就會觸發你在OnException中寫的code,將Log儲存到LogFileName所指定的檔案位置了:

如此一來,就再也不需要把處理例外的程式碼雜亂的混入Business Logic程式碼中了,不失為降低相依性的一個好方法。

完整程式碼可以參考:
https://github.com/isdaviddong/isRock.Framework.AOP-Examples

-----------------
相關教育訓練: http://www.studyhost.tw/NewCourses/Architecture
若這篇文章對您有所幫助,請點選這裡加入FaceBook專頁按讚並追蹤,也歡迎您幫我們分享出去,謝謝您的支持。

2017年11月20日 星期一

MS Enterprise Library 6.0 (五) - 再談AOP, 如何實作?

這系列的上一篇居然是2013年…沒說錯,是2013,四年前!!!

MS Enterprise Library 6.0(一) - Unity Application Block
MS Enterprise Library 6.0 (二) - Logging Application Block
MS Enterprise Library 6.0 (三) - Exception Handling Application Block
MS Enterprise Library 6.0 (四) - Policy Injection Application Block

說真的,如果不是因為開了課,我根本早忘記我曾經寫過上面這幾篇文章。

上週六,是『團隊開發 與 架構設計 實務 』這個課程的第二天上課,在課程中我們談到了一個框架設計上我常用的技巧,也就是如何透過Attribute來實作AOP(嚴格說起來是廣義的AOP)。如果你不確定明白AOP(Aspect-Oriented Programming)的基本概念,可以參考四年前的這篇。(天啊,四年前…)

課程中,我做了一個範例(具體內容後面說),和某位學員討論的時候,突然看到學員的螢幕上出現了一篇看似有點眼熟的文章,語氣跟我好像…咦? 作者怎麼是我?是了,就是剛才說的四年前寫的那篇這篇文章中介紹了PIAB(policy injection application block),這是當年我在Tech Days介紹MS Enterprise Library時,特別喜愛的一個application block,它很精采的把Business Logic和Infrastructure Logic做一個非常有效的切割,達成cross-cutting concerns的獨立性。

這一系列的文章或許是因為點擊率不很高,也或者是當時有別的事情再忙…我寫著寫著居然就忘了…也因此這個系列就沒了下文。時過境遷,這次上課的時候,我也不再介紹PIAB,因為這個PIAB Library的nuget套件很不爭氣的始終停留在2013年都沒更新,因此我們只能從底層架構說明透過Attribute實現AOP概念的作法。

不過這樣也好,學員可以從根本理解實現AOP可能的幾個方式 。然而,美中不足的是這樣去實現AOP的Method呼叫時,就得要有另一個Loader/Lancher來做attribute行為上的判斷。

『這樣呼叫Method時似乎有些不直覺?有沒有更好的做法?』學員問。

『其實你可以自己仿Unity Container做一個Proxy的機制…』因為在課堂上我們還有一併介紹到Unity,因此我這麼回答。

然而因為時間的關係,我也就無法在課堂上直接做一個Demo,想想頗為遺憾,因此課程結束後的這幾天,我抽了點時間把這個心裡想要實現的小套件,仿造PIAB的方式來製作一下。

需求與命題

首先來整理一下這個命題,我們知道AOP想把Business Logic和Infrastructure Logic做一個切割,達成cross-cutting concerns的獨立性,具體情境是什麼呢?看底下這一段code:

上面這段程式碼的第10行使用了Calculate()這個Method來計算BMI,但這段Code有些小問題,例如,傳入身高體重是0時候,可能發生Exception。

你可能會想,這不要緊,我們在Method中加入try…catch,類似底下這樣(當然我知道可以加上傳入參數的檢查,但我想講的點是try…catch啦,所以我們先這樣幹):

這樣做沒問題,但如此一來,我們就讓計算BMI這段code,嚴重的與處理exception中的發mail或發Line訊息的功能相依!

此外,倘若我們想針對該Method被呼叫幾次,做一個Log,你可能也會在Calculate()這個Method中加入讀寫檔案存取log或db的code,這下不得了,簡單的BMI計算(business logic)開始與檔案系統、DB、發mail…etc(Infrastructure  logic)相依,萬一你程式碼中不只一個地方需要進行Log,而是有好幾個method都需要log,那就更精采了…

而AOP希望實現的,就是讓這些Business Logic(BMI計算)和Infrastructure Logic(Log, 錯誤處理, …etc.)之間可以不要彼此過分相依…

如何實現呢?可以透過Attribute。

想像一下,倘若我們可以這樣做:

倘若我們可以透過對Method掛上我們寫好的Attribute,就賦予Calculate()這個Method特殊的功能,例如一旦發生exception,就自動發Line訊息通知Admin,如果該Method被呼叫,就自動在Log file中記錄…。倘若這一切只需要掛上Attribute就能實現,我們就毋須破壞原本計算BMI的Calculate()這個method中的程式碼了…

但,真的可以這樣嗎?
當然可以…

請在專案中透過nuget加入一個套件 isRock.Framework.AOP,完成後,請先引用using isRock.Framework.AOP:

接著設計一個Logging Attribute(請注意繼承自PolicyInjectionAttributeBase):

我們在上面這個自行設計的Attribute當中,透過SaveLog這個方法來儲存Log。並且override了AfterInvoke()來呼叫SaveLog()。

完成後再將原本計算 BMI的Class修改如下(請注意只改了1, 13行):

最後,再調整一下Main中的程式碼(只改了第5行)。

神奇的事情發生了。

你會發現,我們的主程式,上面的main()中其實只改了小小一行(第五行),就讓我們自己寫的Logging attribute作用到Calculate()的身上了。由於Logging attribute中的第6行override了AfterInvoke()這個method,該Method會自動在Calculate()方法被呼叫後自動被執行,其中的SaveLog()程式碼是開檔寫Log…

如此一來,每當Calculate()方法被呼叫,log.txt檔案就會被開啟並被加入一列,變成:

這樣就實現了我們一開始的需求,當某一個Method被掛上Attribute之後,就能夠增加原本沒有的功能。且將Business Logic和Infrastructure Logic做一個切割,達成cross-cutting concerns的獨立性。

我們回憶一下我們做了什麼?

  1. 首先我們引入了Nuget套件 isRock.Framework
  2. Using了isRock.Framework.AOP
  3. 接著設計了一個自己的Logging Attribute(繼承自PolicyInjectionAttributeBase)
  4. 在上述Logging Attribute當中,override了AfterInvoke()方法,該方法會在目標Method(被掛上attribute的Method)被叫用之後自動被呼叫
  5. 在上述AfterInvoke()方法中呼叫SaveLog()開檔並加上『目標Method被呼叫』的Log
  6. 為了讓attribute生效,我們修改原始的BMIProcessor類別,在Calculate()方法上掛上LoggingAttribute:
    [Logging(LogFileName ="log.txt")]
  7. 並且讓BMIProcessor類別繼承自PolicyInjectionComponentBase
  8. 調整主程式為
    BMIProcessor BMI = PolicyInjection.Create<BMIProcessor>();

就這樣,我們透過這個框架,可以讓開發人員輕鬆的設計自己的Attribute,並且將attribute掛在Method上,實現Business Logic和Infrastructure Logic分離的AOP情境。

骨子裡,他還是使用PIAB的作法,透過reflection與Proxy的手法,完成以attribute實現類似AOP的功能:

如果你深入看,會發現我們的PolicyInjectionAttributeBase已經實做了BeforeInvoke、AfterInvoke、OnException三種Method,可讓開發人員輕易的實現自己想實現的Attribute。

嚴格說起來,我們用PIAB這樣的手法雖然可以實現部份AOP的目標,但還夠不全面,這也是PIAB不稱自己為AOP框架的原因。但是,即便只是能實現到目前這樣,也已經很符合我們在日常開發工作當中使用了。

這篇先寫到這邊,改天我們來談談如何實現OnException的Attribute。

完整程式碼可以參考:
https://github.com/isdaviddong/isRock.Framework.AOP-Examples

參考資料:
Introduction to the Policy Injection Application Block

-----------------
相關教育訓練: http://www.studyhost.tw/NewCourses/Architecture
若這篇文章對您有所幫助,請點選這裡加入FaceBook專頁按讚並追蹤,也歡迎您幫我們分享出去,謝謝您的支持。

2017年11月2日 星期四

好工具其實就藏在民間 - 圖檔去背

有一個很讚的網站,叫做 https://clippingmagic.com/ 這個神奇的網站,可以幫助你用簡簡單單的一筆一畫完成圖檔的去背。

你只需要像是上面這樣,用綠筆把圖檔要保留的部分畫起來,再用紅筆劃掉不想保留的部分,就能得到一個去背後的圖檔,剛出來的時候炫爆了。

最近這個網站不炫了,原因是,它…開始收費了。

以前去背靠這網站現在該怎麼辦呢?

雖然其實也不貴,但還是潛意識反射動作的在拿出信用卡前,找找有沒有其他的替代方案…上網查了一下,哇靠,原來我們偉大的PowerPoint內建這個功能!!

你只需要點選要去背的圖檔,然後選擇格式->背景移除,就可以了,它除了會幾乎自動化的幫助完成去背,也一樣可以讓你用綠紅兩色的筆,選擇自己要保留或是移除的部分。

完成之後,把去背成功的圖檔另存新檔就可以了:

PowerPoint…還真是不能小看你的啊