TalentioがoEmbedに対応した話

こんにちはTalentioの佐藤です。

採用管理システムのTalentioでは採用ページを作ることができます。

先日この機能をアップデートし、ブログ等にURLを貼り付けるだけで採用ページを埋め込めるようにしました。これにより採用ページの共有が簡単にできるようになります。

例えば、このブログ ( はてなブログ ) にTalnetioで作成したページのURLを貼るとこのようになります。

これはoEmbedという規格に沿って実装することで実現しています。

oEmbedとは

埋め込みコンテンツの規格です。メタデータのフォーマットや取得フローを定義しています。ドキュメントはこちらです。

コンテンツの提供者と利用者がこの規格に沿って実装をすることで、通常ページのURLから埋め込み用のコンテンツを取得できるようになります。今回のアップデートでTalentioはコンテンツの提供者として必要な実装をしました。具体的には次の実装をしています。

  1. 埋め込みコンテンツを表示するURLを追加
  2. 埋め込みコンテンツのメタデータを返すAPIを実装
  3. メタデータ取得APIと採用ページの紐付け

それぞれについて詳しい内容を見ていきます。

1.埋め込みコンテンツを表示するURLを追加

埋め込み時に表示する画面のURLです。今回のケースではこのURLを追加しています。

2.埋め込みコンテンツのメタデータを返すAPIを実装

埋め込みコンテンツの表示に必要なデータを返すAPIを作ります。Talentioでは以下のようなデータを返すAPIを用意しています。

{
  "type": "rich",
  "version": "1.0",
  "provider_name": "Talentio",
  "provider_url": "https://www.talentio.co.jp",
  "html": "<iframe src=\"https://recruit.talentio.co.jp/r/1/c/talentio/embed/pages/21466\" width="100%" height=300 frameborder=0 title=\"株式会社タレンティオ | カスタマーサクセス\"></iframe>",
  "url": "https://recruit.talentio.co.jp/r/1/c/talentio/embed/pages/21466",
  "width": "100%",
  "height": 300
}

htmlには表示したいコンテンツを指定します。Talentioでは1で作成した画面を表示するiframeを設定しています。widthやheightは実際に描画する際のサイズを指定します。

APIのレスポンスに含めるデータについて、詳細はこちらを参照してください。

3.メタデータ取得APIと採用ページの紐付け

オリジナルのページにAPIのURLを指定したタグを設定し、2つを関連づけます。

実際にTalentioで作成した採用ページには以下のようなタグが設定されています。hrefには2で作成したAPIが指定されており、これにより採用ページとAPIが関連づいています。

<link href="https://open.talentio.com/oembed?url=https://recruit.talentio.co.jp/r/1/c/talentio/pages/21466&format=json" rel="alternate" title="oEmbed Profile of カスタマーサクセス" type="application/json+oembed">

紐付け方法について、詳しい仕様はこちらを参照してください。

埋め込まれるまでの流れ

以上でコンテンツ提供者の実装は完了です。後はURLをoEmbedに対応したサービスに貼り付ければOKです。利用者側のサービスが規格に沿ってデータを取得し、コンテンツを埋め込んでくれます。

具体的には以下の流れでデータを取得します。

  1. 貼り付けたURLにアクセス。仕様に沿ってタグから対応するAPIを探す
  2. 対応するAPIからメタデータを取得
  3. メタデータに沿って埋め込みコンテンツを描画

補足: oEmbedに対応しているサービス

最後にコンテンツの利用者側で対応しているサービスを調べてみました。

見つけられた範囲では、以下のサービスがoEmbed表示に対応しているようです。

毎月1回を1年間続けてきたタレンティオのTechDay運用

こんにちは、管野です。

タレンティオでは月に1回TechDayを開催しています。この日は普段の業務をお休みし、各自が好きなことを学びます。
そして1日の終わりにクロージング(発表)を行い、それぞれの成果を共有します。

2022年3月に始めて1年が過ぎました。そこで今回はTechDayの運用について振り返ってみます。

【目次】

  1. どうしてTechDayをするのか
  2. どうやってTechDayを運用しているのか
  3. TechDayを1年間やってみてどうだったか

1. どうしてTechDayをするのか

アウトプットに関する学習促進の機会を設けるため

発案当初の意図は、会社として学習促進の機会を整えることでした。Techメンバーはそれぞれ色々なインプットを行っていますが、その学びを全て今の業務に活用できるとは限りません。
活用できるかどうかは、本人が着手しているタスクや現在のアーキテクチャに影響されます。

そこでTechDayとして「各自が自由に作業できる日」を設けることになりました。
お試しで始まりましたが、今では後述する他の理由もあって継続しています。

インプットに関する学習促進の機会を設けるため

TechDayはインプットの機会としても有効です。
例えば新機能に関する技術調査や、既存のアーキテクチャで理解が弱い部分を調べることが出来ます。

後述するようにTechDayの終わりにはクロージングとして、ドキュメントにまとめて発表します。
人に伝えることを意識しながら学ぶため、情報を整理したり取捨選択することになり、インプットの質が上がります。

技術的なコミュニケーションの機会を設けるため

タレンティオでは現在フルリモートワークです。
オフィスに出勤していた頃とは違い、気軽に話せるタイミングは減っています。

みんなで集まって話し合うオンラインMTGはいくつかありますが、技術的な関心をテーマに話す場はほぼありません。
そんな中、TechDayのクロージングは各メンバーの関心事や得意分野を知れる機会になっています。

2. どうやってTechDayを運用しているのか

開催頻度は月1にしている

毎月の最終水曜日をTechDayとしています。メイン業務の開発速度を落とさないことが大前提です。
頻度を高くすると普段の業務に支障が出ますし、逆に低くするとTechDayに求める効果が薄れます。今のところ月1が丁度良いと感じています。

曜日はいつでも構わないのですが、今のチームメンバーにとって一番都合が良い水曜日にしています。

何をテーマにするかは各自の自由

GitHub DiscussionsにTechDayのトピックを一つ作り、月ごとにスレッドを立てています。 最初はGitHub Issuesを使っていましたが、業務でもDiscussionsを使うようになってからはそちらに移行しました。

メンバーは前日に「今回何をやるか」をコメントします。記載したテーマを必ずしも守る必要はなく、ここでのコメントはただの周知です。私はテーマがかぶらないようにしたいので、メンバーのコメントを見てテーマを変えたりしたこともあります。

TechDayで何をするか予定を書く

またテーマに厳密なルールはありませんが、なるべく業務に活かせるものを選ぶ傾向にあります。1日という時間制限のため調査や検証系が多くなりますが、「作ってみる」というテーマに取り組むこともあります。

当日は学習に専念して最後にチームでクロージングを行う

当日は始業から18:00までTechDayに専念しています。
もちろんサポート対応や障害など急ぎの時はそちらを優先しますが、基本的に普段の業務は進めません。そのため例えばコードレビューを依頼されることもありません。この日のSlackはとても静かです。

18:00になるとZoom上でクロージング(発表会)が始まります。
この時までにそれぞれ学んだことをKibelaに投稿します。このKibelaをもとに1人10分ほどの発表を行います。

3. TechDayを1年間やってみてどうだったか

TechDayの成果物

ここ半年のTechDayで取り組んだタイトルの一覧を、この記事の最後に載せておきます。そちらを見ると調査系が多いものの、作ってみたりチーム改善に貢献しているのもあるのが分かります。

例えば以下のような成果が生まれました。

CIや単体テストの改善

  • CI上の単体テスト(RSpec)を高速化するため並列実行を導入、12分 -> 3分に短縮した
  • (上記とは別の開催日で)遅い単体テストのコードを見直して、1~2分短縮した

開発環境の改善

  • Pull Requestに出してるブランチをステージング環境に構築できるが、その手順を簡略化した
  • タレンティオの状況に併せたER図ビューワーを作った

チームメンバーの感想

良い点

  • 普段まとまった勉強時間を取るのが難しいこともあるので、業務時間内に学習機会があるのは助かる
  • CIの高速化とか、普段の開発体験につながる成果が出てるのは良いこと
  • クロージングでの共有を前提に調べるため、いつもより情報を整理しようとして理解度が増す
  • クロージングで他の人の話を聞くだけでも、普段行っているWebでの軽い情報収集より理解が深まる
  • 取り組むテーマが限定されていないこと。幅広いテーマの話を聞けるのは興味深いし、楽しい

改善点

  • 現状でも不満ないが、強いてあげるなら1日以上あると嬉しい
    • 1日以内に終わるネタに限るので、何か作ってみるとか大きなことはしにくい
    • 毎回は難しくても半年とか年に1回だけでも、1日以上の開催があると嬉しい
  • クロージングで発表できるテーマに絞ってしまう
    • まとめ方が見えないテーマに関して「とりあえず触ってみる」ということが出来ない

おわりに

TechDayはとても良い取り組みです。個人のスキルアップだけでなく、チームの生産性や、お客様への価値提供に繋がる可能性があります。運用方法はチームの状況によって調整しつつ、引き続き継続していきます。

参考: 直近半年のTechDay記事タイトル一覧

- Amazon Comprehend の調査
- Zigについて調べてみた
- Rails7 主要な新機能の検証
- Bundle Sizeの調べ方
- タレンティオ用ER図Viewerを作ってみた
- 開発環境へのビルド・デプロイプロセスの改善
- 書籍『Webブラウザセキュリティ』を読んだ
- Rails7 のフロントエンド
- WASIについて調べてみた
- Notion APIを調べた
- 開閉アニメーションについて
- Techブログを書いてみた
- Sentry Session Replay機能の検証
- ハッシュ関数と暗号化/復号について
- SendGrid APIの活用
- Source Map
- ワンタイムパスワードを調べた
- 遅い単体テストを改善して少しだけ早くした
- 機械学習にトライ
- zustand を調べてみた
- Sentry Session Replayに関するブログを書きました
- intercomのお問い合わせをスプシに集計する
- Zodの調査
- 「React でのドラッグ&ドロップライブラリを比較してみた」というブログ記事を書いた(ている)
- ChatGPT and Whisper APIsの活用
- 仕事ではじめる機械学習を読む
- Remix を調べた

Reactのドラッグ&ドロップソートライブラリを比較

はじめに

タレンティオの宇野です。 先日、Talentio Hire で React のドラッグ&ドロップライブラリを実装する機会があったのですが、React でのドラッグ&ドロップソートライブラリは数多くあり、どれが要件にマッチするかがわかりづらかったので、比較検討した際の情報をご紹介できればと思います。

対象読者

この記事は以下の読者におすすめです。

  • React でドラッグ&ドロップソートを実装したい方
  • ライブラリを比較する際の基準の例を知りたい方

今回実装する機能

以下のようなドラッグ&ドロップで並び替えを行うオーソドックスなソート機能です。

ソート中

TLDR

今回の実装では、 dnd-kit を選択しました。以下は、その選定理由になります。
サンプルコードを見たい方はこちらをクリックしてください。

注意

この記事は 2023/03 時点の情報です。

候補ライブラリ

ざっと調べた限り、下記のライブラリがドラッグ&ドロップでのソートに対応していそうでした。
もちろん下記以外にもソート用のライブラリは存在するかと思いますが、今回はこれらを比較検討してみたいと思います。

人気度

ライブラリの利用数(ダウンロード数)や GitHub での人気度を見てみます。

ダウンロード数では react-draggable が突出して人気です。
ただし、最近はダウントレンド傾向なので、他のライブラリへの置き換えが進んでいそうです。
次点では、 react-dnd, react-beautiful-dnd が多く利用されています。

npm trends

スター数

Github でのスター数では、 react-beautiful-dnd が人気です。
Attlasian が開発元で Jila 等にも使われているようなので、そちらの信頼度も影響していそうです。

Stars
react-beautiful-dnd 29,353
react-dnd 18,885
react-sortable-hoc 10,378
react-draggable 8,153
@dnd-kit/core 7,005

メンテナンスされているか

  • dnd-kit が最もアクティブにメンテナンスされています。
    • react-sortable-hoc の後継ライブラリでもあり、初回リリースが 2021/01 と後発のライブラリではあるものの活発に開発されています。
  • react-sortable-hoc はすでにアップデートはされていませんでした。
  • react-beautiful-dnd も部分的なアップデートはされていますが、現在は機能開発、改善等のアップデートはされていません。
Version Updated Created
@dnd-kit/core 6.0.8 2023-02-19T14:48:34.147Z 2021-01-02T02:07:10.605Z
react-beautiful-dnd 13.1.1 2022-08-30T04:15:39.512Z 2017-08-10T07:15:47.946Z
react-draggable 4.4.5 2022-04-26T18:04:09.131Z 2014-07-25T21:58:31.684Z
react-dnd 16.0.1 2022-04-19T18:05:21.375Z 2014-10-19T13:55:23.335Z
react-sortable-hoc 2.0.0 2021-03-19T02:56:51.618Z 2016-06-08T03:30:55.021Z

ライブラリの状況を踏まえた評価

上記を踏まえ、この時点で、下記のライブラリは選定対象から外しました。

  • react-draggable
    • 利用者数が多いものの、現在は利用者数が減ってきている。
  • react-beautiful-dnd
    • Atlassian (Jira などの開発)で開発されているので品質には期待できそうだが、 React 18 に未対応、機能面でのアップデートがされていないなど、今後、長く利用し続けるのは難しそう。
  • react-sortable-hoc
    • 機能の要件的には問題ないが、こちらも react-beautiful-dnd と同じくアップデートされていない。

実装してみる

ライブラリの状況は把握できたので、実際にサンプルを実装して検証してみました。
ここでは、前段の選定対象で残った、react-dnddnd-kit の動作を確認します。

react-dnd

codesandbox でのサンプル
(ソートがうまく動作しない場合は、 Open preview in new window からお試しください)

dnd-kit

  • ソート用の preset が用意されているので、比較的簡単に実装が可能
  • ソート時のアニメーションも標準で付与される
  • ドラッグ時にオーバーレイする要素の位置を自由にカスタマイズ可能
  • スマートフォンにも対応している

codesandbox でのサンプル

まとめ

  • アニメーションや細かい要素のカスタマイズ等の要件にマッチ。
  • react-sortable-hoc からの改善点も多く盛り込まれている。
  • 後発のライブラリで現状利用者数は多くないが、頻繁にアップデートされており、これからも改善が期待できそう。

ということで、今回の実装では dnd-kit を採用しました。

npm trends や Google 検索では、過去に人気(ダウンロード)があったものはわかるものの、
新規採用が増えてきていたり、今後も利用しつづけられそうかどうかは判断できないので、これらの情報を踏まえつつ、実際に実装して感触を確かめるのが重要と感じました。

今回は、縦のリスト要素を並び替える目的で検証しました。
カンバンのような横も含めたドラッグ&ドロップでは、また要件が変わり、結果も変わってくるかと思うので、こちらも機会があれば試してみたいと思います。

この記事が、 React でドラッグ&ドロップソート機能を実装する際の参考になれば幸いです。

Sentry Session Replay機能の紹介

こんにちは、タレンティオの森脇です。

先日、SentryのSession Replay機能が、GA版として公開されましたので紹介します。

sentry.io

Sentryとは

Sentryとは、開発者向けのエラートラッキングとパフォーマンス監視のプラットフォームです。 例えば、エラートラッキング機能では、アプリケーションでエラーが発生した場合に、Sentry上でスタックトレース・該当のソースコードなどが確認できます。

Session Replayの紹介

Session Replayは、ユーザーの行動を動画のように再現し、エラーの発生時・発生前後の状況を確認することができます。

今までのSentryが提供する情報だけでは、再現できない問題の解決に時間がかかる場合がありました。 Session Replayでは、ユーザーの行動を視覚的に確認でき、ネットワークリクエスト、DOMイベント、コンソールメッセージ等のより正確な情報を元にトラブルシューティングが行えるようになります。

それでは、実際にどのように見えるかを確認してみます。

SDKのインストール

Session Replayを利用するには、Sentry SDKの Version 7.27.0以上が必要です。

yarn add @sentry/browser
セットアップ

Sentryの初期化時に、以下のように定義します。

examplePublicKeyには、自身の環境のKeyを設定してください。

import * as Sentry from "@sentry/browser";

Sentry.init({
  dsn: "https://[examplePublicKey]@o0.ingest.sentry.io/0",

  replaysSessionSampleRate: 0.1,
  replaysOnErrorSampleRate: 1.0,

  integrations: [
    new Sentry.Replay({
      maskAllText: true,
      blockAllMedia: true,
    }),
  ],
});

以上で完了です。

動作確認

確認のために、テキストボックスに特定の文字列を入れると、例外を発生させます。

<input
 type="text"
 onChange={e => {
    console.log(e.target.value)
    if (e.target.value == 'exception') {
        throw new Error('exception occurs')
    }
  }}
/>

画面を操作しエラーを発生させると、Sentry上でエラーが確認できます。以下のようなブラウザのDeveloper Consoleに近い情報を確認できます。

  • タイムライン
  • ユーザの行動リプレイ
  • パンくず
  • console
  • network
  • DOM Events

session replay

再生ボタンを押すと、ユーザの行動を動画のように再現できます。

(実際にTalentioで動かしたときのイメージ)

Session replayの動画

consoleへの出力内容は、タイムラインと共に確認できます。

console

エラー発生時のユーザの画面操作や、DOM・コンソールの情報が明確に分かります。

Privacyの対策

Session Replayでは、ユーザ画面の表示・入力データは、デフォルトでは*でマスクされます。 また、テキストデータだけではなく、img,object,iframe等のメディア要素もブロックされるため、個人を特定するデータはSentryへ送信されません。 ただし、一部のplaceholderがマスクされていないケースが発生したため、正しくマスクされない箇所は以下で紹介する方法で個別対応が必要です。

特定のDOM要素に属性 or CSSクラスを追加することで、その内容を記録しないようにすることも可能です。

例えば、サイドメニューののDOMにdata-sentry-blockを付与すると、サイドメニューは空白として表示されます。

<div data-sentry-block>
// sidemenu content
</div>

空白のサイドメニュー

パフォーマンスへの影響

Session Replayでは、DOMの変更を検知し、定期的にSentryへデータを送信しています。 そのため、多少のオーバヘッドは発生していますが、最適化のための対策が行われているため、 確認した環境ではユーザが体感できるほどの影響はありませんでした。

パフォーマンス最適化のための対策

  • DOMの変更の検知には、ブラウザのAPIであるMutationObserverを利用している
  • DOMの変更発生時に、全てのDOMを送信するのではなく、初回のスナップショットからの差分だけ送信している
  • サーバへ送信するDOMは、gzip圧縮されており、圧縮はWeb Workerによりバックグランドで行われている
  • 画像などの静的アセットはクライアントから転送せず、Sentryダッシュボードでの動画の再生時にアセット元のホストサーバーから直接取得されます。

実際に確認しても、一度に送信されるデータは数十バイトほどでした。

価格

エラー監視等と同じく、従量課金となっており一定数を超えると追加料金が発生します。

docs.sentry.io

まとめ

Session Replay機能は、ユーザーの行動が正確に確認できるようになるため、 再現が難しいエラーのトラブルシューティング工数削減が期待できます。

導入も容易で、既にSentryの有料プランを利用している場合は、一定数までは追加費用無しで利用できるのでおすすめです。

なぜ技術ブログをやるのか

宮下(mizzy)です。

タレンティオでも技術ブログやりたいね、という話になり、始めることになりました。よろしくお願いします。

技術ブログをなぜやるのか、という点を明確にしないと、メンバーのモチベーションが維持できず、継続ができないので、始めるにあたってまず最初に、やる目的や意義を明確にし、メンバーと共有する、というところから始めました。

せっかくなので、社内向けにまとめた技術ブログをやる目的や意義を、タレンティオ技術ブログの最初の記事として公開したいと思います。

目的・意義は以下の5つの観点で整理しました。

  • 学習促進
  • 読み手を意識したわかりやすい文章を書く技術の向上
  • 対象への理解を深める
  • よりよい技術や課題解決方法の導入促進
  • その他の副次的な効果

それぞれについて説明します。

学習促進

タレンティオには、技術書の購入などを補助する学習支援手当や、各自が自由に技術的なトピックを選び、学習して発表を行う日を月に一度設けるTech Dayと呼ばれる取り組みなど、学習のインプットとアウトプットを促進するための仕組みがあります。

技術ブログを書くことも、このような学習促進の一環として捉えています。

読み手を意識したわかりやすい文章を書く技術の向上

日常業務やTech Dayでは、社内に向けて文章を書くことがほとんどですが、技術ブログでは社外に向けて書くことになります。社外向けとなると、読み手や書くべき内容が変わり、文章の書き方も変わってくるため、読み手を意識したわかりやすい文章を書く訓練になります。

読み手を意識したわかりやすい文章を書く技術は、どのような職種であっても役に立つはず、と考えています。

対象への理解を深める

仕事で利用している技術や学んだ技術などを文章にすることで、自分の中で理解が曖昧な部分が明確になります。また、読み手を意識することで、質問やツッコミなどを想定し、それに対して答えられるよう、更に深く調査したり、内容を整理したりします。これにより、対象への理解をより深めることができます。

よりよい技術や課題解決方法の導入促進

社外に向けて記事を書こうという意識は、よりよい技術や課題解決方法を導入するモチベーションになります。それによって、自社で運用しているサービスもより良いものになっていきます。

また、ブログ記事にするためには、やったこと、解決したことなどを、抽象化・一般化・言語化することが必要となります。課題を抽象化・一般化・言語化することによって、問題意識の共有がしやすくなったり、一般的によく知られているより良い技術や手法を適用しやすくなったりすることが期待できます。

その他の副次的な効果

タレンティオやタレンティオの中の人のことを社外の人に知ってもらうことで、会社の認知や採用への良い効果があるかもしれません。

また、業務ではOSSを活用しており、オープンなコミュニティによるたくさんのアウトプットに支えられています。我々もアウトプットすることで、オープンなコミュニティへの恩返しが少しでもできれば、と考えています。

もしかしたら社外の方から、アウトプットしたことに対して有益なフィードバックが得られるかもしれません。

ただ、これらはあくまでも「副次的」なものなので、これら自体を目的にはしない方が良いと考えています。


参考にした記事

技術ブログをやる目的・意義を整理するにあたって、以下の記事を参考にさせていただきました。ありがとうございます。


余談: 会社ブログと個人ブログ

上に書いた技術ブログをやる目的や意義は、別に会社ブログではなくとも、個人ブログにもあてはまることがほとんどだと思います。なので敢えて「会社の技術ブログ」ではなく「技術ブログ」としていますし、記事を書くのは会社ブログでも個人ブログでもどちらでも構わない、と思っています。

自分が会社員だった頃は、会社の技術ブログはなかったので、個人ブログに書いていましたが、会社のことも問題のない範囲で書いていて、それで何か咎められたことはないですし、会社の認知や採用などに良い影響をもたらしていました。

もし、タレンティオのエンジニアの大半が既に個人ブログで技術記事を書いているのであれば、Ubieさんのように個人ブログを集めたポータルサイトの形にしていたと思います。

タレンティオはそうではないので、技術ブログを書く場を会社で用意する、という形にしましたし、全メンバーの合意を得た上でそのようにしています。

会社で場を用意しましたが、もし個人ブログで書きたい、という人がいれば、個人ブログで書けば良い、とも思っています。

また、会社ブログといえど、個人も大切にしたいので、個人のはてなIDで記事を書いても良いですし、会社のメールアドレスで取得したはてなIDで記事を書いても良い、という形にしています。(自分は個人のはてなIDでこの記事を書いています。)

陳腐な結論になってしまいすが、それぞれにメリット・デメリットありますので、それを理解した上で、目的を実現するためにはどういう形にするのが良いのか、というのを会社やメンバーの状況を踏まえた上で検討し、メンバーの合意を得る、というのが重要なんじゃないかな、と考えています。

ちなみに、この検討や合意のプロセスには、GitHub Discussionsを活用してみたのですが、そのことについていずれ記事として書くかもしれません。