お問い合せフォームをGithubとGoogle Formで用意する
はじめに
完全に無料で運用出来るお問い合わせフォームを作成したいと思い作成しました。
- 完成したもののリンク
:::note alert 警告 ※ こちらのリンクからのお問い合せは本当に必要な場合のみでお願いします。 ※ レイアウトは調整中です。 :::
通常、お問い合わせフォームを作成する場合、AWS lambda や Google Cloud Functions でお問い合わせがあったことを知らせるアプリケーションを作成するか、 他サービスのフォームを埋め込むことになります。しかし、運用には費用がかかり手軽ではありません...。
この記事では Github と Google フォーム を使って、手軽にお問い合わせフォームを作成します。 また、お問い合わせいただいた方に、問い合わせが行われたことを通知するためのメールで自動返信を行う処理も作成しています。
お問い合わせフォームの作成要件
お問い合わせフォームの作成に伴い、以下の要件を満たす状態になるように考えました。
- 完全に無料で運用する。
- お問い合わせを簡単に管理出来る。
- お問い合わせいただいた方に、問い合わせが行われたことを通知するためのメールで自動返信する。
事前準備
以下のサービスを利用する事で無料で開発を行いました。
実装
以下の手順で実装を行いました。
サイト用にリポジトリを作成する
Githubに新規でリポジトリを作成し、 こちら の内容通りに、GitHub Pages サイトを作成します。 お問い合わせフォームのデザインは下記のサイトから気に入ったデザインの html / css / javascript をコピーして、 GitHub Pages サイトを作成します。
https://deshinon.com/2019/03/03/otoiawase-oshare-css-kopie/
参考記事
https://docs.github.com/ja/pages/getting-started-with-github-pages/creating-a-github-pages-site
Google フォームでお問い合わせフォームを作る
Googleフォームを使った「お問い合わせフォーム」 の作成を行います。 Googleフォーム で以下の情報を入力してもらえるように設定します。
https://docs.google.com/forms/d/e/1FAIpQLSeMkXgsT8_xs4mIiF-bc6InDCAwknqLiy5Gh-JrQGnCHAPrJQ/viewform
- 名前・会社名 (必須)
- メールアドレス (必須)
- お問い合わせ内容
参考記事
https://tonari-it.com/create-google-form/
自動返信メールを送る Google Apps Script を実装する
Googleフォーム で作成したお問い合せの結果を、スプレッドシートに保存するように設定します。 設定が完了したら、スプレッドシートに以下のscriptを取り込みます。
{ "timeZone": "Asia/Tokyo", "dependencies": {}, "webapp": { "access": "ANYONE", "executeAs": "USER_ACCESSING" }, "exceptionLogging": "STACKDRIVER", "oauthScopes": [ "https://www.googleapis.com/auth/script.send_mail", "https://www.googleapis.com/auth/script.external_request" ], "runtimeVersion": "V8" }
function onFormSubmit(e) { // フォームの回答を取得 var name = e.namedValues['名前・会社名'][0]; var email = e.namedValues['メールアドレス'][0]; var message = e.namedValues['お問い合わせ内容'][0]; // 自動返信メール件名 var subject = 'お問い合わせいただきありがとうございました。'; // 自動返信メール本文 var body = name + '様\n' + '\n' + 'この度はお問い合わせいただき、誠にありがとうございました。' + '\n' + '後日、改めてご連絡させていただきますので\n' + 'よろしくお願い申し上げます。\n' + '\n' + '─────────────────────────\n' + 'ご送信内容の確認\n' + '─────────────────────────\n' + '\n' + '【氏名】\n' + name + '\n' + '\n' + '【メールアドレス】\n' + email + '\n' + '\n' + '【お問い合わせ内容】\n' + message; // メール送信 MailApp.sendEmail({ to: email, subject: subject, body: body }); keys = Object.keys(e.namedValues).sort() qa_list = keys.map( key => "### " + key + "\n" + e.namedValues[key] + "\n") url = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" token = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" options = { "method": "post", "headers" : { "Authorization": "token " + token, "Accept": "application/vnd.github.v3+json" }, "payload" : JSON.stringify({ "title": "[お問い合せ] " + name + "様", "body": qa_list.join("\n") }) } UrlFetchApp.fetch(url, options)
おまけ
添付したコードでは、自動返信メールを送った後に、Github の issue を作成しています。 お問い合せを issue で管理出来るので便利です。
https://qiita.com/miyatsuki/items/5cc9c17c6d342007cb72
参考記事
https://nansystem.com/create-a-contact-form-with-google-form-and-auto-reply/
Google フォームを自作のHTML/CSSに取り込む
Googleフォーム で 「ページのソースを表示」 を行い、各種値を取得し、入れ込みます。
サンプルコード
<!DOCTYPE HTML> <html> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>お問い合せ</title> </head> <!-- Global site tag (gtag.js) - Google Analytics --> <script async src="https://www.googletagmanager.com/gtag/js?id=UA-158207338-1"></script> <script> window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-158207338-1'); </script> <!-- Google Form --> <form action="https://docs.google.com/forms/u/0/d/e/1FAIpQLSeMkXgsT8_xs4mIiF-bc6InDCAwknqLiy5Gh-JrQGnCHAPrJQ/formResponse" method="POST" target="hidden_iframe" onsubmit="submitted=true;" class="c-form" > <link rel="stylesheet" href="assets/css/main.css" /> <h1 style="text-align: center;">お問い合せ</h1> <p style="text-align: center; margin: 20px auto"> 下記の項目を入力して、「送信する」のボタンを押して下さい。<br>必須の欄は必ず全てご記入下さい。 </p> <p style="text-align: center; margin: 40px auto"> ※回答までには1週間程度かかる場合もございます。御了承下さい。 </p> <form class="c-form"> <div class="c-form__item"> <label class="c-form__label" for="field-name" >名前・会社名<span class="c-form__required">必須</span></label > <input name="entry.14683452" class="c-form__input" id="field-name" placeholder="氏名" type="text" required="required" /> </div> <div class="c-form__item"> <label class="c-form__label" for="field-mail" >メールアドレス<span class="c-form__required">必須</span></label > <input name="entry.448452954" class="c-form__input" id="field-mail" placeholder="sample@gmail.com" type="email" required="required" /> </div> <div class="c-form__item"> <label class="c-form__label" for="field-message">お問い合わせ内容</label> <textarea name="entry.1020368020" class="c-form__input" id="field-message" placeholder="お問い合わせ内容" ></textarea> </div> <div class="c-form__submit"> <button type="submit">送信する</button> </div> </form> <script type="text/javascript"> let submitted = false; </script> <iframe name="hidden_iframe" id="hidden_iframe" style="display: none" onload="if(submitted){window.location='./pages/thanks.html';}" ></iframe> </html>
.c-form { max-width: 600px; margin: 0 auto; } .c-form__item { display: flex; flex-wrap: wrap; justify-content: space-evenly; margin-bottom: 20px; } .c-form__label, .c-form__input { padding: 10px; } .c-form__label { width: 90%; } .c-form__input { width: 90%; font-size: 16px; border: solid 1px #333; border-radius: 4px; } .c-form__input:focus-visible { outline: Black auto 1px; } .c-form__required { color: #fff; background-color: Red; border-radius: 4px; padding: 5px 5px; margin: 0 0 0 18px; } textarea.c-form__input { height: 160px; } .c-form__submit { text-align: center; } .c-form__submit button { font-size: 18px; font-weight: bold; color: #fff; background-color: green; border: solid 1px green; border-radius: 4px; padding: 5px 32px; transition: 0.4s; cursor: pointer; } .c-form__submit button:hover { color: green; background-color: transparent; } @media (min-width: 640px) { .c-form__item { flex-wrap: nowrap; } .c-form__label { width: 40%; } .c-form__input { width: 55%; } }
参考記事
https://zenn.dev/yurukei20/articles/9741118bfb5ee0
https://monomonotech.jp/kurage/memo/m220202_googleform_html.html
まとめ
完全に無料で運用出来るお問い合わせフォームの作成方法をざっくりとまとめました。 作成したソースコードは こちら です。 参考にして頂けると幸いです。
ゲーム業界・ゲーム開発のまとめ
はじめに
個人的な話になりますが、思い起こすと数々のゲーム開発の現場に参画し、いろいろな経験をさせていただきました。その中での多くの経験や出会いによってリリースしたゲームは、何者にも変えられない最高のものだと確信しています。
ゲーム開発で求められるスキルや業務知識のレベルは、決して低くありません。それどころか、特にエンジニアともなれば高度なスキルや専門知識を持たなければ、実務をこなすことは不可能な仕事です。
この記事では、今までの経験で得た知識や技術の共有と、自分の中での内容の整理が出来ればと思いまとめました。
ゲーム会社について
ゲーム業界は非常に競争が激しく、常に新しいゲームや技術が登場しています。そのため、オススメのゲーム会社は常に変化しています。
現在、世界的に有名なゲーム会社としては、Activision Blizzard、Electronic Arts、Nintendo、Sony、Tencentなどがあげられます。これらの会社は、人気のあるゲームタイトルを多数持っており、業界での地位も高いです。
ゲーム開発の最新技術
ゲーム開発において最新の技術としては、以下のようなものがあげられます。
-
レイトレーシング:光や影の再現に使用される技術で、グラフィックスの質を大幅に向上させます。
-
バーチャルリアリティ(VR)や拡張現実(AR):ゲームの世界に入り込むような体験をすることができる技術で、ゲームの体験を向上させます。
-
5G通信技術:5G通信技術を使用することで、ゲームのダウンロードやマルチプレイなどに必要な通信速度を大幅に向上させることができる技術。
ただし、技術は常に進化しており、新しい技術が登場することもあるため、開発においては常に最新情報を収集し、活用することが重要です。
おすすめの本
HLSL シェーダーの魔導書 シェーディングの基礎からレイトレーシングまで
DirectX 12の魔導書 3Dレンダリングの基礎からMMDモデルを踊らせるまで
ゲームの分析方法
ゲームの分析には様々な方法がありますが、以下のようなものがあげられます。
-
プレイヤー行動分析:プレイヤーがゲーム内でどのような行動をするか、どのような操作をするかを分析します。これにより、ゲームのバランス調整や改善点を見つけることができます。
-
プレイヤー収益分析:プレイヤーがゲーム内でどの程度の収益を上げているかを分析します。これにより、ゲームの課金システムの改善点を見つけることができます。
-
プレイヤーセグメンテーション:プレイヤーを複数のグループに分け、それぞれのグループの特徴を分析します。これにより、ターゲットとなるプレイヤー層を特定し、ゲームの運営戦略を立てることができます。
-
A/Bテスト:ゲームの新しい機能やバランス調整などを行う前に、小規模なグループに対してテストを行い、その結果をもとに決定をすることができます。
-
意識調査:プレイヤーに対してアンケートを行い、ゲームに対する意見や要望を収集します。これにより、ゲームの運営戦略を立てるための参考にすることができます。
ゲームの分析は、ゲームの運営や開発において非常に重要であり、ゲームの成功には分析結果を活用することが求められます。
おすすめの本
オススメのゲーム開発のジャンル
ゲーム開発には様々なジャンルがありますが、オススメのジャンルは常に変化しています。ただ、近年では以下のようなジャンルが注目を集めています。
-
バトルロイヤル:プレイヤー同士が戦うゲームのジャンルで、最後の一人またはチームが生き残るまで戦うゲームが代表です。
-
シミュレーションゲーム:実際に起こりうるシチュエーションを再現したゲームのジャンルで、シミュレーションゲームは幅広い年齢層に人気があります。
-
オンラインゲーム:インターネットを介してプレイするゲームのジャンルで、世界中のプレイヤーと一緒にプレイすることができます。
-
ローグライクゲーム:ランダムに生成されるダンジョンや敵を攻略するゲームのジャンルで、近年大人気です。
ただし、ゲーム開発のジャンルは常に変化しており、新しいジャンルが登場することもあります。開発者は常に市場動向やトレンドを見つけ、最新のジャンルに挑戦することが重要です。
最新のトレンド調査の方法
最新のトレンド調査には様々な方法がありますが、以下のようなものがあげられます。
-
オンラインリソースの利用:インターネット上には様々な情報が存在します。Google Trends, Twitter, Reddit, FacebookなどのSNSや、ブログ、ニュースなどのサイトを利用して、トレンドを調べることができます。
-
コミュニティのフォーカスグループ:特定のコミュニティに属する人々を集め、トレンドについて話を聞くことで、トレンドを調べることができます。
-
コンペティションやアワードの観察:各業界で行われるコンペティションやアワードを観察することで、トレンドを調べることができます。
-
専門家とのインタビュー:業界の専門家にトレンドについて話を聞くことで、トレンドを調べることができます。
-
データ分析:大量のデータを分析することで、トレンドを把握することができます。
トレンド調査は、業界やビジネスにおいて非常に重要であり、トレンドに合わせた戦略を立てるために必要です。市場や業界は常に変化しており、定期的にトレンドを調べることが重要です。
モバイルゲーム開発方法
モバイルゲーム開発には、様々なアプローチやツールがあります。以下に一般的な開発手順を紹介します。
-
ゲームのアイデアを決定する。
-
ゲームデザインを設計し、ゲームの仕様書を作成する。
-
ゲームグラフィックやサウンドなどのアセットを制作する。
-
ゲームエンジンや開発ツールを選択し、ゲームをプログラミングする。
-
ゲームをテストし、バグを修正する。
-
リリース前に、多くの人々にゲームをプレイしてもらい、フィードバックを収集する。
-
ゲームをリリースし、アップデートを行う。
モバイルゲーム開発には、Unity, Unreal Engine, Cocos2d-xなどのゲームエンジンが使用されることが多いです。
また、プログラミングにはC++, C#, Javaなどの言語が使用されます。
モバイルゲーム開発には、ゲームデザイン、グラフィックデザイン、サウンドデザイン、プログラミングなど、様々なスキルが必要になります。
ゲーム開発に興味がある場合は、各種のゲーム開発のスクールやオンラインのチュートリアルなどを参考にすることでスキルを向上させることができます。
おすすめの本
図解即戦力 モバイルゲーム開発がこれ1冊でしっかりわかる教科書
スタートアップ・個人で作れる スマホ向けUnity ソーシャルゲーム開発ガイド
おすすめ記事
オンラインゲーム開発方法
オンラインゲーム開発には、モバイルゲーム開発と同様に様々なアプローチやツールがありますが、通信やサーバー管理などの要素が追加されます。
-
ゲームのアイデアを決定する。
-
ゲームデザインを設計し、ゲームの仕様書を作成する。
-
ゲームグラフィックやサウンドなどのアセットを制作する。
-
ゲームエンジンや開発ツールを選択し、ゲームをプログラミングする。
-
オンラインゲームを実現するために、サーバー構築や通信プロトコルなどを考慮して開発する。
-
ゲームをテストし、バグを修正する。
-
リリース前に、多くの人々にゲームをプレイしてもらい、フィードバックを収集する。
-
ゲームをリリースし、アップデートを行う。
オンラインゲーム開発には、ゲームエンジンと同様にUnity, Unreal Engineなどが使用されます。
また、プログラミングにはC++, C#, Javaなどの言語が使用されます。
サーバーサイド開発には、Java, Ruby, Pythonなどの言語が使用されます。
オンラインゲーム開発には、ゲームデザイン、グラフィックデザイン、サウンドデザイン、プログラミング、サーバーサイド開発など、多岐にわたるスキルが必要になります。
また、オンラインゲームはゲーム内のシステムやプレイヤー間の通信など、比較的複雑なプログラミングが必要になります。
また、ゲームのインフラ構築や運用も必要になります。
オンラインゲーム開発においては、
-
システムの通信設計
-
ユーザー管理
-
マルチプレイヤーのゲームバランス
-
データのセキュリティ
-
サーバーのスケール性
などが重要になってきます。
また、オンラインゲームの開発においては、膨大なデータを処理するために、データベースやサーバーのスケールアウトなどのインフラ技術も必要になります。
オンラインゲーム開発に興味がある場合は、ゲーム開発のスクールやオンラインのチュートリアルなどを参考にすることでスキルを向上させることができます。また、オンラインゲーム開発に携わる上で必要な技術は多岐にわたるため、専門性の高い技術も学ぶ必要があります。
ゲームのサーバー構築方法
ゲームのサーバー構築には様々な方法がありますが、一般的には以下のような手順で進められます。
-
サーバーアーキテクチャの設計:ゲームのニーズに合わせて、サーバーアーキテクチャを設計します。ここでは、クライアントサーバ型、P2P型、マルチクライアント型などがあります。
-
プログラミング:サーバーサイドのプログラミングを行います。ここでは、C++, C#, Java, Pythonなどのプログラミング言語を使用することが一般的です。
-
データベースの構築:ゲームのデータを格納するためのデータベースを構築します。ここでは、MySQL, MongoDB, Cassandraなどが一般的に使用されます。
-
サーバーのセットアップ:サーバーのセットアップを行い、ゲームのサーバーを起動します。ここでは、AWS, Azure, GCPなどのクラウドサービスを利用することが一般的です。また、自前サーバーやデータセンターにサーバーを構築することもできます。
-
スケーラビリティと高可用性の構築:ゲームのスケーラビリティや高可用性を構築するために、負荷分散、オートスケールなどの方法を検討します。
-
セキュリティの構築:ゲームのセキュリティを構築するために、DDOS対策、SSL/TLS暗号化などのセキュリティ対策を導入します。
-
テスト:サーバーの機能や性能などをテストし、バグを修正します。
-
リリース:ゲームのサーバーをリリースし、ゲームを運用します。
サーバー構築は、ゲーム開発において非常に重要であり、ゲームのスケーラビリティやセキュリティなどを担うために必要です。また、ゲームのトラフィックやプレイヤー数が増加するため、適切なスケーラビリティや高可用性の構築が必要になります。また、ゲーム開発においては、ゲームのプレイデータやランキング、アイテムなどの情報を格納するためのデータベースが必要です。そのため、データベースの構築や運用も重要です。
さらに、オンラインゲームの運用には、ゲームのアップデートやパッチなどのメンテナンスも必要です。また、ゲームのセキュリティ対策も常に更新し、最新のセキュリティ対策を導入することが必要です。
また、オンラインゲームは、世界中のプレイヤーがプレイするため、サーバーのセットアップ時に、ゲームの言語や地域に合わせたサーバー構築が必要になることもあります。
オンラインゲーム開発は、ゲームのクリエイティブな部分だけでなく、サーバー構築や運用においても非常に重要です。正確なアーキテクチャ設計、適切なスケーラビリティやセキュリティ対策など、プロフェッショナルなチームで開発することが重要です。
おすすめの本
クラウドゲームをつくる技術 ──マルチプレイゲーム開発の新戦力 (WEB+DB PRESS plusシリーズ)
ドラゴンクエストXを支える技術ーー 大規模オンラインRPGの舞台裏 WEB+DB PRESS plus
さいごに
ゲームクリエイターは「ゲームはこうでなくてはならない」という固定観念を変える職業だと思っています。
しかし、ゲーム業界も時代によっていろいろな制限が増え、制限があることが当たり前のことだと考えている状態が多いです。また、こうした状況で無意識のうちにできた制限も本当に多いです。
固定概念に囚われず、ゲームは自由度の高いメディアとして存在し続けてほしいと思います。
現在、自分の感覚や技術はもう時代についていけてないと感じています。そして今後は若いクリエイターが、若い感性や新しい技術でゲームを作ってくる時代へ移っていくと思います。もしかしたら、ゲームクリエイターという職業はなくなり、より幅広い活躍をすることになるかもしれません。
そのような状況でも、先人たちがすでに経験したことがまとめた記事を読むことによって、同じ過ちを犯さなくて済んだり、より整理されたスマートな方法を採用することで、うまく対処することができるようになるのではないかと思います。
記事を読んで頂き、最高のゲームがリリースされれば嬉しいです。
おすすめ記事
Oculus Integration で Firebase Analytics と Crashlytics を設定する
はじめに
Oculus アプリで Firebase Analytics と Crashlytics を実装したので、備忘録としてまとめました。
Firebase とは
アプリを開発の際に、ユーザーベースを拡大、収益を高めるためのツールです。Firebaseを使えば、インフラ構築に手間取ることなくビジネスを収益化し、効率よくアプリを開発し、運用・管理することができるようになります。
-
スマホアプリでの実装
-
Firebaseの基礎的な使い方
事前準備
-
Firebase のアカウント
実装
Firebaseをインストールする
-
"UnityプロジェクトにFirebaseを追加する" の記事に記載されているステップ1〜4に従って実装します。
※ ステップ5はサンプルコードに含まれているため、必須ではありません。
ステップ 1: Firebase プロジェクトを作成する
ステップ 2: アプリを Firebase に登録する
ステップ 3: Firebase 構成ファイルを追加する
ステップ 4: Firebase Unity SDK を追加する -
ダウンロードした firebase_unity_sdkから、 dotnet4 / FirebaseAnalytics.unitypackageと dotnet4 / FirebaseCrashlytics.unitypackageをインポートします。
Firebase Unity SDK は こちら からもダウンロードできます。 -
AndroidAuto-Resolver が有効でない場合、必ず有効に設定します。
Assets > Play Serveces Resolver > Android Resolver -> Settings -
テンプレート google-services.jsonを独自のものに置き換えます。
テンプレートは下記の場所に保存されているので上書きします。
プロジェクトコードを有効にする
Firebase Analytics と Crashlytics がプロジェクトに追加されたら、Oculusメニューからサンプルコードを有効にします: Oculus> Samples> Firebase> Enable Firebase Sample
'unsafe'を許可する
クラッシュを強制する的に発生させるために、Crashlyticsサンプルでは C#の unsafeキーワードを使用しています。これはデフォルトでは禁止されているのでunityで設定して動作できるようにする必要があります。unsafeキーワードは、プレーヤーの設定で有効にする事ができます。 : Edit > Project Settings... > Player > Android settings > Allow 'unsafe' code
ビルドして実行
この時点で、サンプルシーンを開いて、いくつかのイベントとクラッシュをトリガーできるはずです。レポートは、Firebaseコンソール で確認できます。
自分の作成したアプリへも、 StartCrashlytics.cs を使用するだけで簡単にクラッシュを解析する事ができます。
symbols.zip ファイルをFirebaseにアップロードする
Scripting Backend を IL2CPP に設定してビルドし、symbols.zip を作成して Firebase にアップロードするとより詳細なクラッシュ報告を確認することが出来ます。
Firebase CLI コマンドを実行して、生成した Crashlytics 互換のシンボル ファイルを Firebase サーバーにアップロードします。
firebase crashlytics:symbols:upload --app=FIREBASE_APP_ID PATH/TO/SYMBOLS
FIREBASE_APP_ID: Firebase Android アプリ ID(パッケージ名ではありません)
Firebase Android アプリ ID の例: 1:567383003300:android:17104a2ced0c9b9b
Firebase アプリ ID を確認する方法
google-services.json の mobilesdk_app_id に記載されています。
Unity 内で直接 APK をビルドした場合: PATH/TO/SYMBOLS は、ビルドが完了したときにプロジェクトのルート ディレクトリに生成される、圧縮されたシンボル ファイルのパスです(例: myproject/myapp-1.0-v100.symbols.zip )。
最後に、強制的にテスト クラッシュを発生させて Crashlytics の設定を完了し、Firebase コンソールの Crashlytics ダッシュボードで最初のデータを確認します。
快適リモートワーク環境を構築する方法
概要
個人的な話になりますが、新型コロナウィルス感染症 (COVID-19)の感染拡大を防ぐため、一時的にリモートワークという働き方になりました。それに伴い、自宅から社内システムにアクセスする環境を急遽用意することになりました。
感染症や自然災害などを原因とする不測の事態により、これまでの働き方では対応できない局面が増えているからこそ、今後も働き方改革の一環として、リモートワークを導入や検討する企業が増えていくと予想されます。
しかし、スタートアップやWebアプリを開発しているベンチャーなどは、リモートワークを容易に導入できるかもしれませんが、大手企業の場合、リモートワークを導入しても、自宅PCから社内システムにアクセスすることを許可していないところも多い状態かと思います。
リモートワークできる環境をどうつくるか。
インフラの知識が乏しい私が、最低限知っておく必要があった技術・知識と、リモートワークを楽しく快適にする方法を備忘録としてまとめます。
おすすめの本
要件と戦略
-
リモート環境でもオフィスと同様の開発ができること
-
リモートワークを始めるために必要なものを把握する
-
VPN(Virtual Private Network)を理解する
-
-
リモート環境でのミーティングをオフィスと同様にできること
-
リモート環境を考慮したミーティングを準備する
-
リモート環境を考慮したミーティングを進行する
-
作業を行う上で、リモート環境でもオフィスと同様のパフォーマンスが出せる状況を作る必要があります。
事前準備
リモートワークを始めるために必要なもの
-
PC
-
ネット回線
-
長時間作業しやすい机と椅子
-
ヘッドセットマイク
低スペックのPCは作業効率がかなり落ちます。また、円滑なリモートワークには、各家庭に安定したネット回線が敷かれていることが必須です。
チャットツール等でビデオ通話をするのであれば、ヘッドセットマイクはあったほうが便利です。
作業用の机や椅子がなく、ローテーブルで長時間の作業が必要となると、首や腰を痛めます。また、家族と同居していて、一人になれる空間がないのであれば、貸し個室など検討しなくてはいけません。
今後も働き方改革の一環として、リモートワークを導入や検討する機会があるかと思います。
不足しているものがあれば、購入や準備などの検討が必要かもしれません。
自宅PCから社内システムにアクセスする
VPN(Virtual Private Network)を理解
VPNとは、Virtual Private Networkの略で、離れた場所の間を仮想的な専用線でつないで安全なデータ通信を実現する仕組みです。
VPNは大きく2種類のサービスがあります。
リモート環境でのミーティング
毎日顔を合わせて仕事をすることが出来なくなるので、メンバーとWeb会議ツールに関して話し合っておく必要があります。また、Web会議ツールは、事前に必ず接続テストしておくとスムーズに会議が出来ます。
Web会議ツールを使用する上で、周りの音が入りやすい環境なら、聞くときはミュートにすると良いです。キーボードの音が入りやすいので、ミュートにしておくと安心です。
Web会議システムの例
Snap Cameraを使用するとWeb会議に、加工した映像で参加できるようになります。
リモートワークを導入して感じたメリット・デメリット
メリット
コロナウイルスなどの感染症の流行や、災害による交通網の麻痺など、災害時にもリモートワークは対応しやすくなります。もちろん身に危険が及ぶ状況では、仕事どころではないですが、事態が落ち着いてくれば働かなくては生活していくことはできません。
あらかじめリモート対応の準備を進めておくことで、多少の災害時にも事業をストップせずに稼働させることができます。
また通勤時間がなくなる事で、通勤で体力を消耗する事なく作業に集中できます。
デメリット
企業にとってリモートワークで最も危惧するのが、「本当に自宅で仕事ができるのか」という点です。
そのため普段の仕事から社員の仕事量を明確にし、リモートでも変わりなく業務が行えることを証明しなければなりません。
また、判断に困ったときどこに質問すればいいのか明確にする必要があります。リモートワークで自分が対応できない業務などは、柔軟な対応も必要になります。
まとめ
現在、実際にリモートワークで稼働してみてPDCAを回しています。
念入りに準備をすることで快適に業務ができる反面、どれだけ準備をしても、必ずどこかで不備は発生します。
多少の災害時にも事業をストップせずに稼働させる為に、更に経験と準備が必要です。
Görli testnet からテストイーサリアムを受け取る方法
はじめに
「Truffle のチュートリアル ETHEREUM PET SHOP をやってみた」で、ウェブ上に分散型アプリケーションを作成する方法をまとめましたが、MetaMaskとブロックチェーンを接続する 際に、 Ganache を利用してプライベートネットでETHの送金を行いました。
イーサリアムでトークンを作成するにはガス代としてETHが必要です。最終的にはメインネットでトークンを作成することが必要ですが、テストのためだけにメインネットの高額なガス代を支払うのは大変です。 そこで使えるのがテストネットです。テストネットではFuncet経由で無料でガス代を入手することができます。イーサリアムには複数のテストネットがあり、メインネットと同じウォレットアドレスを使用してトークンのやり取りのテストを行うことができます。
テストネットである Görli Testnet Network を Metamask に追加し、 Test Ethereum を受け取る方法をまとめました。ちなみに、Görli は ゲルリ と読みます。
参考にしたサイト
Getting started with the Görli Testnet URL : https://mudit.blog/getting-started-goerli-testnet/
https://mudit.blog/getting-started-goerli-testnet/
参考にした本
- マスタリング・イーサリアム ―スマートコントラクトとDAppの構築
- SolidityとEthereumによる実践スマートコントラクト開発 ―Truffle Suiteを用いた開発の基礎からデプロイまで
- 詳解 ビットコイン ―ゼロから設計する過程で学ぶデジタル通貨システム
- ブロックチェーン dapp&ゲーム開発入門 Solidityによるイーサリアム分散アプリプログラミング
手順
- Metamaskウォレットにログインし、ネットワークのドロップダウンをクリックします。
- [ネットワークの追加]をクリックします。
- 設定ページが表示されます。
- 左側のサイドバーで[ネットワーク]をクリックすると、利用可能なすべてのテストネットワークが表示されます。
- Görli Testnet Network が表示されていない場合は、左側のサイドバーの「高度な設定」をクリックします。
- 下にスクロールすると、[詳細設定]タブに[テストネットワークを表示する]オプションがあります。「オン」にするだけです。
- これらのステップを完了すると、ドロップダウンリストにカスタムネットワークが表示されます。
テストイーサリアムの受信
:::note warn 警告 2022年9月現在下記の方法ではFaucet出来なくなっています。 :::
1.次のWebサイトにアクセスします: https://faucet.goerli.mudit.blog/ TwitterまたはFacebookアカウントが必要です。
2.Metamaskアドレスをコピーして、下記のようにツイートへ貼り付けます。ツイートした後、URLをコピーします。
https://twitter.com/pirorororonn/status/1559002319534301185
3.ツイートのURLを https://faucet.goerli.mudit.blog/ に貼り付け、必要なテストETHの量を選択します。
4.トランザクションが確認されると、Metamaskウォレットの残高を確認できるようになります。
最近試した方法
下記リンクへアクセスし、Metamaskアドレスを貼り付けてFaucetすることが出来ました。
新型コロナウイルス感染症になったので対応を備忘録としてまとめる
はじめに
2022年7月、初めて新型コロナウイルス感染症になりました。
自分の症状を他の人に伝えることが多くあったのと、自分の見たサイトを知りたいと言う人が多かったため、記事を書きました。
目的
この記事の目的は、自分の症状と対応を他の人に伝えるためにまとめています。医療に関する情報発信や新型コロナウイルス感染症に関する個人的な意見を発信する記事ではありません。
注意!
症状は、人によって異なります。実際に自分と一緒に生活をしている人で症状が異なりました。あくまで自分の体験談です。
私は医療関係者ではないので、医療情報は載せていません。
あくまで参考程度に見ていただければと思います。
助けられたサイト
新型コロナウイルスに関するQ&A(一般の方向け)
URL : https://www.mhlw.go.jp/stf/seisakunitsuite/bunya/kenkou_iryou/dengue_fever_qa_00001.html
症状
1日目
朝起床すると異常な喉の痛みが発生する
リモートワークの会社で働いているので、そのまま仕事をする
のど飴で耐えるが一向に症状が落ち着かず、不安になる
午後、昼休みを利用してPCR検査場へ行くが、受付が終了している
持っていた抗原検査キットで検査するが、陰性だったのでそのまま仕事を続ける
定時に疲れがピークになり即効で寝る
2日目
念の為、発熱外来を探し始めるが、病院は既に満員で空いていない
夜、検査結果届く、陽性を確認する
埼玉県はオンライン診療をしていることを知る
3日目
オンラインで発熱外来を受診する
夜、薬が届く
ロキソニンを処方されました。
市販薬だと下記リンクの薬でも代用出来ると思うので、常備した方が良いと感じました。
安心したのか熱が急に上がり、倦怠感が酷くなる
4日目
発熱 39.5
5日目
発熱 39.5
熱が下がらないのと辛い状態が続いたため、パルスオキシメーターを渡される。
6日目
熱下がる
食欲が戻るが、味覚・嗅覚が無い状態になる
7日目
咳は残るものの、体力が回復する
リモートワークで仕事復帰出来る状態になる
隔離期間終了
無理せず生活を取り戻す
味覚・嗅覚が回復する
時々、咳が出るが大きな問題にはならないレベルに回復する
隔離期間終了から更に一週間後
体力が少し無くなっているが、ジムでトレーニングを通常通りに出来るように回復する
咳は出なくなる
最後に
新型コロナウイルス感染症の症状は、多くの場合、長くても2週間程度で完全に治まりますが、軽症の場合はもっと早く、時には1週間以内に回復することもあるそうです。
新型コロナウイルス感染症の症状はつらいものですが、早く回復するためにも発熱外来を早く受診出来る方法を知ったり、事前に常備薬を用意している状態が良いと感じました。
私は医療関係者ではないので、体験記として読んで頂ければ幸いです。
Truffle のチュートリアル ETHEREUM PET SHOP をやってみた
はじめに
「Solidity とは何か? 開発環境を構築する!」で、Solidity の基礎を理解し、スマートコントラクトプロジェクトを作成する事が出来ました。 Dapps開発のフレームワークである「Truffle」の公式サイトで紹介されている「ETHEREUM PET SHOP」のチュートリアルをやってみて、実際にウェブ上に分散型アプリケーションを作成しましたので、備忘録としてまとめます。
https://trufflesuite.com/tutorial/
「Truffle」以外にも Hardhat を使用して Dapps開発をする方法があります。
参考にした本
- マスタリング・イーサリアム ―スマートコントラクトとDAppの構築
- SolidityとEthereumによる実践スマートコントラクト開発 ―Truffle Suiteを用いた開発の基礎からデプロイまで
- 詳解 ビットコイン ―ゼロから設計する過程で学ぶデジタル通貨システム
- ブロックチェーン dapp&ゲーム開発入門 Solidityによるイーサリアム分散アプリプログラミング
ETHEREUM PET SHOP
ペットの「adopt」というボタンを押すとMetaMaskが起動し、表示された金額と手数料を確認してトランザクションが作成されETHで支払うことができます。
Truffle Box を使った Truffleプロジェクトの作成
pet-shop-tutorialというディレクトリを作り、このディレクトリ内で作業していきます。
$ mkdir pet-shop-tutorial $ cd pet-shop-tutorial
今回はチュートリアルのためTruffle Boxというあらかじめ用意されたプロジェクトから作成します。
$ truffle unbox pet-shop
スマートコントラクトを書く
contracts/
ディレクトリの中にAdoption.sol
というファイルを作成します。
pragma solidity ^0.5.0; contract Adoption { address[16] public adopters; // Adopting a pet function adopt(uint petId) public returns (uint) { require(petId >= 0 && petId <= 15); adopters[petId] = msg.sender; return petId; } // Retrieving the adopters function getAdopters() public view returns (address[16] memory) { return adopters; } }
truffle compile
を実行します。
マイグレーション
migrations/
ディレクトリの中に2_deploy_contracts.js
というマイグレーションファイルを作成します。
var Adoption = artifacts.require("Adoption"); module.exports = function(deploy) { deploy.deploy(Adoption); }
プライベートネットを作るツールとして、Ganache を利用します。
「Ganache」を起動した状態にして、ターミナルで truffle migrate
を実行します。
スマートコントラクトのテストコードの作成
「test」ディレクトリ内に「TestAdoption.sol」というテストコードを作成しましょう。
pragma solidity ^0.5.0; import "truffle/Assert.sol"; import "truffle/DeployedAddresses.sol"; import "../contracts/Adoption.sol"; contract TestAdoption { // The address of the adoption contract to be tested Adoption adoption = Adoption(DeployedAddresses.Adoption()); // The id of the pet that will be used for testing uint expectedPetId = 8; // The expected owner of adopted pet is this contract address expectedAdopter = address(this); // Testing the adopt() function function testUserCanAdoptPet() public { uint returnedId = adoption.adopt(expectedPetId); Assert.equal(returnedId, expectedPetId, "Adoption of the expected pet should match what is returned."); } // Testing retrieval of a single pet's owner function testGetAdopterAddressByPetId() public { address adopter = adoption.adopters(expectedPetId); Assert.equal(adopter, expectedAdopter, "Owner of the expected pet should be this contract"); } // Testing retrieval of all pet owners function testGetAdopterAddressByPetIdInArray() public { // Store adopters in memory rather than contract's storage address[16] memory adopters = adoption.getAdopters(); Assert.equal(adopters[expectedPetId], expectedAdopter, "Owner of the expected pet should be this contract"); } }
truffle test
を実行します。
スマートコントラクトと連動したUIの作成
フロントエンド部分のロジックは src ディレクトリで、スマートコントラクトの連携する部分を実装する為に、 /src/js/app.js
ファイルを編集します。
App = { web3Provider: null, contracts: {}, init: async function() { // Load pets. $.getJSON('../pets.json', function(data) { var petsRow = $('#petsRow'); var petTemplate = $('#petTemplate'); for (i = 0; i < data.length; i ++) { petTemplate.find('.panel-title').text(data[i].name); petTemplate.find('img').attr('src', data[i].picture); petTemplate.find('.pet-breed').text(data[i].breed); petTemplate.find('.pet-age').text(data[i].age); petTemplate.find('.pet-location').text(data[i].location); petTemplate.find('.btn-adopt').attr('data-id', data[i].id); petsRow.append(petTemplate.html()); } }); return await App.initWeb3(); }, initWeb3: async function() { // Modern dapp browsers... if (window.ethereum) { App.web3Provider = window.ethereum; try { // Request account access await window.ethereum.request({ method: "eth_requestAccounts" });; } catch (error) { // User denied account access... console.error("User denied account access") } } // Legacy dapp browsers... else if (window.web3) { App.web3Provider = window.web3.currentProvider; } // If no injected web3 instance is detected, fall back to Ganache else { App.web3Provider = new Web3.providers.HttpProvider('http://localhost:7545'); } web3 = new Web3(App.web3Provider); return App.initContract(); }, initContract: function() { $.getJSON('Adoption.json', function(data) { // Get the necessary contract artifact file and instantiate it with @truffle/contract var AdoptionArtifact = data; App.contracts.Adoption = TruffleContract(AdoptionArtifact); // Set the provider for our contract App.contracts.Adoption.setProvider(App.web3Provider); // Use our contract to retrieve and mark the adopted pets return App.markAdopted(); }); return App.bindEvents(); }, bindEvents: function() { $(document).on('click', '.btn-adopt', App.handleAdopt); }, markAdopted: function() { var adoptionInstance; App.contracts.Adoption.deployed().then(function(instance) { adoptionInstance = instance; return adoptionInstance.getAdopters.call(); }).then(function(adopters) { for (i = 0; i < adopters.length; i++) { if (adopters[i] !== '0x0000000000000000000000000000000000000000') { $('.panel-pet').eq(i).find('button').text('Success').attr('disabled', true); } } }).catch(function(err) { console.log(err.message); }); }, handleAdopt: function(event) { event.preventDefault(); var petId = parseInt($(event.target).data('id')); var adoptionInstance; web3.eth.getAccounts(function(error, accounts) { if (error) { console.log(error); } var account = accounts[0]; App.contracts.Adoption.deployed().then(function(instance) { adoptionInstance = instance; // Execute adopt as a transaction by sending account return adoptionInstance.adopt(petId, {from: account}); }).then(function(result) { return App.markAdopted(); }).catch(function(err) { console.log(err.message); }); }); } }; $(function() { $(window).load(function() { App.init(); }); });
MetaMaskとブロックチェーンを接続する
- 右上の丸いボタンをクリックし、マイアカウントの「設定」を選択する。
- 「ネットワーク」を選択する。
- 「ネットワーク追加」をクリックする。
- ネットワーク名とRPC URLに
http://127.0.0.1:7545
を入れる。 - チェーンIDに
1337
を入れる。 - 通貨記号に
ETH
を入れ「保存」を押す。 - 右上のXをクリックし設定を終了する。
- Ganacheのアカウント1の残高が反映されたことを確認する。
Dappの完成
npm run dev
を実行します。
Dappがブラウザ上で表示できます。「adopt」ボタンをクリックすると、MetaMaskによりトランザクションが送られ、ETH払いでペットを購入することができます。
まとめ
この記事では、truffle unbox pet-shop
で作成される、Truffleのチュートリアルで ETHEREUM PET SHOP の流れにそって、実際にウェブ上に分散型アプリケーションを作成する事が出来るようになりました。
今後は以下の内容をまとめる予定です。
公開されているテストネットワーク Görli testnet にデプロイする。