トレタ開発者ブログ

飲食店向け予約/顧客台帳サービス「トレタ」、モバイルオーダー「トレタO/X」などを運営するトレタの開発メンバーによるブログです。

最速かつ継続的に価値を届け続けるためのユーザー理解

こんにちは。デザイナーの上ノ郷谷です。私たちトレタが提供している予約/顧客管理サービスは、ユーザーである飲食店のスタッフからみると会社が選んだ業務ツールです。しかも予約や顧客を管理することは飲食店にとって大切とはいえ、メインの業務ではありません。そういった現場で使ってもらい、サービスの価値を上げていくには、いつも通りに使っていたら、気付かないうちに便利になっていると感じてもらえるような、できるだけ早く、継続的に価値を提供していく必要があると考えています。使うための学習や、操作中の迷い、没入させてしまったりすることがすべてコストになってしまうからです。

そのために私たちは、根源的なユーザー理解と、開発チーム内での認識にブレがないように情報フォーマットを持って、コミュニケーションコストを下げるなど、さまざまな取り組みを行なっています。今回はその中でも根源的なユーザー理解のために行なっているいくつかの取り組みについて書いてみます。

要望レビュー会

トレタではセールスチームやサポートチームがユーザーから聞いた要望を投稿するフォームが用意されています。ここで投稿された内容はスプレッドシートに蓄積されるだけでなく、社内コミュニケーションツールとして使っている Slack の専用チャンネルにも流れます。この要望をデザイナーとセールスチームのメンバーとで毎週レビューする会を行っています。

この会ではどういった店舗からの声なのかだけではなく、手段の提案に近い要望の背景にある課題や、プロダクト上で何が問題になっているかの現状把握、運用面での工夫を含む、解決プランの提案、検討中の仕様共有も行います。デザイナーはこのヒアリング会の中で手段の提案になりがちな要望から課題を抽出することを意識しています。

要望レビュー会は、ユーザーの理解以外にも、セールスチームのメンバーと製品開発メンバーの距離を縮めて保つことも目的のひとつです。

店舗ヒアリング

要望レビュー会のなかで、その要望がどんな店舗からあがっているのか、店舗の立地や規模など課題を明確にするために知るべき事があったり、直接話を聞いてみたいと思った場合はすぐに担当のセールスメンバーに声をかけて、訪問させていただくようにしています。店舗でのヒアリングはデザイナーだけではなくエンジニアも行くことがあります。

店舗でのヒアリングは、基本的に営業時間中ではなく、開店前の準備中だったりします。貴重な時間のなかで、しっかり話も伺いたいので聞きたい内容は事前に準備します。ですが、実際は雑談形式になる事が多いです。事前に用意した「聞くこと」についてももちろん尋ねますが、できるだけ業務中に近い内容を話してもらうためだったり、雑談の方が普段抱えている課題を引き出しやすいのと、ある点に集中して質問して答えを求めないほうが、状況や関連している原因に気付くことが多いからです。そのため私は、ヒアリング時はノートではなくカードに、話を聞いていて気になったキーワードを書くようにしています (私は付箋だと書くときにあつかいにくいので、メッセージカードを使っています)。

f:id:NiPeke:20161219001222j:plain

会社に戻ったらキーワードを書いたカードを机の上に、事前にまとめていた聞きたかったことを基準にマッピングしていきます。そうすると雑談で前後したりしていた話の筋がすうっと通り、業務時間外のインタビューでは知ることが難しかった現場の声が見えてきます。このマッピングしたカードと、要点や所感をまとめたものをすぐに社内情報共有ツールを通して、メンバーに共有しています。

導入店さまには営業中にも客としてもお邪魔します。基本的に食事を楽しむためですが、どういったタイミングで何をするためにどれくらいの時間 iPad に触れているかを見たりしています。余談ですが、会社からも導入店さまの店に行くことを推奨されていて、それを補助する福利厚生もあります。

さいごに

ほかにも根源的なユーザー理解のための取り組みはありますが、特徴的なものを挙げてみました。私たちはサービスの価値を上げるために、サービス提供者という立場にいながらも、できるだけユーザーと同じ視点でサービスに触れる必要があります。その視点から課題を明確にし、仮説検証、改善プランのレビューを重ね、提供する価値の精度を高めるというイテレーションを回し続けることで、最速かつ継続的に価値を届け続けるプロセス、組織を作っていっています。


この記事はトレタ Advent Calendar 2016の記事です。はインフラエンジニア津田の「明日からできる日常の自動化」でした。は QA エンジニア井上の「Todoist で始めるタスク管理」です。

DevFest.Asia 2016 Singapore にいってきました(前編)

f:id:ryotah:20161215231207j:plain

この記事はトレタ トレタ Advent Calendar 2016 15日目の記事になります。

こんにちは、フロントエンドエンジニアの堀口です。
弊社のカンファレンス補助制度を利用して、DevFest.Asia 2016 Singapore に参加してきました。

DevFest.Asia は CSSConf.Asia 2016 SingaporeJSConf.Asia 2016 Singapore 、2つのカンファレンスをあわせたものです。

開催日は11月24日〜26日の3日間。ちょうど、トレタ(Web版) のシンガポール対応の時期と重なっていたため、現地のスタッフへのプレゼンも兼ねてシンガポールへいってきました。

今回は、前編で面白かったセッションを、後編でカンファレンスの雰囲気を、簡単に紹介したいと思います。

セッション紹介

カンファレンスのスライド一覧は以下から確認できます。
devfestasia/talks: List of talks with slides (CSSConf.Asia and JSConf.Asia)

資料が公開されていて、個人的に興味深かったセッションを紹介します。

CSSConf

Make websites, not apps

... At least, web developers don't have to build the browser first. And we get so much built-in in browsers already

Mozilla の人による、「ブラウザにはいろいろ便利な機能があるんだよ。まずはそれらを使ってみましょう」というお話。

他のセッションも結構そうだったけど、CSSの日なのにCSSの話じゃなかったりと、結構自由です。

The Evolution of CSS4 Color

W3C のテクニカルディレクターによる「色」の話。CSS4の話はちょっとだけです。

CSS (Variable) Secrets

CSS Variables are a revolution for separation of style and behavior

CSSの変数の話。CSS Variables & JavaScript とか見ると胸があつくなります。

JSConf

Performance Profiling for V8

Google の人によるChrome V8の最適化の話。

From Zero To Binary Search Tree

(スライドと動画がなかったので、別のカンファレンスから)

データ構造の話。List, HashTable, Stack, Queue, Graph, LinkedList, Tree, BinarySearchTree についての説明と実装方法について。

コードは GitHub で公開されてました。
itsy-bitsy-data-structures/itsy-bitsy-data-structures.js at master · thejameskyle/itsy-bitsy-data-structures

Applying The Magic Of Neural Networks

ニューラルネットワーク、機械学習の話。RPGっぽい話(攻撃、防御、回復どれにする)から説明に入るので、わかりやすい印象があります。

NeuroJS: Capturing And Visualizing Brainwaves With Angular 2

デモが途中で失敗したり、解決方法を Stack Overflow で調べたり、一番もりあがったセッションはこれかもしれないです。内容も面白いです。ちなみに、Angular はあんまり関係ないです。

Wombat-Driven Understanding: An Interactive Guide To Using npm

npm 入門の話。プロジェクトを作って公開するまでを説明してくれます。
Show Notes for live coding in WDU talk at jsconf.asia, 26 Nov 2016 も一緒に見るといいと思います。

Yosuke Furukawa - Exploring Future Node

Node.js の今までとこれからの話。v8.x, HTTP/2, ES Module の話など、未来の話を聞くのは楽しいですね。

まとめ

テーマが幅広いこのようなイベントだと、普段気にしていない情報のキャッチアップや、気になっているけど放置してしまっている技術の勉強ができてとても楽しいです。
直接仕事には使えないけど何か楽しいぞ、という話に触れられるのもいいですね。

カンファレンスの雰囲気がどのようなものだったか、は後編に書きたいと思います。(たぶん来週のどこかで)


トレタ Advent Calendar 2016、明日は フロントエンドエンジニアのすえださんに FluxとDDDについて考えてみた を書いてもらいます。お楽しみに!

リリース自動化だけじゃないfastlane活用方法

この記事はトレタ Advent Calendar 2016 1日目の記事になります。

こんにちは、昨日に引き続き開発部の堀見です。

今年はトレタ初のエンジニアアドベントカレンダーをやることになりました!
「トレタ Advent Calendar 2016」やります - トレタ開発者ブログ

弊社はまだまだ小さい組織で少人数なので、言い出した当初は「半分埋まれば良いか〜」とか言っていましたが、なんと・・・全日程埋まっています!!!!🎉🎉🎉

弊社のデザイナー・サーバサイド・インフラ・フロント・iOSのエンジニアが勢揃いしてますので、ぜひトレタ Advent Calendar 2016 の購読ボタンを押してウォッチしてください🙏

ということで、初日は筆者からiOSネタを投下します。

背景

最近多くのiOS開発現場ではfastlaneでリリース作業が自動化されていると思います。トレタでも去年からfastlaneを導入済みで、ブランチをmasterにマージするとCIでアーカイブ作成・iTunesConnectにバイナリをアップできるようになっています。これによりリリース作業の負担軽減や、作業の属人性が減らせました。

しかし、日々のiOS開発ではまだまだ作業効率化の余地があると思います。今回は筆者がよく非エンジニア等のチームメンバーから依頼される、ちょっとした作業をfastlaneを使って自動化してみました。おそらくiOSエンジニアであればお願いされた経験があるものが多いと思います。

Provisioning ProfileにUDIDを追加する

弊社ではベータ版アプリを社員にはIn-house、社外の協力会社様向けにはAd-Hocビルドで配布しています。そのため社外でテストしたい端末が増えると、都度UDIDをDeveloper Portalに追加するという作業が発生します。

一瞬で終わる作業ですが、大抵ログインセッションが切れていてポータルに再ログイン、ポータルTOPからDevice追加画面に進み(ページ遷移が多い!)、デバイス名とUDIDを入力してようやく終了。・・・と思いきや、provisioningにデバイスIDを追加しないと意味がありません。というか、これをよく忘れてビルドをアップし、インストールできませんと言われて気づくことが割とあります...。意外と時間がかかってしまう作業です。

そこで以下のようなlaneを用意し、コマンド一発でデバイス追加とprovisioningの更新を行えるようにしました。

desc 'Usage: fastlane add_device name:デバイス名 udid:デバイスのUDID'
lane :add_device do |options|
  if options[:name] && options[:udid]
    register_devices(devices: {options[:name]: options[:udid]})
    sigh(force: true)
  else
    UI.error "Usage: fastlane add_device name:'New device name' udid:'UDID'"
  end
end

ブラウザをポチポチ操作していれば数分はかかりますが、これなら10秒程度で終わります。デバイス追加をお願いする際は、name:デバイス名 udid:デバイスのUDIDの形式で送ってもらうようお願いしておけば、依頼が来て即ターミナルにコピペ・コマンドを叩いて終了です。

ベータ配布済みのアプリのProvisioningを新しいものに差し替えたい

ベータ版配布サービスで既に配布しているAd-Hocアプリに、利用できるユーザを追加したいというケースもよくあります。前述のデバイス追加とProvisioningの更新をやっていれば新しいビルドをアップするだけで解決するんですが、長いビルド時間を待つのは億劫だし、同じビルド番号のアプリが配布サイト上に重複していくのも嫌な感じです。なので、普段は既にアップしているipaを手元にダウンロードして、Provisioningを入れ替え、アップし直すという地味な作業をやっています。

これもfastlaneからコマンド一発で行えるようにしました。

まずベータ配布サービスからアップ済みのipaをダウンロードしてきます。弊社ではHockeyAppを使っているので、download_hockey_ipaというActionを作りました。ビルド番号などを指定したらAPI経由でipaをダウンロードしてくるシンプルなものですが、地味に行数が長いので詳しくはGistで。

download_hockey_ipa.rb

ダウンロードが完了したらsighで最新のProvisioningをダウンロードし、resignでipaの中身を差し替え、再度hockeyでipaをアップします。幸いダウンロード以降はfastlaneに含まれているアクションを組み合わせて完結しました。

desc 'Usage: fastlane update_hockey_ipa_profile build_number:1234'
lane :update_hockey_ipa_profile do |options|

  tmp_download_path = '/tmp/resign.ipa'
    
  download_hockey_ipa(
    api_token: ENV["FL_HOCKEY_API_TOKEN"],
    build_number: options[:build_number],
    public_identifier: 'Hockeyアプリのidentifier',
    ipa_path: tmp_download_path
  )

  sigh(username: "dev@example.com", development: true, app_identifier: "*")
  resign(signing_identity: ENV["DEVELOPMENT_SIGNING"], ipa: tmp_download_path)
    
  hockey(ipa: tmp_download_path, strategy: 'replace')
end

hockeyアクションはデフォルトだと新規のビルドとしてipaをアップしますが、strategy:'replace'オプションを加えておくとHockey上にある同じ番号のビルドを置き換えてくれるようです。

最新のLocalizationを適用した確認用アプリを用意する

弊社のアプリは英語圏にもサービス展開しており、通常の機能開発と並行してローカライズも行っています。言語リソースはCrowdinで管理していて、翻訳が完了したらxliff形式で訳語データをダウンロード、コードにimportするという流れです。

これもまたブラウザからファイルを取ってきてimportして...とやっていると地味に時間がかかるので、コマンド一発で解決します。

まずはCrowdinから言語リソースをダウンロードしてきます。OneSkyなどはfastlane-plugin-oneskyを使えば済むようですが、Crowdinは無かったので自前でActionを用意。こちらも長いのでGistを参照↓

download_crowdin_resource.rb

続いてCrowdinからダウンロードしたxliffをプロジェクトにインポートします。xcodebuildコマンドをシェルで叩いてもいいんですが、fastlane-plugin-localizationを使うと簡潔に書けそうなのでこちらを使います。

最終的なlaneはこんな感じ。import処理はprivate laneに書いて、betaビルドのlaneから必要に応じて呼び出し、Hockeyにバイナリアップするようにしています。

private lane :update_localization do |options|
  tmp_localization_path = '/tmp/localization.xliff'
  download_crowdin_resource(
    api_token: ENV["CROWDIN_API_TOKEN"],
    download_path: tmp_localization_path,
    project_identifier: 'toreta',
    language: options[:language],
    file_to_download: 'ipad.xliff'
  )
  import_localizations(source_path: tmp_localization_path, project: 'Toreta.xcodeproj')
end

desc 'Usage: fastlane beta update_localization:true language:en'
lane :beta do |options|
    
  if options[:update_localization]
    update_localization(language: options[:language])
  end
    
  sigh(username: "dev@example.com", app_identifier: "*")
  gym
  hockey
end

まとめ

fastlaneを使って日々の作業を地味に自動化する方法を紹介しました。 一つ一つは些細な作業ですが、意外と自分の時間が削られてしまうし、「後でいいや」と後回しにすればチームメンバーを待たせてしまいます。こうした小さな効率化もエンジニアの責務としてやるべきだなと思いました。

fastlaneはもはやリリース自動化ツールではなく、アプリエンジニアが日々こなすあらゆる仕事の量を軽減し、生産性を高めてくれるツールになっている印象です。fastlane/AvailablePluginsにもあるように有志で開発されたプラグインもどんどん充実してきているので、今後さらなる効率化が図れそうです。


明日は サーバサイドエンジニアの 芹沢PageRankについて調べてみたです。お楽しみに!

© Toreta, Inc.

Powered by Hatena Blog