[筆記][活動] 關於《林伯Lean Bot》誕生的那些事 — 技術麻瓜的第一個開源專案

其實這是一篇我想寫很久的文章,與其說是如何打造一個Programming的專案,更重要的事情是一個技術麻瓜如我能夠真的將自己的點子實現,而且透過自己研究不同網路資料、到最後在g0v的會場中凝聚大家的力量完成的過程。

以這篇文章做個紀念,同時也時時警惕自己隨時踏出(非技術的)舒適圈。

林伯(Lean bot)是什麼?

林伯其實是一個結合跨辦公室通訊軟體Slack, Google Calendar, Google Sheet與線上表單完成的簡易版請假系統。實際上這個開源專案共分做幾個部分:

  1. 公司同仁可以透過跟Slack機器人講話,以口語的方式來填寫請假申請(Messenger bot的概念)
  2. 該申請會送至已經佈滿公式的HR自動計算後台,自動計算該員已經請了多少假期,還有多少額度
  3. Slack機器人會送出訊息「xxx送出請假申請,什麼假種,何時」給HR
  4. 在公司行事曆上將會自動設定「該員- 請假事件」的行程,供其他同事參考

它還有粉絲專頁呢 >> https://zh-tw.facebook.com/leanbot/

關於林伯(Lean Bot)誕生的故事?

在去年的某段期間,我曾經身兼HR,負責相關的內部營運事務。實際上在新創公司,很多位置找不到人來處理也是很常見的狀況,因而當時我便先接下了這份任務。擔任HR時,我發現「請假」對中小企業的HR而言,特別是沒有ERP(企業內部管理系統)的HR而言是非常困擾的。每天都可能會有同仁要申請請假,若皆以紙本申請則太過繁複且浪費資源,若直接讓同事線上直接申請送出表單,HR若沒有定期(以請假而言,可能需要每天)上去檢查表單情況的話便很容易狀況外。

於是我想要設計一個,若有公司同仁線上送出了請假表單,則我會收到通知的系統。
理想上,最好這通知不僅僅只是一個pop-out notification, 應該是一個簡單的摘要(誰,何時,要請什麼假種)。

原本以公司舊有的設計,應該是由同仁申請完假期之後,自行通知HR與單位主管,並且要在自己的行事曆上標註「請假事件」好讓真的有要找該同仁需求的同事知道。所以,我希望最好的情況是連後面的行事曆事件都能一併系統化處理就好了。(因為公司同事很常忘記要標注請假)

所以簡單整理一下我的需求:

  1. 讓同事送出請假申請的時候,我也能收到通知。(最好是摘要的格式)
  2. 這個通知最好是在Slack上(因為我們公司用的是Slack, 信件寄給我的話太Spam了)
  3. 送出申請後可以自動在該同仁的行事曆上,標註為「請假事件」

最原初的做法,林伯 ver0.1 — — 技術麻瓜的漫漫長路

網路上其實有很多如何將Google表單結合Slack通知的做法。簡言之,我們可以將「線上表單」這回事棄之不顧,重要的是收到的回答表單(Google sheet)有更動的時候,則Slack發出通知即可。

這是當時我參考的文章>>
http://jd.mares.co/tutorials/2015/09/20/slack-google-apps-script-stand-ups.html

因為我覺得這個人寫得很仔細了,所以我就不一一細談每個步驟。主要的流程是這樣的:

1. 設定好你的Google Sheet(就是填完線上表單後,收到的結果會出現的那個表單)

如果按照最原始的設定的話,只會有時間戳記跟後續你設定問題的答案。會建議簡單整理一下,畢竟之後我還要把它改造成HR收資料且做統計的後台,我的設定是以「時間戳記」「User email」「假別」「開始日期」「結束日期」「請假天數」等來做為區隔,在參考文章中有提到可以先將每一排都先定義好名字(Named Ranges),之後也會比較方便使用。

2. 設定Slack的通知機器人

前往 https://[你的團隊名稱].slack.com/services/new 找到 Incoming WebHooks 並且將他設定為開啟(Integrate)
在Integration的設定中請特別注意以下幾項:

  • Post to Channel: (請選擇一個你想要機器人送出通知的Channel)
  • Webhook URL: Leave as default, click Copy URL(讓它預設即可,記得要複製URL)
  • Descriptive Label: (這只是描述channel用途,那麼就看你想要填什麼吧)

3. 設定你Google Sheet的代碼(簡言之,寫code讓他送到Slack發出通知吧)

Google sheet中選擇工具、程式編輯器則可進到Coding畫面,記得新增一個全新的專案。請參考文章當中的Send a response from Google Apps Script的部分(實際上你可以複製貼上這個人的代碼再做細微調整)

不過值得注意的事情是,為了要讓兩邊的資訊是可以串接的,以下的設定必須要符合你在Slack上的設定。

  • 在 var url = ‘[YOUR INCOMING WEBHOOK URL]’; 這邊的代碼,請把剛剛複製的incoming webhook URL貼上取代
  • 在var payload = { “channel”: “#” + channel, “username”: “New Update”, 的部分,channel是你希望機器人發出通知的channel, 而User name則是你希望機器人的名字是什麼。
  • 在代碼中的“Yesterday”, “Today”, “Blockers” 可以改為:請假人、何時請假(年-月-日)、假種
takedayoff

以上就完成了Google表單與Slack通知的連動,則後面的行事曆呢?
技術麻瓜如我,自然選擇了Zapier這個服務來作為小幫手:Zapier是一個連動兩個App的網路服務,你可以設定:
如果A app怎麼了則B app應當有什麼反應。

所以我就設定剛剛那一份Google sheet(請假申請的答案回收)若增加了一列新的內容,則取得特定領域的資料送到Google calendar。有一個小tip是最好有一個公司共用的行事曆,而不是每次都可以自動分辨送到誰的行事曆,這難度太高了。

所以我就設定可以取得欄位[使用者],並且自動加上 Out of office 的字樣送到公司公共行事曆。

以上,就是林伯 ver0.1的故事。
當然他有點短處:
1. Zapier作為免費的服務,有時候他突然就秀逗了…
2. 我一直在想有沒有可能除了通知會送到Slack之外,連填寫請假申請都可以變成在Slack中完成呢?
這就是林伯 ver 1.0的故事開端了。


眾志成城,林伯1.0在g0v的初亮相!

screen-shot-2016-11-30-at-1-28-15-am

因緣際會之下,主管詢問我要不要一起去參加g0v uncon黑客松的活動,身為一個技術麻瓜總是得要進大觀園的。因而我們決定組隊黑客松將林伯(Lean bot)這套請假系統做得更加完善,且貢獻給開源社群。

既然有了其他成員的參與,我們便將一些想優化、更完善的功能丟入許願池中:

1. Google sheet 請假計算後台的完善

  • 收到的請假資料
  • 可以按照月份進行資料調閱
  • 各種假期的年度統計
  • 每個同仁的年度請假額度(各個假種還可以請多少天假)

2. 可以用Slack進行請假(透過與機器人直接對話的方式)

3. 公司同仁也可以隨時調閱自己剩餘的假期額度(透過與機器人直接對話的方式)

而我個人身為一個非技術人員,能做的當然就是整理Google sheet了。讓資料導入之後可以自動觸發其他公式,把資料按照使用者、時間、假種進行分類,以顯示出上面所提到的不同樣子。當時在設計這個表格時也感謝成員之一的Mosky(Pinkoi的data engineer)給了一些後台設計的想法。(data 工程師果然就是不一樣)

結構如下:

  • 第一個tab(Data)指的是raw data, 也就是表單填寫時的資料。可以看出很明顯的mail(user), 假種與請假時間。
  • 第二個tab(Old)是Optional的,是為了若有公司想要導入舊資料計算時,可以直接使用的表格。
  • 第三個tab(逐月統計)實際上是以Pivot的形式,整理出「請假年月」、「請假人」與「請假天數」。舉例而言,若將請假年月設定為2016–08,則就會叫出所有2016年8月的請假申請。
  • 第四個tab(年度統計)則是目前該公司同仁已經使用的假期數目總和,按照不同的假種進行分類。
  • 第五個tab(年度剩餘額度)則是扣除該同仁請的假,還剩下多少假期。值得注意的事情是這邊由於因年資不同會有額度差異,因而設計了新欄位(就職日,On board date)來以公式的方式自動計算每一個人不同的額度。
  • 第六個與第七個Tab, 則是按照每個公司不同的假期制度設定數字,前面的計算都會直接以後面的數字來自動加減。

實際上我還有有個隱藏的tab叫做(計算後台),如果你在Google sheet點選左下方Hamburger menu可顯現。這個tab可就真的是讓這些資料之所以自動分析出各種表單的關鍵了。

我在計算後台先使用Query公式將raw data的資料取出 Name, Vacation start date, Categories, Days 等欄位。
而Vacation start date 以text公式取出「歸屬年月」,這樣在逐月統計時即可以直接使用。比較特別的事情是為了等下方便做條件篩選,我用ArrayFormula的方式將「時間-人名-假種」結合成一個欄位,這樣之後再對照或整理時就只要比對該欄位,而非一次對應三個欄位選項,會方便得多。

舉例而言,在年度請假總計當中,我的公式設定如下:

以filter公司篩出符合「時間-人名-假種」符合「2016年-特定人名-特休」,則加總該數字。

sum(filter(‘計算後台’!$F$2:$F, ‘計算後台’!$K$2:$K=$B$1&” “&$B10&” “&”特休 Annual Leave”))

不過為了怕數字有誤,所以保險加上了IfError的公式,如果該數字送回來有誤(如果這個人還沒有請過這假期的話,通常會是有誤的結果,因為資料不符合),則顯示為0:

=sum(iferror(filter(‘計算後台’!$F$2:$F, ‘計算後台’!$K$2:$K=$B$1&” “&$B10&” “&”特休 Annual Leave”),0)

至於詳細的Query大家可以點表格去看,藏在每一個表格中的公式>>
https://docs.google.com/spreadsheets/d/1278CFK8m2w6NY4JN9T4GfSPsVxlGi1P4W2Ndo6cQlC8/copy


其餘的部分,就我所知是用Hubot的方式來打造機器人(一句話超級不負責任,但畢竟我們是分工的啊…我很認真地在我份內業務)
不過,感謝大家的努力,我們把口語請假這部分打造完成了。

以下為正式成功認證截圖:


當然,我們也如我們所言的將它貢獻出來了。
Github >> https://github.com/vacationhq/askforleave

之所以過了這麼久才寫這篇文章,是因為老實說,我還蠻驕傲於最開始的自己願意埋頭做這件事情的。之所以自己想要做,是因為覺得自己做得到,是覺得我應該也可以嘗試看看,或許因為這種心態讓我最終可以貢獻些什麼,我認真地很喜歡當時作為Maker的自己。

以這篇文章做紀念,同時也希望自己能一直保持著Growth Mindset去面對自己不知道的事情。
對於林伯(Lean Bot)有興趣的朋友,也歡迎自己參考Github來動手做做看。

カオナシ

Like what you read? Give Aki a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.