Articles tagged with: case of akvabit

事例:株式会社ライライ様


既存システムのコスト削減が喫緊の課題に

  Topへ↓

ライライ様は、さまざまな撮影現場で活躍されているスタッフと映像プロダクションの間に立ち、両者をマッチングする業務を主に担っておられます。
映像の撮影現場はさまざまなスキルが臨機応援にスタッフに求められる場です。現場によって必要な作業を見定め、その作業に長じたスタッフを迅速に現場に紹介できるライライ様のビジネスは、映像プロダクションに高い価値をもたらします。
ただし、その分、作業指示や報告や請求書の発行作業に煩雑な事務作業が発生していました。それらを管理するための既存のシステムでは膨大な運用コストがかかっており、今回、kintoneを中心とした仕組みに切り替えることで、コストの削減を実現しました。

コスト削減を踏まえた業務要件のヒアリング

  Topへ↑

お客様(映像プロダクション)からのご発注を請け、それを案件として作成する。さらにスタッフの空き状況を見ながら案件にスタッフを割り当てる。スタッフはその案件の現場に入り、作業が終われば交通費や経費や作業内容を報告する。その報告内容を基にライライ社はスタッフの支払い書を発行し、映像プロダクションに対する請求書を発行する。
ご発注から請求までの流れは単純に書くとこのような感じです。

一方、映像撮影の現場の業務は多種多様です。ライライ様はそれらの業務や作業による金額設定を細かく定めています。たとえば、スタッフの習熟度による単価設定も二十種類以上の段階を設けるなど。
そうした業務を基にした金額は支払書や請求書に確実に反映させなければなりません。

ライライ様はそれまで、Salesforce+SVF Cloudを使った仕組みでビジネスを回しておられました。
その仕組みを回すために、各撮影現場に派遣されたスタッフは各々で作業報告を行わなければなりません。作業報告のプラットフォームとして、ライライ様はSalesForceを採用されていました。そのため、Salesforceにスタッフの数だけアカウントを作成し、スタッフはSalesforceにログインして報告を行っていたのです。
すると当然、月々のコストは相当な額にのぼります。
月々の支払額が負担になっていたこと。Salesforceの年次契約の更新日が迫っていたこと。さらにSalesForceの中で多くのカスタマイズが必要になっていて、その費用の見積もりももらっていたこと。それらを考えた結果、システム刷新の判断をくだしました。そこから、弊社へのご依頼につながりました。

この時点でライライ様はkintoneを採用すると決めておられました。まずkintoneを使ってアカウントのコストを減らすこと。それが最優先のミッションだったのです。
もちろん、kintoneの導入によって事務の方の各種計算や発行事務の負担を減らすことも求められていました。

kintoneとWordPressと帳票Onlineを提案

  Topへ↑

ライライ様から弊社にご連絡をいただいたのは2021/1/28。すぐにZoomで打ち合わせを行い、さらに2/3には訪問して状況を伺いました。
その際、Salesforce社に年間契約の延長か停止かの連絡期限が3/12に迫っていることを伺いました。そこでSalesforceを解約すると連絡した場合、4/12には契約が終わってSalesforceが使えなくなります。
Salesforceからデータを移行させつつ、kintoneの特性を生かしたアプリを設計する。さらにスタッフが報告できるためのプラットフォームを作る。そしてSVF Cloudで出力していた帳票とほぼ同じレイアウトの帳票を出す。それらをSalesforceの契約が切れるまでの間に作り上げる必要がありました。

そこで弊社は、2月の上旬にはスタッフの報告手段をkinconeにした提案書(42P)を提示し、すぐに着手にかかりました。
その後さらに打ち合わせを進めた結果、スタッフとの連絡手段はkinconeでは難しいことが分かりました。そこでスタッフとの連絡手段をWordPressに切り替えた提案書(44P)を提示したのは2月の中旬でした。その際、帳票発行の仕組みはアイ・コン社の帳票Onlineで提案しました。

弊社にとっては、メンバーを増やしてから初の案件

  Topへ↑

ライライ様からご連絡をいただく約4週間前。年明けから弊社は二人のメンバーを迎えました。
ライライ様の案件は二人のメンバーに活躍してもらう良いチャンスです。
まず、前の現場でWordPressを扱ったことがあったメンバーに一連のウェブサイトの構築をお任せしました。さらに帳票Onlineの設計はもう一人のメンバーに携わってもらうことにしました。
また、Salesforceからのデータ移行プログラムは代表が作りました。

今回、スタッフのアカウントはすべてWordPressにまとめました。ライライ様の場合、Salesforceに約100名分のスタッフアカウントを割り当てていたことによる月額コストが経営を圧迫していました。そのため、kintoneにもスタッフのアカウントを持たせず、別のやり方を検討したいというのがライライ様のご要望でした。
当初はkinconeで可能かと思いましたが、連携する情報の多さからWordPressに切り替えました。
WordPress内にスタッフのみが見られるページを設け、そこに作業開始時間、終了時間、交通費や作業内容といったこまごました項目をすべて打刻してもらうようにしました。
スタッフが打刻した瞬間、入力した内容はkintoneの作業報告アプリに取り込まれるよう、phpで開発を加えました。

kintoneの設計にあたり、Salesforceからの移行を考える必要がありました。そのため、案件管理や顧客管理、スタッフ管理などについてはSalesforceのフィールドを連携できるように設計しました。
さらに、作業報告アプリはWordPressからの連携に加え、スタッフの支払書や映像プロダクションへの請求書に出力できるような考慮が必要でした。

帳票発行の一連の仕組みについて、ライライ様がMacをお使いだったことから思わぬ遠回りをしてしまいました。そのいきさつについては
この記事に記載しています。
結論として、何とか帳票も出せるようになりました。

もう一つ苦労したのは、さまざまな計算です。内部の計算ロジックはSalesforceの内部でカスタマイズされていたものを流用しました。
ただ、Salesforceの場合、内部のカスタマイズ言語はAPEXというJavaベースの言語です。私もAPEXはあまり詳しくなく、新たに入ったメンバーも同じ。
彼には帳票を設計しながら、この計算ロジックを読み解き、なおかつ計算ロジックをkintoneのJavaScriptに適用してもらう作業に従事してもらいました。

導入してから

  Topへ↑

正直にいうと、Salesforceの契約が終わってすぐの月は、帳票出力の運用がまだ不安定なままでした。その際、ライライ様にはご迷惑をおかけしました。
今では上記のリンクに書いたような帳票発行の運用方法を変え、帳票は出せています。また、スタッフの打刻も順調に動いています。

現在は2ndフェーズの開発の真っ最中です。
他の種類の仕事を担っているスタッフさんの打刻ページや、NaviTimeの実装、Rakumo/Google Calendarとのスケジュール連動を行っています。

三島様より

導入からの日々について三島様はこう語ってくださいました。

「経理作業・スタッフ管理等PC作業の自動化は、弊社の長年の課題でした。
特に、請求・報酬金額のまとめ作業は、チェック項目が細かく時間がかかる上に、手作業だとミスも多くなるので、少しでも負担を減らしたいと考えておりました。
Kintone導入後は、スタッフの打刻から帳票作成までの時間が大幅にカットされました。
弊社の規定はかなり細かいため、まだシステムの確認・改修作業は続きますが、それらが終われば、他業務に人員を割けるようになるので、会社全体としての成長につながるのではないかと考えています。
これからもアクアビット様と打ち合わせを重ねて、より良い形にしていきたいと思っております。」

まとめ

弊社にとってライライ様の案件は弊社メンバーが加わって初めての取り組みだったこともあってとても印象に残っています。

私が帳票発行の設計で迷走しかけた後も、変わらずお付き合いくださっていることに感謝いたします。
三島さんはやり取りのレスポンスが速く、同じテンポを感じています。
まずは2ndフェーズを早く完了させてしまいます。

ライライ様のご紹介

商号 株式会社ライライ
本社 〒105-0021 東京都港区東新橋2-7-3 BIZMARKS 新橋汐留 2F
TEL 03-6874-4642
代表者 代表取締役 中田 平
従業員数 従業員3名 / 請負登録スタッフ70名
設立 2017年7月24日
資本金 100万円
ウェブサイト http://www.rightright.co.jp/

事例:某弁護士法人様


事務所の立ち上げにあたって、多忙な先生とスタッフの連携に備える

  Topへ↓

利益相反(コンフリクト)の点で具体的な名前を出せないのですが、某弁護士法人様は、高度な専門知識を駆使した法律事務所としてご活躍しておられます。
弊社が初めてお話をいただいた時、事務所開設に向けた準備を行っている最中でした。
代表社員弁護士の先生は、事務所の立ち上げ前から弁護士として幅広く活動されており、そのスケジュールは多忙の一言に尽きました。
スタッフを雇用し、事務所として立ち上げる中、スタッフと先生のコミュニケーションをいかに円滑に回していくかは、喫緊の課題でもありました。
弊社がkintoneを提案した結果、最初の立ち上げ時からスタッフと先生のコミュニケーションロスを抑えながらの運営ができました。

いかにして先生の予定や業務を共有するかのヒアリング

  Topへ↑

弁護士とは多忙な職業という印象を持っていましたが、代表の先生がこなすスケジュールの多忙さは私の想像を超えていました。
まさに分刻みという言葉がふさわしい先生のご予定をスタッフとどのように共有するか。予定の共有をせずに事務所の運用は回りません。
先生がご相談したのが、鎌倉に事務所を構えておられるヒトノコト(https://hitonokoto.com/)の渡辺みさきさんでした。
渡辺みさきさんが、なぜ事務所のサポートをしようと思ったかは、代表の先生やオフィスメンバーが働き易い職場を作りたいと思い、そのためには情報共有が欠かせないと判断されたからだそうです。
そこで渡辺みさきさんは、弊社代表の私と知己であったことから、システム構築のご相談を弊社に持ち掛けていただきました。

弊社代表がお話を伺ったところ、代表の先生の多忙なスケジュール管理を行うには工夫しなければ難しいと感じました。
当初、ヒトノコトの渡辺さんはCybozu Officeをご提案しようとされていました。ですが、お話を伺ってみたところ、他システムとの連動を行わずにスケジュール共有を行うのは難しいと判断しました。そこでkintoneをご提案しました。

kintoneについては、弊社は諸アプリの作成には携わっていません。こちらはヒトノコトの渡辺さんから別の方にご依頼していただきました。
その方が事務所の運営に必要な各種アプリを構築し、事務所の方が使えるように作業を行っていただきました。
弊社は標準機能では難しい他システムとの連動に注力し、並列で開発する体制を組んでいただきました。

kintoneとTwillioとGoogle Calendarとカレンダーの連動を提案

  Topへ↑

先生はiPhoneを駆使して連絡をとっておられます。スケジュール管理もiPhoneの中に入っているカレンダーが中心でした。
ところが、kintoneはカレンダーとの連動ができません。なぜならiPhoneのカレンダーは外部との連動をそもそも許可していないからです。ただ、唯一連携ができたのがGoogle Calendarです。そのiPhone内の連携オプションを利用し、Google Celanderとkintoneの連動を開発することによって、kintoneとカレンダーの連動を実現しました。
これによって、先生がiPhoneのカレンダーに入れた予定をすぐにスタッフはkintoneでGoogle Calendarからの予定を取得する事で共有でき、スタッフが入れた予定も先生が取得できるようになりました。
なお、事務所が立ち上ってすぐ、もう一人弁護士の先生が入所されたのですが、その先生にも同じような仕組みで予定の共有を可能にしました。

もう一つ、考慮しなければならなかったのが、事務所から先生に連絡を行う場合です。例えば事務所に先生宛の電話があった場合、その要件をすぐに先生に伝える必要があります。
先生からは、kintoneの通知ではなくiPhoneのSMSで連絡をもらったほうがありがたい、というご希望がありました。
そこで、kintoneのアプリ上にボタンを設置しました。そのボタンをスタッフが押すことで、アプリに格納した情報を先生のiPhoneにSMSとして飛ばすように設定しました。その連携にあたってはJavaScriptでTwillioにAPIリクエストを投げることで実現させました。

カレンダーの表示を見やすくするための工夫

  Topへ↑

苦労したのは、多忙な先生と予定を合わせることです。というのも、先生の端末をお借りしての操作が必要となったからです。カレンダーとGoogle Celandarの連動設定、Google Calendarの設定、さらに内部のGoogle Cloud Platform上での認証設定などを行う必要があったからです。ガソリンスタンドの休憩スペースで落ち合って作業したのは良い思い出です。
先生の激務のさなか、分で刻まれるスケジュールの合間を縫っての作業でしたが、それ以外にお手を煩わせることがなかったのは幸いでした。
もう一人の先生の端末も後日事務所にお伺いして設定することができました。

もう一つ苦労した点は、カレンダーの見え方です。スタッフの方が日・週・月で先生の予定を把握するためのデザインや色の設定などを工夫しました。
特に二人の先生が抱えたそれぞれの予定に加え、数名のスタッフが入れた予定など、多くの予定が混在する情報をどのように整理するか、色分けの部分は何度か打ち合わせを行わせていただきました。

それと、Google Calendarへのアクセスの際にGoogleから認証を求められますが、このやり方については、動画でマニュアルを作成し、スタッフの皆さんにご理解をいただけるように努めました。
当初はスタッフからの連携方法や先生の端末操作などの操作に慣れていただく必要があり、その間は先生のお手間を煩わせたこともあったかと思います。が、無事に弊社の手を離れて今に至ります。

導入してから

  Topへ↑

弊社には時折Twillioからの通知が来ますが、今のところ弊社の手を離れ、自立して動いてくれているようです。
多忙な先生のスケジュール管理にもkintoneが活躍できる場を見いだせたことは、弊社にとっても貴重な知見となりました。

渡辺様より

今の状況について渡辺様はこう語ってくださいました。

「新入社員としてジョインしたメンバーも、最初は使うのをためらっていたけど、使って見たら便利だという事がわかったので使っている、との話も聞いています。
自分で使い勝手を考えて、ある機能を使っているようなので、いいサイクルになってきているのではないかと想像しています。」

まとめ

弊社にとって某弁護士法人様は、iPhoneのカレンダーをどうkintoneにつなげるのか、という点で工夫したことで印象に残っています。

また、多忙な皆さんのスケジュールの合間に伺ったタイミングで的確に作業を終わらせなければならず、とてもメリハリの利いた開発になったことでも思い出に残ります。
今も順調に動いているということで、安心しています。

某弁護士法人様のご紹介

情報については、非公開です。

事例:株式会社テル・コーポレーション様


既存基幹システムで対応できない周辺のシステム管理が課題に

  Topへ↓

テル・コーポレーション様は、分譲マンションの開発・販売業務、分譲戸建て住宅の開発・販売業務、居住用・事業用物件の賃貸管理業務、土地・建物の売買仲介業務、不動産の有効利用コンサルタント業務など、幅広い不動産事業を展開されています。1988年の創業以来、着実に業績を積み上げてこられました。
契約や販売など、業務の基幹となる部分は賃貸管理システムで長年運用されていましたが、賃貸管理システムで補えない周辺の管理コストが煩雑になってきました。
もともと、テル・コーポレーション様は社内の連絡手段についてはCybozu Officeのオンプレミス版をお使いでした。周辺の情報共有手段を同じサイボウズ社のkintoneにすることで、近しいインターフェースを持ったシステムで回すことを検討されておりました。
その結果、周辺の管理をkintone中心とした仕組みに切り替えることで、業務の改善を果たすことができました。

煩雑な社内フローをkintoneに置き換えるためのヒアリング

  Topへ↑

不動産事業を行う中で、管理が必要な業務は契約や支払だけではありません。
例えば入居されている方からのクレームや要望事項も発生します。また、解約時の諸手続きや、オーナーや仲介業者との金銭の授受、鍵や駐車/駐輪場の管理、保険業者や内装業者、行政とのやりとりも必要になってきます。
テル・コーポレーション様がもともと使われていた賃貸管理システムは、そうした周辺の管理まで対応していませんでした。そのため、Excelを使って管理しており、煩雑な運用をもたらしていました。例えば紙に出力したExcelを基にしたクレーム報告書を社内で回覧し、押印欄に閲覧者が印鑑を押印するワークフローの存在など。
例えばクレームが発生した場合、その状況は物件や入居者の状況、事象によって千差万別です。それらを内部で情報として共有し、きちんとした指示を出す必要があります。

今回、弊社にいただいたご依頼は、Excelで管理していた周辺の業務を全てkintoneに集約すること。それとCybozu Officeをオンプレミス版からクラウド版に移管することでした。

今回はシステムのご担当者様と頻繁に連絡を取り合いながら作業しました。そのため、要件定義の細かい部分にまで弊社で踏み込む必要がありませんでした。

kintoneとRepotoneU Excelを提案

  Topへ↑

今回のご依頼で特筆すべきは、既存のExcelで運営していたクレーム報告書をどのようにkintoneで実現するかでした。
クレーム報告書の体裁を保ちながら、内部の仕組みをkintoneに置き換える。そのような方法を採った理由は、テル・コーポレーション様の社内にITに不慣れな方がいらっしゃるため、と伺いました。
そのため、kintoneからクレーム報告書を同じような体裁で出せるようにしました。押印欄を設け、実際の疑似印鑑も出力できるように。

そこでRepotoneU Excelを提案しました。RepotoneU Excelは帳票のテンプレートを登録することで、出力項目とのマッピングが可能です。
その際、テンプレートとなるExcelには拡張子が.xlsm、つまりマクロが可能なワークブックを使用しました。それによって、kintone内で生成されたExcelにマクロが埋め込まれるようにしたのが工夫点です。そのExcelをkintoneからダウンロードし、御担当者様が開いた時点でExcelマクロを動作させることによって、RepotoneU Excelの機能だけでは実現できなかったさまざまな表現を可能にしました。
例えば、あるクレーム報告書の場合、約20カ所の押印欄がありました。これも、kintoneの日時フィールドとユーザー選択項目を組み合わせた結果を疑似印鑑として表示させることで実現しました。
なお、マクロの実行にあたっては、テル・コーポレーション様のセキュリティ・ポリシーに合わせた形で実行できるようにカスタマイズしたことも付け加えておきます。

コロナがまん延する中での開発

  Topへ↑

テル・コーポレーション様に初めてお伺いしたのは2020/3/9のことでした。すでにコロナウィルスが世間に深い影響を与え始めていた時期です。
ただ、開発にあたってコロナはあまり影響を与えませんでした。それは、打ち合わせのほとんどをオンラインで完結できたためです。

テル・コーポレーション様はコロナ前からリモートワークへの切り替えをお考えでした。それがコロナによって拍車がかかり、オンラインでの打ち合わせの状況が整いつつあったことが功を奏しました。

さらに、やりとりの記載にあたってはご担当者様と何度か認識を合わせておいたため、複雑なやりとりもkintoneのスペースだけで完結できました。
社内の状況に精通したご担当者様とのやりとりによって、そこまで苦労せずに開発を進めることができたのは良かったです。結果、Zoomなどのオンライン・ミーティングすら二、三回で済みました。
私がテル・コーポレーション様を訪れたのは、初回の打ち合わせを除けば一回のみ(2020/9/28)です。それも、Cybozu Officeのオンプレミス版からクラウド版にデータを移行する作業が主でした。この時はすでに本来の開発は大体終わり、運用に移っていました。

開発で苦労した点があるとすれば、kintoneのプロセス管理を駆使していたため、エラーが発生した場合の再現が難しかったことです。グループやロールや組織、役職も多く作成しましたし、プロセス管理のステータスの数もたくさん作成しました。
特に、プロセスが進んだタイミングや保存時でアプリ間のデータ処理やスペースをまたいだデータ連動を複雑に組んでいたため、不具合があった際の調査に時間がかかり、苦労しました。

導入してから

  Topへ↑

プロセス管理のフロー修正や、賃貸管理システムとの連動にあたっての修正など、最初の目的を達成した後もさまざまな修正が発生しました。
が、今年の秋になって賃貸管理システムの入れ替えも終わったことで、いったん当初の目的は終わりました。

今後も新しくなった賃貸管理システムと協力して、kintoneの運用を行っていただく予定です。
今は、ご御担当者によってkintoneのアプリを次々と作成していただいている状況です。

代表取締役 浅井輝彦様より

代表取締役の浅井輝彦社長はこのように語ってくださいました。

「kintoneの導入によって、紙の書類が少なくなり、時間を効率よく使えるようになりました。それによって、テレワークもスムーズに導入出来ました。ありがとうございました。

株式会社テル・コーポレーション 
代表取締役 浅井 輝彦」

まとめ

弊社にとってコロナ禍においてもリモートワークを駆使して作り上げたことで、テル・コーポレーション様の作業は印象に残っています。
特に、リアルで運用されていた帳票をそっくり再現しながら、kintoneでプロセス管理を使いこなせたことでも、弊社にとって貴重な事例となりました。
あらためて、テル・コーポレーション様の皆さま、ありがとうございました。

テル・コーポレーション様のご紹介

商号 株式会社テル・コーポレーション
本社 〒151-0053 渋谷区代々木四丁目42番19号 テルコーポレーションビル
TEL 03-5302-5311
FAX 03-5302-5312
代表者 代表取締役 浅井 輝彦
設立 昭和63年
ウェブサイト https://teru-co.co.jp/

kintone Café JAPAN 2021でミッションに挑みました


11/13に催されたkintone Café JAPAN 2021は、全国のkintoneユーザーや技術者有志が集まるイベントです。有志によって運営されています。
毎回、さまざまな趣向をこらしたイベントが行われ、kintoneを愛する人々の知見と刺激と交流を生んでいます。

今回のJAPANでも複数のセッションが企画されていました。私は冒頭のセッション
Excelインポートミッション!君はこのトラップに気付けるか!?
のミッションに挑戦者として指名されました。技術者代表として。

このミッションの具体的な進行を私が運営者に教えてもらったのは、JAPANイベントが始まる30分前。
指令されたのは、Excelとkintoneを画面共有で皆さんに見せながら、その場でExcelに仕込まれた不正データを見抜き、データを整えた上でkintoneにインポートするミッション。

私にとって幸いだったことは、初っ端が私ではなかったことです。
最初の挑戦者であるキンスキ松井さんに課された10分間のミッション。これはまさにスリルに満ちていました。
頻発するエラーに四苦八苦される松井さんの姿を見ながら、私はミッションの雰囲気を把握することができました。


さて、私の出番です。私に割り当てられた時間は15分。技術者枠なのでさらに難易度はアップしています。
スタートの合図とともに、割り振られたスペース上のアプリとインポート対象のExcelを開きます。
すると、松井さんのミッションにはなかったルックアップやチェックボックスフィールドが加わっていました。さらには、Excel上での住所連結、氏名分割までも。
結局15分ではミッションをクリアできず、二回の延長をお願いして約20分を要してしまいました。
ただ、皆さんにはとても盛り上がってもらえたようです。Twitter上でたくさんの応援や感動したとのお褒めもいただきました。ありがとうございました。


このセッション、出た本人がいうのもなんですが、神企画だったと思います。
観覧されている皆さんにとっては、手に汗を握るスリルがあり、データをインポートする方法の知見がたまります。ミッションで使われるExcelのデータも一見それほど複雑ではないため、kintoneに触れて間もない方でも理解できる配慮がなされています。
さらに、ミッションを課された私にとっても、奔放なExcelデータをkintoneに取り込む経験がたまります。

実際、システム開発を営んでいると、今回のミッションで提供されたようなExcelに遭遇することはしばしばあります。
都道府県の列に見知らぬ県が混ざっていたり、誤字やスペースが混ざっていたりのデータはザラにあります。選択肢にない値や異体字、さらには違う文字コードのデータが混ざっていて文字化けする場合もあります。厄介なことに目には見えない改行コードが混ざっていることもあります。

普通、そうしたデータのインポートには時間をかけて対応します。入念に移行のデータを検証し、準備する時間を確保するのがセオリーです。
そうした移行に関する手続きは、昨年のkintone Advent Calendarで以下の記事としてアップしたのでご参考にしていただければ。
kintoneにシステム移したいんや

ただしこの記事に書いたような、移行の作業にじっくりと専念ができるかどうかは何ともいえません。そうはお客様が許してくれない場合があるからです。
例えばお客様先で利用を始める段になって、システムにバグが出ることもあります。それがプログラムのミスならまだいいのです。kintoneは修正が比較的容易にできるのですから。
問題はデータに不備があったり、アプリの設計と食い違っていたりした場合です。しかも、こちらの移行設計のミスならまだしも、お客様が直前で項目を修正したり、今までに発生していなかったデータがCSVに紛れ込んでいたりするからタチが悪い。
訪問したお客様先のその場で設計変更が必要になり、その場でデータを旧システムからもらい、その場でデータを加工して取り込む状況に追い込まれることだってありえます。

さすがに、お客様先で今回のミッションのように15分の制限時間を課されることはないでしょう。
ですが、技術者としては現場での応急対応が求められることは想定しておかないと。
アウェイの場での孤独な作業。お客様からの無言の期待と圧力を感じつつ、その場でExcelのデータとkintoneアプリの構成を比較して正しいデータに直す。それには臨機応変な対応が必要ですし、さまざまなエラーのパターンを同時に考えながら手を動かすことも必要です。こうした場数を経験しておくと後で技術者のキャリアの上で役に立ちます。
私も何回か、現場で加工したデータを取り込みなおしたことがあります。

こうしたやり方は従来のウォーターフォール型の開発では許されません。アジャイル開発やスクラム開発でもあまり推奨されないはずです。ですが、kintoneは症状の度合いによってこうしたLive感に満ちた開発・修正が可能です。むしろ、そこに真価を発揮します。
今回のミッションは、その経験を思い起こさせてくれました。また、出た当初のkintoneに惹かれた気持ちも思い出させてくれました。
このミッションにチャレンジすることは、kintone技術者としてのスキルを鍛えてくれるはずです。

Twitter上でもこのミッションを自社の研修に使ってみたいというつぶやきを見かけました。弊社でも同様にミッションを課してみようと思います。

司会の「けいん」さん
@soulxoxo

サポートの「よしみ」さん
@yoshiminxkay

一人目の挑戦者の「松井」さん
@kinsukicom

ガヤりの「とうげ」さん
@touge_moved

の皆様、ありがとうございました。あと、観覧者の皆様、声援ともどもありがとうございました。

時間が取れるかどうかはわかりませんが、今回のミッションの中で行った処理については、ゆくゆくは記事にしたいと思います。
なの、ケインさんがnoteでミッションに必要なアプリやExcel一式をダウンロードして使えるようにしてくださっています。

続いてのセッション『それkintoneで作って下さい!駄菓子屋さんの棚卸システムを1時間で仕上げちゃおう!
は、まさにkintoneのファストシステムの良い例です。
ファストシステム。最近ではこの言葉は使われていませんが、kintoneが出た当時はファストシステムと銘打たれていました。迅速に構築のできるシステムであることを訴えて。
今回のセッションでは、要件定義をもとに基本設計とアプリ構築を同時に行いながら、棚卸しシステムのプロトタイプを一時間で作り上げてしまいました。
このセッションは弊社のメンバーにぜひ見てもらいたいと思いました。従来のシステム開発なら、持ち帰って検討して要件定義した後に実装するため、早くても三週間はかかっていたでしょう。それが一時間でできてしまうkintoneの性能と機能をフルに活用した良い例です。

続いてのセッション『教えて!みんながkintoneから学んだこと』も良かったです。
先日のcybozu daysでは、kintone SIGNPOSTが正式にお披露目されました。現場の課題をどのようにシステム要件にし、それをシステムとして組み上げるか。その際はシステム開発に留まらず、コンセプトや社内のビジネスフローの再構築にまで話を広げる必要があります。その中では体制やコンセプトの整理も求められるでしょう。
現場の声としてあがった本セッションの内容は、kintone SIGNPOSTの生きた事例として参考になりました。

続いてのセッション『チャレンジ!きんとん関数ドリル』は、
ここ二年間でkintoneに追加された機能として特筆される関数を取り上げていました。このセッションではkintoneの関数の奥深さを味わうことができました。
私は出題された10問のうち6問しか合わず、関数についての理解の浅さを露見させてしまいました。
なんでもJavaScriptで解決してしまおうとする考えから切り替えていかなければ。
それにしても、松田さんによる関数の分析はお見事としか言いようがありません。ここまで理解してこそkintoneエバンジェリスト。私も精進しなければ。

この後もkintone SIGNPOSTの紹介や懇親会などがありました。が、実家にいた私は両親と食事に出かけたため、この後の懇親会には参加していません。さぞや盛り上がったことでしょう。

また来年も開催されると思うので、楽しみにしたいと思います。

重ねて皆様、ありがとうございました。

当日のTwitterまとめはこちらです。


事例:北新海運様


kintoneを導入したことによる日常業務の効率化

  Topへ↓

北新海運様は、海運の国内運送を主に担っておられます。
海外の船がコンテナバースに到着し、荷揚げされたコンテナ。この荷物を国内のお客様に運ぶのが北新海運様の業務です。

従来はExcelで運用されていたお客様への請求業務や、ドライバーへの指示、ドライバーの稼働実績の取りまとめ。
それらをリリース間もないkintoneに切り替えることで、運用工数の削減を実現しました。

Excelによる単価管理やドライバーへの指示業務の煩雑化

  Topへ↑

お客様からのご発注を受け、それをドライバーへの運行指示書に印刷する。そして、その結果をお客様への請求書として発行する。ご発注から請求までの流れは単純に書くとこのような感じです。
ところが、お客様からの発送指示は千差万別。その発送場所によって単価が変わります。また、コンテナのフィートによっても単価が変わります。
配車指示を的確に行わねば、効率的な運用はできません。
また、案件ごとに単価が変わるので、その単価を的確に反映した請求書を発行し、同時にお客様によっては請求データを一覧表として発行しなければなりません。
そうした複雑な業務が伴う海運業務を行うには、Excelでは限界が生じていました。

また、ドライバーが従事した業務によって手当を計算する作業も負担になっていました。
複数の場所で荷を下ろす場合や、積み場所の変化。さらには、構内業務に従事する場合には別の計算方法が必要です。そして、それらが組み合わさった場合の作業もきちんと集計せねばなりません。そうした複雑な作業実績の集計は業務の負担となっていました。

リリースしたばかりのkintoneを提案し、採用。

  Topへ↑

Excelから離れ、新たなシステムを構築しなければ。
北新海運様で事務を統括する立場にあった紀村様は、旧知のデザイナー様に相談しました。
相談を受けた株式会社アトリエmの室井様は、そのご相談を受け、弊社にご相談くださいました。

その当時、まさにリリースされたのがクラウドサービス「cybozu.com」とそのサービスの一つであるkintoneでした。私はこのkintoneのβテスターであり、kintoneがリリースされたタイミングで導入できる機会を待っていました。そこにいただいたのが北新海運様のお話。
2012年の正月明けに北新海運様にお伺いし、紀村様にご要望を伺いました。
そしてご要望がkintoneで実現できると判断し、kintoneをご提案しました。

社長様は初めて会った私と、出来たばかりのサービスであるkintoneを信頼してくださいました。そして、ご発注にいたりました。
それが2012年1月26日のことです。

APIのリファレンスがなかった時期ゆえの苦労

  Topへ↑

私の手元には、この当時にサイボウズさんから頂いたMicrosoft Wordの「kintone API マニュアル」があります。表紙にはV0.1と書かれています。
この当時、リリースされたばかりのkintoneにはすでにAPIが実装されていました。とはいえ、レコードの追加・取得・更新・削除ぐらいしかできませんでした。今のリクエスト方法やレスポンス結果とそう仕組みは変わらないとはいえ、今のようなリファレンスは整っておらず、ウェブ上にブログなどの情報もほとんどありませんでした。
加えて、当時の私はRest APIを使った実装の経験がなく、ノウハウも持っていませんでした。

他にも問題はありました。それは、帳票をどうやって出すか、でした。
当時はまだプラグインの仕組みがありません。つまり、今のようなサードパーティーさんによる帳票発行プラグインもありません。
kintoneを使ってどうすれば帳票を出せるのか。まずその調査から始めました。

当時、すでに私は某案件でWeb上のphpライブラリ(TCPDF+FPDI)を使って帳票発行を実装した経験がありました。
そもそも、北新海運様からお話を伺った当初は、Accessによる実装という選択肢も有力でした。kintoneとAccessのどちらを採用するか決めかねていました。
Accessのレポートで帳票を出すのか、それともウェブ上でphpを使って帳票を出すのか。
私はそのどちらでもなく、Excelを使うことにしました。

VBA(Excelマクロ)からRest APIのリクエストを出し、その結果を受け取れれば、Excelで帳票が出せるのではないか。
私はそう判断し、ウェブ上であれこれと調べ、何とか実装にこぎつけられました。

結果、2012年の4月から運用を開始しました。ですが、当初は何度も調整が発生しました。
私自身、まだkintoneを完全に理解出来ておらず、ルックアップフィールドをはじめとしたフィールドの載せ替えなども何度も行いました。
夏前まではさまざまな調整が発生しましたし、帳票の発行についてもレイアウトや表示書式などなんども調整しました。おそらく全て落ち着くまでは1年はかかったように思います。

導入して9年

  Topへ↑

その後、当初の実装フェーズには含めていなかったドライバーの実績集計についても実装を終え、そちらも運用を開始しました。
さらに、北新海運様の業務拡張による別会社設立の際も、同じ仕組みの上に若干のカスタマイズを加えて実装し、運用を開始しました。

以来九年、Excelによる帳票発行の仕組みも含め、北新海運ともう一社の仕組みは動いています。

紀村様より

導入からの9年について、紀村様はこう語ってくださいました。

「アクアビット長井さんの原稿を拝見し、9年前の導入当時を思い出します。

弊社 有限会社北新海運は今年で創業17年目の会社になります。
9年前、私は入社3年目で事務全般を担当しておりました。その作業内容は受注・売上・請求だけではなく運賃管理・ドライバーの売上管理、それに伴う給料計算に至るまで殆ど全てでした。さらに車両の増車に伴う業務負担もあり現行をやり過ごすことが出来たとしても近い将来、必ず困った事態に陥る事は目に見えていたのです。

とはいえ当時リーマンショックからやっと立ち直ったばかりの小さな会社、そして海上コンテナ業界は輸出・輸入という特殊な世界のため専門ソフトがない中、システム導入を専門会社に依頼すれば何百万単位の金額が出てくる事は以前に在籍していた他社で見聞きし、十分に分かっていることでした。
コロナ禍における在宅勤務による環境の大きな変化でシステムが予算的にも身近になった昨今と違い、当時はシステムゼロからの依頼は予算の乏しい会社にとっては大きなハードルだったのです。

そこで広告・宣伝・HP作成等々の会社を経営なさっている友人にその問題点を相談をしたところ、アクアビットの長井さんをご紹介いただきました。
長井さんには何度も打ち合わせには来社、この業界の業務の流れをいちから丁寧に聞いてくださり、夜遅くなることもしばしばありました。

当時は長井さんが個人事業主ということもあり少し不安ではありましたが、kintoneを使ってのシステム構築でコストを非常に下げられるご提案を頂いたことで、初期投資として仮にリスクがあっても最小限にとどめられる事も想定し社長が決断して下さいました。
導入事例の中では1年程かかったとの文面がありましたが、kintoneの業務作業を並行・チェックをしながら手直しをし、追加リクエストもあったので、実は2年位はかかったと思います。その後、長井さんとのやり取りも年々少なくなってきましたが、それは業務システムが問題なく動いている証拠だと思います…いや、実はリクエストはまだまだありますが、kintoneバージョンアップがそこまでいっていないというのも本音です(笑)。

大手企業が作るシステムも大事ですが、実は中小企業の“小”の会社こそがこの様なシステムをすぐにでも必要としていると思います。初期投資が大きいために二の足を踏むオーナーさんも沢山いらっしゃると思います。そのなかには直ぐにでも使えるシステムが欲しい中高齢のアナログ世代の方々が相当いらっしゃいます。少なくともコンテナ輸送業界はそうです。
その様な会社を直ぐにフォロー出来るのがkintoneだと私は思います。
そして、この業界を少しでも知る長井さんの様なアドバイザー的な方がもっと増えることも今は大事かと考えます。

長井さんにはずっと以前よりkintoneの講習会参加を勧められておりましたが、今だ実現に至っておりません。コロナ禍収束の折には講習参加を真剣に考えたいと思っている今日この頃です。
有限会社北新海運 紀村多栄」

溝木様より

また、北新海運の溝木社長からはこのようなありがたいお言葉をいただきました。抜粋して掲載させていただきます。

「弊社も今年で創業16年になります。
長井様には色々なご相談に乗って頂き大変助かっております。
最初のころは、私はExcel、Wordも分からず、パソコンには色々苦労しました。

そこでお知り合いになったのが長井様で御座います。
弊社にとって何か良い業務方法ないか、何回も同じことを打つのではなく一回で作業を終わらす方法、当時、長井様は色々な方法を考えて下さいました、弊社の要望を聞きながら猛勉強をされたと思います。弊社の職業柄大変だったと思います。とても使いやすく助かっております。

専門的なことは今でも分かりませんが、長井様のおかげで業務が短縮になったのは確かです、継続は力なりとありますが、今では弊社にとって最高のパートナーです。
私がこれをやりたいとお話すると、私の考えが分かっているかのようにパソコンExcel、kintoneを組んでくれます。

昔の人は、「人は必要だから出会うと言います」必要でないのなら一生出会う
ことはないでしょう。
弊社もこれから色々なことに挑戦していきます、その度に長井様にお願いする
ことが多いと思います。
これからも末長く宜しくお願い致します。

有限会社北新海運 
代表取締役 溝木昭夫」

まとめ

涙が出そうになるほど、感動しました。
お二方より頂いた文章は、段落を整えた以外はなにも直していません。私と弊社にとってとても心強く、嬉しいお言葉です。

私も今までにいくつもの失敗をしてきました。特に、kintoneに出会う前、ホームページ制作を手掛けていた時期は。何度も。
でもこうしたお言葉をいただけると頑張ってきてよかったと思えますし、これからも頑張ろうと思えます。また、kintoneが私のスタイルに合っていたのだと強く思います。
北新海運の皆様、本当にありがとうございます。また、ご紹介を頂いたアトリエmの室井様、本当にありがとうございます。

北新海運様のご紹介

商号 有限会社 北新海運
本社 〒272-0522 千葉県市川市宮久保5-9-7
   
本社営業所 〒143-0001 東京都大田区東海5-4-1 大井海貨5号上屋北側1階
TEL 03-5755-7813
FAX 03-5755-7814
代表者 取締役 溝木 昭夫
従業員数 25名
設立 2005年(平成17年)9月28日
資本金 500万円
ウェブサイト http://www.hokushinkaiun.com/

ライフログのkintone盛り alasql仕込みのGoogle Chart添え


1.読まなくてもいい献立の前書き

  目次へ↓

唐突ですが皆さん、ライフログって言葉覚えてますか? 何!忘れた? そんな言葉あったっけ?

それならば説明しましょう!システムが行った作業の結果がログ。ウェブ上にログを残すからウェブログ。略してブログ。そして、人生のイベントを記録するのがライフログ。今やこの言葉は、数多くの新語とともにハードディスクの肥やしと成り果てています。

ところが、まだ忘れるのは早い!という訳で、kintoneでライフログです。

このライフログという概念は2000年代の初め頃に産声をあげていたといいます。ITジャーナリストの佐々木俊尚氏は、2010年の秋に発表した『キュレーションの時代』の中でライフログの概念は2010年代の間にはまだ根付かないだろう、と的確に予言されています。なぜなら、日本にはプライバシーの公開に気持ち悪さを持つ人が大多数だから、と。つまり、ライフログとはまだこれからの概念なのです。佐々木氏はその本の中で、ライフログを集めるツールとしてFourSquare_logoをプッシュしています。このFourSquare_logoですが、ある時期に仕様が迷走したこともあって日本ではすっかり影を潜めてしまいました。ですが、海外では位置とモノを関連付けたデータをがっちり握った企業として存在感を保っているようです。FourSquare_logoとは、一言でいうと訪問場所でチェックインすることで自分がいつどこにいたかを後世の自分、またはどこかの物好きのために記録しておくツールです。それはまさにライフログ。なお『キュレーションの時代』はかつて弊社のブログでも取り上げています。

kintoneは言うまでもなく優れたプラットホームサービスですし、仕事の改善にはテキメンに効きます。それはもう間違いない。でも、プライベートな使い方だってできるのですよ。ワークライフバランスを充実させるにはプライベートでもkintoneを使い倒したほうがいいと思いませんかみなさん!?

私にとって幸いなことにkintoneFourSquare_logoの連携事例はウェブにほぼ皆無です。そこは青い大海原、ブルーオーシャン!というわけでささやかですが、連携事例を公開したいと思います。あわせて、これもkintoneとの連携事例が極めて少ないGoogle Chartと絡めて。題して「ライフログのkintone盛り alasql仕込みのGoogle Chart添え」

2.ご用意いただく材料

  目次へ↑

ちなみにこのレシピの内容を再現せんと志す奇特な方は、以下のものをご用意ください。

  • FourSquare_logoのアカウント(チェックイン用のアプリSwarm_logoも忘れずに)
  • kintoneのスタンダードプラン
  • phpが動き、cronが実行できるサーバー(レンタルサーバーでも可)
  • Google Maps Platform上で動くライブラリを呼び出すためのAPI KEYの入手。こちらをご参考に

このレシピは2018年12月時点の「さくらのレンタルサーバー スタンダード」(phpは7.2.10(CGI版))で動作することを確認しております。
また、Google Maps Platformで動くAPIについては、月あたり40000リクエストまでが無料枠内だそうです。このレシピはプライベート利用なので、そこまでいかないことを念頭においています。
ちなみに、みんな大好き「zapier」でも、Swarm_logoでチェックインする度にkintoneに新たなレコードを追加できます。が、それをいっちゃぁおしめえよ、ということでお付き合いいただければ幸いです。
このレシピは一日単位でkintoneにライフログを一括で登録することに意義を持たせています。そして激動の一日を振り返りつつ、自分をねぎらいたい、そして昨日を忘れ去りたい「あ・な・た」の味方になることも!

なお、いうまでもなく、ライフログはみだりに公開するものではありませんぞ。このレシピのせいであなたのデイリーライフに何か問題が起こっても責任は取れませんのであしからず〜

3.献立の出来上がりイメージとレシピ

  目次へ↑

FourSquare_logoはAPIがOAUTH付きで公開されています。なので私の策略はこうです。まず、午前0時を過ぎたあたりでFourSquare_logoの前日分のチェックインデータをkintoneにシュっと放り込んでやろう。そして溜まったデータをウヒャヒャと一覧で眺めてみよう。ついでに今年、どんぐらい国や県を訪れたんやろう、と地図に出して一人ニヤけて悦にいる。うーん、ダークロースト。

まずは着地点をお見せします。上が世界の長井。下が日本の長井です。

世界の中心で長井を晒す

日本の中心で長井を晒す

ともにkintoneのカスタマイズビューではなく通常の一覧を使って長井を晒しています。世界地図は日本と台湾に色がついており、日本地図は東京が最も濃く、次に神奈川。データはFourSquare_logoSwarm_logo)でチェックインしたデータをphpでkintoneに取り込みます。地図を書き込むのは一覧画面のヘッダスペースです。そのため、世界地図版と日本地図版で一覧を分けています。

kintoneのアプリの構造はこんなんです。

フィールド名 フィールドコード
場所 場所 文字列(1行)
文字列(1行)
都道府県 都道府県 文字列(1行)
コメント コメント 文字列(1行)
日時 日時 日時

あと、アプリの設定画面で下図の3つのファイルを登録してください。
https://www.gstatic.com/charts/loader.js
とhttps://cdnjs.cloudflare.com/ajax/libs/alasql/0.4.11/alasql.min.js
はCDNから使います。最後のjsファイルはこの後説明します。
kintone_app

ここであらためて全体の構成図をご覧いただきましょう。一目瞭然とはこのことですね。

構成図

4.FourSquareの下ごしらえ

  目次へ↑

日々のチェックイン履歴をFourSquare_logoに溜める方法は、簡単に書くとこんな感じです。

  • Swarm_logoのアプリを立ち上げ、チェックインしたい場所でチェックインボタンを押す。
  • Swarm_logoの候補の一覧にその場所が登場します。
  • 登場しなくても検索すれば場所が指定できます。
  • 指定した場所でチェックイン(構成図の①)を行えば時間とともに自動的に記録(構成図の②)されます。気が向けばコメントも入れられます。

どうです?モンスターボールを投げなくてもよいし、ポータルを三角形で囲わなくてもよいのです。簡単ですよねFourSquare_logo

さて、今回の記事ではAccessTokenをFourSquare_logoから取得する処理(構成図の③)から説明します。AccessTokenはこのレシピの中で一度取得するだけです。なぜ一度だけでよいかというと、AccessTokenはユーザーを特定するのに使われるからです。つまり、一度AccessTokenを取得しておけば、何度でも使いまわしができるのです。FourSquare_logoには他にもたくさんのAPIが用意されています。処理によってはその都度AccessTokenを取らねばならず、ソースも複雑な下ごしらえが求められることもあります。ですが、このレシピではユーザーのチェックイン情報だけをとるのが目的なので、一度きりでよいのです。

5.FourSquareのAPI KeyとAPI Secretを取り寄せる

  目次へ↑

まず、https://ja.foursquare.com/にアクセスしてください。

FourSquarePage

そして、右上の開発者をクリックします。

すると、https://developer.foursquare.com/にページが遷移します。

FourSquareDeveloperPage

がでたら、右上のCreate Accountからアカウントを作成してください。

多分、FourSquare_logoで作ったアカウントがそのまま開発者アカウントとして引き継がれるはずです。

そしたら下図のようにMy Appsを選びましょう。アプリの作成のリンクがあるはずです。

FourSquareMyApp

こんな風に入れてください。

FourSquareMyAppRegist

この中で重要なのは3点。

  • Client ID、Client Secretは次の作業で使うのでちゃんとメモっておきましょう。
  • Client ID、Client Secretは墓まで持っていきましょう。人に教えちゃダメ!
  • Redirect URI (s)もちゃんと考えておきましょう。これは次の作業でこさえるスクリプトのURIです。

Application Urlという項目もありますが、ここは適当でよいです。他の項目も商用で使わなければ空白でよいはず。

6.FourSquareのアクセストークンの取り寄せとソースの仕込み方

  目次へ↑

続いて、アクセストークンを取得するためのphpを示しましょう。98行。38ステップです。

コメントに内容は記載しているので、まずはソースを味わってみてください。

設定A ⇒ 条件分岐B ⇒ 条件分岐C ⇒ 処理D ⇒ 処理E ⇒ 処理F ⇒ 条件分岐G ⇒ 処理H ⇒ 条件分岐I ⇒ 処理Jの順に進みます。

  // 設定A //
  // マイアプリで表示されたClient ID
  $client_id = 'KOKONIHAHONMAYATTARARANDAMUNAMOJIRETSUGAHAITTORUNEN';
  // マイアプリで表示されたClient Secret
  $client_secret = 'SEYAKEDOKOKONISOREDASHITARAORENOKOUDOUGABARERUKARADASAHENNEN';
  // リダイレクトURL (このスクリプト自身のアドレスです)
  $redirect_uri = 'https://*****.*****.ne.jp/*****/****_*********.php';
  // アクセストークン取得URLのベース
  $access_token_baseurl = 'https://foursquare.com/oauth2/access_token';
  // 認証URLのベース
  $authenticate_baseurl = 'https://foursquare.com/oauth2/authenticate';

  // 結果表示HTML用
  $html = '';
  // 結果表示見出し
  $html .= '<h2>実行結果</h2>';

  // 条件分岐B //
  //初回は$_GET['code']がなく中の処理は実行されない。「許可」され、リダイレクトされた場合に実行
  if( isset( $_GET['code'] ) 
    && !empty( $_GET['code'] ) 
    && is_string( $_GET['code'] ) ) {
    // 処理E //
    // 認証画面でFourSquareの実行が許可されると$_GET['code']付きでこのスクリプトが呼び出される。
    // アクセストークンの取得に利用するコード
    $code = $_GET['code'];
    // 処理F //
    // アクセストークン取得のためのパラメータを設定したUrlを組み立てる。
    // リクエストURL
    $request_url = 
      $access_token_baseurl . 
        '?client_id=' . $client_id . 
        '&client_secret=' . $client_secret . 
        '&grant_type=authorization_code' . 
        '&redirect_uri=' . rawurlencode( $redirect_uri ) . 
        '&code=' . $_GET['code'] . 
        '&state=users/self';
    // curlを初期化する
    $curl = curl_init();
    curl_setopt( $curl , CURLOPT_URL , $request_url );
    curl_setopt( $curl , CURLOPT_HEADER, 1 );
    // 証明書の検証を行わない
    curl_setopt( $curl , CURLOPT_SSL_VERIFYPEER , false );
    // curl_execの結果を文字列で返す
    curl_setopt( $curl , CURLOPT_RETURNTRANSFER , true );
    // タイムアウトの秒数
    curl_setopt( $curl , CURLOPT_TIMEOUT , 5 );
    // 実行し、結果を$jsonに代入
    $res1 = curl_exec( $curl );
    $res2 = curl_getinfo( $curl );
    curl_close( $curl );
    // 取得したJSONデータ(ヘッダーサイズでTrimしないとFourSquareはエラーになる)
    $json = substr( $res1, $res2['header_size'] );

    // JSONをオブジェクト型に変換する
    $obj = json_decode( $json );

    // 条件分岐G //
    if( !isset( $obj->access_token ) ) {
      // アクセストークンを取得できなかった場合
      $error = 'アクセストークンを上手く取得することができませんでした。';
    } else {
      // 処理H //
      // アクセストークンを[$access_token]に代入する
      $access_token = $obj->access_token;
      // アクセストークンをブラウザーに出力する
      $html .= '<p>取得したアクセストークンは <b><mark>' . 
        $access_token . '</mark></b>です。</p>';
    }
  } elseif( isset( $_GET['error'] ) ) {
    // 「拒否」して返された場合怒る。
    $error = 'なんで「許可」してくれへんの!?';
  } else {
    // 条件分岐C //
    // 初回はこの処理が行われるはず。
    header( 'Location: ' . $authenticate_baseurl . 
      '?client_id=' . $client_id . 
      '&response_type=code' . 
      '&redirect_uri=' . rawurlencode( $redirect_uri ) );
    // 処理D //
    // headerの後はexit()
    exit;
  }

  // 条件分岐I //
  // エラー判定
  if( isset( $error ) && !empty( $error ) ) {
    $html .= '<p><mark>' . $error . '</mark>' . 
      'もう一度、認証をするには、' . 
      '<a href="' . explode( '?' , $_SERVER['REQUEST_URI'] )[0] . '">こちら</a>' . 
      'をクリックして下さい。</p>' ;
  } else {
    // 処理J //
    // ブラウザーに[$html]を出力 (結果としてアクセストークンの文字列が表示されます)
    echo $html;
  }

もう一度上の処理をおさらいします。
・最初にこのスクリプトが呼ばれた際、URLにcodeパラメーターはついていません。
・だからBの条件でEFGHの処理は行われず、条件分岐Cの処理が実行されます。
・その中ではLocationヘッダを送信しています。なので、その下の処理Dでただちに認証画面にリダイレクトされます(認証画面は割愛します)。
・そこで認証が終われば、再びこのスクリプトがcodeパラメーター付きで呼ばれるよう、処理DのLocationヘッダの中にredirect_uriパラメーターを指定しています。
・再びこのスクリプトが実行されると、今度は条件分岐Bで処理E、Fが実行されます。
・FではFourSquare_logoのアクセストークンを返すAPIが呼ばれます。
・なので、無事にアクセストークンが返ってくるという流れです。お判りでしょうか?

そしたらこのスクリプトファイルをどこかのウェブサーバーに送ってください。phpファイルの実行権限付きで。先ほどFourSquare_logoのマイアプリの設定でRedirect Url (s)に入力していただきましたが、その内容と合わせておいてください。

たとえばhttps://hanamogera.com/mokeke/foursqaure_tokun_yokose.phpに送るとします。そしたらブラウザーのアドレスバーに直接上のアドレスを指定し、実行します。

すると結果が以下のように表示されるはずです。このマーカー部分をコピーしておきましょう。

アクセストークン

おめでとうございます。アクセストークンはこれであなたのものです。ついに調理人として存分に腕を振るう時が来たのです!!

7.FourSquareからCheckinデータの取り寄せとソースの仕込み方

  目次へ↑

続いては、いよいよAccessTokenを使ってFourSquare_logoにデータくれ!とおねだり (構成図の④) してみましょう!もらったデータをkintoneにシュッと投げ込むまで(構成図の⑤)のphpも説明します。まずはphpを以下に示します。115行。64ステップです。

こちらもコメントに内容は記載しているので、まずはソースを味わってみてください。
先のスクリプトはソースに大分シェフの手を加えましたが、このスクリプトは素材の味を生かすような作りにしています。

設定A ⇒ 設定B ⇒ 設定C ⇒ 設定D ⇒ 設定E ⇒ 条件分岐F ⇒ 条件分岐G ⇒ 処理H ⇒ 処理I ⇒ 処理J ⇒ 処理Kの順に進みます。

  // 設定A //
  // アクセストークン (前の処理で取ってきた文字列です)
  $access_token = 'YATTAYOAKUSESUTOKUNTORETAYOKOREDESIAWASENINARERUNE';

  // 設定項目 (ここはアクセストークン以外はデフォルト)
  $params = array(
    'oauth_token' => $access_token ,// アクセストークン (これでユーザーが認識される)
    'locale' => 'ja' ,              // ローカライズ (jaは日本)
    'm' => 'swarm' ,                // モード (foursquare OR swarm)
    'v' => '20150801' ,             // バージョン (APIのバージョン。今のところ左の年月日)
    'limit' => '250'                // 取得件数 (250が上限)
  ) ;
  // 設定B //
  // GETメソッドで指定した場合 (設定項目のパラメーターを差し替える)
  foreach( array( 'locale' , 'm' , 'limit' , 'sort' , 'afterTimestamp' , 'beforeTimestamp' ) as $val ) {
    if( isset( $_GET[ $val ] ) && $_GET[ $val ] != '' ) {
      $params[ $val ] = $_GET[ $val ] ;
    }
  }

  // 設定C //
  // 設定項目 (日付や並び替えなどの条件を追加します。例えば2018/11/30の00:15時点で実行されたとします。
             するとstrtotime("today")は2018-11-30 00:00:00が返されます。
              strtotime("yesterday")は2018-11-29 00:00:00が返されます。
              それをもとにした$params["afterTimestamp"]は2018-11-29 00:00:00より後のチェックインデータを、
              それをもとにした$params["beforeTimestamp"]は2018-11-30 00:00:00より前のチェックインデータを取得します。
              $params["sort"]はoldestfirstを指定すると上記の日付範囲のチェックインデータのうち古いものを最初に取得します。
              ここ重要です。kintoneライフログ調理師試験に出ますので、要おさらい!!) //
  $today = strtotime("today");
  $yesterday = strtotime("yesterday");
  $params["afterTimestamp"]=$yesterday;
  $params["beforeTimestamp"]=$today;
  $params["sort"]="oldestfirst";

  // リクエストURL (usersの次のselfは固定文字)
  $request_url = 'https://api.foursquare.com/v2/users/self/checkins?' . http_build_query( $params );

  // 設定D //
  // cURLでリクエスト
  $curl = curl_init();
  curl_setopt( $curl , CURLOPT_URL , $request_url );
  curl_setopt( $curl , CURLOPT_HEADER, 1 );
  curl_setopt( $curl , CURLOPT_SSL_VERIFYPEER , false );
  curl_setopt( $curl , CURLOPT_RETURNTRANSFER , true );
  curl_setopt( $curl , CURLOPT_TIMEOUT , 5 );
  $res1 = curl_exec( $curl );
  $res2 = curl_getinfo( $curl );
  curl_close( $curl );

  // 設定E //
  // 取得したJSONデータをオブジェクト形式に変換する (ヘッダーサイズでTrimしないとFourSquareはエラーになる)
  $json = substr( $res1, $res2['header_size'] );
  $obj = json_decode( $json );

  // 条件分岐F //
  // エラー判定 (metaのcodeの値が200だと正常に取得されている)
  if( !$obj || !isset($obj->meta->code) || $obj->meta->code != 200 ) {
    //ログ出力して調査!
  } else {
    // 説明
    $data = array();
    $count = 0;
    // 条件分岐G //
    //取得したデータオブジェクトの -> response -> checkins -> itemsの中をループする //
    foreach( $obj->response->checkins->items as $item ) {
      // 処理H //
      //$itemの中にはチェックインの場所についての栄養が豊富に含まれています。緯度経度やコメントや市長など。詳しくはhttps://developer.foursquare.com/docs/api/users/checkins //
      // チェックインID
      $id = $item->id ;
      // ベニューのID
      $venue_id = $item->venue->id ;
      // ベニューの国 (国名は日本語で取得できる)
      $venue_country = $item->venue->location->country;
      // ベニューの都道府県 (取得した後、Google Chartの都合で末尾の「都」「府」「県」は除去する)
      $venue_prefecture = $item->venue->location->state;
      switch ($venue_prefecture){
        case '北海道':
          break;
        default:
          $venue_prefecture = mb_substr($venue_prefecture,0,-1, "UTF-8") ;
          break;
      }
      // ベニューの名前 (改行は除去しておく)
      $venue_name = str_replace(array("\r\n", "\r", "\n"), '', $item->venue->name);
      // チェックイン日時(オフセットと合わせる。要は日本の時間に合わせる)
      $createdAt = $item->createdAt + 54000 - 86400;
      // 日時の整形 (kintoneにあった日付データ形式に変更する)
      $createdAt = date( 'Y-m-d' , $createdAt )."T".date( 'H:i:s' , $createdAt ) ;
      // コメント (改行は除去しておく)
      $shout = ( isset($item->shout) ) ? str_replace(array("\r\n", "\r", "\n"), '', $item->shout) : '';
      // kintoneに投げるデータです。フィールドコードとデータ型を合わせることを忘れずに。
      // 処理I //
      //kintoneに投げるデータをここで指定します。文字列データは文字列型にキャストしておくとふっくら仕上がります //
      $data[$count] = array(
        "場所" => array("value" => (string)$venue_name),
        "コメント" => array("value" => (string)$shout),
        "国" => array("value" => (string)$venue_country),
        "都道府県" => array("value" => (string)$venue_prefecture),
        "日時" => array("value" => $createdAt)
      );
      $count++;
    }
  }

  // 処理J //
  // kintoneの対象のアプリIDを指定する。(1111というのはダミーです)。FourSquareからのデータもあわせて。
  $postdata = array("app" => 1111,records=>$data);
  // 処理K //
  // kintoneのアクセストークンを指定する。ベーシック認証がある場合はそちらもあわせて指定。
  $headers = array(
    "X-Cybozu-API-Token:" . "kintoneNOAPURISETTEIDESHUTOKUDEKIRUTOKUN",
    "Authorization:" . "Basic " . base64_encode("YUUZAAID:PASUWAADO"),
    "Content-Type:" . "application/json"
  );
  // 以下の******はお使いのkintoneのサブドメインを入れてください。
  $curl = curl_init('https://******.cybozu.com/k/v1/records.json');
  curl_setopt($curl, CURLOPT_POST, true);
  curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
  curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($postdata,JSON_UNESCAPED_UNICODE));
  curl_setopt($curl, CURLOPT_HEADER, true);
  // curlで出たエラーを補足するためのものです。
  $fp = fopen('curl.log', 'a');
  // 詳細な情報を出力する
  curl_setopt($curl, CURLOPT_VERBOSE, true);
  // STDERR の代わりにエラーを出力するファイルポインタ
  curl_setopt($curl, CURLOPT_STDERR, $fp);
  if(curl_exec($curl) === false){
    //ログ出力して調査!
  } else {
    return true;
  }
  curl_close($curl);

このスクリプトもウェブサーバーに送ってください。ファイルの実行権限付きで。あと、ファイルのUrlはきちんとメモしておいてくださいね(^_^)

次にcronの設定を行います。cron実行のための構文はサーバーによって違います。ここに載せているcron設定はさくらインターネットの例ですが、phpファイルの実行パスと、スクリプトのファイル名はどのサーバーでも求められるはずです。このレシピは毎日00:15に自動で実行するように設定しています。

Cron設定1

cron2-1

8.kintone上でデータの盛り付け

  目次へ↑

さて、7までのレシピ(2018/12時点の)に忠実に行うとチェックインデータは毎日順調にkintoneに流れ込むはず。あとはデータを盛り付けるだけ。「ライフログのkintone盛り alasql仕込みのGoogle Chart添え」とうたっている以上、最後の仕上げにGoogle Chartを添えるのを忘れるなかれ。それぞれの一覧ごとに違うマップを表示するJavaScriptを以下に示します。この中でkintoneのデータをalasqlで集計し、その結果をGoogle Chartで地図に表示しています。

世界地図の場合、処理A ⇒ 条件分岐B ⇒ 処理C ⇒ 処理D ⇒ 処理E ⇒ 処理V ⇒ 処理F ⇒ 処理W ⇒ 処理G ⇒ 処理H ⇒ 処理I ⇒ 処理J ⇒ 処理Kの順に進みます。
日本地図の場合、処理A ⇒ 条件分岐L ⇒ 処理M ⇒ 処理N ⇒ 処理O ⇒ 処理V ⇒ 処理P ⇒ 処理W ⇒ 処理Q ⇒ 処理R ⇒ 処理S ⇒ 処理T ⇒ 処理Uの順に進みます。

(function () {
  "use strict";
  // 処理V //
  // 再帰処理による一回のリクエスト制限を超えた全レコードを取得 //
  function fetchRecords(appId, opt_query, opt_fields, opt_offset, opt_limit, opt_records) {
    var query = opt_query || '';
    var offset = opt_offset || 0;
    var limit = opt_limit || 500;
    var allRecords = opt_records || [];
    var params = {app: appId, query: query + ' limit ' + limit + ' offset ' + offset };
    if (opt_fields) params.fields = opt_fields;
    return kintone.api(kintone.api.url('/k/v1/records', true), 'GET', params).then(function(resp) {
      allRecords = allRecords.concat(resp.records);
      if (resp.records.length === limit) {
        return fetchRecords(appId, query, opt_fields, offset + limit, limit, allRecords);
      }
      return allRecords;
    });
  }

  // 処理W //
  // json形式で取得したkintoneのレコードをalasqlで扱えるようレコードセット形式に変換 //
  function convertToRows(records) {
    var rows = records.map(function(record){
      var keys = Object.keys(record);
      var row = {};
      keys.map(function(key){
        row[key] = record[key].type === 'NUMBER' ? Number(record[key].value) : record[key].value;
      });
      return row;
    });
    return rows;
  }

  // 一覧ページ
  kintone.events.on('app.record.index.show', function(event) {
    // 処理A //
    //Google Cloud Platformで発行したAPI KEYです。
    //API KEYがない場合、以下の処理Cでgoogle.charts.load('upcoming', {'packages':['geochart']});としても動きますが、世界地図の色塗りができません。また、コンソールでエラーが表示されます。
    //作成したプロジェクトの認証はリファラーを限定するとよいです。https://subdomain.cybozu.com/* のように指定すると、対象のサブドメインに対して動作します。https://akvabit.cybozu.com/だと動きませんので注意が必要です。
    //あと、許可するAPIですが、「Maps JavaScript API」「Geolocation API」「Geocoding API」の三つを有効にしています。
    const ApiKey = 'k54u6 jkrawyeie-wkjykethiudarwhyeiu_rekyjur';
    // 条件分岐B //
    //世界地図ビューの場合 //
    if (event.viewId === 5351051) {
      // 処理C //
      //google chartを読み込む。種類は地図 //
      google.charts.load('upcoming', {'packages':['geochart'],'mapsApiKey':ApiKey});
      // 処理D //
      //google chartの読み込みが完了したらコールバックでdrawWorldMapを呼び出す //
      google.charts.setOnLoadCallback(drawWorldMap);
      function drawWorldMap() {
        var obj = {};
        // 処理E //
        //このファイルの3-17行のfetchRecords関数を呼び出す。対象アプリは自分で、フィールドは[場所][国] //
        fetchRecords(event.appId, '', ['場所', '国']).then(function(records) {
          // 処理F //
          //取得したレコードをSqlで扱えるようなレコードセットの形式に変換するconvertToRows関数(このファイルの20-30行)をご参照 //
          obj.rs1 = convertToRows(records);
          // 処理G //
          //alasqlでsql文のソースを組み上げ、バインドパラメータに処理Fで得たレコードセットをセットする //
          var result = 
            alasql(
              "SELECT t.[国], COUNT(t.[場所]) as [回数] \
              FROM ? AS t \
              GROUP BY t.[国] \
              ORDER BY t.[国]", [obj.rs1]);
          // 処理H //
          //google chartのデータテーブルのインスタンスを新たに確保する //
          var data = new google.visualization.DataTable();
          // 処理I //
          //google chartのデータテーブルの列と行を追加します。alasqlでグループ集計された国ごとの訪問回数です。 //
          data.addColumn('string', '国');
          data.addColumn('number', '訪問場所数');
          result.forEach(value => {
            data.addRow([value["国"], value["回数"]]);
          });
          // 処理J //
          //google chartの世界地図の色塗りの書式を設定する //
          var options = {
            datalessRegionColor: '#ffffff',
            colorAxis:{
                maxValue:500,
                colors:['#D8F6CE','#21610B']
            }
          };
          // 処理K //
          //google chartの世界地図のデータに処理Iで格納した内容を代入し、kintoneのヘッダスペースに描画する //
          var chart = new google.visualization.GeoChart(kintone.app.getHeaderSpaceElement());
          chart.draw(data, options);
        });
      }
    // 条件分岐L //
    //日本地図ビューの場合 //
    } else if (event.viewId === 5351053) {
      // 処理M //
      //google chartを読み込む。種類は地図 //
      google.charts.load('upcoming', {'packages':['geochart'],'mapsApiKey':ApiKey});
      // 処理N //
      //google chartの読み込みが完了したらコールバックでdrawJapanMapを呼び出す //
      google.charts.setOnLoadCallback(drawJapanMap);
      function drawJapanMap() {
        var obj = {};
        // 処理O //
        //このファイルの3-17行のfetchRecords関数を呼び出す。対象アプリは自分で、フィールドは[場所][都道府県] //
        fetchRecords(event.appId, '', ['場所', '都道府県']).then(function(records) {
          // 処理P //
          //取得したレコードをSqlで扱えるようなレコードセットの形式に変換するconvertToRows関数(このファイルの20-30行)をご参照 //
          obj.rs1 = convertToRows(records);
          // 処理Q //
          //alasqlでsql文のソースを組み上げ、バインドパラメータに処理Pで得たレコードセットをセットする //
          var result = 
            alasql(
              "SELECT a.[都道府県], COUNT(a.[場所]) as [回数] \
              FROM ? AS a \
              GROUP BY a.[都道府県] \
              ORDER BY a.[都道府県]", [obj.rs1]);
          // 処理R //
          //google chartのデータテーブルのインスタンスを新たに確保する //
          var data = new google.visualization.DataTable();
          // 処理S //
          //google chartのデータテーブルの列と行を追加します。alasqlでグループ集計された都道府県ごとの訪問回数です。 //
          data.addColumn('string', '都道府県');
          data.addColumn('number', '訪問場所数');
          result.forEach(value => {
            data.addRow([value["都道府県"], value["回数"]]);
          });
          // 処理T //
          //google chartの地図を日本地図の都道府県とし、色塗りの書式を設定する //
          var options = {
            region: 'JP',
            resolution: 'provinces',
            datalessRegionColor: '#ffffff',
            colorAxis:{
                maxValue:600,
                colors:['#F2FBEF','#21610B']
            }
          };
          // 処理U //
          //google chartの世界地図のデータに処理Sで格納した内容を代入し、kintoneのヘッダスペースに描画する //
          var chart = new google.visualization.GeoChart(kintone.app.getHeaderSpaceElement());
          chart.draw(data, options);
        });
      }
    }
  });
})();

いかがでしょうか? ここはカスタマイズビューでリッチにデータを表現しても良いですし、条件に応じて絞り込めば、さらに面白いこともできます。チェックインデータにはカテゴリーもありますので、例えば訪れた酒場だけを抜き出し都道府県で図示したり、訪れたラーメン屋だけを都道府県で抜き出すことだってできます。例えば私の趣味ですが、今までに訪れた滝を色分けすればこうなります。城とすればこう。駅だとこう。他にも登った山や訪れた蒸留所や酒蔵、ブルワリー。各地の日本酒や世界の酒、料理などで色分けしても面白そうです。
残念なことにGoogle chartはまだ市町村には対応していません。もしそうなればもっと面白いライフログが作れそうです。もちろん、地図で塗り分けるほかにもGoogle chartはかなりのグラフの種類を用意しています。そこは皆様の自由です。
なお、ライフログとは、別に人様に見せて放浪癖を誇るものでも、旅行経験を自慢するものでもありません。あくまでもプライベートな利用がよろしいかと思います。ご自身の今までの人生とこれから残された人生に何を成すかを定める助けになればそれで十分です。そのあたり、ライフログについての私の考えは、このレシピ同時に書いたこちらで世に問うてみました。またご覧頂ければ幸いです。
このレシピをまとめるなら、要するにkintoneをプライベート用途に使おうよ、との主旨です。そういう使い方がもっと増えればkintoneはより身近なものになるのですから!

9.当レシピの参考にさせていただいたブログ

  目次へ↑

最後になりましたが、このレシピを作るのに、以下の5サイトを参考にさせていただきました。ありがとうございました。

 Foursquare(Swarm) APIの使い方まとめ (サンプルコード付き)
 Get Check-Ins for a User
 kintone でSQLを使う
 GoogleのGeochartを使ってみた
Google Maps Platform