はじめに

こんにちは。TIS Ventures Inc. (TVI)の下田です。
簡単に自己紹介しておくと、8月末からシリコンバレーで働いています。海外生活は2度目で4年近くになります。
主に、バックエンドとフロントエンドとWindowsディスクトップアプリが開発できるアーキテクトです。現在は、モバイルアプリを勉強中です。

今回、TVIに勤める同僚と10月にサンノゼで行われたAPI Worldに参加してまいりましたので、レポートしたいと思います。

※TVIはDev.toでブログを公開しています。本記事の英語版もありますので、興味のある方は是非、以下をご覧ください!

API World Hackathon Report No.2 – DocuSign Clickwrap with React – DEV Community 👩‍💻👨‍💻

API Worldと、そのハッカソン

API Worldは、世界最大のAPIに関するカンファレンスです。
出展企業のブースの他にも、5つ以上のステージでプレゼン等が行われていました。

ハッカソンも2日に渡って行われており、100人以上が参加していました。

私は、DocuSignというドキュメントの電子署名サービスを提供している会社のチャレンジに応募し、1等賞(500$)🏆をゲットできました。

ハッカソンでやったこと

日米通じて初めてのハッカソン参加で、レギュレーションの不慣れもあり、チーム結成に出遅れてしまいました。
しかし、22名の参加者にチーム結成依頼を出し、1日目の15時過ぎになんとか4名でチームが結成できました。

私が担当したのは、

  • チャレンジするテーマの選定、
  • ReactのフロントエンドのコードとGo言語のバックエンドのコード提供、
  • DocuSignのAPIの調査と組み込み
  • プレゼン資料作成
  • ジャッジとスポンサーへのピッチ2回

とだいたい全ての作業を英語で行いました。

特に2日目は、チームメンバ3名が全員欠席(2名は無断欠席)するという過酷な状況でしたがなんとか仕上げることができました。

DocuSignのチャレンジ内容

私たちのチームが選択したのは、DocuSign社がスポンサーの「ClickWrap」というAPIを使うチャレンジです。

Challenge #2: DocuSign – Implement “Click to Agree” Functionality using the DocuSign Click API (2)

「ClickWrap」というのは、DocuSign社が提供する、Webサイトなどでよくある「契約条項の同意」を促すサービスです。彼らの専用のサイトに「契約条項の同意」のドキュメントを登録することができ、その管理ページで生成されるコードを自分たちのWebサイトに取り込むことで、簡単に、「契約条項の同意」に関する機能を埋め込むことができるというものです。

以下のガイド(英語)を参考に契約同意のドキュメントを登録したり、JavaScriptのコードを生成したりしました。

実際にできたものは、以下のようなイメージです。

TIS内で行なったReactの集中勉強会で作成した、タスク管理アプリケーションをベースに2日間で改造しました。
ユーザーのサインアップ画面に、「契約条項の同意」ボタンを埋め込みました。ボタンをクリックすると、DocuSignのサーバーから「契約条項」のドキュメントが、Downloadされ画面に表示されます。 「Agree」ボタンを押すことで、契約の同意が行われタスク管理画面に遷移します。

上記のdevpostのサイトのプロジェクト紹介のページは、ハッカソンの2日目に私が英語で書き下ろしたものです。

コーディングのTips

DocuSignが提供している機能は、ピュアなJavaScriptコードを生成しますが、私が使っているアプリケーションは、Facebookのフレームワークである、Reactを使用しています。 このハッカソンでの実装が、DocuSign社のClickWrap機能を、初めてReactのアプリケーションに組み込む例となりました。

このことは、DocuSign社のジャッジの方もおっしゃっており、これが一等賞に選ばれた理由の一つであるようです。

コーディングの流れは、以下の通りです。

1) docusign-click.js をReactのアプリの index.html に埋め込みます。

<script src="https://demo.docusign.net/clickapi/sdk/latest/docusign-click.js"></script>

2) 以下のような、ClickWrapのJavaScriptを実行するReactのコンポーネントを作ります。

しかし、実はこのままでは、後述する “dangerouslySetInnerHTML” の設計上の動作仕様で正常には動きません。

import React, { Component } from "react"
import uuid from "uuid"
import InnerHTML from "dangerously-set-inner-html"
const clickwrapCode = (clientUserId) => `
<div id="ds-clickwrap"></div>
<script>docuSignClick.Clickwrap.render({
environment: 'https://demo.docusign.net',
accountId: 'bra-bra',
clickwrapId: 'bra-bra-bra',
clientUserId: '${clientUserId}'
}, '#ds-clickwrap');</script>
`
class TermsOfConditionsView extends Component {
  render() {
    return <div dangerouslySetInnerHTML={{__html: clickwrapCode(uuid.v4())}}/>
  }
}
export default TermsOfConditionsView

3) “dangerouslySetInnerHTML” の落とし穴

上記2のコードは、DocuSignの契約条項同意書を表示しません。
実は、”dangerouslySetInnerHTML” のscriptタグは評価されないようになっているからです。

詳細は以下の記事を参考ください

4) “dangerously-set-inner-html” というコンポーネントを使ってscriptタグを動かす

上記の3で記述した問題は、次のコンポーネントで解決されます。
divタグの代わりに、InnerHTMLタグを使うだけでOKです。

5) 最終的には、以下のコンポーネントのコードになります。

import React, { Component } from "react"
import uuid from "uuid"
import InnerHTML from "dangerously-set-inner-html"
const clickwrapCode = (clientUserId) => `
<div id="ds-clickwrap"></div>
<script>docuSignClick.Clickwrap.render({
environment: 'https://demo.docusign.net',
accountId: 'bra-bra',
clickwrapId: 'bra-bra-bra',
clientUserId: '${clientUserId}'
}, '#ds-clickwrap');</script>
`
class TermsOfConditionsView extends Component {
  render() {
    return <InnerHTML html={clickwrapCode(uuid.v4())}/>
  }
}
export default TermsOfConditionsView

ハッカソンを終えての感想

日米通じて初参加のハッカソンで賞が取れたことはとても嬉しいです。
英語のピッチも初めてでしたが、自分なりに上手くアピールできました。
今後の改善点は、スカウティングの初動とアメリカ人の自由さの管理です。

ちなみに、無断欠席していたTarbezというメンバは、表彰式で一等賞であると発表された際にやってきて、ちゃっかり記念写真と賞金の半分を持って行きました。タフさは見習いたいと思いました。

(左から、私(顔は隠してます)、ちゃっかりもののTarbezくん、司会者です。)

おわりに

今後もシリコンバレーでの働く風景や、ハッカソンなどの腕試しレポートは積極的に紹介して行きたいと思います。

また、TIS Ventures Inc.では、シリコンバレーで一緒に働く仲間を探しています!
もしご興味のある方は、ぜひTISの採用ページまでコンタクトください!

英語はもちろん、バックエンドはGo言語やJava、フロントエンドはReactやVueなんかも使っています。

将来アメリカで成長したい方、活躍したい方、ぜひご応募してみてください!


本コンテンツはクリエイティブコモンズ(Creative Commons) 4.0 の「表示—継承」に準拠しています。