マイブログ リスト

2024年8月15日木曜日

SpringBoot+MysqlのWebアプリをAWSに無料デプロイする

    

 おはようございます。

最近、SpringBootでwebアプリを作っていて、いい感じになりました。
というわけで、どこか無料のサーバーを借りて公開したいという気持ちになりまして。
いろいろ調べてみたところ、WebサーバもDBも、まとめてAWSにデプロイできたので、この場を借りて紹介したいと思います。

まずは、今回作ったwebアプリを軽く説明します。

その名は「キメラ召喚バトル」

入力した文字列から、脳内メーカーの要領でキメラを生み出し、戦わせるという内容。
ユーザー情報や、生まれたキメラの情報はDBに保存しています。

バージョン等は下記の通りです。

  • SpringBoot 3.3.2
  • Java 17
  • MySQL 8


次にAWSについて、荒く短く説明します。

AWS(Amazon Web Service)とは?

いろいろなサービスを提供します。
(多すぎて説明できないので、以下に今回使うものだけ解説します)
  • EC2(Elastic Compute Cloud):サーバを借りられるサービス。今回はWebサーバとして利用。
  • RDS(Relational Database Service):DBを借りられるサービス。今回はMySQLにします。
  • Elastic Beanstalk:簡単にデプロイできるサービス。EC2とRDSの連携を自動的にやってくれる。
ちゃんと知ってる人はツッコミたい部分もあると思いますが、今回の用途だと大体こんな感じです。
上記の利用料金ですが、Elastic Beanstalkは無料、EC2とRDSは1年分の無料枠が用意される設定があり、間違えなければ無料でデプロイできます。

(→私は間違えたので料金請求されました。詳しくは後ほど)


目標設定

AWSには設定項目がたくさんありますが、

「無料で簡単にとりあえずデプロイすること」

を目標にやりますので、細かい部分は触れないようにします。

前提条件

SpringBoot+MySQLでアプリを作り、ローカルで動作できていることを前提にします。

事前準備

Spring側の application.propertiesの設定を変更します。

DBを使っている場合、おそらく下記のようになっていると思います。
(Dockerなどでローカルに建てたDBにアクセスしている想定)


    spring.datasource.url=jdbc:mysql://localhost:3306/my_database
    spring.datasource.username=user
    spring.datasource.password=password
   

それを下記のように追記します。


    spring.datasource.url=jdbc:mysql://${RDS_HOSTNAME:localhost}:${RDS_PORT:3306}/${RDS_DB_NAME:my_database}
    spring.datasource.username=${RDS_USERNAME:user}
    spring.datasource.password=${RDS_PASSWORD:password}
   

意味としては、後に設定するRDSの環境変数を確認し、あればそっちの値を参照するというようなものです。
(ローカル動作の場合には、環境変数が存在しないのでコロン以下のこれまでの定数値を参照できます)

この変更を加えたら、Spring側はjarファイルをビルドしておきます。

AWSの準備

まず登録してログインします。(割愛)

次に、訳あって事前にロールの作成を行う必要があります。
理由は後に説明しますので、とりあえず下記の通りに作成しておいてください。

すべてのサービス > セキュリティ、ID、およびコンプライアンス > IAM を選びます。
(画像右下)

その後、左メニューからアクセス管理 > ロールを選択。
ロール画面右上の「ロールを作成」をクリックして、以下の通り入力していきます。
  • 信頼されたエンティティタイプ:AWSのサービス
  • サービスまたはユースケース:EC2 
  • ユースケース:EC2
「次へ」を押すと、大量のポリシーが表示されているので、検索に「beans」と入力して絞り込み、下記の3つを選択して「次へ」を押します。
  • AWSElasticBeanstalkMulticontainerDocker
  • AWSElasticBeanstalkWebTier
  • AWSElasticBeanstalkWorkerTier


ロール名を「aws-elasticbeanstalk-ec2-role」とし、画面下の「ロールを作成」
これでロールの作成はOKです。

ElasticBeanstalk環境作成

すべてのサービス > コンピューティング > Elastic Beanstalkを選びます。

「環境を作成」をクリックすると、合計6ステップの入力画面に移行するので、
下記のように設定していきます。(デフォルトで良いものは記載省いています)



Step1

  • アプリケーション情報
    • 任意のアプリケーション名を入力
  • プラットフォーム
    • プラットフォーム:Java
    • ブランチ:Corretto 17 (javaのバージョンに合わせる)
  • アプリケーションコード
    • コードをアップロードを選択
    • ラベル名:任意のバージョン名を入力
    • ローカルファイルを選択し、Springのjarファイルをアップロード。

Step2

  • サービスアクセス
    • サービスロール:新しいサービスロールを作成して利用
      • 名前は「aws-elasticbeanstalk-service-role」のままでOK
    • EC2インスタンスプロファイル
      • 作成した「aws-elasticbeanstalk-ec2-role」を選択
※以前はEC2のロールも自動作成されていたらしいのですが、セキュリティの都合でそれはできなくなったそうです。だから、自分で作る必要があったんですね。→
参考サイト

Step3

  • データべース
    • データベースを有効化:true
    • インスタンスクラス (要注意ポイント!!
      • 「db.t3.micro」に変更。
    • ユーザー名
      • 任意で入力
    • パスワード
      • 任意で入力

インスタンスクラスのデフォルトが「db.t3.small」になっていますが、これには無料枠がありません。無料で済ませたい場合は「db.t3.micro」に必ず変更してください。

ユーザー名・パスワードは、環境変数を通じてSpring側に共有されるので、好きに決めて問題ありません。

Step4

  • 容量
    • インスタンスタイプ:t3.microを残して、t3.smallを削除
コチラも、無料枠はt3.microにだけ用意されているので、t3.smallは削除しておきます。

Step5

  • プラットフォームソフトウェア
    • 環境プロパティ
      • PORT:8080を追加

spring側のポートは8080がデフォルト、nginxは5000がデフォルトのため、
spring側がデフォルトの場合は、「環境プロパティを追加」を押して、
「名前:PORT、値:8080」を設定します。

Step6

Step6は確認なので、問題なければ「送信」をクリック。

環境の構築と立ち上げに少し時間がかかります。
終わり次第、ドメインと表記されたURLからデプロイされたWebアプリにアクセスできます。

DBのテーブル作成などは、Spring側で「spring.jpa.hibernate.ddl-auto」を設定しておけば、自動作成してくれます。事前にローカルで検証してください。

DBを手動で操作する場合は、EC2のインスタンスに接続し、そこを足掛かりにしてRDSのエンドポイントに接続する形になります。(詳細は省きます)


無料枠の落とし穴

最後に、無料になっているかを確認してみましょう。
Billing and Cost Management にアクセスし、コストサマリー下部の「請求書を表示」をクリック。そこで下にスクロールすることで、サービス別料金が表示され、何に料金が発生しているかを確認できます。
私は、下記の2点で失敗しておりました。

1.インスタンスの選び方
EC2、RDSのインスタンスの初期値がsmallになっているので、microに変える必要がある。
こちらは上記の手順の中で説明したとおりです。

2.パブリックIPv4
これまでの手順でRDSのインスタンスを作った時、デフォルトで「パブリックアクセス可能」の設定になってしまうようです。
パブリックIPv4は、外部からのアクセスするための設定であり、近年有料化(0.005$/hrs)された機能です。EC2の方には無料枠がありますが、RDSは有料でした。
Elastic BeanstalkではデフォルトでONになってしまってしまうようなので、RDSのインスタンスを直接編集して手動でOFFにしてください。



以上です。
今回の手順では、パブリックIPv4の関係で厳密には完全無料ではなく$0.005くらいはかかってしまうかもしれませんが、許してください。私はよく分からないうちに$9.43の請求になってました。

記事を書いてみての感想ですが、他の人が再現できるように手順を構成するのは、なかなか大変でした。
アプリをデプロイするまでに、ここには書かれていない様々なトライ&エラーがあったわけですが、改めてそれを1つ1つ検証して、必要なものとそうでないものに分けていくという過程を経ることで、AWSへの理解が倍くらいに深まったと思います。
  • Lv0 なにもできない
  • Lv1 よくわからんけどできた
  • Lv2 どうすればできるか分かった(今ココ!)
という感じです。

最後に、作成した「キメラ召喚バトル」のリンクを貼っておきます。

無料枠は1年しかないので、枠が切れる頃には終了する予定です。

2024年7月23日火曜日

透過pngの余白を自動調整するプログラムを作ってみた

おはようございます。
最近、キメラを召喚して対戦するゲームを作っています。

キメラの画像はコチラの透過pngの素材を使わせていただいているのですが、
どうにも余白が不揃い(全体的に右寄り)で、少し扱いづらい。
(でもメッチャ可愛いし使いたい)

なので、余白の自動調整をするプログラムを作ります。

ロジックとしては、

1.画像を読み込む
2.余白を全カットする
3.いい感じに余白をつけなおす
4.出力する

という想定。


というわけで、調査開始。

調べてみると、ちょうどいい記事を発見。
【画像処理】OpenCVを使って画像周りの余白削除(トリミング)を自動化してみた!(1)

pythonは3日くらいしか触っていませんが、何となくopenCVをインストールして、ところどころ修正を入れながら、適当な画像で変換開始!



うん、真っ黒だね!!!


コードを触って確かめていくと、どうやら最初の画像読み込み(cv2.imread)の時点で、真っ黒になっているらしく、透過pngの場合には「flags = cv2.IMREAD_UNCHANGED」が必要だったらしい。


    # 画像の読み込み
    img = cv2.imread(image, cv2.IMREAD_UNCHANGED)


オプションをつけてから、読み込んだ画像をそのまま吐き出すと、無事に透過pngが扱えることを確認!

良かった~、と安心して、

修正したプログラムを再度実行!!




うん、真っ黒だね!!!

今度はなんだ(# ゚Д゚)!?

どうやら、グレースケール・2値化したときに、やっぱり真っ黒になっている。
現状のコードではダメらしい(知らんけど)

ロジックとしては、地と図で2値化できればいいはずなので、ChatGPTに聞いてみる。


(こういう限定的な用途での実装コードは結構頼れるなぁ)


    # アルファチャンネルを抽出
    alpha_channel = img[:, :, 3]

    # 透明部分を黒(0)、不透明部分を白(255)に二値化
    _, binary_mask = cv2.threshold(alpha_channel, 0, 255, cv2.THRESH_BINARY)


上記のコードで、いい感じに2値化できるらしい。

というわけで修正したコードを実行。


余白ゼロ、超コンパクト!
いい感じだ( *´艸`)


最後に、余白をいい感じに追加

余白の追加は、cv2.copyMakeBorder()でできるらしいので、
横は中央揃え、縦は下揃えとして適当に計算するコードを追加。
(めんどくさいので全部直書き)


    #完成画像のサイズ定数
    TARGET_HEIGHT = 1300
    TARGET_WIDTH = 1300
    BOTTOM_MARGIN = 100

    # 余白の計算(bottom固定、左右中央揃え)
    crop_h, crop_w = crop_img.shape[:2]
    bm = BOTTOM_MARGIN
    tm = TARGET_HEIGHT - crop_h - bm
    lm = (TARGET_WIDTH - crop_w)//2
    rm = TARGET_WIDTH - lm - crop_w

    # 余白が足りない場合のエラー表示(要:定数の調整)
    if(tm < 0 | lm < 0):
        print("error:" + image_name)
        continue

    # 余白の追加
    margined_image = cv2.copyMakeBorder(crop_img, tm, bm, lm, rm,
                                         cv2.BORDER_CONSTANT, (0,0,0,0))


実行結果

Before

After




プログラムの完成版はこちら


import cv2
import os
import glob

# 余白を削除する関数
def crop(image): #引数は画像の相対パス
    # 画像の読み込み
    img = cv2.imread(image, cv2.IMREAD_UNCHANGED)

    # アルファチャンネルを抽出
    alpha_channel = img[:, :, 3]

    # 透明部分を黒(0)、不透明部分を白(255)に二値化
    _, binary_mask = cv2.threshold(alpha_channel, 0, 255, cv2.THRESH_BINARY)

    # 輪郭を抽出
    contours = cv2.findContours(binary_mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)[0]

    # 輪郭の座標をリストに代入していく
    x1 = [] #x座標の最小値
    y1 = [] #y座標の最小値
    x2 = [] #x座標の最大値
    y2 = [] #y座標の最大値
    for i in range(0, len(contours)):
        ret = cv2.boundingRect(contours[i])
        x1.append(ret[0])
        y1.append(ret[1])
        x2.append(ret[0] + ret[2])
        y2.append(ret[1] + ret[3])

    # 輪郭の一番外枠を切り抜き(※5pxの余裕を持たせた)
    x1_min = min(x1)-5
    y1_min = min(y1)-5
    x2_max = max(x2)+5
    y2_max = max(y2)+5
    cv2.rectangle(img, (x1_min, y1_min), (x2_max, y2_max), (0, 255, 0), 3)

    crop_img = img[y1_min:y2_max, x1_min:x2_max]

    return img, crop_img

#フォルダ名、拡張子
INPUTDIR = 'images_fot_trim'
OUTPUTDIR = 'trimmed_images'
EXT = 'png'

#完成画像のサイズ定数
TARGET_HEIGHT = 1300
TARGET_WIDTH = 1300
BOTTOM_MARGIN = 100

# 編集後の画像の保存ディレクトリの作成
if not os.path.isdir(OUTPUTDIR):
    os.mkdir(OUTPUTDIR)

# INPUTDIR内の全ての画像に対してループ
for image in glob.glob(INPUTDIR + '/*.' + EXT):

    # 相対パスの部分を削除
    image_name = os.path.basename(image)

    # クロップ
    img, crop_img = crop(image)

    # 余白の計算(bottom固定、左右中央揃え)
    crop_h, crop_w = crop_img.shape[:2]
    bm = BOTTOM_MARGIN
    tm = TARGET_HEIGHT - crop_h - bm
    lm = (TARGET_WIDTH - crop_w)//2
    rm = TARGET_WIDTH - lm - crop_w

    # 余白が足りない場合のエラー表示(要:定数の調整)
    if(tm < 0 | lm < 0):
        print("error:" + image_name)
        continue

    # 余白の追加
    margined_image = cv2.copyMakeBorder(crop_img, tm, bm, lm, rm,
                                         cv2.BORDER_CONSTANT, (0,0,0,0))

    # 切り取った画像を保存
    cv2.imwrite(OUTPUTDIR + '/' + image_name, margined_image)

    print(image_name + " finished")

print("margin adjustment completed!!")



余談

現状の処理ではモンスターの左右端から同じだけの余白を入れているが、
人の目で見て「中央に揃っている」という印象になるためには、画像の重心が中央にくる必要がありそうだ。
画像の2値化はできているので、x軸に沿って画素を数えることで重心を算出すれば、さらに良くなりそう。

2024年2月5日月曜日

Unity公式ドキュメントを通して読んでみた

つよつよエンジニアになるには、公式ドキュメントを読むことが大事だと、誰かが言っていた。

というわけで、仕事で主に扱っている『Unity』の公式ドキュメントを通読してみた。

→実際読んだのはコチラ(2021.3)


サイドバーには23の項目があるが、それぞれの項目に深いネストがあり、機械的に計測すると1960のページがあるよう……。

関係ないところは飛ばしつつ、1か月以上かけて流し読みしたので、役立ちそうな部分や面白かった部分を紹介してみます。


読んでいる際の筆者の指向性は以下の3点。

・Unityならではの仕組みを勉強し直す。

・Unityを使ってAndroid+iOSのアプリを作ることを想定(ゲームに限らず)

・個人的に面白いと思ったことは調べてみる。


では、おすすめのページを以下に記していきます。


プロパティの編集

特にNumeric field expressionsについて。
複数のオブジェクトを規則的に並べたいとき、例えば、position.xにL(0,10)に入力すると、その範囲で規則的に配置してくれる。
手動でUIを均等配置したいとき、覚えておくと使えそう。

ガベージコレクションのベストプラクティス
Unityにおける最適化

Unityのパフォーマンスを上げるうえでの基礎知識。
中でも「文字列とテキスト」の文字列の連結処理に関する注意書きは、自分でも引っかかったので感慨深い。
for文などで、str += "add string" のようなコードをループ処理すると、大量のメモリを消費するため、GCが起きて一瞬止まることになる。
そういうときはStringBuilderを使いましょう。

特殊なフォルダ名

Assets
Editor
Resources
StreamingAssets
など、見たことあるフォルダ名は、Unityの予約語でした。
どういう役割や機能を持っていたのか、
もしも知らずに名前変えてしまうと痛い目に合いそうなので、1度目を通しておくと安心です。

iOS用のプラグインをビルド

iOS用プラグインのお作法について。
プラグインをそのまま使うならいいけど、改造するときなどは最初のとっかかりとして、この辺りを知っておきたい。

スクリプティングの概念

おそらくプログラマの本業にもっとも使う領域
実務経験があるなら、ほとんど知っているとは思うが、
せめてこのカテゴリ以下については目を通しておきたい。

この項目を知らなくてもコードは書ける。
だが、知らずに自分でcommon関数を作らないためにも見ておきたい。
例えば、「ある数値をmin-maxの間に納めたい」という場合、
if(x < min){ x = min; }
if(x > max){ x = max; }
みたいなコードを書くこともできますが、
実はそういうユーティリティは、ここに入ってるので、下記関数で一発。
x = Mathf.Clamp(x,min,max);
(私はこれまで、Clamp関数を何度も自作しました……。反省。)





ー番外編ー
プログラマは触らないかもだけど、個人的に面白かった仕組み2戦。

法線マップ(バンプマップ)

3D空間を扱うとき「ポリゴンが形を作って、テクスチャを張り付けて」というのが基本のイメージだけど、細かい凹凸パターンをポリゴンで真面目に作るとデータ量がマッハ。
大まかな形はポリゴンで作り、テクスチャ側で凹凸をつける仕組みが法線マップ。
ポリゴン上は平面なのに、ちゃんと影ができるぞ!

色空間

リニア色空間とガンマ色空間について。
光の強さを0.0から1.0まで均等に割り振ったのがリニア色空間ですが、
人間の目は、明るさに対してよく反応するため、白が強く見えてしまいます。
そこに補正を加えたものがガンマ色空間です。
「なんか思ったより明るい/暗い」という時には、この辺りが怪しいかも。


以上。

他にもシェーダとか、URPとか、知っておきたい項目はいろいろあるので、
通読でなくても、ちょこちょこ公式ドキュメントを読みましょう。
今すぐどこかで使えるものではないけども、いつかどこかで役に立つはず。
どんな分野にも基礎練習ってあると思いますが、プログラムにおいてはこういうことなのかも?


2020年5月7日木曜日

【RSS】Bloggerの更新情報を表示する

これは、Bloggerの更新情報を取得して、HPにブログの最新記事情報を載せた時のお話です。


ある日の出来事…

*:.。..。.:+·゚·✽:.。..。.:+·゚·✽:.。..。.:+·゚·✽:.。..。.:+·゚·*:.。..。.:+

(会・ω・社) HPに自社ブログの最新情報のせてよ。

(´・ω・`) 御意。

(´・ω・`) ぽちぽち💻

(´・ω・`)つ できました。


変更前
HPにブログ記事を載せる前
変更後
HPにブログ記事を載せた後(iflame)

(会
・ω・社) ・・・なにこれ。
(´・ω・`) iframe に スマホサイトぶち込みました。

(会👁ω👁社) ・・・。
・ω・`) はい。ごめんなさい。ほんと、ごめんなさい。

*:.。..。.:+·゚·✽:.。..。.:+·゚·✽:.。..。.:+·゚·✽:.。..。.:+·゚·*:.。..。.:+

こんにちは👀
月島ファクトリープログラマー(?)のmotchyと申します👶
冒頭の経緯から、BloggerのRSS情報の取得~表示を行いました。

BloggerのRSS情報を取得するのに便利なライブラリに出会いましたので、今回はそちらのライブラリをご紹介します。

rss-parser
https://www.npmjs.com/package/rss-parser

ココのとおりに実装するとアラ便利。
タイトル・日付・リンクがとれるとれる。
ひゃっほー(´・ω・`)🎵

ということで、変更後が下記になります。
とってもスッキリしました。


変更前
HPにブログ記事を載せた後(iflame)
変更後(すっきり)
HPにブログ記事を載せた後(RSS)

現在は、新着5件だけ表示するだけなのですが、そのうち「and more」的なおしゃれな英語使って、10件づつ動的にとれるようにできたらいいなと思ってます。

思った以上にお手軽に対応できたので、WEBサイトにブログ埋め込みたいんじゃーな人は、rss-parser是非使ってみてください。


【参考にさせていただいたサイト】
やっぱりはてなブログを自分のホームページに埋め込みたい
Blogger用のブログパーツを作成する


2019年11月21日木曜日

【JavaScript】コーディング規約を選定した話


初めまして、MtFormです。
今回はVue.jsのプロジェクトのコーディング規約を定めるにあたっていろいろ迷ったお話です。


コーディング規約とは(ざっくり概念)


プログラムって、同じ動作をする場合でも異なる書き方ができますよね。
例えば、
let a,b,c;
と書くか、
let a;
let b;
let c;
と書くか。

このあたりは個人の好みで書き方が分かれてしまうので、複数人でコードを書くとバラバラの記法になって、バグの原因になったりします。
そこで、コードの書き方を統一するためのルールを定めることにしました、これがコーディング規約です。




メジャーなJSコーディング規約


コーディング規約を1から全部決めるのは大変なので、大手の企業が公開しているコーディング規約を使わせていただきます。(場合によってはカスタマイズします)
今回は3つの候補に絞りました。

JavaScript Standard Style


・2015年に提唱された。ESLintのサブセットである(カスタマイズ済のESLint)
・行末のセミコロン禁止のため、人によっては受け入れられない。
※セミコロンを必須とした「JavaScript Semi-Standard Style」もある。

Google JavaScript Style Guide

・ESLintの候補として表示されるほど標準的なスタイル
・AngularやGWTなどを開発しているGoogle製

Airbnb JavaScript Style Guide

・ESLintで候補として表示されるほど標準的なスタイル
・GitHub上で最も人気のあるスタイル(starが90kで第1位、第2位は22.7k:2019年11月現在)
・オープンな議論を通じてスタイルが決定している。
・スタイルについてパフォーマンスに関するエビデンスがある。



選ばれたのはAirbnbでした


どのスタイルガイドもESLint(JSの構文チェッカー)に対応しているのですが、パフォーマンスに対するエビデンスがあるということで、Airbnb JavaScript Style Guide を利用することにしました。

今回のプロジェクトはVue-CLIで作られていたので、導入は次のコマンドでOK
$ yarn add @vue/eslint-config-airbnb -dev
これでESLintの設定がvue.jsとAirbnb JavaScript Style Guideに対応してくれました。

構文チェックは次のコマンド
$ yarn lint --no-fix
試してみると50個くらいエラーが検出されて焦りましたが、--no-fixオプションを外して実行するとlint側で勝手にコードを修正してくれるのでエラーは5個くらいまで減り、
残りも日本語のリファレンスを見ながら修正できました。



苦戦したポイント

個人的に引っかかった部分は次の2点。


comma-dangle

https://mitsuruog.github.io/javascript-style-guide/#commas--dangling

配列の末尾には、カンマが必須らしい!
末尾カンマはJSONだとエラーになるから気持ち悪いなあと思いつつリファレンスを読んでみると、
・末尾コンマはbabelが自動的に消してくれる
・gitの差分がきれいになる
とのこと。
確かに、差分はこっちのほうが断然わかりやすい!
スタイルガイドはgit管理の部分まで視野に入ってるんですね。

BAD
const array = [
  apple,
  banana,
  chocolate
];

GOOD
const array = [
  apple,
  banana,
  chocolate,
];


operator-linebreak

https://mitsuruog.github.io/javascript-style-guide/#variables--linebreak
代入で=の前後に改行を入れてはいけない。
でも、そこを直したらmax-lenの100文字に引っかかってエラーになるんだけど……。
という板挟みの状況に陥ったわけですが、リファレンスにはちゃんと書いてありました。

そういう場合は、「値を丸括弧で囲むこと」だそうです。

BAD
const text =
  'superLongText';

GOOD
const text = (
  'superLongText'
);


結論

Airbnb JavaScript Style Guideは、リファレンスが丁寧!!
以上です、ありがとうございました。

参考サイト


・JavaScriptのスタイルガイドまとめ(おすすめ4選)
・JavaScript Standard Styleのススメ
・セミコロンは省略?人気スタイルガイドに学ぶJavaScriptのコーディング規則
・JavaScriptの有名なコーディングスタンダードまとめ
・ESLintをAtomに導入し、Reactの構文にも対応したAirbnbのJSスタイルガイドを使う


2019年6月13日木曜日

【facebook】Messengerプラットフォーム


ある日の出来事…
*:.。..。.:+·゚·✽:.。..。.:+·゚·✽:.。..。.:+·゚·✽:.。..。.:+·゚·*:.。..。.:+

インスタントゲームを作ったはいいが、ゲームのリテンションが低すぎてつらいよお…あれ、facebookさんがコッチを見ている…(´;ω;`)ウッ

(face・ω・book)つ …スッ「再エンゲージメントのためにゲームボットを設定する

(´;ω;`)!!

*:.。..。.:+·゚·✽:.。..。.:+·゚·✽:.。..。.:+·゚·✽:.。..。.:+·゚·*:.。..。.:+

こんにちは👀

月島ファクトリープログラマーのmotchyと申します👶

冒頭の経緯から、インスタントゲームでボットを使用したいと考え、facebookのMessengerプラットフォームを使用しました。

今回は、インスタントゲームでMessengerプラットフォームを使用するまでの過程について投稿させていただきます。
以下、3つのステップでご説明します。

  1. Facebookページを作成しよう!
  2. Webhookを設定しよう!
  3. Messengerプラットフォームを使えるように申請しよう!

1.Facebookページを作成しよう!
ゲームボットを使用するには、インスタントゲームと連動するFacebookページが必要になります。なので、まずはゲーム用のページを作成しましょう😃

2.Webhookを設定しよう!
ゲームとFacebookページを連動させることによって、メッセンジャーを使用してメッセージの送受信を行った際、バックエンドにHTTPコールが送信されます。
サーバーのエンドポイントをページのイベントと紐づけるために、Webhookの設定をします。
facebookのチュートリアルは正直わかりにくかったので、わたしは下記サイトを参考にし(て、インフラの方に設定してもらい)ました。

3.Messengerプラットフォームを使えるように申請しよう!
Messengerプラットフォームを使用するには、pages_messagingというSend APIの承認が必要になります。アプリダッシュボードの「Messengerのアプリレビュー」から簡単に申請することができます。

上記の手順を行うと、プレイヤーがインスタントゲームを終了するたびに、「2.Webhookを設定しよう!」で用意したサーバーにPOSTリクエストが飛んできます。
このPOSTリクエストから、プレイヤーにメッセージを送信するためのPSIDを含んだ下記のユーザー情報が取得できます。

これでユーザーにゲームやれやれってメッセージを送り放題だ👿👿👿
わーい👿👿👿

…は、facebookさんは許さない。もうひと手間。

設定は3ステップで終了ですが、ボットを受け取るか受け取らないかはユーザー次第です。

2019年1月以降の新規ユーザーについては、ユーザーボットがデフォルトで無効に設定されるようになりました。
そのため、インスタントゲームに、ゲームボットを承認してくれるかユーザーに問う処理を実装してください。


★最後に
*:.。..。.:+·゚·✽:.。..。.:+·゚·✽:.。..。.:+·゚·✽:.。..。.:+·゚·*:.。..。.:+

Messengerプラットフォームの対応については、設定のフェーズでかなり時間がかかった印象だったことから今回の投稿内容に至りました。

ただ、思い返して書き起こしてみたはいいものの、そんなに難しいことしてないので、ちょっと悔しいです。(facebookのチュートリアルきらいだ…(´・ω・`)ボソ。)

また何か新しい機能を使用した際には、ブログ更新したいと思います。

以上です。
最後まで読んでいただき、ありがとうございました。

*:.。..。.:+·゚·✽:.。..。.:+·゚·✽:.。..。.:+·゚·✽:.。..。.:+·゚·*:.。..。.:+


2018年12月4日火曜日

【facebook】インスタントゲーム広告実装について


こんにちは👀
月島ファクトリープログラマーのmotchyと申します👶

このたび、弊社で作成したfacebookインスタントゲームに広告表示対応を行いました。
今回は、この対応に伴い使用したAudience Networkや広告表示の実装方法についてご紹介させていただきます。


*:.。..。.:+·゚·✽:.。..。.:+·゚·✽:.。..。.:+·゚·✽:.。..。.:+·゚·*:.。..。.:+


★広告を表示したゲーム


弊社では現在、「Space Evaders」「Fruit Paradise」と2つのインスタントゲームをfacebookにあげております。

今回は、「Fruit Paradise」に広告表示対応を行いました。

※ゲームをプレイしてみたい人はコチラからドウゾヽ(゙·ω·゙)人(゙·ω·゙)ゝ
「Space Evaders」
「Fruit Paradise」

※ゲームの開発記が気になる方はコチラをドウゾヽ(゙·ω·゙)人(゙·ω·゙)ゝ
「Space Evaders」
「Fruit Paradise」


*:.。..。.:+·゚·✽:.。..。.:+·゚·✽:.。..。.:+·゚·✽:.。..。.:+·゚·*:.。..。.:+


★インスタントゲームの広告の種類


2018/12現在、facebookのインスタントゲームでは、下記の種類の広告を配信することができます。今回弊社では、リワード動画の表示対応を行いました。

・インタースティシャル動画広告
 スキップ可能、完全視聴で収益発生

・リワード動画
 スキップ不可能、完全視聴で収益発生


*:.。..。.:+·゚·✽:.。..。.:+·゚·✽:.。..。.:+·゚·✽:.。..。.:+·゚·*:.。..。.:+


★開発手順


広告配信はfacebookのAudience Networkを使用して対応しました。
そもそも、Audience Network・・・って、ナニ_φ(·ω·` )?
という感じですが、すごくざっくりいうと、facebookが提供している広告配信サービス的なものな認識。

対応は、下記URLの手順と要件を参考に実施しました。
「Audience Networkでインスタントゲームの収益化を始める」

以下、上記の手順に沿って行った実装~リリースについて、順を追ってご説明させていただきます。

1.Facebookアプリにインスタントゲームを設定


今回は、既存のゲームに対して広告対応を行うため、ここはパス。
まずはゲームを作ってねということです。

2.アプリダッシュボードからAudience Networkの利用を開始


「Audience Networkでインスタントゲームの収益化を始める」の「Audience Networkの利用開始」という項目に、とっても丁寧に書いてくれてます。
ただ、アプリ管理者の権限がないと実施できない項目なので、この設定ができないときは、権限を付与してもらうか、アプリ管理者に実施してもらいましょう。
アプリを作った本人ならば大丈夫です。

3.収益化マネージャを使用して、Audience Network広告の配置を作成


作成方法や各項目の役割については下記を参照してください。
「広告スペースについて」
「広告スペースを作成する」

4.支払い情報の追加


言葉のままです。Audience Networkからの支払いを受けるために必要な設定項目です。
納税者識別番号や納税関連書類について入力や提出が求められるので、企業で使用する場合は、偉い人に設定してもらうようお願いしましょう。
「支払い情報の追加」
ここまで設定をすると、実装後に広告が見れるようになります。

5.インスタントゲームのソースコードに広告配置を統合


3 の工程で設定される配置IDを使用して、広告配置の実装を行います。
下記のURLから、実装するにあたっての前提条件の記載やデモソースが見れるので、こちらを参考にするといいと思います。
「Monetizing your game with Audience Network」

実装工程は、インスタンスの生成⇒ロード⇒表示 これだけです。
なお、わたしは、下記リファレンスの例に沿って実装しました。
「API Reference v6.2」

2019/6/12:追記
下記状況を考慮した実装について
⓵PCから広告表示をしようとした場合
後続の「6.テスト」にも記載していますが、インスタントゲームの広告はPCでは表示できません。この場合、getSupportedAPIs( ) の引数に広告取得APIを渡し、広告を取得するAPIがサポートされているか否かを確認する必要があります。
サポートされていない場合(PCの場合)にはそれ相応の実装を行う必要があります。
わたしは、PCからは広告は見れない旨のメッセージと、通常プレイボタンを表示する対応をおこないました。
新規で作成したユーザーで広告表示をしようとした場合
facebookでは、ユーザー情報等からターゲティングを行い表示する広告を配信しています。そのため、facebookに登録したばかりのユーザー等はターゲティングが行えず表示する広告を取得できません。
この場合は「表示できる広告がありませんよー」という例外がスローされます。
わたしは、表示できる広告がない旨のメッセージと、通常プレイボタンを表示する対応をおこないました。

「Monetizing your game with Audience Network」の、「ベストプラクティスとトラブルシューティング」の対応をちゃんとしていれば、エラーハンドリングについて改めて意識することはないですが、ターゲティングができていないユーザーに対して例外がスローされることにちょっと感動したので、追記させていただきました。
いじょ。

6.テスト


「Monetizing your game with Audience Network」にも記載がありますが、広告表示のテストは、デスクトップやエミュレーターでは実施できません。
そのため、広告表示のテストは、モバイルデバイスからテストを実施する必要があります。
   
【課題】
上記に伴い、テスト時は修正した資産のアップロード⇒テストを繰返し実施していたのですが、修正がはいるたびにアップロードをしたため、必要以上にバージョンがあがってしまいました。
対象のアプリに紐付くテスト用のアプリを作成してみましたが、テスト用のアプリIDに対して資産をアップロードしても、紐付いている本番用のアプリのバージョンも一緒にあがってしまいました。
今回は暫定対応として、改修対象のアプリと紐付かないまったく別のアプリをテスト用に登録し、広告表示のテストはそちらでおこないました。

んー、まわりくどい・・・めんどくさい(´·ω·`)

テスト方法については、もっといい方法があると思うのですが・・・模索中です。
いい方法をご存知の方がいらっしゃったら、コメントをください・・・(´·ω·`)
バージョンをバカバカ上げるような修正をしなければいいじゃないか。。。というコメントはご勘弁ください・・・( ノД`)ワーン。

7.リリース


ここで少し要注意。
広告の審査とアプリの審査は、別で実施しているようです。
facebook for developersの申請が通っても、facebook for businessのレビューが承認されないと、広告の表示はされません。


*:.。..。.:+·゚·✽:.。..。.:+·゚·✽:.。..。.:+·゚·✽:.。..。.:+·゚·*:.。..。.:+

★全体を通して


初めてだらけだったので、時間もかかり、戸惑う部分も多かったですが、振り返ってみると、広告表示って思ったよりも簡単にできるんだなと思いました。
小規模ゲームでも、さくっと広告がつけられるのはとっても魅力的なサービスだなと思います。
設定がすこーしだけ面倒ですが、実装自体は簡単なので、インスタントゲームを作るならば、広告表示は入れたほうがいいと思います。

今後は、より効率よく収益が上げられるように、収益化マネージャーの設定等もお勉強してみたいと思います。(いまはほとんどデフォルト)
なにか面白いことがあったら、ブログに書こうかな。


以上です。
最後まで読んでいただき、ありがとうございました。