freeeのiOSアプリをSiri Shortcutsに対応させた話

こんにちは。モバイルエンジニアの高野です。

iOS 12がリリースされましたね!様々なアップデートがありますが、とりわけ目立って幅広いアプリで活用できそうなのはやはりSiri Shortcutsではないでしょうか。

ということで、弊社のiOS版クラウド会計freeeでも早速Siri Shortcutsに対応したバージョンを本日リリースしました!

Developers blogですので今回はどのようにこの機能を開発していったかを紹介します。

どんな機能?

Siriに「口座を同期して」と話しかけて口座の同期を開始する様子

弊社のプロダクトには、クレジットカードや銀行口座の明細をAPIなどから取得する同期機能が備わっており、定期的にバックグラウンドで明細取得されます。しかし、任意のタイミングで明細を取得して、最新の状態で会計処理をしたい時もしばしばあります。

今回はこの機能をSiri Shortcutsに対応させて、好きなタイミングでSiriを使って簡単に明細取得をできるようにしました。

Siriに「口座を同期して」と話しかけると、登録してあるクレジットカード・銀行口座の同期を開始し、新しい明細の取得が完了したらPush通知で知らせてくれる、という体験になります。

もちろん、Shortcutに対応させたことで、Siriに話しかける方法だけではなく、Spotlightのサジェスト・場合によってはロックスクリーンにもShortcutが表示される(ロックスクリーンに表示される条件はブラックボックスですが)ことになります。

WWDCのセッションの中で、Shortcutとして提供する機能はアプリ内で繰り返し行われる重要な機能が適していると言及されていましたが、今回それにピッタリの題材になったかなと思います。

Siri Shortcutsに対応させるために行うこと

ここから、今回の機能のために必要だった作業の流れを紹介していきます。

まずSiri Shortcutsに対応させるための開発には、SiriKitを利用します。SiriKitにはIntents frameworkとIntents UI frameworkが含まれています。

対応するにあたって参照したドキュメントは以下です。
SiriKit | Apple Developer Documentation

また、Appleが提供するサンプルコードであるSoup Chefも参照しました。
Soup Chef: Accelerating App Interactions with Shortcuts | Apple Developer Documentation

Intentの定義

さて、ではまずはIntentを定義します。IntentというのはSiriが受け付けられるリクエストのことを指します。

今回は「口座を一括同期する」と言うIntentが必要なわけですが、システムが標準で提供する特定ドメイン(MessagingやPayment等)のIntentとは合致しないため、カスタムインテントを作っていきます。

Intent Definition fileという新たに追加された形式のファイルを使って、Intentのタイトルやサブタイトル、パラメータ、リクエストに対してのレスポンスを定義していきます。このファイルはXcode 10~の「File > New > SiriKit Intent Definition File」から作成できます。

Intent Definitionを作成している様子のスクリーンショット

今回の定義は非常にシンプルで、タイトルや説明文などを記述しているだけです。CategoryにStart・Do・Run・Goなど汎用的な物が指定できるため、幅広いアプリでSiri Shortcutに対応させることができますね。

Intent Definition fileでIntentの内容を定義してからビルドすると、Intent Definition fileの内容に基づいたprotocolやclassを定義するコードが自動生成されます。 このコードのコンフリクトを避けるため、Intent Definition fileを開いた状態にし、XcodeインスペクタのTarget Membershipパネルで

  • 共有Framework(詳しくは後述します)の設定を”Intent Classes”
  • App、App Extensionの設定は”No Generated Classes”

と設定します。そうすることで、共有Frameworkに向けてのみコード生成されるようになり、コンフリクトが避けられます。

Intents App Extension

次に、Siri経由のリクエストをハンドリングするためのApp Extensionを用意します。

ユーザーからのリクエストに対して常にアプリを起動して反応する場合、このApp Extensionを作る必要はありません。ですが、ユーザーのリクエストに反応して何らかの処理をバックグラウンドで行いたい場合は、このIntents App Extensionを用意する必要があります。
バックグラウンドで処理を完了できれば、ユーザーはそれまで表示していた画面から離れることなくアクションを実行でき、より良いユーザー体験を提供することができるため、基本的にはIntents App Extensionを用いてバックグランドでタスクを完了できるようにした方がいいのではないかと思います。

Intents App Extensionの役割の大部分は、Siriとアプリが提供するShortcutを機能させるロジックとの橋渡しになります。今回私が実装した内容も、部分的に省略していますがだいたい以下のようなレベルの簡素な物です。

import Intents
import OurPrivateFramework

class IntentHandler: INExtension, FreeeFetchWalletableTransactionsIntentHandling {
  override func handler(for intent: INIntent) -> Any {
    return self
  }
  
  func handle(intent: FreeeFetchWalletableTransactionsIntent, completion: @escaping (FreeeFetchWalletableTransactionsIntentResponse) -> Void) {
    // 口座同期を開始するAPIにリクエストを送る
    APIClient.callTheAPI { success in
      completion(FreeeFetchWalletableTransactionsIntentResponse(code: success ? .success : .failure, userActivity: nil))
    }
  }
}

Siriからの要求をハンドリングするメソッドが、自動生成されたprotocolで定義されているので、そのメソッドの中で共有Frameworkに実装されたロジックを実行する感じです。
前述の、Intent Definition fileのスクリーンショットに「User confirmation required」という項目がありますが、Shortcutの実行前にユーザーに確認を促すべきアクションなどの場合はこれにチェックを入れ、IntentHandlerでconfirmするメソッドを実装する形になります。

注意点として、UIApplicationDelegateapplication(_:continue:restorationHandler:)はIntents App Extensionを提供しないアプリにおいてSiri経由のリクエストハンドリングする場合にも呼び出されるAPIですが、仮にIntents App Extensionを用意していたとしても、バックグラウンドでの処理ができなかった場合などに対応するため、application(_:continue:restorationHandler:)は実装するように、とドキュメントに書かれています。

Shared Framework

次に、AppとApp Extensionの間で共有する機能をこの共有Frameworkに実装します。「Intentの定義」のところで少し触れた共有Frameworkのことですね。Intent Definition fileを元に自動生成されるコードも、前述したTarget Membershipの設定を変更し、このFrameworkに含まれるようにします。

弊社のアプリでは、Siriから実行するための口座同期を開始するAPIの定義などがこのFrameworkに含まれています。

Siri対応に限らずApp Extensionを提供する際にはいずれにしろこのようなFrameworkが必要になることが多いですし、仮にApp Extensionに対応していないアプリでも、サービスのコアとなる機能をこのレイヤーに切り出しておくと設計としても良いのではないかと思います。

ShortcutのDonation

最後の仕上げとして、Shortcutとして提供したい機能をSiriに提供します。アプリ内でSiri Shortcutsに対応させる機能が利用される度にDonationするコードを実行します。ドキュメントによると、この時の時刻や位置等の環境を元にSiriがサジェストしてくれるようになるということです。

ただし、Siri経由でその機能が実行された場合は、システムは暗黙的にそのことを認知するようで、明示的にDonationする必要なありません。
逆にユーザーが一度も行ったことのないアクションを提供はしてはならず、将来的にユーザーが行う可能性の高いアクションについてはRelevant ShortcutsとしてSiriに提供するようにと書かれています。

アクションは、NSUserActivityINInteractionを使ってSiriに提供できますが、今回はINInteractionを使って、以下のようなコードでDonationしました。

let intent = FreeeFetchWalletableTransactionsIntent()
INInteraction(intent: intent, response: nil).donate { _ in }

エラー処理など省略していますが、Donationするのに最低限必要なコードはこれだけです。
これを、アプリ内で口座の同期ボタンがタップされる際に実行しておくようなイメージです。

Add to Siri

さて、ここまで行えばSiri Shortcutsには対応できていて、SpotlightやロックスクリーンへのShortcut表示は行われる下地が整った状態になります。 ここで更にSiriらしく、アプリ内で任意の音声フレーズを今回作成したShortcutに割り当て、音声でShortcutを実行できるようにする方法を紹介します。

まずはIntents UI frameworkに含まれるINUIAddVoiceShortcutButtonを使って、Add to Siriボタンを画面に表示します。
INUIAddVoiceShortcutButtonのイニシャライザは、enumとして定義されるINUIAddVoiceShortcutButtonStyleを引数として受け、それに応じてボタンの外観を変更します。現時点ではblack, blackOutline, white, whiteOutlineが定義されており、その中からアプリに合う物を選ぶことになります。

let button = INUIAddVoiceShortcutButton(style: .white)
view.addSubView(button)

表示はこのようになります。

Add to Siriボタンのスクリーンショット(白背景と黒背景)

INUIAddVoiceShortcutButtonのdelegateを設定しておくと、このボタンがタップされた時にdelegateのpresent(_:for:)メソッドが呼ばれます。その引数に渡されるINUIAddVoiceShortcutViewControllerを表示することで、フレーズを登録する画面がをユーザーに提供することができます。すでにフレーズが登録されている場合は自動的にボタンのラベルが変化し、ボタンをタップすると、編集画面を起動するためのpresent(_:for:)メソッドが呼ばれます。

現時点でINUIAddVoiceShortcutButtonのリファレンスに載っているサンプルコードだと、ボタンにaddTargetで設定したセレクタでINUIAddVoiceShortcutViewControllerインスタンスを作って画面に表示している箇所があり、この理由は分かりませんが、delegateを使ったほうがシンプルに書けると思います。

まとめ

大まかにではありますが、会計freeeでSiri Shortcutsに対応した際の流れを紹介しました。

弊社のモバイルチームではHack dayという、いわゆる20%ルール的な制度を設け、その中でエンジニアが自律的に作りたいものを作っていけるようにしています。実は今回のSiri Shortcuts対応はその中から生まれた機能です。この制度を使ってこれまでに色々な機能のリリースや、開発基盤の整備などが行われています。

ということで、freeeのモバイルチームではやっていきによってfreeeのプロダクトをもっとよくしてくれる仲間を募集しています!

スモールビジネスの未来をアプリで切り拓くモバイルエンジニア募集! - freee 株式会社のモバイルエンジニア中途の求人 - Wantedly

jobs.freee.co.jp

リモート勤務で、人の言葉を忘れ始めてしまいました — 九岡 佑介 (mumoshu) インタビュー(後編)

こんにちは id:ymrl です。おととい公開した前編に引き続き、freeeでSREエンジニアとして働く九岡佑介(@mumoshu)さんのインタビューをお楽しみください

mumoshuさんの写真

人の言葉を忘れ始めてしまいました

— ところでmumoshuさんはfreeeでも珍しい、地方からのリモート勤務をされているわけですけど、リモートでのやりづらさはないですか?

最初の数ヶ月は五反田の本社で勤務していたんですけど、いまは完全にリモートで月に1〜2回東京に来る生活をしています。ほとんどの開発メンバーが五反田にいるのでもともと月1回は本社に来るという約束になっていたんですが、いまのところ東京での登壇の予定などがよくあるので、それに合わせて本社に出社しています。

freeeメンバーとのやり取りほとんどがWorkplace上でやっていて、ずっとオンラインでやりとりしてきた人とこのあいだのオフサイト(社員合宿)で初めて会って、顔と名前がようやく一致するなんていうこともありました。やりとりは非同期的なテキストコミュニケーションが多いんですが、自分はついミーティング中に仕事しちゃうタイプなので、都合のいいときに非同期に話が来る状態のほうがやりやすいです。基本的にコミュ障なんだと思うんですよね。

自分みたいなタイプはマネージメントする立場からはやりづらいと思うんですけど、それでもチームの理解があることと、自分がこっちのほうが向いているなと思えること、そして人から指示されて動くような内容の仕事ではないというのが、リモートで仕事ができている理由のように思います。

リモートで働くようになって困ったことといえば、人と喋る機会が減って人の言葉を忘れ始めてしまいました(笑)。もともとあんまり喋らないほうなんですが、リモート勤務だとその傾向がもっと強まってしまって、朝に家族と話して、子どもを保育園に預けるときに先生に挨拶すると、あとはお昼にカレー屋さんでカレーを注文するくらいしか喋らなくなっちゃうんですよね。

そういう話をマネージャーとの1 on 1で話したら「リモートランチ」というのをセットしてもらえるようになりました。毎週いろんな人とビデオ会議を繋ぎながらご飯を食べているんですが、そのたびにそんなに話したことのない人と話せるので助かっています。

やっていき・のっていき

— freeeでの仕事の進め方はどうですか?

自分の所属しているSREチームはそんなに人数が多くないんですが、その中でいくつかのプロジェクトをやっているので、その関係で兼務兼務兼務みたいな感じで話をすることが多いです。

他のチームのエンジニアとは、Kubernetesを導入するプロジェクトで交流することが多いですね。で、デプロイが終わるとそのプロジェクトの人とは仕事上は疎遠になったりします。もちろん寂しさがないわけではないんですが、職人芸を発揮して離れていくというのは業務上の責任は果たせていると思うし、ある意味で理想的だと思うんですよ。

いちおう人なので、人との関わりは持ちつづけたいと思っているんですけどね。人間として矛盾しているかもしれません。日々出会いと別れですね。そんな感じで、常に職人芸を発揮できるものを探しつづけないといけません。

freeeでの仕事は、全体的にやりやすいなと思っていて、とにかくメンバーの「やっていき・のっていき」の精神がこの規模になっても感じられるのはすごいですよね。ふつうは会社の規模が大きくなったら、その人の仕事の範囲を越境したときのインパクトは大きくなるのでやりづらくなるはずなんですけど、そのあたりに貪欲な人が多いなと思っています。こういうのは一人のエンジニアの力ではぜったいに作れない文化で、すごくいいなと思っています。

そういう文化さえあればKubernetesだろうが何だろうが、新しくて良さそうなものなら何でも入れられるなって気がしますね。Kubernetesを入れようっていう話をしても背中を押してくれない人が誰もいなかったし、入社2日目のまだ何もよくわかってないような状態で出たミーティングで、もうKubernetesの導入が決まってしまったんですよ。あれはびっくりしました。

上手くいっているものを変えるのって、普通ならわかりづらいと思うんです。そういうときって「変えないと死ぬ」派と「今うまくいってるならいいじゃん」派に分かれて、前者がベンチャー的だなと思うんですけど、freeeはその二択という感じでもなくて、特徴的だと思います。暑苦しい人ばかりだとコンフリクトしそうだし、バランスがいいのかな。

インタビュー風景

職人が必要でなくなるときのために

— 最後に、mumoshuさんがこれからやっていきたいと思っていることををお聞きしたいんですが、将来目指しているものとかはあったりするんですか?

たぶんひととおりKubernetesの導入が上手くいってくると、Kubernetes職人みたいなかたちでインフラエンジニアがやることって無くなっていくと思うんですよ。いま社内に「Linux担当」っていう人はいないじゃないですか。あまりにもデファクトになった技術ってそうなっていくと思うんですよね。そうするとKubernetes担当の人としては一社では生きていけなくなってくるだろうし、生存戦略として他のこともやっていかなきゃと思っています。

そういう中で、機械学習のプラットフォームを作るのには興味があります。

大学院のときに自然言語処理をやっていて、テキストを解析して機械学習にかけて人間にとって意味のある結果を出す分野のことをやっていました。生データを加工して学習データを作って、それをモデルにして高速に問題を解いたりすることをしていました。

それをプロダクションに載せるっていう夢を持ってWeb業界に入ったんですけど、一転二転してインフラエンジニアやってるんですよね。

最近はどこもかしこも機械学習って言っていて、10年前とはあまりに世界が違うなと。そのわりに面倒臭さって変わってなくて、10年経ってこのままならKubernetesの次を探すときもこの泥臭いままなのかな、やることが残っていそうな匂いがしています。

それから、どこの会社の社内システムでもググれば大体のことはわかる、という世界を作ることにも興味があります。どこの会社でも何らかの自動化や効率化をしてきていると思うんですけど、それは会社によってだったり、やった人によってだったり、やり方に違いがあるんですよね。これまで何度か転職をしてくるたびに、「あ、これはあの会社とはこう違うんだな」というのを実感することを繰り返してきています。

でも、たとえばAWSを使っていて、EC2だとかRDSだとかElastiCacheの使い方のズレってそんなにないですよね。やっぱりAPIが切られているとそのAPIとして用意されている中でしかズレないのでキャッチアップしやすいですよね。

どこの会社のシステムもそういう風に同じAPIを軸に組まれていたら、もっとキャッチアップしやすい人材流動性の高い社会になると思うし、いろんな会社に首を突っ込みやすくなると思っています。そういう社会にしたいなと思っています。

いまSREチームとして他のチームの人から相談を受けるときも、社内独自でやってしまっている工夫についてはまだまだ眠っている暗黙知がある気がしていて、答えなければいけないプレッシャーにウッとなることがあります。Kubernetesのことは何を聞かれてもだいたいググって出てくるので、簡単だし怖くないんですけど。

freeeにはそういうところも期待しています。いつになるかはわからないけど、最終的には一社に一人freee担当がいて、そういう人が一人いるだけでいろんなシステムが自動化・効率化されていって会社が回る、みたいな世界を作れるといいですよね。

とはいえそういうfreee担当そのうちLinux担当とかKubernetes担当みたいになってそうですけど。やっぱりまずは職人芸の世界があって、それがだんだん職人が要らなくなっていくみたいな世界観をもって生きています。

インタビュー風景


長きにわたったインタビューでしたが、お付き合いいただきありがとうございました。

freeeではmumoshuさんのような職人気質のエンジニアを積極採用中です!!

jobs.freee.co.jp

jobs.jobvite.com

www.wantedly.com

Kubernetesでアプリエンジニアが勝手にやれるインフラを作りたい — 九岡 佑介 (mumoshu) インタビュー(前編)

こんにちは!freeeでエンジニアをやっている id:ymrl です。

ふだんマイペースに更新しているこのfreee Developers Blogですが、たまにはfreeeで働く個性豊かなエンジニアを紹介したいなと思い、第一弾として最近AWS Container Heroに就任したSREエンジニアで、kube-awsをはじめとするOSSのメンテナーとしても知られる九岡佑介(@mumoshu)さんにインタビューしてみました。Kubernetesの話やリモートワークの話を聞いていたら内容が盛り盛りになってしまったので前後編でお送りしようと思います。

mumoshuさんの写真

転職するごとにレイヤーが下がっていった

— mumoshuさんはこれまでKube-AWSの開発をされてきて、それもあって先日AWS Container Heroにも就任されたわけですけど、もともとKubernetesまわりのことをしはじめたのはいつ頃、どういうキッカケだったんでしょうか?

やりはじめたきっかけは、Chatworkのメッセージ基盤をScalaに移植するプロジェクトでした。このプロジェクトはアプリケーション側がずいぶんチャレンジングだったんですが、実はインフラもチャレンジングで、そこで採用したのがKubernetesでした。

そのころのインフラは社内で内製していたソフトウェアがあって、当時のChatworkをメンテナンスしていくのには最適化されていたんですが、Akka HTTPとScalaで作った新しいアプリケーションを動かすには不向きでした。また、当時のチームの構成としてアプリケーションエンジニアが多くそのモチベーションも高かったので、もっとプログラマブルで、アプリケーションエンジニアが使いたくなるようなインフラにして、その力を最大化できるものを求めていました。ちょうどそのときに使いやすそうだったのがKubernetesでした。

自分がかつてアプリケーションエンジニアあがりのインフラエンジニアなこともあって、そのころの自分が「これならインフラも見ようかな」と思えるインフラを構築したいと考えていました。自動化のしやすさや、必要だと思っている機能がひととおり揃っていて、自分たちで作りこまなくても使える状態というものが理想でした。

—アプリケーションエンジニアとしての経験が、いまのmumoshuさんのインフラエンジニアとしてのありかたに繋がっているんですね。なぜアプリケーションエンジニアからインフラエンジニアになったんでしょうか?

新卒のときは大手メーカー系の会社で、エクセルと電話を使って開発のディレクションをするような仕事をしていました。自分では全くコードを書かない仕事だったんですが「これなら自分が書いたほうが早いな」と思うこともしばしばありました。

そんなある日、社内で他の人から「あなたは優秀なのに、こんなことをしていていいのか?」と叱責されたのが最初のきっかけでした。自分でも「この仕事は全然面白くないな」と感じていたときだったので、考えた結果「自分で書こう」と思いました。

それから1年くらいその会社でプロダクションコードを書きました。当時HTML5とかCSS3とか、prototype.jsとかjQueryみたいな技術が出始めた頃で、いろんな会社のAPIをマッシュアップしてWebサービスを作っていました。

その頃はフロントエンドのことばかりをやっていた感じで、インフラのことなんて何も知りませんでした。エクセルを埋めて社内システムに登録して、あとは不明点などを電話で相談しているといつの間にかインフラが構築されている、という感じでした。そのときの「インフラわかんない感」を繰り返したくないなとか、その頃インフラもやっていたらこんな感じであってほしかったな、というのを未だに追いかけているのかもしれないです。

そのあと転職をするに従って、だんだん扱うもののレイヤーが下がっていきました。

2社目にいたときにScalaのPrayframework2に傾倒していて、自分の気にいった技術を社内で使ってもらうための外堀を埋める活動として、ドキュメントの翻訳をやったり、登壇をしたり、いろいろなことをしてきました。その一環でちょっとだけインフラを触ったのが自分にとって初めてのインフラでした。といっても他の人がAWSを設定したのをチョロっと触っただけだったので、今思えば「そんなところからよく初めたな……」という感じですけど。

インフラエンジニアとして仕事をするようになったのは3社目で、当時その会社ではじめてScalaを採用するというタイミングでした。そこで2社目でScalaを使っていたということでインフラに起用され、デプロイの自動化やモニタリングの仕組みなどをわからないなりに構築する機会を得ました。ここでそれまで触ってこなかったインフラの世界に一気に触れることができました。

その次の会社は、会社のエンジニアとしては5人目、自分がはじめての専任のインフラエンジニアという感じで、このときにはほぼアプリケーションコードを書かなくなっていました。このときの仕事はいろいろと大変でしたが、この経験がいまに一番生きていると思います。

インタビュー風景の写真

freeeに来たのは大きなチャレンジがあるから

— そのあと、現在も技術顧問をしているChatworkに行かれて、そしてfreeeに来たわけですけど、なぜfreeeを選んだんでしょうか?

Chatworkでは1年以上かけてKubernetesを導入するという大きなチャレンジがあって、あれは自分と、当時のチームでしかできないとても大きなチャレンジだったと思います。このチャレンジをやりきった上で、もっと大きなチャレンジをしたいと思うようになりました。

そこでChatworkには技術顧問として関わりつつ、本業としてそういう大きなチャレンジを探しているときに出会ったのがfreeeでした。

freeeには「規模」と「セキュリティ」という大きなチャレンジがあると思っています。freeeで扱う会計などのデータは、法律でどう守られるべきなのかが定められていたり、それ専用の監査のやり方が用意されているような情報です。そういうものが流れるシステムの監査に耐えられるインフラをKubernetesで作るのはとても大変なことだと思っています。

KubernetesをはじめとしたContainer Orchestrationの世界では、こういった厳しい監査のあるセキュリティ施策は未知の領域で、後付け後付けで改善されていっているんですが、それでもまだまだ進化の余地が残されているなと感じています。

規模の話でいうと、10人くらいで開発・運用を回しているような小規模なシステムでは、求められる要件が何であれKubernetesはオーバーキルなんですよね。しかし100人とかになってくるとカオスになってきて、「間違えることができない」が重要になってくるはずです。そういうときにKubernetesの、必要な機能が一通り揃っていて、それを組み合わせて使えばOKという特徴が生きてくると思っています。

自分は「ただ引き継ぐ」ことができない性格で、ついつい作りこみをして技術的負債を残してしまうので、そういう意味でも一通り揃っている機能から必要なものを選んで使えるKubernetesは合っているなと思っています。Kubernetesはやりすぎる余地があまりないし、もしやりすぎてしまってもその成果をOSSにしちゃえれば技術的負債にならないので(笑)。

そういったものを使いこなして、別次元の監査が要求されるような世界でも、開発者の生産性を落とさず監査に耐えられるような状態を作れたらいいなと思っていて、そんなチャレンジはfreeeでしかできないと思いました。

インフラは職人芸の世界

—— 自分にできないような大きなチャレンジの舞台として、今のmumoshuさんはインフラエンジニアをされているわけですが、自分はインフラのほうが向いていると思うようなところはあったりするんでしょうか?

インフラのほうが、職人芸が残っている分野な感じがしているんですよね。新しい技術が出てきたときに、最初は職人が絶対に必要になると思うんです。

Kubernetesもそうなんですけど、新しい技術を使うためにはどうしても必要とされるスキルセットが違うし、たくさんのことを憶えなければいけないですよね。そこまでして使いたい人というのはなかなか現われないと思うんです。でも、そんな中で物好きな人が勉強して使えるようになると、その人がその会社で最初の職人になるんですよね。

インフラの世界は、そういう職人芸が必要なものがまだまだたくさんあるのが面白いところかなと思っています。

インフラエンジニアとしては、アプリケーションエンジニアだった頃の自分が欲しいインフラを作っていきたいということを常に考えています。Kubernetes自体の運用はまだ職人芸というか特殊技能なんですが、その上でアプリケーションエンジニアが勝手にサービスを動かすということができるといいですよね。サーバーの台数を調節するなんていうのもアプリケーションエンジニアが勝手にやれるようにできるし、勝手にやったほうが絶対良いものになると思っています。それができるのがKubernetesだと思っています。

自分がアプリケーションエンジニアだったら、やっぱり人に押しつけられたものを使わされるのは嫌ですしね。これまで使ってきた仮想マシンベースのインフラと、Kubernetesベースのインフラを用意して、各自が使いたい方を自由に選べて、それをSREがサポートできる。そんな座組にできたらいいなと思っています。

mumoshuさんの写真


前編、いかがでしたでしょうか。リモートワークや未来の話で盛りあがったインタビューは後編に続きます。後編は明後日に公開予定です。お楽しみに!

2018/09/14追記: 後編を公開しました!

developers.freee.co.jp


jobs.freee.co.jp

www.wantedly.com

freeeの新しく公開されたAPIを使って、非エンジニアが音声で勤怠打刻をしてみました!

こんにちは、freee株式会社のgokiです。

私は2017年の新卒としてビジネス職で入社し、現在はProduct Value Boosterという、営業チームや導入支援チームに自社プロダクトの価値を咀嚼してお伝えするお仕事をしています。

非エンジニアではあるのですが、いろんな業務改善ツールを作ることが好きで、趣味でいろいろ作ったりしています。

IFTTTを使って音声で勤怠打刻をしたかった理由

皆さんは、勤められている会社で勤怠って付けていますか?

ほとんどの人が”YES”だと思うのですが、あれってなかなか面倒だったりしますよね。

freeeでは、会計や人事労務管理はすべて自社のサービスを使用しているのですが、クラウドとはいえ、勤怠のためにPCをつけて、ログインして打刻、という作業時間がもったいないなぁ、と感じていました。

人事労務freeeがタイムレコーダー(打刻)のAPIを公開!

そんな勤怠打刻の悩みを悶々と抱えていた矢先、なんと人事労務freeeがタイムレコーダー(打刻)のAPIを公開しました)!

人事労務freeeのタイムレコーダー(打刻)APIのリファレンスの画像

嬉しーーーーー!!!

タイムレコーダー(打刻)APIについて

指定した従業員のタイムレコーダー(打刻)情報を 登録 / 取得する ことができます。 登録の場合は、webの画面やアプリと同じく出勤 / 退勤 / 休憩開始 / 休憩終了 の登録ができます。 このAPIを用いて、自社のツール・ICカードや生体認証に対応した打刻機からAPIを呼び出すことで出退勤の管理を自動化することができます。

※タイムレコーダー(打刻)機能は、ビジネスプランのみ有効です。 https://developer.freee.co.jp/docs/hr 人事労務API 概要 | freee Developers Community

これで色んな方法で打刻ができます!

やっぱりやるなら音声入力

実は前回、Google HomeとIFTTTを使って、音声で経費の仕訳を作成するという記事を書かせていただきました。

developers.freee.co.jp

大変ご好評もいただいたこともあり、今回の打刻APIの活用アイデアを考えたときに、私は真っ先に音声入力が思い浮かびました。

前回のノウハウもありますし、何より音声入力ってやっぱり楽ですしね。

というわけで、前振りが長くなってしまいましたが、

「OK Google!出勤したよ!」と言ったら、自動的に人事労務freeeで出勤を記録する仕組みを作りたいと思います。

基本的な仕組み

仕組みとしては、前回の音声仕訳と同じく「①Google Assistant →②Google スプレッドシート→③freee」という順番でデータを飛ばそうと思います。

①と②の間をIFTTTで、②と③の間はGoogleのスクリプト“Google Apps Script(略称GAS)”を使用して、freeeが公開したAPIを叩くという方法です。

下準備で必要なもの

  • Googleアカウント
  • Google Assistantアプリのスマホへのインストール
  • IFTTTアカウント
  • 人事労務freeeのビジネスプランのアカウント

IFTTTの設定

準備が終わったら、あとはIFTTTの設定です。IFTTTにログインしたら「New Applet」よりAppletの新規作成を行います。

IFTTTのNew Applet画面のスクリーンショット

Appletのトリガーであるthisの部分は次のように設定します。

service
Google Assistant
trigger
Say a simple phrase

最後のtrigger fieldsについてですが、今回は、「出勤したよ」と喋りかけたら自動で打刻の処理をしたいので、次のように設定しました

What do you want to say?
出勤したよ
What's another way to say it? (optional)
出勤しました
And another way? (optional)
出勤するよ
What do you want the Assistant to say in response?
今日も一日頑張ってください

IFTTTの設定クリーンショット

これで、「出勤したよ」と話しかけたことをトリガーにアクションを実施できるようになりました。

ちなみに、このトリガー後のGoogle Assistantからのレスポンスは「今日も一日頑張ってください」とし、朝からテンションが上がるように設定しました。

続いて、thatにあたるアクション部分を作成します。

service
Google Sheet
action
Update cell in spreadsheet

を選択します。

action fieldsは、「音声打刻」というスプレッドシートを指定し、そのシートのA1セルを出力先に指定しました。

Spreadsheet name
音声打刻
Which cell?
A1
Value
clock_in

IFTTTの設定のスクリーンショット

また、出力先への値としては「clock_in」を指定しています。

これは、freeeの打刻APIでリクエストを送るときのtype(出勤・休憩開始・休憩終了・退勤)を指定する必要があるので、今回は出勤を指定する「clock_in」を入れています。

APIにて操作可能な打刻種別は以下のとおりです

clock_in
出勤
break_begin
休憩開始
break_end
休憩開始
clock_out
退勤

あとは同じ要領で休憩や退勤も作成

ここまでで、Google Assistantに話しかければ、Googleスプレッドシートに出勤情報を飛ばすことができました。

同じ要領で休憩開始、休憩終了、退勤なども作成すれば、IFTTT側の準備は終了です。

「①Google Home →②Google スプレッドシート→③freee」のうち、①→②が完成しましたので、

次からは②スプレッドシートから③freeeへの入力について説明します。

Google スプレッドシートとfreeeの連携の仕方

前回の記事でも書きましたが、Google スプレッドシートとfreeeの連携は意外と簡単です。

実はfreeeのヘルプページにはスプレッドシートからAPIを送信する用のサンプルシートがあります。

support.freee.co.jp

ただし、上記のサンプルシートについては、人事労務freeeではなく、会計freeeの取引登録APIなので、そのまま使うことはできません。

しかし、これを使えば、OAuth2認証で必要なアクセストークンなどを簡単に取得することができるうえ、POSTリクエスト(APIの叩く操作)もコードを数行書き換えるだけですぐ終わるので、めちゃくちゃ楽です。

Googleスプレッドシートの変更点

まず、サンプルシートをIFTTTの値出力先にするため、名前を「音声打刻」に変更します。

IFTTTからを値を受け取るシートを作成し、連携認証をマニュアルに従って行えば準備完了です。

Google Assistantから休憩開始を喋りかけてみて、A1セルにbreak_beginが入力されれば成功です。

Googleスプレッドシートのスクリーンショット

あとは、スプレッドシートの「ツール」→「スクリプトエディタ」から少しコードを書き換えるだけで完成です。

コードを変更した箇所

今回は、会計freeeの明細POSTのコードをコピーして、下記の部分だけ変更を加えました。

変数のrequestUrl を "https://api.freee.co.jp/hr/api/v1/employees/従業員ID/time_clocks"に変更

POSTする内容の記述を下記のように変更

  var d = new Date();
  var postdate = Utilities.formatDate( d , "JST" , "yyyy-MM-dd" ); 
  var gSheet = ss.getSheetByName( "IFTTT" );
  var posttype = gSheet.getRange( 1 , 1 ).getValue();

  var requestBody = 
        {
          "company_id" : 事業所ID,
          "type" : posttype,
          "base_date" : postdate,         
        };

打刻の場合はリクエストに必要な情報が少ないので、とってもシンプルかと思います。 説明するまでもないかもしれませんが、リクエストのtypeの値をIFTTTから出力されるA1セルの値にしています。

事業所IDと従業員IDの取得について

事業所IDと従業員IDについては、もともとサンプルファイルには事業所IDの取得リクエストができるようになっています。

さらに従業員IDについても、「ログインユーザーの取得」という人事労務freeeのAPIを叩けば分かるのですが、

そのコードを書くのがめんどくさいので、人事労務freeeにログインして「従業員情報」のリンクのURLが

https://p.secure.freee.co.jp/employees#従業員ID/年/月となっているので、そこで調べてコードに直打ちしています。

準備完了!!

これで準備が整いました、最後にスクリプトエディタのトリガー設定にて、シートが更新されると打刻のスクリプトが動くように設定しておけば完了です!

トリガー設定のスクリーンショット

音声打刻の使用感

作成してからは、これで打刻を行うようにしていますが、とても快適です!

「OK Google!出勤したよ!」で終わるので、とっても時間短縮。

あとは、Google Assistantが「いってらっしゃい、今日も頑張って」と返してくれるのも心がほっこりします。

Googleアシスタント(アプリ)のスクリーンショット
自分が設定したのだけど、応援してくれるのがうれしい...

もっとイメージがわくように、動画もいつか撮影して載せたいと思いますが、今回は写真ですみません。

人事労務freeeのビジネスプランを使っている方は、ぜひぜひ試してみてくださいね!

打刻APIを使えばいろんな連携ができそう。

私は技術にめちゃくちゃ詳しいわけではないのですが、今回のAPI公開で

GitHubやSlackから勤怠打刻したり、生体認証で勤怠を打刻したりといったことができるようになりそうですね!

個人的に音声については目が不自由だったりする方には最高の勤怠ソリューションかな?とか思いました。

もし、このようなテクノロジーを使って、いろんなビジネスの課題を解決することに興味がある方は、ぜひぜひfreeeという会社のこともチェックしてみてください~

jobs.freee.co.jp