Python Flask Starterの動画を見ながらStripe CLIを使ってみた
みなさんどうも、たいがーです?
4連休、いかがお過ごしでしょうか。気がついたらすでに連休最終日ですね。
今回は、今までなかなか触れていなかったStripeを触ってみました!
今回やってみたこと
参考動画を視聴しながら、Flask(Python用のウェブアプリケーション)を使い、 Stripe APIやStripe CLIの使い方を確認していきます。テストイベントの作成も行っていました。
Starter動画は、Python Flaskの他に.NET、Echo(Go Web Framework) 、Express(Node.js Web Framework)、Slim(PHP Web Frame work)、Sinatra(Ruby Web Frame work)があるので、みなさんも使用している言語によって試してみてくださいね!
ちなみに私はこれまで、Flaskをあまり使ったことがありませんでした。書き方から詳しく動画で解説してくださるので、使ったことがないフレームワークに触れる良い機会でもあると思います!
実行環境
- macOS Catalina ver.10.15.5
- Python 3.8.2
- pip 20.1.1
- Homebrew 2.4.8
- Chrome
実際の手順
Stripe CLIのインストールから始めていきます。
Stripe CLIとは?
The Stripe CLI is a developer tool to help you help build, test, and manage your integration with Stripe directly from your terminal. The Stripe CLI is easy to install, works on macOS, Windows, and Linux, and offers you a range of functionality to make your developer experience with Stripe better.
Stripe CLIは、Stripeをあなたのターミナルから直接構築、テスト、管理するのに役立つ開発者ツールです。 Stripe CLIはインストールが簡単で、macOS、Windows、およびLinuxで動作し、Stripeの開発者エクスペリエンスを向上させるためのさまざまな機能を提供します。
StripeからもCommand Line toolsが提供されています。
今回はサンプルリストを閲覧や、テストイベントの作成に使っていますが、Stripe CLIでどういうことができるのか詳しく知りたい方はReferenceからご覧ください!
まずはStripe CLIのインストールから始めていきます。
Stripe CLIをインストールする
今回、私はHomebrewを使ってインストールを行いました。
$ brew install stripe/stripe-cli/stripe
Homebrew以外にも、apt-getやyumなどでもインストールすることができます。(他の手順については、下の参考ページからご覧ください。)
$ stripe --version stripe version 1.4.6
うまくインストールもできていそうですね。次にStripe CLIを利用するためにログインを行います。
$ stripe login
するとこのようにペアリングコードが表示され、Enterキーを押すとブラウザが開かれます。
ブラウザが開かれると、ターミナル上と同じペアリングコードが表示されているはずです。
それぞれのペアリングコードを確認した後、アクセスを許可します。
すると、このようにアクセスが許可されたと表示されます。このキーは90日後に期限が切れるため、その際にもう一度認証する必要があります。
サンプルリストをチェックしてみる
続いて、Stripeのサンプルリストをチェックしてみます。
$ stripe samples list
このように入力すると、このような形でabc順にサンプルリストが表示されます。
- そのサンプルのGitHubのリポジトリ名
- サンプルの説明文
- リポジトリのURL
ちなみに表示されたリスト内で、今回参考にするサンプルはこちらです。
- developer-office-hours
- Starter templates for following along with Developer Office Hours
- Repo: https://github.com/stripe-samples/developer-office-hours
こちらのリポジトリ内にある、starterディレクトリ内のファイルが今回見ていくサンプルです。
ちなみに、こちらで表示されるサンプルリストは、このJSONファイルから取ってくる仕様になっているようです。新しいStripe Sampleリポジトリが追加されると、GitHubアクションがこのディレクトリを自動的に更新する仕組みだそうです。(README.mdより)
サンプルを見てみる
developer-office-hoursというサンプルを見ていきましょう。まずは、サンプルをダウンロードします。
$ stripe samples create developer-office-hours
すると、このように表示され、使用する言語を選択します。
✔ Finished downloading Use the arrow keys to navigate: ↓ ↑ → ← ? What server would you like to use: node php-slim ▸ python ruby ↓ go
今回はPythonを使っていくので、Pythonを選択します。
✔ Finished downloading ✔ Selected server: python ✔ Files copied ✔ Project configured You're all set. To get started: cd developer-office-hours
それでは、developer-office-hoursを開いてみましょう。
中身はこのようになっています。
- LICENSE
- README.md
- client/
- server/
clientディレクトリには、非常に単純なindex.htmlページがあります。また、serverディレクトリには、シンプルなFlask用のserver.pyがあります。
どのような形を作っていくか分かったところで、今回は1から構築していくため、ダウンロードしたディレクトリごと削除します。
実際に自分で作っていく
公開用のファイルを作成する
まずはclient、serverディレクトリを作成し、clientディレクトリ内にindex.htmlというファイルを作成します。
$ mkdir client server $ vi client/index.html
実際のindex.htmlファイルは、このような形にします。こちらは、先ほどのサンプル内にあったindex.htmlとほぼ同じ形ですが、少し変更しています。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <title>Stripe Payment Page Sample</title> <link href="https://stripe-samples.github.io/developer-office-hours/demo.css" rel="stylesheet" type="text/css"> </head> <body> <div id="main"> <div id="container"> <div id="panel"> <h1>Office Hours</h1> </div> </div> </div> <script src="https://js.stripe.com/v3/"></script> <script charset="utf-8"> var stripe = Stripe('pk_test_XXXXXXXXXXXXXX') </script> </body> </html>
index.html内にはstripe.jsスクリプトを加えました。バンドルに含めたり、自分でホストするのではなく、常にhttps://js.stripe.comから直接ポーリングしているため、遅延や非同期はありません。常に最新バージョンのStripeクライアントを使用できます。
ちなみにチェックアウトページだけでなく、このスクリプトを全てのページに含めることによって、Stripeは顧客がWebサイトを閲覧する際の詐欺の可能性がある疑わしい動作を検出できるようになります。
また、ページに関連するJavaScriptをインラインで書くことはよくあります。クライアントディレクトリにあるJavaScriptファイルを含むいくつかのStripeサンプルのインラインスクリプトタグで参照します。
また、Stripeを操作するためにAPIキーを使っています。
Stripe authenticates your API requests using your account’s API keys. If you do not include your key when making an API request, or use one that is incorrect or outdated, Stripe returns an error.
Stripeは、アカウントのAPIキーを使用してAPIリクエストを認証します。 APIリクエストを作成するときにキーを含めなかったり、正しくないか古いキーを使用したりすると、Stripeはエラーを返します。
Every account is provided with separate keys for testing and for running live transactions.
すべてのアカウントには、テスト用およびライブトランザクションの実行用に個別のキーが用意されています。
Publishable API keys are meant solely to identify your account with Stripe, they aren’t secret. In other words, they can safely be published in places like your Stripe.js JavaScript code, or in an Android or iPhone app. Publishable keys only have the power to create tokens. Secret API keys should be kept confidential and only stored on your own servers. Your account’s secret API key can perform any API request to Stripe without restriction.
公開可能なAPIキーは、Stripeでアカウントを識別することのみを目的としており、秘密ではありません。つまり、Stripe.js JavaScriptコードのような場所や、AndroidアプリやiPhoneアプリで安全に公開できます。公開可能なキーには、トークンを作成する権限しかありません。 シークレットAPIキーは秘密にして、自分のサーバーにのみ保存する必要があります。アカウントの秘密APIキーは、StripeへのAPIリクエストを制限なしに実行できます。
今回は公開可能なAPIキーを使っています。APIキーは、ダッシュボードで見ることができるのでそちらを確認してみてくださいね!
Stripe APIを使ってみる
次にPythonの仮想環境を作り、今回に必要なflask、Stripe API、python-dotenvをインストールします。
$ cd server/ $ python -m venv venv $ . venv/bin/activate (venv) $ pip install flask stripe python-dotenv
python-dotenvをインストールしたので、シークレットキーは.envファイルに入れましょう。
一度、うまく呼び出せているかどうか、こちらで試してみます。
import stripe import os from dotenv import load_dotenv, find_dotenv load_dotenv(find_dotenv()) stripe.api_key = os.getenv('STRIPE_SERCRET_KEY') print(stripe.Plan.list())
- 実行結果
{ "data": [], "has_more": false, "object": "list", "url": "/v1/plans" }
今は、何もプランを作っていないので、このような空のリストが帰ってきました。プランは、Stripe APIを使うか、ダッシュボードで作成することができます。
ローカルホストで文字列のリクエストが送信できるかを試してみる
続いて、先ほどのFlask用のファイルを変更していきます。
import stripe import os from flask import Flask, render_template, jsonify, request from dotenv import load_dotenv, find_dotenv load_dotenv(find_dotenv()) stripe.api_key = os.getenv('STRIPE_SERCRET_KEY') app = Flask(__name__, static_folder='../client', static_url_path='', template_folder='../client') @app.route('/') return 'Hello, Stripe Devs' app.run(port=4242)
このように書き換えることで、clientディレクトリ内のアクセスキーを使用することができます。 実行してみると、このようなメッセージが出てきます。
* Serving Flask app "setup" (lazy loading) * Environment: production WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. * Debug mode: off * Running on http://127.0.0.1:4242/ (Press CTRL+C to quit)
続いて、うまく動いているかどうかを確かめるため、curlコマンドを使用しローカルの実行サーバーにHTTPリクエストを送信します。 一度、別ウィンドウで開き、そこでコマンドを叩いてみます。
$ curl localhost:4242 Hello, Stripe Devs
うまく行ったようです! Flaskの方も見てみましょう。
* Serving Flask app "setup" (lazy loading) * Environment: production WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. * Debug mode: off * Running on http://127.0.0.1:4242/ (Press CTRL+C to quit) 127.0.0.1 - - [25/Jul/2020 21:27:58] "GET / HTTP/1.1" 200 -
リクエストが送信できていそうですね!
ローカルホストでHTMLの取り出しリクエストが送信できるかを試してみる
先ほどのPythonファイルを、今度はこのように変更していきます。
import stripe import os from flask import Flask, render_template, jsonify, request from dotenv import load_dotenv, find_dotenv load_dotenv(find_dotenv()) stripe.api_key = os.getenv('STRIPE_SERCRET_KEY') app = Flask(__name__, static_folder='../client', static_url_path='', template_folder='../client') @app.route('/') def index(): return render_template('index.html') app.run(port=4242)
それでは、先ほど同様curlコマンドを叩いて結果を見てみましょう。一度サーバーを再起動させる必要があるため、"Ctrl+C"で終了させてからもう一度Pythonコードを実行しましょう。
$ python setup.py * Serving Flask app "setup" (lazy loading) * Environment: production WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. * Debug mode: off * Running on http://127.0.0.1:4242/ (Press CTRL+C to quit) 127.0.0.1 - - [25/Jul/2020 21:37:59] "GET / HTTP/1.1" 200 -
また、curlコマンドではHTMLファイルの中身が帰ってきました。
ブラウザで、http://127.0.0.1:4242/を開いてみると、このようなページも表示されるはずです!
Flaskのルートの定義を増やしてみる
Pythonコードを変更し、別の取得ルートを追加します。今回は、テストAPIキーの公開可能キーを表示させるように変更します。.envファイル内に公開鍵の定義をすることもお忘れなく!
import stripe import os from flask import Flask, render_template, jsonify, request from dotenv import load_dotenv, find_dotenv load_dotenv(find_dotenv()) stripe.api_key = os.getenv('STRIPE_SERCRET_KEY') app = Flask(__name__, static_folder='../client', static_url_path='', template_folder='../client') @app.route('/') def index(): return render_template('index.html') @app.route('/public-keys') def public_keys(): return jsonify({'key': os.getenv('STRIPE_PUBLIC_KEY')}) app.run(port=4242)
再びサーバーを起動し直し、今度はcurlコマンドを少し変更してみます。ルートを指定して実行させます。
$ curl localhost:4242/public-keys {"key":"pk_test_XXXXXXXXXXXXXX"}
うまく、公開鍵が返ってきましたね!
サーバー上の公開鍵を呼び出して、HTTPクライアントを使用するように変更する
先程までPythonのコードを変更していましたが、index.htmlに戻ります。
今までHTMLファイルの中に公開鍵を直接入力していましたが、サーバーの公開鍵を読み取るように変更していきます。今回は、fetchを使っていきます。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <title>Stripe Payment Page Sample</title> <link href="https://stripe-samples.github.io/developer-office-hours/demo.css" rel="stylesheet" type="text/css"> </head> <body> <div id="main"> <div id="container"> <div id="panel"> <h1>Office Hours</h1> </div> </div> </div> <script src="https://js.stripe.com/v3/"></script> <script charset="utf-8"> var stripe; fetch('/public-keys') .then((responce) => responce.json()) .then((data) => { stripe = Stripe(data.key); console.log('Success:', data); }) .catch((error) => { console.error('Error:', error); }); </script> </body> </html>
ここでもう一度サーバーを再起動し、今度はブラウザで表示します。そして、Chromeの開発者ツールを開きます。
Sourceタブを選択し、indexファイルをクリックすると、このように先ほどまで編集したindex.htmlが表示されます。
ここで行番号をクリックすると、デバッガーを更新することができます。すると、クリックした行番号でコードの実行が中断されます。
今回は、20行目の時点でコードの実行が中断されました。なので、サーバー上の公開鍵を読み取る前であり、この時点ではstripeは未定義です。
続いて、20行目の選択を解除しました。右の矢印をクリックし、次のアクションを実行してみます。
dataのところにマウスを当ててみると、key: "pk_test_XXXXXXXXXXXXXX"と表示されました!サーバー上の公開鍵を読み取れているようです。
また、ネットワークタブで見てみると、こちらもpublic-keysのリクエストを表示されていました。
うまくサーバー上の公開鍵を読み取れたところで、次の動作をやってみます。
POSTリクエストを受け取る新しいルートを追加する
タイトル通りです。新しいルートを追加していきます。
再びPythonファイルを開き、このように変更します。
import stripe import os from flask import Flask, render_template, jsonify, request from dotenv import load_dotenv, find_dotenv load_dotenv(find_dotenv()) stripe.api_key = os.getenv('STRIPE_SERCRET_KEY') app = Flask(__name__, static_folder='../client', static_url_path='', template_folder='../client') @app.route('/') def index(): return render_template('index.html') @app.route('/public-keys') def public_keys(): return jsonify({'key': os.getenv('STRIPE_PUBLIC_KEY')}) @app.route('/my-route', methods=['POST']) def my_route(): print('This is `test`: ') print(request.json['test']) return jsonify({'request': request.json}) app.run(port=4242)
新しく追加した関数内では、支払いや顧客を作成するなど、何らかの動きを作成します。しかし、今回はどのように動いているかを知るため、このような形で記載してあります。
再び、curlコマンドで実行してみましょう。サーバーは再起動し、このようにコマンドを実行してみます。
POSTメソッドを渡し、渡すデータは{"test": 123}とします。コンテンツタイプはapplication/jsonを選択します。
curl -X POST localhost:4242/my-route -d '{"test": 123}' -H "Content-Type: application/json"
するとこのように結果が返ってきました。
$ curl -X POST localhost:4242/my-route -d '{"test": 123}' -H "Content-Type: application/json" {"request":{"test":123}}
実際に、POSTメソッドで実行され、指定した通りに出力されています。
$ python setup.py * Serving Flask app "setup" (lazy loading) * Environment: production WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. * Debug mode: off * Running on http://127.0.0.1:4242/ (Press CTRL+C to quit) This is `test`: 123 127.0.0.1 - - [25/Jul/2020 23:00:46] "POST /my-route HTTP/1.1" 200 -
続いて、ページ内にボタンを作成し、そこから操作できるようにHTMLファイルを変更していきます。
ページ内にボタンを作成し、そこから操作するように変更する
"Click ME!"というボタンを追加し、クリックしてからコールバック関数を呼び出されるように設定します。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <title>Stripe Payment Page Sample</title> <link href="https://stripe-samples.github.io/developer-office-hours/demo.css" rel="stylesheet" type="text/css"> </head> <body> <div id="main"> <div id="container"> <div id="panel"> <h1>Office Hours</h1> <button type="submit" id="btn">Click ME!!</button> </div> </div> </div> <script src="https://js.stripe.com/v3/"></script> <script charset="utf-8"> var stripe; fetch('/public-keys') .then((responce) => responce.json()) .then((data) => { stripe = Stripe(data.key); console.log('Success:', data); }) .catch((error) => { console.error('Error:', error); }); var btn = document.getElementById('btn'); btn.addEventListener('click', function(e){ e.preventDefault(); fetch('/my-route', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ test: 'abc123', customer: 'cus_xxx', payment_method: 'pm_card_visa', addless: { line1: 'Main St', } }), }) .then((responce) => responce.json()) .then((data) => { stripe = Stripe(data.key); console.log('Success:', data); }) .catch((error) => { console.error('Error:', error); }); }); </script> </body> </html>
もう一度サーバーを再起動し、ブラウザで確認してみましょう。"Click ME!"というボタンが追加されているはずです!
ボタンが追加されていることが確認できた後で、うまくそのボタンから処理が動くかを確認してみます。
左上の赤丸のついたボタンをクリックし、ネットワークタブをクリアします。(このマーク、海外では禁煙マークのようですね。)
クリアした後、もう一度"Click ME!!"ボタンをクリックしてみます。
見事、my-routeというネットワークリクエストが発生しました!また、こちらのHeaderのRequest Payroadを確認すると、上記で入力したデータが表示されています。
また、出力結果はこのようになっています。
$ python setup.py * Serving Flask app "setup" (lazy loading) * Environment: production WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. * Debug mode: off * Running on http://127.0.0.1:4242/ (Press CTRL+C to quit) 127.0.0.1 - - [25/Jul/2020 23:47:25] "GET / HTTP/1.1" 200 - 127.0.0.1 - - [25/Jul/2020 23:47:26] "GET /public-keys HTTP/1.1" 200 - This is `test`: abc123 127.0.0.1 - - [25/Jul/2020 23:47:44] "POST /my-route HTTP/1.1" 200 -
それぞれ定義したように、メソッドやルートによって出力が異なっています。
ここまで、GETメソッド、POSTメソッドを使い分けてきました。最後にwebhookを使っていきます。
Webhookを使って、IDを取得する
今回は、2パターンの動きによって、表示させるコメントを変更させます。
まずは、支払い目的でイベントが作成された時は、'Payment was created!と表示され、payment_intent.idが出力されます。また、'status'として支払いのステータスや支払い意図のステータスなども表示されるようにします。
次に、イベントタイプがチェックアウトタイプだった場合は、'Checkout Session completed!というコメントとチェックアウトIDが出力されます。
import stripe import os from flask import Flask, render_template, jsonify, request from dotenv import load_dotenv, find_dotenv load_dotenv(find_dotenv()) stripe.api_key = os.getenv('STRIPE_SERCRET_KEY') app = Flask(__name__, static_folder='../client', static_url_path='', template_folder='../client') @app.route('/') def index(): return render_template('index.html') @app.route('/public-keys') def public_keys(): return jsonify({'key': os.getenv('STRIPE_PUBLIC_KEY')}) @app.route('/my-route', methods=['POST']) def my_route(): print('This is `test`: ') print(request.json['test']) return jsonify({'request': request.json}) @app.route('/webhook', methods=['POST']) def webhook(): event = stripe.Event.construct_from( request.json, os.getenv('STRIPE_SERCRET_KEY') ) if event.type == 'payment_intent.created': payment_intent = event.data.object print('Payment was created! ' + payment_intent.id) print('status: ' + payment_intent.status) if event.type == 'checkout.session.completed': checkout_session = event.data.object print('Checkout Session completed! ' + checkout_session.id) return jsonify({'message': 'success'}) app.run(port=4242)
サーバーを再起動させ、Stripe CLIを使用していくつかのテストを実行します。
まずは、stripe listenコマンドを使い、Stripeからローカルへ直接接続させるようにします。そうすることで、パブリックURLにコードを公開する必要はなくなります。
$ stripe listen --forward-to localhost:4242/webhook > Ready! Your webhook signing secret is XXXXXXXXXXX (^C to quit)
次に、stripe triggerコマンドを使ってみましょう。
こちらのコマンドによって、イベントタイプを発生させ、支払いインテントを作成してみます。
$ stripe trigger payment_intent.created Trigger succeeded! Check dashboard for event details.
出力結果を見てみると、支払いができたことがわかります。
Payment was created!pi_1H8pUDKfp1cgOMZLj1JnX6uO status: requires_payment_method 127.0.0.1 - - [26/Jul/2020 00:40:34] "POST /webhook HTTP/1.1" 200 -
リスナーも確認してましょう!
2020-07-26 00:40:34 --> payment_intent.created [evt_1H8pUDKfp1cgOMZLlFSVsRF7] 2020-07-26 00:40:34 <-- [200] POST http://localhost:4242/webhook [evt_1H8pUDKfp1cgOMZLlFSVsRF7]
続いて、チェックアウトイベントを発生させてみます。
$ stripe trigger checkout.session.completed Setting up fixture for: checkout_session Setting up fixture for: payment_page Setting up fixture for: payment_method Setting up fixture for: payment_page_confirm Trigger succeeded! Check dashboard for event details.
どうやら、いけてそうですね・・・!出力結果も見てみましょう!
Payment was created!pi_1H8plQKfp1cgOMZLGZAhaDrM status:requires_payment_method 127.0.0.1 - - [26/Jul/2020 00:58:21] "POST /webhook HTTP/1.1" 200 - 127.0.0.1 - - [26/Jul/2020 00:58:23] "POST /webhook HTTP/1.1" 200 - 127.0.0.1 - - [26/Jul/2020 00:58:23] "POST /webhook HTTP/1.1" 200 - 127.0.0.1 - - [26/Jul/2020 00:58:24] "POST /webhook HTTP/1.1" 200 - Checkout Session completed!cs_test_LC0Y5imfNoG9UXhtoS8QgmRXHKKYMakPxxtpOMOd7zp9WNhMZenrSTBg 127.0.0.1 - - [26/Jul/2020 00:58:24] "POST /webhook HTTP/1.1" 200 - 127.0.0.1 - - [26/Jul/2020 00:58:24] "POST /webhook HTTP/1.1" 200 -
いい感じですね!!最後にリスナーも確認してみましょう!
2020-07-26 00:58:21 --> payment_intent.created [evt_1H8plQKfp1cgOMZLjKuEOCGO] 2020-07-26 00:58:21 <-- [200] POST http://localhost:4242/webhook [evt_1H8plQKfp1cgOMZLjKuEOCGO] 2020-07-26 00:58:23 --> payment_intent.succeeded [evt_1H8plTKfp1cgOMZL6tglivaI] 2020-07-26 00:58:23 <-- [200] POST http://localhost:4242/webhook [evt_1H8plTKfp1cgOMZL6tglivaI] 2020-07-26 00:58:23 --> charge.succeeded [evt_1H8plTKfp1cgOMZLVTJzP4xV] 2020-07-26 00:58:23 <-- [200] POST http://localhost:4242/webhook [evt_1H8plTKfp1cgOMZLVTJzP4xV] 2020-07-26 00:58:24 --> payment_method.attached [evt_1H8plTKfp1cgOMZLO7WmojKH] 2020-07-26 00:58:24 <-- [200] POST http://localhost:4242/webhook [evt_1H8plTKfp1cgOMZLO7WmojKH] 2020-07-26 00:58:24 --> checkout.session.completed [evt_1H8plTKfp1cgOMZLI6shf8Cx] 2020-07-26 00:58:24 <-- [200] POST http://localhost:4242/webhook [evt_1H8plTKfp1cgOMZLI6shf8Cx] 2020-07-26 00:58:24 --> customer.created [evt_1H8plTKfp1cgOMZLcJ2lGKsF] 2020-07-26 00:58:24 <-- [200] POST http://localhost:4242/webhook [evt_1H8plTKfp1cgOMZLcJ2lGKsF]
もっと色々できそう
今回は、Stripe CLIのインストールから実際の決済イベントの作成、Webhookの利用までをやっていきました。
個人的に改めてwebのメソッドの部分やFlaskの書き方などが復習でき、すごくいいコンテンツでした!
まだまだ他の動画もたくさんupされているので、参考にしながら自分でも決済ツールを活用していく方法を考えていこうと思います。
以上、たいがーがお送りしました?