【これが私たちのオフィス】エンジニアチームを支えるコミュニケーションツール

f:id:zacky2:20220210154514p:plain

はじめに

こんにちは、エンジニアの津崎( @820zacky )です。 今日は、弊社で全社的に使っているSlackについて、 エンジニアチームがどのように利活用しているかについてご紹介いたします。

弊社には金融や商社といったメール文化の会社出身の方もいるのですが、入社後は全員Slackを使ってもらっています。最初はスタンプやスレッドに慣れないようですが、特に不満の声はなくみなさん使いこなしています。

Slack自体が、情報のハブになっていて、さまざまな機能を果たしているので、こちらを深堀りして紹介したいと思います。

Slackの利活用

エンジニア同士のチャットコミュニケーション

エンジニアチームがメインで使っているチャンネルでは、 雑談も混じるような形で、カジュアルにチャット感覚で利用しています。 リアルなオフィスで行われる会話に近いイメージです。

f:id:zacky2:20220210153730p:plain f:id:zacky2:20220210153151p:plain f:id:zacky2:20220210153250p:plain

業務連絡だけでなく、気軽に考えを書き込むことで、一人で困って問題を抱え込むことを防いだり、チームの一体感の醸成につながっています。

エンジニア同士の音声コミュニケーション

SlackのHuddle機能を使って、ちょっとした相談や、ペアプロ、レビューをしています。 今までに音声チャットツールとして、Slackビデオ通話や、GoogleMeet、Aroundなどを試してきましたが、ダントツで使いやすいため定着しています。

すぐ繋げられる。誰が話してるかわかる。他の人の通話に乱入できる。ラジオ感覚で聞ける。といったメリットがあります。 Huddleのおかげで、ちょっとした相談のハードルがめちゃくちゃ下がっています。

がっつりペアプロやモブプロをしたいときは、PhpStorm の Code With Me という機能で同時編集をしていますが、簡単なペアプロであれば、画面共有で済ませることもあります。

各種ツールからの通知を確認

障害アラートやGitHubのコメントなどをSlackに通知しています。 さまざまなツールと連携しているので、Slackの通知だけ見れば良いようになっています。

- Google Calendar
- Google Drive
- Jira
- AWS CloudWatch アラート
- プロダクト(バッチ処理結果やユーザー登録結果など)
- Rollbarのエラー通知
- Figma

報告や意見を受け付ける窓口

エンジニアチームではバグ報告やプロダクトへの意見を受け付ける窓口専用のチャンネルを設けています。

これを整備するまでは、個人のDMで相談があったり、メンション先のエンジニアを誰にしていいのかわからない、といった問題がありました。

f:id:zacky2:20220210142124p:plain
開発総合窓口チャンネルのワークフロー
エンジニアに依頼、相談、報告したいときは「開発総合窓口チャンネル」を開いて上記のワークフローを通してもらうようにしています。 Slackワークフローを整備することで、フォーマットの統一化を行いコミュニケーションコストの削減を行なっています。

「バグ報告」ではなく「バグかもしれない報告」にしているのは、気になることがあれば気軽に相談してほしいというニュアンスを表現するためです。

f:id:zacky2:20220210141851p:plain
サービス改善提案のワークフローによる投稿
1クリックでJiraのIssueに変換できるといった機能も実装しています。

全社的な情報共有や他部署の動向を知る

全員が参加しているチャンネルにて、経営会議の内容の共有や、健康診断のアナウンスといった全社的な情報共有を受け取っています。

営業やCS、MACAP(M&Aのアドバイザーチーム)といった他部署のコミュニケーションもそれぞれのチャンネルを覗くことで見ることができます。 M&Aに関わる秘匿情報などはprivateチャンネルで行われていますが、それ以外のコミュニケーションは基本的にオープンにするという社内文化があります。

部署を超えた雑談コミュニケーション

普段から雑談を行うことで、相談や報告の心理的ハードルが下がるという効果があると言われています。 弊社では雑談用のチャネルが複数あり、活発に雑談が行われています。

カスタム絵文字を使ったコミュニケーションも活発です。 絵文字についてはこちらの記事をご覧ください。

tech.macloud.jp

部活動コミュニケーション

弊社にはたくさんの部活があります。特に会社の制度というわけでなく、好きな人が勝手に集まってやっている活動です。 部活ごとにチャンネルがあり、それぞれでアナウンスや雑談が行われています。

私が認知している部活は以下です。

- 筋トレ部
- サウナ部
- キャンプ部
- 漫画部
- キネマ部(映画部)
- ゲーム部
- ボルダリング部
- フットサル部
- ワーケーション部

弊社最大の部活である「筋トレ部」に興味がある方はこちらをご覧ください。

update.macloud.jp

おわりに

本当はエンジニアチームで使っているツール群を紹介するつもりだったのですが、 Slackについてのボリュームがデカすぎたので、今回はSlackの利活用についてのみ紹介しました。

エンジニアチームがSlackをどのように活用しているかイメージが伝わったら幸いです。

www.wantedly.com

www.wantedly.com

これが私たちの勝ちパターン【開発メンバーの型】をご紹介

f:id:tsukahara1991:20220125001537j:plain Free Office Image on Unsplash

こんにちは。エンジニアの塚原(@AkitoTsukahara)です。

弊社の開発チームでは業務の知見を「型」として文書化し、チーム内で共有しています。これまでにもいくつか型の紹介をさせていただきました。

tech.macloud.jp

tech.macloud.jp

tech.macloud.jp

今回は型の中でも一番読み返されているであろう「開発メンバーの型」について、ご紹介させていただきます。 この型はメンバーが高い生産性を実現するためのルールでもあり、新しく入社したメンバーがチームで活躍するための道標にもなっています。 ですので以下のような方におすすめの記事になっております。

  • 開発メンバーのルールを明文化したいリーダー
  • 新しく入社したメンバーをサポートするメンター
  • チームで活躍したいメンバー

これより以下はほぼ原文ままになります。

弊社ではプロジェクト管理にJira、開発手法にスクラムを採用しています。 これらの専門的な用語には注釈を付けさせていただきました。


これはなに

M&Aクラウドにおける開発メンバーの型です。
これに沿って生産性の高い状態で作業できるようにする。

マインドセット

チームの仕事である

開発チームの仕事はチームでやることである。
成果物はチームの共有物。自分だけの仕事が進んでもユーザに大きな価値は届けられない。 そのために以下のことを前提として意識する

  • 自分の仕事を終わらせるために人のリソースを使う(無駄使いはしない)
  • 人の仕事を終わらせるために自分のリソースを使う

理解が甘いものは外に出さない

  • 仕様について
    • 自分がタスクとして取り組む作業の仕様は、自分が納得いくまで理解してから取り組む
      • 背景の理解
      • 影響範囲の理解
        • ページや機能の影響範囲
        • 社内ユーザ含むユーザへの影響範囲
  • コードに対しても納得して人に説明できる状態になること
    • 自分が書いているコード
    • 他人が書いたコードも、自分がレビューした場合、自分のものとして納得して説明できるようにする

開発メンバーがやること

タスクをやる

着手するまえに

  • 「ユーザーストーリー」*1と「AC」*2を理解する
  • 想定されていた仕様や影響範囲に誤りがないかコードや仕様を調べる
  • 小さいタスクでも情報を持っている人に仕様の認識合わせをする
    • 急ぎでなければSlackでも良いが、口頭や通話も積極的に活用する
    • 口頭で話した内容は Jira issue*3に経緯と結論を記録しておく
  • タスクをやる前にタスクが属する一連の作業の全体像を掴む
  • 具体的にコードをどのように変更すれば良いかイメージする
    • 必要に応じて書き出して抜け漏れを防止する

タスクの進め方

  • 「 READY」のタスクを受け取り「IN PROGRESS」に移す*4
  • 着手前に想定した方針にしたがって変更を行う
  • 方針を立てる前にとりあえずコードを書くはNG

f:id:tsukahara1991:20220125113204p:plain
Jiraのカンバンボードでタスクの進捗ステータスを確認する

自分の状況をオープンにする

  • 詰まった時だけではなく、できれば今何をやっていてどういう風に進めようとしているのかもオープンにする
  • ※詰まるとは?
    • 調べて突破口になる解決策が全く見えない時
    • タスク内容によるが、以下のような目安
      • 仕様や背景が分からない場合。すぐに聞く。
      • 技術的に詰まった場合(調べていて新たな検討できる情報がない時)
        • まずはググってみる、関連実装探してみる
        • 15分程度で詰まりつつあるくらいであれば Slack などに投げ込んでおく。非同期できく。
        • 1時間以上詰まる場合には積極的に指名したり口頭相談したりヘルプを求める

実装について

  • 「すでにある実装」はあくまで参考にとどめ、あるべき形考えてそれを表現するコードを書く。
    • ただし、大きく設計が変わる場合には他との整合性が取れなくなる可能性があるので、チームに提案ベースの相談をしてから進めると良い
  • 変更するコードの影響範囲を調べ、それぞれの箇所でユーザに価値が変らず届けられているか確認する
  • アーキテクチャに関わる実装変更が必要であると判断した場合は、コードを変更する前にメンバーを集めて意見を募る

ストーリーポイント*6が妥当かどうか

  • ストーリーポイントは基準となるタスクをあらかじめチームで決めておき、0.5,1,2,3,5,8,13とフィボナッチ数列の数から決める
    • 8ポイント以上の大きいタスクの場合は、1ptの調査タスクを実施してから残りの作業分を1,2,3,5に振り分ける
  • ストーリーポイントの決め方や基準となるタスクに違和感があったらそれ自体を議論する

時間の使い方について

自分のタスクをやっているときに詰まったり、トラブルがあったときの動き方。

  • 他の人の助けがあればすぐ解決するものは人の力をうまく使う
    • 誰かに聞けば分かることなのに半日や一日使うのはNG
    • 明確に、その領域に対しての学習のために幅広く何かを学ぶという目的があればある程度時間を使っても良いが、右往左往している時間は勿体無いので減らすこと。誰かと協力して短時間で解決した後に、腹落ちのためにちゃんと調べても近い学習効果は得られる
  • 時間をかけていいこと
    • 誰かに聞いても分からなかったこと
    • 他に回避の道がない場合。自分しかできない仕事の場合
      • 記録を残しつつ、進捗や学びは共有しつつ進める

我々はユーザにアウトプットを届けるために仕事をしている。また、一人の力ではなくてチームのアウトプットとして外に出しているのでその過程もチームの力をうまく使うこと。

レビューをやる

1チケット制限

M&Aクラウドの開発チームでは「1チケット制限」を導入してます。
基本的にタスクは1つだけを持つこととし、二つ以上のタスクは並行して行わないようにしています。
目的は、複数のタスクが並行で走ることによるコンテキストスイッチの増加による生産性の低下を防ぐこと。

レビューは自分の仕事と同等か、やや優先するくらいの気持ちで

1チケット制限の前提において、誰かのPRが来ているということは、その人は手が空いてしまっているということ。
合間の時間にチケットとは無関係の仕事を進めることはできますが、あまりに時間が開くと優先度の低い仕事をやってしまうことがあります。
そのため、レビュー依頼が来たら30分~1時間程度以内で最初のチェックをすると良いです。

マージされなければ1チケット制限は解除されないので、マージまで伴走する気持ちで進める。
例えば良く分からないコードがあった場合に「よくわからないから後回しにしてしまおう」ではなくて、「よくわからないので口頭で解決しよう」が推奨されます。

リリースする

他の人の仕事も含めて巻き戻しや修正の判断ができる状態になったら「リリたん」(リリース担当)の一人になります。

会議を前に進める

チームでの成果や合意の方向に向いて発言をすること。
会議目的からずれる発言は、一旦メモをしておき、後で適切な会議に持ち込んだり非同期で話すなどする。
単に自分が言いたいだけの話は、会議以外の少人数の集まりの時にする。

会議体

インフラ確認会

  • 新しいAWSコンポーネントを使ったりする時には、開発チーム全体に背景情報と知見共有のために「インフラ確認会」を開催する。
  • 既に何度も類似の設定がされている場合にはインフラの変更であっても小チーム内のみの確認でOK
    • ただし、設定する内容は開発チーム全体に影響する可能性があるのでSlackなどで全員が作業したことが分かるように連絡はしておく
  • 以下の情報を資料に含めてメンバーが設定する
    • 背景情報(解決したい問題など)
    • 設定概要(ここまでエンジニア全員が出席する会)
    • 設定詳細(興味ある人、小チームメンバーが出席する)
      • ドキュメントと見るべきところ。 ドキュメントが分かり易ければリンクだけ貼っておくでも良い

その他

人のマインドシェアを取らないように動く

前提: 仕事を任す人がリーダーであってもPdMであっても、リソースは限られているので全てのタスクについて詳細情報を持って適切なタイミングでリマインドすることは不可能。スケールするチームのためには、メンバーそれぞれが一番詳細度の高い情報を持ってタスクを進めることが肝要。

任された仕事について、責任を持って詳細まで含めて着地に持っていくこと。
仕事を任された時点でその仕事はメンバーの持ち物。
以下のように動く。

  • 最終ゴールまでにやらなければいけないことはメンバー側が情報を全て持っていること。また、そのように情報を集める
  • メインのタスク以外で任された細かいものも、いつまでに回答 or 終わらせるかなど明示的にコミュニケーションする

※「人を頼ってはいけない」とは違うので注意。前述の「時間の使い方について」の通り、チームとして成果を得るために情報が足りなければ他の人のリソースも積極的に活用する


採用やってます

弊社ではエンジニア採用を行っています。 スタートアップ企業でのWeb開発に興味のある方は、ぜひカジュアルにご応募ください🤝

www.wantedly.com

www.wantedly.com www.wantedly.com

*1:ソフトウェアの機能がユーザーにとってどのような価値をもたらすのかを示すもの

*2:受け入れ基準 (Acceptance Criteria):プロダクトオーナーの視点から何を持ってプロダクトバックログアイテムが完成したかを確認するための基準

*3:Jiraにおけるタスクの意味

*4:「 READY」、「IN PROGRESS」は Jiraのタスク進捗ステータスを表します。

*5:スクラムチームの開発者のための15分のイベントである。複雑さを低減するために、スプリント期間中は毎⽇、同じ時間・場所で開催する。

*6:ユーザーストーリーを実装するのに必要なコストを見積もるための単位

【6人採択!】 PHPerKaigi2022 に8人全員で合計12個のプロポーザルを提出しました【全員インフルエンサー】

f:id:yamotuki:20220119120026p:plain

※この記事は採択発表の前に書いております。採択発表後に一部追記しました。
結果、6人が採択され、発表することになりました!

こんにちは。エンジニアの鈴木(@yamotuki)です。
今年もPHPerKaigiの時期がやってきました!

弊社では、去年はエンジニア全員でプロポーザルを出し、全員が採択されて発表を通して盛り上げることができました。(一昨年はひっそり私だけ参加しておりました)

今年はプラチナスポンサーとしても協賛しています。

「スポンサーチケットがあるのでトーク採択されなくてもいいや」なんてのは甘い!
弊社メンバーは「全員インフルエンサー」のバリューを胸に、エンジニアであるなら発表で参加したい! そんな気持ちでプロポーザルを提出しております。

8人で出した全12個のプロポーザル、全て紹介します。
さあ、何個採択されるのか?!
採択されて欲しいものがあったら清き1票をお願いします! 盛り上げていきましょう!

※【採択】【不採択】を追記しました。
※紹介順序は順不同

【採択🎉】(LT)Predefined Interfacesを使って便利な独自クラスを作りましょう!

CTO荒井さんによるプロポーザル。「最近コード書いていないのでネタが無い」などとと言いつつしっかり出してきてます。流石。

皆さんはPHPでの開発でPredefined Interfaces(定義済みInterface)を使っていますでしょうか?PHPにはIteratorやStringableといったシンプルですが便利なInterfaceが用意されており実装することで、独自のクラスをPHPのプリミティブな型と同様に扱うことができます。どうやってPredefined Interfacesを使うのか、どんなメリットがあるのかを解説します。

https://fortee.jp/phperkaigi-2022/proposal/2c8b0e09-b321-49ba-89c7-d9b25ecc844e

【採択🎉】(LT)PHPの緩やかな比較の実態

入ったばかり20歳國村さんによる発表です。
「おいおい最近の若い人はPHPの内部実装にも詳しいのかよ...」そんな風に思ったおじさま/おばさま方、ここでしっかりPHP内部構造も学んでおきましょう。

みなさんよくご存知の通り、PHPには等価演算子が2つあります。
「==」と「===」です。
前者は緩やかな比較、後者は厳密な比較が行われます。
PHPやJavaScriptに馴染みのある方ならよくご存知だと思います。

言語問わずよく使う演算子の1つである等価演算子ですが、実際の言語仕様は知っていても
内部の実装は知らないなんてことはよくあると思います。

今回はみんな嫌いな緩やかな比較の実装がどこにあるのか、そしてどんな実装がされているのかをお話しようと思います。

https://fortee.jp/phperkaigi-2022/proposal/3f638a7b-3e63-4a34-a14e-5658011bb60c

【採択🎉】(LT)気づいた時にリファクタしよう!Laravelのデータベースクエリを最適化するTips

塚原さんによるプロポーザルです。 弊社で長年の負債だった部分をちびちび改善しようという取り組みについてですね。メンバーみんなで細かく改善すれば大きな問題も怖くありません。

みなさんはパフォーマンス改善のためにアプリケーションの最適化に取り組んだことがありますでしょうか?
何もデータベース構造を再構築したりと大規模な改修することだけが最適化ではありません。機能実装のついでに関連処理をリファクタリングしてあげるだけでも十分な最適化になります。

このトークでは気づいた時にちょっとリファクタできる程度のデータベースクエリの最適化Tipsを解説いたします。
5分間で可能な限り詰め込んでお届けします!

こんな方におすすめ

業務でLaravelを利用されている方
日頃からパフォーマンスを意識した実装をしたい人

https://fortee.jp/phperkaigi-2022/proposal/3a75fecf-0165-481f-9dfd-0f2959e699ed

【不採択🥺】(レギュラートーク)Laravelのデータベースクエリを最適化するためのヒント

塚原さんの上記LTのロングバージョンという位置付けですね。
発表が終わったらPHPer共通の悩みであるクエリ最適化について、ヒントを元に話が盛り上がりそうですね!

みなさんはデータベースクエリのパフォーマンスを意識して実装されていますでしょうか?
実装した当初は軽快に動いていたアプリケーションもサービスの成長とともに少しずつ遅くなっているかもしれません。あるタイミングで最適化プロジェクトを発足させたり、日々のコードレビューで指摘し合う際に役立つヒントをお届けできればと考えています。

このトークではデータベースクエリ最適化のヒントをサンプルコードを交えて解説いたします!

こんな方におすすめ

業務でLaravelを利用されている方
サービスが成長してきたので、クエリの最適化をしたい人
日頃からパフォーマンスを意識した実装をしたい人

https://fortee.jp/phperkaigi-2022/proposal/b17f350f-8e58-42b2-8276-1021d9769fff

【採択🎉】(LT)PHPスカラー型をクラスでラップして便利に使えるようにするライブラリ「Stannum」を作った話

弊社期待の新メンバー、大石さんによるLTです。 自然発生的に「大石大活躍」などというスタンプが発生するくらい活躍してくれてます。そのレベルの高さが垣間見えるLTですね。

PHPは言語仕様上、stringやintegerといったスカラー型にRubyやPythonのような他の言語のようにメソッドが生えておらず、手続き型のAPIを用いてそれらを操作する必要があります。
しかしながら、メソッドが生えている方が便利な場面もあり「そのように書けたらなあ...」と思う事もあると思います。
これらを達成するのにエクステンションを用いて言語仕様を拡張しスカラー型にメソッドを生やす事も出来ますが、今後の言語仕様の追加や変更に追従しなければならないなどの点を考慮して、純粋なPHPのクラスでスカラー型をラップしてそこに便利に扱う為の関数を生やしたライブラリを作った話をしたいと思います。

https://fortee.jp/phperkaigi-2022/proposal/ee394d8a-b03d-4226-aef1-f512a42ac328

【採択🎉】(LT)【Laravel】サクッとN + 1問題を見つけて倒しチャオ!

津崎さんによる”チャオ”シリーズです。 この言葉がついている時には勢いがすごいLTになるのでは、と期待できますね。楽しみです。

N + 1問題とは、ループ処理の中で都度SQLを実行してしまうことで必要以上にSQLが発行されてしまい処理が遅くなってしまう問題です。
N + 1問題が存在していても、ユーザーに影響のない程度の処理時間なら改修する必要はありません。
しかしながら、データ量が増えたりページへのアクセスが増えることで後から問題になってしまうこともあります。
今回は、そんなN + 1問題をサクッと検出して、問題が発生する前にN + 1問題を撲滅する方法をご紹介します。

https://fortee.jp/phperkaigi-2022/proposal/4307d420-7ef0-4b69-b3f7-005b72bf87b0

【不採択🥺】(レギュラートーク)保守容易性指数とコミット数でバグりやすいファイルを見つけてテストを書こう

同じく津崎さんによるレギュラートーク
めちゃめちゃ実用性高く、面白そうです。これは採択間違いないでしょう。

みなさん、あなたが保守しているコードベースで一番バグが混入しやすいファイルが何か知っていますか?

このトークでは、保守容易性指数(Maintainability Index)とGitHubのコミット数を用いて、
保守性が低くて、よく変更されているファイル(= バグが混入しやすいファイル)を見つけ出す方法についてご紹介します。

https://fortee.jp/phperkaigi-2022/proposal/f675960f-1ed9-4027-b36b-0aaa6263abf0

【不採択🥺】(レギュラートーク)PHPer がスクラムマスターに任命されたら 〜ピンチは突然訪れる〜

弊社の「真のリーダー」であるスクラムマスター濱田さんによるトークです。
皆さんもスクラムマスターに任命されることは”まれによくある”と思いますが、ここでしっかり予習しておきましょう。

先行きの不透明な開発プロジェクト。
鳴り止まない障害アラート。
挙句の果てに、リリースした機能がユーザーにあまり使われていない!
そんな課題を解決すべく、ごく普通の PHPer がある日突然スクラムマスターに任命されて...!?

エンジニアがスクラムマスターに任命される。
まれによくあるイベントです。

このセッションでは、

スクラムとは何か
冒頭で挙げた課題に対して、スクラムではどのように立ち向かうのか
エンジニアとしてどのような能力をスクラムマスターに活かせるか
逆に注意すべきポイントは何か
といった内容を、 PHPer からスクラムマスターに転身した自分の体験を踏まえて紹介します。

https://fortee.jp/phperkaigi-2022/proposal/8c1b5110-7b4c-4c97-a359-66821eb68cee

【不採択🥺】(レギュラートーク)一人のPHPerからプロジェクトマネージャーになる道筋

わたくし鈴木のレギュラートークです。
PM業務に必要なマインドセットとスキルセットについてお話しします。

プロジェクトマネージャー、なりたいですか?

いわゆる「PM」は「プロダクトマネージャー」と「プロジェクトマネージャー」の二つを内包することが多いですが、ここでは後者の「プロジェクト」をマネージする(なんとかする)人についてです。
前者の「プロダクトマネージャー」はPdMなどとも呼ばれ非エンジニアがなることも多いですが、プロジェクトマネージャー(以下PM)はエンジニアが担当することも多いのではないでしょうか。

プロジェクトには数日で終わるものも、数ヶ月かかるものもあるかと思います。最初は単に小さなタスクをこなしていたエンジニアがどうやったらPM(=プロジェクトを"なんとかできる"人)になれる能力がつくのでしょうか?

本セッションではPMの仕事内容と、それに対応するスキルセットの身につけ方についてお話しします。

【注】会社によりPMの職務範囲は変わるので、私の観測範囲内でのお話です

https://fortee.jp/phperkaigi-2022/proposal/5f36f1e1-f065-43e6-babb-3161c5acdb62

【不採択🥺】(レギュラートーク)[Github Dependabot] 「自動作成されたPRだけで脆弱性対策バッチリ」なんて思っていないですよね?

こちらも鈴木によるプローザルです。
セキュリティ領域はセンシティブな情報が多い中、ネタを捻り出しました。

みなさん、脆弱性対策してますか?

コードに潜む脆弱性対応は以下の二つに分類できるかと思います。

自分たちで書いたコードの脆弱性
依存ライブラリ・フレームワークの脆弱性
このうち後者では、Github を使っているならば Dependabot 機能による脆弱性検知が使えます。
Dependabot security updates 機能を有効にしておくと、勝手にPRを出してくれますよね。
便利です。これの内容チェックしてマージするだけ。
めでたしめでたし。

・・・とならないので注意です。
実は、検知していても自動PRになっていない脆弱性があります。
「PRになるのはcriticalレベルのもの。多分そうだろう。」などと勘違いしておりました。
危ない危ない。

本セッションでは Dependabot の説明、注意点、運用方法のケーススタディをお届けします。

https://fortee.jp/phperkaigi-2022/proposal/d922b304-beb8-46c1-8558-9952abe7cb95

【採択🎉】(レギュラートークPHPコードを消すライブラリを作った

「全員インフルエンサー」のバリューの旗振り役、久保田さんによるプロポーザルです。
ええ? PHPで feature toggle で分岐しているのに php-del を使っていない?! いますぐ使った方がいいですよ!
このセッションで予習しておきましょうね。

kubotak-is/php-delというPHPコードをComposer Bin Commandを利用して消すライブラリを作成しました。
特定の形式でコメントを書いておくと、そのコメントを基準にPHPコードを削除します。
なぜそんなライブラリを作ったのか、その実装はどのようになっているのかを紹介します。
このセッションではComposer Bin Commandの作り方や自作のComposerライブラリをpackagistで公開する手順などを学ぶことができます。

https://fortee.jp/phperkaigi-2022/proposal/0efa9d19-aa48-4a3f-898e-7d5ca9c43db6

【不採択🥺】(LT)Composer Bin Commandを作ろう!

こちらも久保田さんによるLT。上のコマンドを作成するときに得られた知見を話してくれそうです。

PHPUnitやPHPStanのようなComposerでインストールしてコマンドで呼び出すライブラリ・アプリケーションの作成方法を紹介したいと思います。

https://fortee.jp/phperkaigi-2022/proposal/f5b99ae5-a4e7-4878-9ebb-382b260a0cf0

終わりに

いかがだったでしょうか?
面白そうと思ってくれたプロポーザルがありましたら、ぜひ清き1票をお願いします。
採択・不採択決定後はぜひ当日をお楽しみに!

スクラムの取り組みをメンバー視点で見る

f:id:kubotak:20220112183348p:plain

こんにちは、こんばんは、kubotak(@kubotak_public)です。

昨年末より弊社では「真のスクラム」という名のスクラム開発を実施しています。
今までは「なんちゃってスクラム」というわけではないんですが、スクラム開発のエッセンスを多少取り入れたような今にして思えば全くスクラム開発ではないなにかをやっていました。

私はスクラムマスターではなく「真のスクラム」を熱く語れるわけではないのでメンバー視点で「真のスクラム」になった結果何が変わったのかを紹介したいと思います。

スプリントが2週間から1週間に

以前は1スプリントを2週間として実行していました。
これを1週間と短くし、月曜日にスプリント計画、金曜日にスプリントレビューとレトロスペクティブを行うように変わりました。
私個人としては短くなったことで単純に忙しないな!と思うのと、開発時間の多くは火・水・木曜日になり余計に短いと感じます。
また、短くなったことで以前に比べるとスプリント全体で完了する成果物の大きさが小さく・細かくなりました。
小さいサイクルを回してすぐに出すことでよりアジャイルな開発になったのかなと思います。

スプリント計画をメンバー全員で実施

以前はPO及び一部のメンバーでスプリント計画を実施し、タスクのポイントなどをつけていました。
これを全員で実施するように変更しました。
プランニングポーカーを用いてデザイナー含めたスクラムメンバー全員でタスクに対するポイントを出し合い、合議により見積もりを行っています。
これによりメンバー全員が個別のタスクの詳細を理解することができ、誰がタスクにアサインされても問題ない状態になりました。
もちろんタスク毎に向き不向き、得意不得意があるかもしれませんが全員で見積もり行うことで平均化されますし、そのタスクに必要な情報の詳細を持っている人が明確になるので聞きに行くということも可能になります。

今までは一部のメンバーしか情報を共有できていなかった部分も、透明性が上がったといえると思います。

タスクにユーザーストーリーとACを追加

タスクにはユーザーストーリーが追加され、なぜ、誰のためにその実装が必要なのかを明文化しました。
また、ユーザーストーリーとともにAC(acceptance criteria)も追加し、そのタスクはどういう状態であればユーザーストーリーが完了になるかも明文化されました。

この2つは作業者としては非常に重要で、「なぜわたしたちはこのプロダクトを作っているのか」が明確化されて納得感を持ってタスクに取り組めます。
また、何を持ってこれは完成と言えるのかも記載されているので品質の担保ができます。
そしてこれは自動テストのストーリーとしても役立っています。

DoD(完了の定義)はタスク毎ではなく全体の完了の定義としているため、ここではACを取り上げています。(完了と受け入れ基準の定義 Definition of Done vs Acceptance Criteria

スプリントレビューを実施

PO以外にも、タスクにおけるユーザーストーリーから影響がある人を呼んでそのスプリントで完成したプロダクトを見たり触ったりしてもらうような時間を作りました。
このとき、「顧客が本当に欲しかったもの」やその顧客に近いCSの声などをフィードバックとしてもらうことができるようになりました。

これにより、「私達が作っていたものは間違っていなかったんだ」という自信を持った上でリリースに挑むことができます。
もちろん実際にはデータを元にその追加機能の優劣は後から判明することとは思いますが、少なくとも「この機能使われないのでは?ほんとに喜ばれるのか?」という不安を払拭し、モチベーション高く開発に挑める良い施策だと思っています。

まとめ

細かい話などはおそらくスクラムマスターから今後紹介されることと思いますが、現在スクラムメンバーとしてスクラム開発を実施して良いなと思った点をあげてみました。
正直最初は新しい用語や取り組みによってやや混乱を覚え「これホントに良い開発できるのか?」と思いましたが初回のスプリントレビューで払拭された感じがします。
スクラム開発によって顧客に向き合った開発ができるようになったんだと実感しています。

さいごに

まだまだスクラム開発駆け出しの弊社ですが、もっと改善したい、一緒にスクラム開発したい、と思った方はぜひ応募ください。
ちなみに、データエンジニアや機械学習エンジニアも積極採用中ですのでお声がけください。

www.wantedly.com

2022年 新年のご挨拶

f:id:kazuhei0108:20220104091310j:plain

あけましておめでとうございます。

M&AクラウドでCTOをしている荒井です。

年末はPythonのFastAPIというフレームワークをいじっていました。APIドキュメントの自動生成機能がついていて画期的なので、どこかで使いたいなあ。

fastapi.tiangolo.com

昨年は大型の資金調達もあり、チームメンバーも増え、とてもにぎやかな1年になりました。

去年末から弊社開発チームは、スクラムの原点に立ち返り、エンジニアだけではなくPOとデザイナーも含むスクラムチームを組成して再出発しました。

せっかくですので、今年からはこのテックブログもエンジニアの枠にとらわれずに、スクラムチーム全体で記事を書いて行けたらと考えております。

それでは本年もよろしくお願いいたします。

記事をお楽しみに!

【Athena】M&Aクラウドの2021年を絵文字で振り返る【使ってみた】

f:id:zacky2:20211220150627j:plain

はじめに

この記事はM&Aクラウドアドベントカレンダー2021の21日目の記事です。

adventar.org

みなさんどうもこんにちは。エンジニアの津崎です。 普段はPHPとTypeScriptを使ってマッチングプラットフォームの開発を行っています。

今日はデータ分析全然わからないけどやってみチャオ!というノリで、M&AクラウドのSlackで使われている絵文字の使用数ランキングを出してみました。 分析にはAWSのデータ分析ツールであるAthenaを使っています。 Athenaを使って実際にデータを分析するのは今回が初めてだったので、SlackのメッセージデータをAthenaに格納する作業に時間の9割が持っていかれました。

結果発表🎉

まずは、集計結果をみてましょう!

(再生ボタンをクリックしてください)

動画版はこちら:

youtu.be

  • 集計物:メッセージに対するリアクションとして使われた絵文字の使用数(メッセージ本文の絵文字を含まない)
  • 対象チャンネル:publicチャンネルすべて
  • 対象の絵文字:カスタム絵文字
  • 対象期間:2021/01/01 ~ 2021/12/13 くらい
  • データサイズ: 800MB程度(無圧縮)
  • 分析対象メッセージ:11万

【3位】お大事に

f:id:zacky2:20211218184948p:plain

3位は「お大事に」でした。これは予想外。 f:id:zacky2:20211218185857p:plain

おっと、大丈夫です。M&Aクラウドの社員の健康状態は良好ですよ。 体調不良メッセージに対して「1 Team」な精神で部署をまたいで「お大事に」をつけているので使用数が多くなっているんじゃないかなと思います。

また、別の意味の「お大事に」でも使われているのも使用数が多い要因になっていそうです。

f:id:zacky2:20211218185748p:plain f:id:zacky2:20211218185817p:plain

【2位】1 Team (Fever)

2位は「1 Team」でした。 「1 Team」はM&Aクラウドのバリューの一つです。M&Aクラウドの社員はみんな「1 Team」が好きなのがよくわかりますね。笑 この絵文字は、シンプルに「1 Team」な行動に対してよく利用されます。一丸となって仕事を成し遂げたときや、他メンバーを思いやるメッセージなどです。

f:id:zacky2:20211218185925p:plain

f:id:zacky2:20211218190400p:plain

【1位】 ナイスシェア

f:id:zacky2:20211218182341p:plain

「ナイスシェア」がぶっちぎりの1位でした。 M&Aクラウドのバリュー「1 Team」の要素として「共有・共感・共鳴」があります。「ナイスシェア」というのはまさに「1 Team」を表しているなと思います。 この「ナイスシェア」は、部署間でのよい情報共有や、ニュースやネット記事などの有益な情報をシェアした時、大事なことのリマインドといった「ナイスシェア」なタイミングによく利用されています。

f:id:zacky2:20211218190902p:plain f:id:zacky2:20211218190934p:plain f:id:zacky2:20211218190923p:plain

ランキング振り返り

さて、いかがだったでしょうか? 上位3つとも「1 Team」な絵文字になっていて、M&Aクラウドらしさがよくでたランキングでした。

ちなみに、今回はただのランキングだと面白くないのでBar Chart Raceというグラフ形式で作ってみましたが、 序盤から「ナイスシェア」が独走状態で、2〜4位が熾烈な争いをしている様子もみれて面白かったかなと思います。

個人的には「f:id:zacky2:20211218205855p:plain:w40」が健闘しているのが興味深かったです。これはカスタマサーサクセス部の若手である西川君のためのスタンプです。彼の頑張りっぷりが現れています。

どうやってやったかざっくり

ここからは集計結果ではなく、どのようにこれを作ったかという話をします。

Slackのエクポート機能(手動) 
     ⬇️
S3にアップロード(手動)
     ⬇️
Lambda (Athenaに投入する前にデータの変換処理)
     ⬇️
Glue クローラでテーブル作成
     ⬇️
AthenaでSQLを使ってデータ集計
     ⬇️
Google SpreadSheetで表作成
     ⬇️
flourishでグラフ化 

Lambdaとは、AWSのサーバレスでプログラムを実行してくれるサービスです。サーバを用意せずクラウド上でプログラムを実行できるのでとても便利です。

Athenaとは、AWSビッグデータ分析ツールです。AWSのS3というクラウドストレージに格納されたファイルをSQLで分析できます。最近はS3以外にも色々連携ができてなんでもできる感じに進化しているようです。

Glueクローラとは、S3に格納されたデータを解析してAthenaが分析できるようにテーブル化してくれるものです。

flourishとは、グラフ作成ができるWebサービスです。Bar Chart Raceを簡単に作れるということだったので利用しました。

(以下はエンジニア向けな内容となります。)

今回はAthenaを使ってみたいというモチベーションがあったため、試行錯誤しながら時間をかけて分析の準備を行いました。 簡単に分析したい場合は、PHPなどのお好みのスクリプトJSONを集計してあげれば、数十分程度で集計できるかなと思います。

Slackのエクポート機能(手動)

Slackの標準機能でメッセージのログをエクスポートします。 (これには多分管理者権限クラスの権限が必要です)

S3にアップロード

S3にバケットを作ってファイルをアップロードします。 ZIPだと数十MBなのに解凍すると数百MBになってアップロードに数時間かかりました。

Lambda

SlackのメッセージはJSON形式で保存されているのですが、Athenaで読み込めるJSON形式と違ったため変換の必要がありました。(これに気づくまでかなりの時間を溶かした) Athenaでは1行1オブジェクトの形になっている必要があります。 例えば以下のような形です。

{id:1, text:"taro"}
{id:2, text:"jiro"}

Slackメッセージは簡単にいうと以下のような感じになっていました。

[
  {
    id:1,
    text:"taro"
  },
  {
    id:2,
    text:"jiro"
  }
]

Lamddaの関数を作り、JSON形式を変換する処理を書きました。また、Athenaに食わせるために試行錯誤した結果、以下のような機能も追加しています。

  • メッセージ以外のJSONファイル(channels.json, users.jsonなど)を除外する
  • ディレクトリ名(Slackチャンネル名)をランダム文字列に変換する(ディレクトリ名に日本語があるとGlue クローラーが途中で落ちるっぽい)
  • ディレクトリをフラットにして格納する(Slackチャンネルごとにディレクトリが切られているとクローラーが別テーブルとして認識してしまい、1000個以上のテーブルに分割されてしまうので、苦肉の策として)
  • 処理に最大処理時間の15分以上かかってしまうので、引数で処理範囲を渡して分割して実行できるようにした
    • 本来こういう処理はGlue ジョブでやるべきなのかもしれません

f:id:zacky2:20211218193934p:plain 並列実行が完了した図

Glue クローラーでテーブル作成

Glue クローラーでS3内にある変換後のJSONを解析しテーブルを作ります。 テーブルが1000個以上できたり、途中で処理が止まったりしてかなり苦しめられましたが、Lambda側での工夫によりなんとかなりました。

f:id:zacky2:20211218194144p:plain テーブルを単一にしたくてチェックしても全くいうことを聞いてくれなかった。本当にじゃじゃ馬。

f:id:zacky2:20211218194041p:plain

大量にできてしまったテーブルを100個ずつ手動で頑張って消してる図(SQLスキーマごと消せば簡単であることに途中で気づいた)

AthenaでSQLでデータ集計

待ちに待ったこの瞬間。 10万のSlackメッセージがAthena上から検索できます。 PHPスクリプトで分析すればAthenaにデータを入れるために数時間溶かすことなく分析できたのに、いろいろな苦労を経てようやく分析の準備ができました。

f:id:zacky2:20211218195100p:plain

メッセージが単一テーブルとしてはいった・・・!

f:id:zacky2:20211218195020p:plain

11万レコード!

元のデータがJSONなのでカラムの中に配列データがあり、配列データの中に配列データがあるといったデータ構造をしています。 クエリはSQLなのでMySQLなんかと似てますが、配列の分析をするところでちょっと苦労しました。

いつどの絵文字が何回使われたかを日別で出力します。

WITH reaction_record AS (
    WITH reactions_table AS (
        SELECT client_msg_id,
            reactions,
            ts
        FROM "slack-data"."dest2"
        where reactions is not null
    )
    SELECT date_format(from_unixtime(cast (ts as double)), '%Y/%m/%d') AS date_ymd,
        reaction.name,
        reaction.users,
        reaction.count,
        ts
    FROM reactions_table,
        UNNEST(reactions_table.reactions) AS t(reaction)
)
SELECT reaction_record.date_ymd,
    reaction_record.name,
    sum(count)
FROM reaction_record
group by date_ymd,
    name
order by 
    date_ymd

UNNEST()という関数で配列データを展開してテーブル化したりしています。 調べながらやればなんとかなりました。

f:id:zacky2:20211218200201p:plain

11万レコードありますが、わずか2.7秒で処理が終わっています。 まあ普通のRDSで実行した場合に11万レコードがどのぐらい時間がかかるかはちょっとわかりません。(このデータ量じゃ大差ないかも)

スキャンしたレコードが150MBとなっていますが、無圧縮のJSONだと800MB程度あったはずなので、WHERE句の絞り込みによって余計なデータの読み込みを抑えてくれていそうです。

GoogleSpreadsheetでさらに集計

flourishでBar Chart Raceを作るには以下のような表が必要です。

f:id:zacky2:20211218200841p:plain

AthenaのSQLで上記のような表を作る方法を思いつかなかったので、GoogleSpreadSheetで加工します。

ステップとしては以下です。

  • 2021/1/1 ~ 2021/12/31までの列を作る
  • Athenaで出力した表から特定日の絵文字使用数を取ってくる
  • 上記の表を累積の表にする(前日までの累積+今日の値)
  • 後述のemojiの画像URLを表に追加する
  • カスタム絵文字以外を除外する

カスタム絵文字以外は絵文字の画像URLを取得するのが難しかったため捨てました。 ちなみに、本当に一番使われてる絵文字は「+1 (👍)」でした。

emojiのkeyと画像URLのマッピングを取得する

APIを叩く

curl -H "Authorization: Bearer {token}" https://slack.com/api/emoji.list > emoji.json

csvに変換する

 jq -r ".emoji|to_entries|.[]|[.key, .value]|@csv" emoji.json > emoji.csv

Flourishでグラフ化

app.flourish.studio

簡単にサインインでき、使い方も適当にやったらできました。簡単です。 グラフのグループ化や速度、画像の表示など調整して完了です。

まとめ

以前PHPスクリプトでシンプルなランキングの集計をしたことがあったのですが、 Athenaで分析作業をすること自体が初めてだったので、かなりトライアンドエラーで進めていきました。

  • Lambda ほとんど初めて使った件
    • 実行してログ確認して修正するのめっちゃ地道
    • 15分の実行上限を超えるので、レンジを区切って手動で並列実行
  • Glue クローラじゃじゃ馬問題
    • 実行完了したはいいものの、JSONがぶっ壊れていてAthenaで読めない (1行のJSONにしなくてはいけない)
    • Glue クローラ なぜか途中で落ちる
    • 単一のテーブルではなく大量のテーブル(1000テーブル)として生成される
  • jqわからんw
  • Google Spreadsheet上でゴリゴリ表を作る(最終的にflourishに食わせるデータを作るために)

Thank you for reading !

次のアドベントカレンダーは営業部の南戸さんです。お楽しみに!

【fyui_001】中途入社しました。

f:id:fyui001:20211213170049p:plain

この記事はM&Aクラウドアドベントカレンダー15日目の記事になります!

皆さん、おはこんばんにちは。 9月からM&Aクラウドにジョインした@fyui_001こと國村です。

入社までの経歴

M&Aクラウドに入社するまでは3社ほど転々としていました。 主にPHPでWebアプリケーションを作りながら、インフラ構築やちょっとしたマーケティングとかもやらせて頂いたり、 マルチにいろんな仕事をしてきました。以下が簡単な経歴説明になります。

  1. 高校を休学して都内の受託web系開発に従事。

  2. 高校を中退し、ポータブルオーディオのリテールビジネスにおいてテクノロジーソリューションに従事し、 自社オウンドメディア・各種アプリケーションの開発・運用、自社eコマース及びリアルショップのコンバージョン・マーケティング戦略に貢献。

  3. デジタルソリューション事業にて自社の新規案件へ生産性・保守性の高い土台提供や新規技術の研究及び展開を担当

今回前職でもうあまり成長できないなと感じており、転職を考えていたところLapras経由でCTOの荒井さんからお声掛け頂いたので ジョインする運びとなりました。

入社してみて感じたこと

開発プロセスやコミュニケーション、採用しているアーキテクチャなど様々な変化がありました。 その中で自分が感じたことをいくつか紹介したいと思います。

アーキテクチャを意識した開発思想

自社開発・受託開発と様々な職場で経験を積んで来ましたが、アーキテクチャをしっかり意識した開発や負債解消などする機会がありませんでした。

一方M&AクラウドではDDDなどの開発思想を取り入れて開発しており、ビジネスサイドと技術サイド両方の要求に応えられるような設計になっています。 また、進行中のプロジェクトでも頻繁に実装方針の意見交換が行われており、開発チームのメンバー全員が設計・開発に高い関心を持って日々の開発を進めているように感じています。 今まで完成度はもちろんのこと、設計・アーキテクチャに高い関心を持ってより良いシステム開発を意識している環境に居たことがなかったので、最高だなと感じています。

メンバーの意識の高さ

いい意味でメンバーの意識の高さを感じています。 UI・UXや設計、技術トレンドなどを追っていたり、Nuxt道場などの勉強会をしておりとても向上心の高いメンバーが集まってると思いました。

また、毎週スプリントを進めた中で良かったところと悪かったところをディスカッションして日々の開発にどう活かすかなど熱く語りあっていたりなど、すごい真面目に開発に取り組んでいてドンドン上を目指してチームやサービス、会社としてどう成長行くか考えて行く文化が、とても刺激的で素敵だと思います。

この先は

M&Aは専門知識が多く、会社の事業ドメインを理解するのは大変でやらないといけないことはてんこ盛りですが、未知の知識が得られる機会を楽しんで行きたいと思ってます。

事業ドメイン知識も浅く、慣れないアーキテクチャ・設計でまだまだメンバーに助けられていますが、これからどんどんキャッチアップして事業・プロダクトの成長を支えられるように頑張りたいと思います!

最後に

M&Aクラウドでは、エンジニアを絶賛募集中です! 興味がありましたらぜひ以下からご応募ください!

https://www.wantedly.com/projects/513494

Slack,Zapierに連携アプリが無くても大丈夫! LambdaでPuppeteerを動かせばいいのさ

f:id:tsukahara1991:20211209022736j:plain

みなさんこんにちは。M&Aクラウドでエンジニアをしています塚原(@AkitoTsukahara)です。 弊社のアドベントカレンダーの12日目を担当させてもらっています!

弊社では様々な業務を自動化する取り組みが活発です。エンジニアチームであれば、GitHubのPR通知やFigmaのメッセージ連携などSlackアプリやZapierを利用して、自動化しており、SlackアプリやZapierのお陰で自動化の幅はかなり広がっています。

f:id:tsukahara1991:20211208232252p:plain よく利用するSlackアプリ

一方で連携機能が提供されていないサービスは自動化し辛くなっています。 1つの例として、勤怠管理システムで考えていきましょう。弊社ではリモートワーク時に勤怠管理システムにログインして、出退勤のボタンを押す必要があります。ちょっとの手間ですが、ついつい忘れてしまったりして、月末に勤怠漏れ修正の報告依頼しないといけません。報告するだけで済めば良いのですが、修正報告は上長、コーポレート担当者の承認が必要です。1つの報告あたり1人1分かかるとして、全社員が数回打刻漏れしているとすれば、結構な時間を修正報告に時間を費やしていることになります。この非効率な作業を少しでも減らせるように、勤怠入力を自動化していきたいですね。

そこで今回はSlackやZapierで連携機能が提供されていないツールでも自動化する方法を紹介いたします🙋‍♂️

アーキテクチャ

f:id:tsukahara1991:20211209180814p:plain

  1. Slackの入力をトリガーにAWS Lambdaに実装されたAPIにPOSTリクエス
  2. AWS Lambdaではpuppeteerを利用して、ブラウザ操作して「出退勤」入力
  3. AWS Lambdaからのレスポンスデータを受け取り、Slackメッセージを送信

このアーキテクチャのポイントはAWS LambdaでZapierからのリクエストを受けて、Puppeteerを起動させているところになります。

※Puppeteer
PuppeteerはHeadlessChromeを利用して機械的にブラウザを操作できるNode.jsライブラリです。今回は「MF勤怠にログインして、出退勤ボタンを押す」という一連の操作を自動化しています。

AWS Lambda
AWS LambdaはAWSが提供するサーバレスコンピューティングサービスです。利用者はプログラムコードを準備し、Lambdaにアップロードするだけでプログラムを実行することができるようになります。今回はPuppeteerを利用するコードをLambdaにアップロードして、Slackから呼び出せるようにしています。

STEP1

エンジニアチームではメンバー同士の稼働状態を確認するために、出勤時に「SK」、退勤時に「TK」とSlackにメッセージするルールになっています。今回のMF勤怠入力のトリガーはこの「SK」、「TK」というワードがSlackにメッセージされることにしましょう。出退勤報告とMF勤怠入力が両方できてまさに一石二鳥ですね。

STEP1ではSlackでの入力を受けて、APIにリクエストできるようにZapierを設定しています。

まずはSlackの入力を検知します。 ZapierのSlack連携トリガー「New Message Posted to Channel in Slack」で出退勤報告するチャネルを指定し、 次のAction「Only continue if...」で自分のアカウントのみで実行されるようにSlackのUserIDが設定されています。 Action「Conditionally run...」では出勤と退勤処理を分けられるようになっています

f:id:tsukahara1991:20211209015709p:plain

次にAPIにリクエストできるようにします。 出勤(PathA)の処理を設定していきます。 ActionのPOSTに必要になるデータを入力します。 URLにはAWS Lambda APIのPATH、 Id,mail,passwordにはMF勤怠に必要なログインデータを入力します。

f:id:tsukahara1991:20211209015739p:plain

STEP2

Puppeteerを起動するAPIの設置場所にAWS Lambdaを利用しています。

Puppeteerを利用するにはchrome-aws-lambda をLambda Layerとして登録しておく必要があります。詳しくはこちら

Lambda上で実行されるコードは以下のものを用意しました。 「MF勤怠にログインして、出退勤ボタンを押す」という操作をコードに直したものになります。

'use strict'
const chromium = require('chrome-aws-lambda')
const puppeteer = require('puppeteer-core');

exports.handler = async (event, context) => {
  
  const stamp = event.stamp;
  const id = event.id;
  const mail = event.mail;
  const password = event.password;
  
  const browser = await puppeteer.launch({
    //headless: true,  // ブラウザが動く様子を確認する
    //slowMo: 300,  // 動作確認しやすいようにpuppeteerの操作を遅延させる
    args: chromium.args,
    defaultViewport: chromium.defaultViewport,
    executablePath: await chromium.executablePath,
    headless: chromium.headless,
  });
  const page = await browser.newPage();

  //chromeを開く
  await page.goto('https://attendance.moneyforward.com/employee_session/new');
  // ログイン情報を入力
  await page.type('#employee_session_form_office_account_name', id, { delay: 50 });
  await page.type('#employee_session_form_account_name_or_email', mail, { delay: 50 });
  await page.type('#employee_session_form_password', password, { delay: 50 });
  //ログイン
  await page.click('input[type="submit"]');

  // 2秒読み込みをまつ
  await page.waitForTimeout(2000);

  if (stamp === 'SK') {
      //「出勤」
      await clockIn(page);
  } else {
      //「退勤」
      await clockOut(page);
  }
  
  await browser.close();
  return context.succeed('OK');
};

const clockIn = async (page) => {
  await page.click('.attendance-card-time-stamp-clock-in');
};

const clockOut = async (page) => {
  await page.click('.attendance-card-time-stamp-clock-out');
};
コードをかけなくても大丈夫?

エンジニアでない方にはいきなり出てきたソースコードでびっくりさせてしまったかもしれませんね。。 でも「自分はコードは書けないから無理かな」と諦めるにはまだ早いですよ!

Google ChromeではWebブラウザ上の操作を記録、再実行、編集、保存さらにはPuppeteerスクリプトのエクスポートができる機能がリリース予定。この機能を活用すれば、ほとんどコードを書かずとも上記のコードと同じようなものを用意できるかもしれません。 リリース時期は2022年の1月頃となっています。期待してこの機能リリースを待ちましょう!

Chrome DevToolsドキュメント「Record, replay and measure user flows

STEP3

打刻に成功しているとAPIから”OK”とレスポンスが返ってくるので、それを受け取ってSlackに打刻完了しました。とメッセージを送信できるように設定しています。

f:id:tsukahara1991:20211209020122p:plain

以上がおおまかな設定方法と処理の流れとなっております。 今回のようにAWS LambdaにAPIを設置するとネットワーク経由で自動化のリクエストができるようになり、Puppeteerを利用してブラウザ操作を自動化することができます。この組み合わせを応用していけば、多くの業務が自動化できるのではないでしょうか。

補足

自動化しようと試行錯誤する前にやっておきたい事前確認

  • 業務データに関わることは関係者に自動化OKか
  • すでにSlackなどで連携機能が提供されていないか

自動化してみたものの利用できなかったり、同じようなものがあったりと無駄な作業が発生しないようにしましょう。 自分も社内メンバーに事前確認したり、連携機能がないか確認しました。 リリース当初からSlackアプリを検討していると記述がありましたが、その記事は2年前。。。 是非ともMoney ForwardさんにはSlackアプリを提供いただきたいです🙏

今回の勤怠入力自動化は自分個人しか利用できない形になっていますが、今後は仕様・機能を整備して社内メンバーが利用できるように拡張していこうと考えています。 そのために越えないといけない課題は

  • 打刻失敗時の検知方法
  • 複数人のSlack ID管理
  • MF勤怠のログインID・パスワードの管理 etc

もっと良い実装方法がないのか社内エンジニアにレビューしてもらって、機能拡張やっていきます💪

まとめ

いかがだったでしょうか? 連携アプリが提供されていなくてもAPIを自前で用意することができれば、ツール同士の連携・自動化が可能になります。 自動化したいけれど諦めたままになっている業務があれば、ぜひ今回の手法を応用して挑戦してみてください。

みなさんの業務自動化に少しでも力になれましたら幸いです🙇‍♂️

明日は中名生さんです!

PHPコードを消すライブラリを作った

f:id:kubotak:20211207104943p:plain この記事はQiita AdventCalendar 2021 PHPの8日目の記事です。

こんにちは、こんばんわ、kubotak(@kubotak_public)です。
早速ですがタイトルの通り「PHPコードを消すライブラリ」を作りました。

packagist.org

まずはこのライブラリの生まれた背景と用途について説明します。もしよければstarつけてください。

これはなに?

以下のようにコメントでコードを挟み、composerで導入したコマンドを実行することで対象のコードを削除します。

before

public function code() {
    /** php-del start flag-a */
    $something = 1;
    /** php-del end flag-a */
}

run command

vendor/bin/php-del flag-a

after

public function code() {
}

なぜ作ったのか?

使い方は簡単ですね。しかしこんな仕組み、いつ使うんでしょうか?
話が変わってしまうんですが、弊社ではスクラム開発を行っており、Feature Flag(Toggle)を利用してデプロイとリリースを分離しています。
変更影響があるコードはFeature Flagによって管理され、それがONになることで有効化するようになっています。

(イメージ)

if ($featureFlag) {
  // 新しい処理
  return;
}
// 既存の処理

※弊社のFeature Flagについては過去記事を参照ください
Feature toggles を複数の環境へ即時反映する仕組みを開発しました - M&Aクラウド開発者ブログ

察しの良い方はすでにお気づきかと思います。
このコード、Feature FlagをONにした後はif文及び既存の処理は不要になります。
今まではこれを消すタスクを積んで消す必要がありました。
また、このコードを追加していない開発者が見た場合、どのコードを消すべきかちゃんとコードを読み解く必要もあります。

ほしいもの

つまり、Feature Flagを使うコードを実装する時点で、消すことも想定してコードを書いておいて、後から自動で消えてしまえば負担が少ないのではないか・・・
という思いから出来上がったのがこのphp-delです。

先程のコードに適応すると次のようになります。

/** php-del start flag */
if ($featureFlag) {
/** php-del ignore start */
  // 新しい処理
/** php-del ignore end */
  return;
}
/** php-del end flag */
// 既存の処理

※ignoreコメントで挟んだ箇所は削除対象から除外されるので残ります。

弊社以外にも需要があれば是非どうぞ、ということでOSSとして公開しています。

さいごに

今回OSSとしてComposerで配信するコマンドを作ってみて、次のようなことを感じました。

需要は自分たちだけのものでも良い

誰もが喜ぶライブラリじゃなくても、自分たちのニーズに答えられるものなら開発意欲も湧いて良いなと思いました。

他のOSSコードを読むようになる

他のOSSはこの処理どうやって実装してるんだろう?という疑問からPHPUnitやPHPStanなどの実装をチラ見したりしました。
普段あんまり見に行かないコードなのでそういうものに触れる機会にもなって良いと思います。
composer.jsonのbinに追加するだけでvendor/binに配置される仕組みめっちゃ良いです。

少しでもいいな、と思ったらぜひstarつけてください。

【離職率0%】弊社エンジニアが辞めない理由とは【スタートアップ】

f:id:yamotuki:20211129183843p:plain

(これはM&Aクラウド Advent Calendar 2021の12/3の記事です)

こんにちは。M&Aクラウドのエンジニアの鈴木です。ネット上では@yamotukiという名前で活動しています。

「エンジニアといえば転職してキャリアアップ」「キャリアアップといえばエンジニア」(要出典)などと言われる昨今ではありますが、弊社は7期目にして奇跡的にもまだエンジニアが離職していません。

その奇跡はどこから来るのか?
同僚のエンジニア達にヒアリングをして、起源を突き止めたいと思います。

【仮説】エンジニアはいつ離職を考えるのだろう?

エンジニアが離職を考える時期として、以下のような年次と理由があるかなと思っています。これは完全に主観です。以下のようなものに当てはまらなければ、特段辞める理由は無いのではと仮説を立てました。

  • 1年
    • そもそも職場にマッチしてなかった。「思っていたんと違う」
    • 労働条件が言われたのと違う。「ブラックじゃん?」
  • 2年
    • ジョブホッパー的な気質の場合には2年もやると転職を考える頃。「経験を積んだので昇給すると思っていたのにしなかった。」
    • 苦手なタイプの同僚が増えた。「あいつ嫌い」
  • 3年
    • 仕事に飽きてきた。「チャレンジさせてもらえない」
    • 技術スタックの固定化。「いつもおんなじ技術使ってるわ」(2年目でも言えるかも。まあ理由は二つずつくらいが収まりがいいのでこちらへ)
  • 4年
    • 求められる役割が増えた。「マネージメントなんてやりたくないよ」
    • 色々できるが故に仕事がたくさん降って来すぎる。「マジで忙しい」

さて、実際に聞いてみたらどんな感じでしょう?

ヒアリングしてみた

同僚たちをそれぞれ slack の huddle で突然呼び出して、ざっくばらんに理由を聞いてみました。
弊社には1年目から4年目のエンジニア社員が居るので、年次が浅い方から聞いていきましょう。(※CTOは現在は入社5年目かと思いますが、エンジニア職から離れておりPdMとして活躍しているので今回スコープから外しました。またサービスが2018年5月に開始してからまだ3年半ほどしか経っていないので、実質4年目が最長です。)

1年目

國村さん(入社2ヶ月と10日)

――「入ったばかりではありますが、辞めないで続けている理由ってどんなのがありますか? まずは雑な質問から。」

國村「入ってみて、みんないい意味で真面目だな、と思いました。タスクを終わらせることに真面目に取り組んでいて、課題を解決しようという姿勢が整っている。それがいいなと思ってます。特にみんなチーム一体になってタスクを終わらせようという姿勢が良い。」
國村「あとは事業として可能性がある未開拓領域を掘り進めて開拓しているところですかね。」

――「なるほど。入社直後に辞めたくなる理由があるとしたらミスマッチだと思いますが、それはどうですか?」

國村「特になかったです。」

――「それはなんでだと思います?」

國村「面接で色々聞けたから。逆に、荒井さん(※CTO)に結構きっちり聞かれたと感じました。だからミスマッチしないのかなと。」
國村「あとは内定が決まった後のアトラクト会でチームの空気感を掴みました。それが入社の決め手でした。そこで感じたチームの雰囲気と、入ってみたあとで変わらなかったです。」

仮説にあった「思っていたんと違う」はなかったようです。

塚原さん(入社8ヶ月)

――「とりあえず大きな質問からするのですが、続けている理由ってどんなのがありますか?」

塚原「メンバーに受け入れてもらって、ここでも仕事できるという手応えを感じています。」
塚原「転職の目的だったスキルアップとしては、最初に比べて結構できるようになったので目的は達成しているかなと。高いレベルを求められるし、社内のエンジニアのレベルが高いので刺激的です。」

――「入社前と後でミスマッチとかありました?」

塚原「スキル面で言うと、入社前に荒井さんからは『入ってから頑張ってキャッチアップしてほしい。今の実力のままだと大変なので頑張れ』と言われていました。そう言う意味ではギャップはないです。」
塚原「あと、人間関係の面で言うと、雰囲気良く受け入れてもらったと思ってます。この前エンジニア飲み会(※塚原さん主催による塚原さん&國村さん歓迎会)も開けたので、楽しくやってます。ただ、私は気にしいなので、自分はミスマッチを感じていないが、周りがどう思っているかは心配ではありますね。」

――「なるほど。私はミスマッチなかったと思いますよ。人間関係面で言うと完全に馴染んでいると思います。スキル面で言うと、今は開発総合窓口対応やアラート一時受けなどやってもらってますよね。最初は結構頻度高く私も見に行かないといけない感覚だったけど、今は見る頻度減ってきてます。それはちゃんとやってもらっているという安心感を感じているからだと思います。」

塚原「逆質問なのですが、タスク振っている側(鈴木側)として何か考えていることってあったりします?」

――「明示的にそこまで考えているわけではないけど、特定分野の仕事でめっちゃ詰まっていて、終わった後にメンタル落ちているかなーと思ったりすると、同種の仕事を一時的に振らないでコンフォートゾーンの活躍してもらえる仕事を振っているかもしれないです。」

塚原「なるほど。そういうのも離職率減っている理由かもしれないですね。実はインフラ系タスクとか、フロントエンドのタスクとか難しくて辛い時期があったので。その時は、自分が活躍できず、進んでいる感がなかったです。」

塚原さんについても、仮説にあった「思っていたんと違う」はなかったようです。
逆に求められる水準が高すぎても辛くなってしまうので、塩梅は大事だなと感じました。  

2年目

濱田さん(入社1年と9ヶ月)

――「辞めないで続けている理由って何がありますかね? 最初に思いつくもので。」

濱田「飽きてないから。ですかね。直近だとスクラムマスターやるという話とか。単にコード書くだけで既存の保守だけだと成長が止まってしまう。今の環境だと課題が新たに見つかって改善していこうというサイクルがあるので飽きないですね。転職して改めて成長機会を探す必要がないです。」

――「課題がでてくる、というのはやはりスタートアップだから、とか会社が成長しているからというのはありますかね?」

濱田「そうですね。前職の大手プロバイダだと、事業内容の関心ごとがほとんど変わらないというのがありました。大きく成長していないので目指すべき目標がそんなに変わらないというか。」
濱田「新しい役割で言うと、他にはサブチームリーダーとかファシリテーターとか役割を新たに任せてもらってますね。成長環境として、役割を通してや生産性向上委員会(※実質的なリーダー会)の中で自分にフィードバックがあり『自分の中でどういう課題があるか』というのを意識する機会になってます。」

仮説にあった3年目の「チャレンジさせてもらえない」がないというのが良さそうです。濱田さんはまだ2年目ですが、3年目を超える古参の風格を漂わせています。

3年目

久保田さん(入社2年0ヶ月)

――「ざっくりとした質問なのですが、辞めないで続けている理由って何がありますか?」

久保田「僕は多分特殊ですね。いつ辞めるか入る時に考えてます。前職もそうでした。」

――「時期で決めているってことですか?」

久保田「IPOしてから転職は考えたいんです。IPO無理だとなったら考えるかもしれないけど。IPOに至るまでのチームの変わっていく姿とか技術スタックが変わっていく姿とか、それに技術的適材適所を見極める経験をしたい。そうすると次に行っても再現性のあるスキルが手に入るかなと。」

――「IPOしたらすぐなのか、ベスティング(※ストックオプションから生株変換までの期間)の間は残るのか。」

久保田「その後の世界が重要かどうか、は自分は知らない。その時のことがわかっていないのでまだ分からないです。経営は多角化していくとかしていけば、そのフェーズで僕が必要なのかわからないですね。」
久保田「SOがどれくらいとかあんまり気にしていないですね。あったらあったで嬉しい。それは居る居ないに関わっていないです。一応期待していない。上場後に(株転換で)毎年1000万入ってくるとかだったらちょっと居てみるかーとはなるかも。」

――「経験したいと言うのが強そう?」

久保田「そうですね。僕自身の成長としては、自分は努力していない気がしてます。人の成長は環境次第だと思っていて、僕自身が努力家ではない。やらなきゃいけない環境とか、やらなければいけない環境で成長を促そうというところです。前職にずっといたらダメ人間になっていた。」  

――「楽すぎて?」

久保田「ずっと変わらない繰り返しに入ったというのと、周りに学ぶ人が減った。僕よりできる人というのが周りを見渡すとあんまりいなくなってしまった。」
久保田「今は会社自体が足掻いている。それに合わせて自分も足掻いていく。それで成長していく。今スクラムを真面目に取り入れようとしているのもいい流れ。」

――「スクラムのいいところが自然に身についていく?」

久保田「スクラムに悪いところがあるかはまだわからないですが。上手くいくように濱田さん主体でやっているが、我々も働きかけていく。それが学びになると思いますね。」  

――「周りが求めてくれることをやれば良い?」

久保田「不得意分野はあるし、やりたくないところはある。そういうものを無理矢理やることになれば話が違うよってなる。例えば荒井さんのCTOの立ち振る舞いとか、それは自分には難しい。」

「いつもおんなじ技術使ってるわ」はなさそうでした。久保田さんは、大きな流れに身を任せて自分も成長しよう、というタイプですが、そういう人はスタートアップにマッチしてそうです。

津崎さん(入社2年6ヶ月)

――「辞めないで続けている理由ってなんでしょう? あえてざっくりした質問なのですが。」

津崎「ひとつじゃなくていいですか?」

――「もちろん」

津崎「まだ上場に向かってやっているので、その上場した時の景色をみたいです。」
津崎「あとは、学ぶこともまだあります。データ分析とか大臣制度でチャレンジできる余地が残されているので。」
津崎「停滞感が長く続くと辞めたくなると思います。今は事業も爆発的な成長はないけど、堅実に成長はしている。エンジニアチームの仲間が1人辞めます、2人辞めますというのが増えたら『ぐぬぬ』ってなると思います。むしろ人が減ってやること増えるので辞めてる場合じゃないんでしょうけど。」

――「停滞感を感じている時期はありましたよね?」  

津崎「入社してからはあんまり感じてないです。けど、SKE2(※募集と検索周りのリニューアルプロジェクト。4ヶ月。)の長いトンネルの中にいる時には思ってました。憂鬱に思ってましたね。」

――「今の定常保守だと思っていない?」

津崎「普通ですね。来期が始まるし、スクラムも始まるしという期待感があります。」

――「変わらないというのが辛い?」

津崎「そうかもしれないですね。個人的にはすごく飽き性なので。入社したばかりだと、『新しい新しい』ってなるけど、時間が経つと慣れてしまって刺激が減ったように感じます」

以降、停滞感を感じないために”自分の中のあるべき姿”に向かってどうやったら進んでいけるのだろう?とお悩み相談になりました。
任された仕事を着実に自分のものにして、また次の新しい仕事を任せてもらうループを作ると、停滞感を感じている暇などないのでは無いか、という仮説を鈴木は持ちました。
津崎さんは”あるべき姿”に向かうために自分に定期リマインダをかけたり、付箋を貼ったり工夫はしているけど、「すぐ脳内から消去されてしまう」というのを悩んでいました。機械がやる自動リマインダは無視されがちですね。
津崎さんから"鈴木へ対して"自動定期リマインダをかけることで鈴木が人力チェックと人力リマインダをすることになりました。

こういう話をする機会大事ですね。

4年目

鈴木(入社3年3ヶ月)

セルフインタビューです。私が続けている理由ってなんでしょう?

  • スキル面ではまだやれることがあると思っている
    • リーダー業務やPM業務をやってみているが、まだ完全にうまくできるようになったとは思っていない。また別の会社に行って0からドメイン知識を得て学んでいくのだと効率が悪い
    • 設計のスキルは、自分が考えた設計が長期保守に耐えられるかという視点で同じコードを保守し続けた方がスキルが上がると思っている。時間によるフィードバックを受け取りたい
    • 弊社で身につけられないスキルは、数百万単位のアクセスあるような高トラフィック環境における実務だと思っているが、それは今は自分が必要としていない。また、インフラについては既に前職である程度やったので必要ない。 
  • 金銭面では、SOを持っていて、給料の高い他社に転職するよりまだ残ったほうが期待値が高いと思っている

仮説との対応でいうと、求められる役割が増えた。「マネージメントなんてやりたくないよ」が別に問題になっていないパターンですね。

終わりに

なかなか面白いヒアリング結果でした。

入社から間も無いエンジニアに対しては、入社でのフィルタや期待値調整がうまくいっており、ミスマッチが少ないのが良いポイントかと思いました。面接した人のうち内定までの倍率が10倍を超える(※ぼかします。許可が取れたら書き換えます。)と言われている弊社エンジニア採用はうまくいっているようです。

入社年度にかかわらず、弊社のエンジニアは変化に強いというより「変化が無いと死んじゃう」泳ぎ続けるタイプが多いかもしれないなと感じました。
それぞれが活躍できるタスクを割り振りつつ、一段難しいタスクも捌けるように成長してもらう。そういう職場作りが肝要ですね。

インタビュー見て「同じような志向を持っているなあ」と思ったそこのあなた。多分弊社とマッチしていると思うのでぜひカジュアル面談からいかがでしょうか。CTOでもいいですし、他のメンバーとカジュアル面談したいと指名してもらっても良いかと思います。

www.wantedly.com

おまけ: 入社理由については以下の記事にまとまっています。ぜひ合わせてご覧ください。

update.macloud.jp