- 投稿日:2020-09-18T17:01:49+09:00
〇〇のセールを見逃さないサービス作りました。【AV半額オブザーバー】
はじめに
みなさんは、AVのセールを見逃して後悔した事はありませんか?
私にはあります。と言うことでAVの割引を見逃さない為のサービスを作りました。具体的に言うと、割引になってる作品を人気順の一覧で見れるページと、会員登録から『指定の作品が割引になったとき』のみ通知を送るページを通して、より便利な購入体験を提供します。
https://hao.japaneast.cloudapp.azure.com (18歳未満はアクセス禁止です)
出来ること
①割引作品を人気順に表示
これが一応メインコンテンツですね。紳士淑女のみなさんはFanzaから定期的に似たようなメールが届くかもしれませんが、メールをいちいち確認するのって面倒じゃないですか?
しかもキャンペーンページは一時的な物なのでブックマーク出来ません。なので割引作品の一覧を毎日更新し、人気順に表示するリストを作成しました。両サイドにはリストの前後40件の作品画像を背景として使用しています。一覧性という面ではかなり拘った仕様なので、使っていただけると幸いです。
②女優別で割引作品をリスト化
例によって黒塗りの多い画面ですが、女優さんの名前を登録すると出演作品が割引になった場合自動でリストに表示する事ができます。お気に入りの女優さんの作品がセールになってないか確認したい。そういう時にぜひご活用ください。
③マイリストを設定
URLを直接入力することで監視リストに動画を追加することができます。Fanzaにも似たような機能はあるのですが、ポチポチって押してるとすぐリストの件数が膨れ上がりがちなので、「これぞ!」と思うお気に入り動画の記録にオススメです。
開発の舞台裏
「個人開発だし、どうせフロントはJSで書くからNode.js使おう」
技術選定に関しては多分ここから始まったと思います。PHPという選択肢もあったのですが、今更感が強かったので今回は不採用。逆にフロントは詳しくなかったので資料が充実しているVue.jsを選びました。インフラはKeyVaultなる素敵機能を使ってみたかったのでAzureです。
(大正義KeyVault君、実際これが無ければ普通にAWS選んでた気がする)
大まかな開発の流れとしては
①設計
②バッチの実装
③バックエンドの実装(ルーティングとか主要なAPI)
④フロント(htmlやVue.js)の実装
⑤バックエンドの修正(フロントを実装した事でバグや考慮漏れが多数発覚)
⑥デザイン
⑦インフラ周りの設定とか
⑧リリースという感じだったような気がします。一応番号は振りましたが④⑤⑥に関しては「プロトタイプが欲しい」「今日はデザインの気分じゃない」「あれ実装してないじゃん」みたいな理由で結構反復横跳びしてますね。
まあ時系列順に振り返ると、設計に関しては結構グダりました。
というのも、今までオープン系のアプリ開発しかやったことがないし、ましてや設計なんて初めてなので、「DBから作ろうぜ!」って発想になる訳です。まあこれも依存の方向から考えると一定の合理性はあるのですが、そうなると問題なのが「アレこうした方が良くね(仕様変更)(仕様漏れ)」からの「DB設計直さなきゃ駄目じゃん……」からの「既存設計に引きずられて苦しい………(死)」となる黄金パターン。今回はどっぷり嵌りました。
ねー、WebバックエンドのDB設計なんて機能が増えれば当然カラム増えるのになんで最初にやったんだろね。
今から思えば裏側はモックに留めてフロントから仕様をガチッと固めてしまうのが最速な気がしますが、その反省は次回に活かすとします。
そしてある程度設計が固まってから実装に取り掛かったのが5月の頭ですね。
この段階ではフロントエンド全然わからんマンだったのと、バックエンドもいきなりWebサーバ書くのは脆弱性作りそうだったので消去法でバッチから作り始めました。(その結果、後で半分以上書き直しになった)特に大変だった所は無いと思いますが、JSをガッツリ書くのは何気に初めてだったので、バッチ処理全体を書くのに丸々1か月も掛けてしまいました。Promiseが全然分からなくて死んでたり、コードのどこが非同期処理で動いてるのか今一掴めずに「forが動かねぇ……」って絶望してたのも今となっては懐かしい思い出です。
6月は丸々ルーティングとHTML、ログイン認証の実装に使いました。
後述しますが、特にログイン機能の実装は結構大変でした。まず認証が通らなかったり、逆にどんな値でも通ったり、通ってもセッションを保持できなかったりとてんやわんやです。SNS認証とか実装しなくて本当に良かった7月はようやく機能とデザインの実装です。
CRUDとかバックエンドの側の実装は6月から並行でちょいちょい着手してたのですが、いざ動かしてみたら変な所で止まったりバグッたりと散々だったので、実質書き直しになりましたね。デザインに関してはTailwindCSSを使って見たのですが、今思えば教養として素のCSSを書いたほうが良かったかもしれません。TailwindCSS、作る時は便利なんですがHTMLが汚くなるし、
sm:invisible
するとSafariで表示崩れるし、運用フェーズだと都度都度ビルド要るしでなかなか面倒。
8月前半は細かいデバッグや表示の追加をメインに行いました。レスポンシブの対応とかもそうですが実際使ってみると思ったより使い勝手微妙だなみたいな感じになったので位置を修正したり、ツールチップを実装したりしました。表示に関してはあまりゴテゴテするのも良くないかもとか思ったけど、余白を生かしたデザインとかアレはアレで高度芸能(素人は手を出さない方が無難)なので、今回は出来るだけ詰め込んでみました。次回作はもっとゴリゴリに表示を動かしたいを思います。8月後半は予定を繰り上げてAzure上にVMを立ち上げ、テスト環境を構築。
まあ私のTwitter見てる方は既にご存知かもしれませんが、詰まりに詰まり散らかしました。うん、何というか3ヶ月半掛けて作った動くはずのアプリが突然動かなくなったら焦るよね。
まあ原因の9割はmysqlのせいだったんですけど、テーブル名にキャメルケースを使ってはいけない。大事な事なのでもう一回言うけど、テーブル名にキャメルケースを使ってはいけない。Do you understand?
データベースオブジェクトの命名規約9月はほぼ消化試合でしたね。本番移行って言っても丸々同じ手順を繰り返すだけですし、まあ強いて言えば、ここに来てダダ下がりしたモチベの維持が大変でした。リアルでも色々忙しかったのもあり、ここの工程はボリューム的には正味一週間ぐらいで終わりそうな感じだったのですが、何やかんやで丸1か月掛かりました。
ちなみにAzureのVMやKeyVaultで幾らか詰まると思ったのですが、その辺りは意外にも公式ドキュメントだけですんなり構築できました。流石マイクロソフト謹製のPaaSですね。ネタに出来なくて残念です
出来なかった事
・TypeScript
・Nuxt.jsとかのナウいフレームワーク
・綺麗なコード
・自動テストとか
まあ今回の1件でJavaScriptとSQLさえ書ければ全てが解決するという事を証明してしまったので、学習意欲はわりかし低めです。下2つは時間があったら極めたいなと思いつつ「時間があったら」などと逃げ口上かましてる時点でやる気無いんだよなぁ みつお
それにTypeScriptは記法の癖が強いし、Nuxt.jsも何というか色々勝手にやってくれる代わりに覚えること多いしで、個人的にあんまり好きじゃないです。あときれいなコードは目指したかったんだけど、それが開発速度を担保してくれるかって言うとそうでもないので、動いて読めてそこそこ整理されてればいいかって感じに妥協しました。
一つ反省点を上げるとすれば、自動テストを導入するかどうかをさておいても、テスタブルな実装は目指すべきだったなと思います。具体的な所で言うと、APサーバの実装で内部の処理とレスポンスの返却を同じメソッドに書いてしまった結果、単体でテスト出来ないコードが生まれたりって感じですね。インターフェースいちいち考えるの面倒くさかったとは言え、最後のテストが地味に大変だったので、ここはもうちょっと拘っても良かった気がします。
頑張った点とか
①自動ログイン
これは今日日どんなサイトでも付いてる機能なのでどうにか実装したかったのですが、結構手間取りました。というのもnode-modulesにあるpassport君は自動ログインをサポートしてないので、認証の発火とCookieへの読み書き、ハッシュ化したトークンの生成や管理は自前で実装する必要があります。
(あれ?これもう自分でミドルウェア実装したほうが早くない?)まあ最終的にランダムかつ一意なハッシュを定期的にセットし、passport経由で認証を通すことに成功しました。まあメッセージ返す部分は結局解決できなくて、ログイン認証の前に「ログイン認証のメッセージ」を返すAPIを叩くことで解決しました。悔しい……
②女優検索DBはmysqlなのですが、流石にLike検索で返すのは遅い&不便なので、ngramによるフルテキストキーを貼ってあいまい検索を実装しています。細かい調整とかは出来なかったのですが、まあまあ実用範囲かなと、本当はサジェストとかやりたかったんですが、それは次回の宿題ですね。
③ツールチップ
これはログイン先にあるマイページでの演出なのですが、URLや縮小画像にマウスカーソルを持っていくと近傍にオリジナルのパッケージ写真を表示するようになっています。実装としてはシンプルにJSでイベントを発火してdiv要素の内容とCSSを都度都度DOMで書き換える感じです。ただ何故かz-indexが適用されず、悩みに悩んで一日詰まった結果、div要素の位置を5回ぐらい変更してようやく適応される位置を見つけることが出来ました。
④reCAPTCHA
このサービス、実はそこそこセキュリティにも力を入れていて、ログイン画面にはDDoSにも対応したBOTの検出機能を実装したりしています。ただ登録画面に関しては人とBOTを区別するのは難しいのでreCAPTCHAを使用しました。セキュリティ上バックにも実装が必要って言うのは分かりますが、フロント側で一度作り込んだJSを書き換えるのは結構ヒヤヒヤしました。登録時に実際のURLが必要ですが、実装するなら最初からテンプレートを組み込んでコメントアウトしておいた方が良いです。
ちなみにバックの実装はこんな感じの関数を書いて適宜叩けばOKなので意外と楽でしたね。reCAPTCHAfunction reCaptcha(token){ if(!token){ console.log("Error token is null"); return false; } let options = { url: 'https://www.google.com/recaptcha/api/siteverify', method: 'POST', form: { secret:/*シークレット*/, response:token }, json: true } request(options, (error, response, body) => { if (error) { console.log(error); return false; } // 閾値により判定する if (body.score < 0.5) { return false; }else{ return true; } }); }
⑤Slackの活用
通知の送信用として使用しているG Suiteには2000通/日の送信制限があります。まあ制限にかかることは無いと思いますが、容量を無駄に削るのも嫌なので、自分宛ての通知(お問い合わせとか鯖の情報とか)はバックエンドからSlackAPIを経由して送信するようにしています。これが中々便利で、メールと違ってスマホにプッシュ通知が出るので通知を見逃すという事もありません。これから個人開発を始めようという方はぜひ使ってみて下さい。
詰まった所とか
①Promise
最初はメソッドチェーンとか面倒臭いなって感想しか出てこなかったんですが、短い関数でちゃっちゃっとPromise返したら、async/awaitで普通に同期実行できると知ってすぐに手のひらクルーしました。
便利ですねこれ。………………え?まだコールバック関数とか使ってる人居るんですか?
Promise自体の説明に関してはやめ太郎さんの書かれた記事が日本一分かりやすいので是非どうぞ
4歳娘「パパ、Promiseやasync/awaitって何?」〜Promise編〜
②passport前述の通りログイン関係でPassportを使っているのですが、ログインした後セッションを有効化出来ないという現象が発生しました。具体的にはユーザー情報が入ってるはずのreq.userが何故かundefinedのまま……………
まあ結論から言えば犯人はAxios君でしたね。axios.defaults.withCredentials = true;を適当な所に書いてあげれば、認証情報を含むCookieをサーバに送信できるようになります。
③Cheerioスクレイピングと言えばCheerio君。ただコイツには結構苦労させられました。結論から言えば近傍5つ以内にClassが振ってない要素を取得するには新卒Sierを秒で退職してMicrosoftに就職を成功させるぐらいの豪運を必要とします。実質砂金掘りですね。
必要な要素が取れないときは闇雲に試行回数を増やすよりも、別のページから同じ情報が取れないか探したり、PCの電源ケーブルを抜き差ししたり、懐かしのゲームを楽しむのが肝要です。実際私も自棄になり、開発をほったらかして一日中エスコン6をプレイしていたら何故か要素が取れない問題が解決しました。
あと
each
で要素の取得をぶん回すとき、attr("href")
は先にfind("a")
を指定しないとちゃんと拾ってくれないので気を付けましょう。
④Vue.jsまあこれに関しては後で別の記事に起こそうと思いますが、特に苦労した部分だけでも紹介したいと思います。
・v-modelの変更を監視してイベントを発火したい。まあ誰しも一度はやると思いますが、
<input v-model="hoge" @change="huga()">
みたいな感じのやつです。
ちなみに↑のコードはv-model
と@change
でイベントリスナーが二重になってるので@change
は動きません。
一応公式ではv-modelをv-bindに書き換える方法が推奨ですが、v-bindだと何故かバインド出来ない現象が発生したので別の対策を講じます。(←今思えば普通にタイポだった可能性ある)対策、new Vue()の時にmodelのリスナーを追加する
let vue = new Vue({ el:'#app', data:{}, watch:{/*監視したいv-modelの名前*/:function(){ //変更があった時に走らせたい処理を記述 }} });
・new Vue()の中からMethodsのメソッドを呼びたい。当然ですが
this
が必要です。この例に限らず、Vueでundefined
って怒られた時はまずthis
の付け忘れを疑いましょう。
⑤LinuxこれLinux(Ubuntu)君は全然悪くないけど、環境移行する時に結構詰まったので覚え書きを残しておきます。
まずアプリを雑にインストールするとWindowsとバージョンが違うという事を肝に命じておくべきだと思う。Node.jsとか結構顕著で、何と12.18.3 LTSだと
try{hoge()}catch{/*何もしない*/}
みたいな変な文法のコードを書いても普通に動いたりする。動くなやあと一度やった変更はメモったほうが良いですね。ミスした時もリカバリが効きやすいのと、環境立て直す時「何かCronの動きがおかしい」→「時刻設定がグリニッジ標準時でした」とかやりがちなので対策したほうがベターです。
⑥mysqlリピートアフターミー、テーブル名にキャメルケースを使ってはいけない。
何故かって言うと雑にmysqlをインストールした時、WindowsとLinuxでバージョンが違うから。8.0(win)だと
CREATE TABLE
の時に名前を全部小文字にしやがるしてくれるけど、5.7(Lin)だと普通に通る。なので突然テーブルが見つかりませんとか言われて死にます。死にました。あとLinux版は権限周りが固いっぽいので、雑にパスワードを設定すると
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
で怒られます。良い子のみんなはRSA2048に記号挟んだパスワードをぶち込んでいこうな!
まとめ
作り終わった今だから思うのですが、半分以上無駄な機能を作ってしまった気がします。作った当初はDMMにお気に入り機能があると知らなかったのでガッツリ作り込む気満々でしたが、ただ単に「半額〇〇の一覧をブックマークできるサイト」というコンセプトならログイン機能とか付けずにトップページだけ作って2~3ヶ月でリリースするのが最適解でした。
まあそのおかげでCRUDの実装とかも出来ましたし、Linux触ったり、SQLをガッツリ書く経験も積めたので結果オーライだと思います。これで私も真にフルスタックエンジニアの仲間入りですね。
まあそんな与太は置いておくとしても、やはり個人開発に関して大切なのは『モチベの維持』と『まあいいかの精神』だと思います。というのも納期が無い開発で仕様なんて固まってる訳ないですし、設計はグダグダ、人手は足りてないといった具合に個人開発はおおよそ炎上or凍結プロジェクトの前提条件を満たした状態でスタートします。今回モチベの維持としては主にGitHubを利用しました。定期的にPushしないと芝が枯れるという危機感は進捗にかなり貢献してくれますね。後はまあ今のバイト先が普通にブラックなのでそこから脱出したいという思いも地味にあったりします。
『まあいいかの精神』と言うのは、一定以上のクオリティを求めない事ですね。今回実はパフォーマンスに関しては結構ザルでして、VMのスペックに関しては同接100~200ぐらいしか見込んでないですし、アプリ自体もDBにインデックス張ったぐらいで計算量の最適化はやってなかったりと中々お粗末な仕上がりです。
ただ、同人界隈でも「出ない神本より出る糞本」という言葉がありますし、「それでも要件は満たすから良いだろ」ぐらいの割り切りが肝要だと自分は思います。それに今回アプリを作ることで、間違いなく自分の実力は伸びました。実を言うと9月にモチベが枯れかけた理由も半分以上それで、急に実力が上がったせいか「今更これを公開するのか?」みたいな躊躇いと気恥ずかしさを乗り越える必要がありました。ここだけの秘密ですよ。
あとここまで辿り着けた要因の一つとして、Twitterで進捗を呟く度に「いいね」を下さるファボ魔(約2名)の存在も大きかったと思います。多分アレが無ければ8月ぐらいで折れていた疑惑ある。大変感謝です。
それとこれは余談なのですが、次回作については既に設計が上がっています。詳しいコンセプトはまだ秘密ですが、今度こそきっと皆様の度肝を抜くサービスをお届け出来ると思います。それではまた次回、goodbye
- 投稿日:2020-09-18T16:29:02+09:00
Twitter広告APIを利用してキャンペーンを作ってみる その4~Tiwtter広告APIのAPI申請編~
経緯
私が所属している会社では待ラノという小説投稿サイトを運営しています。
待ラノではオススメ小説のランキング上位5作を定期的にTwitterの公式アカウントで紹介しています。
紹介された小説をTwitter広告のキャンペーンを利用してプロモーションをしようってなりました。そもそもTwitter広告のキャンペーンって何?
Twitter広告のキャンペーンですが、簡単いうと1日にかける予算や期間内にかける総予算を指定して、Twitterに広告を出す機能です。
Twitter広告APIでキャンペーンを作る理由
1つのキャンペーンで複数のツイートをプロモーションする場合、1日にかける予算を一気に消化されてしまいます。
しかもどのツイートにどれだけ予算が消化されているかがわかりません。
そのため、1つのツイートに1キャンペーンを紐付けることで消化される予算の見える化を行うことになりました。ただ手動でTwitterの広告コンソールから、1ツイートに1キャンペーンを毎回作ることになると結構手間です。
というわけで、Twitter広告APIを利用して動的にキャンペーンを作成することになりました。Twitter広告APIでキャンペーンを作成するためには
以下の手順が必要です。
- Tiwtterアカウントを作成する(省略)
- Tiwtterアカウントにメールアドレスと電話番号を設定する(省略)
- TiwtterAPIの利用申請をする
- TiwtterAPIのAPIキーとトークンを取得する
- TiwtterAPIを利用してツイートをする
- Tiwtter広告APIの利用申請をする ←イマココ
- Tiwtter広告APIでを利用してツイートを使ったキャンペーンを作る
今回は6の【Tiwtter広告APIの利用申請をする】について説明していきます。
本稿は、その1とその2が完了している前提で記載されております。1.Twitter広告APIガイドのページ(英語)にアクセス
まずはTwitterにログインした状態で、Twitter広告APIガイドへアクセスします。
注:日本語のTwitter広告APIガイドは存在しておりますが、申請フォームがバグっているせいでチェックボックス等が正しく押せない状態になっておりますので、こちらの記事同様に英語ページで申請を行ってください。2.「Apply for Ads API Access」ボタンをクリックします。
3.英語で申請フォームに回答していきます。
まずは「基本情報」です。
以下の項目を入力していきます。
- 「Company(企業名)」
- 「Country(国)」
- 「State/Province(都道府県)」
- 「City(市)」
「Company Handle(Twitterの企業アカウントID)」
■その2で作成したアプリのIDを取得します。
「developer.twitter.com/en/apps/」のリンクをクリックしてください。
そうすると開発ポータルに遷移するので、対象のアプリの「設定(歯車)」ボタンをクリックしてください。
「アプリID」が表示されますので、先程の入力フォームに記載してください。
「I acknowledge that the provided app will be capped at 5 tokens for the Developer phase.(指定されたアプリは開発者フェーズについてトークンが5つまでに制限されることに同意します。)」
次に「代表連絡先」です。
以下の項目を入力していきます。
- 「First Name(名)」
- 「Last Name(姓)」
- 「Title(役職)」
- 「Job Function(職務)」
- 「Job Level(職務レベル)」
- 「Email(メールアドレス)」
- 「Phone(電話番号)」
次に「Twitter広告APIの利用目的」です。
「Of the following, which best describes your business?(次のうち、御社の事業について最もよく当てはまる説明はどれですか?)」
「Of the following, which best describes your business?(次のうち、御社の事業について最もよく当てはまる説明はどれですか?)」
「...tell us about your business(御社のビジネスについて教えてください)」
「...what do you plan to build on the Ads API?(広告APIに何を構築する予定ですか?)」
「...describe your unique differentiators in the Ad Tech ecosystem(広告テクノロジー市場での御社の差別化要素について説明してください)」
「Do you have API partnerships on any other platforms?(Twitter以外のプラットフォームでAPIパートナーシップを組んでいますか?)」
次に「顧客情報」です。
「Where are your customers based? Please indicate your top market(顧客基盤はどこにありますか?御社の最大市場を教えてください)」
「Which industries are most common among your customers?(どの業界の顧客が最も多いですか?)」
「Tell us more about your strategic customers/advertisers(御社の戦略顧客/広告主について詳しく教えてください)」
次に「商品情報」です。
「Of the following campaign objectives, where is your offering strongest?(次のキャンペーン目的のうち、御社の商品が最も優れている部分はどこにありますか?)」
「How is your product distributed?(商品の流通方法を教えてください)」
「List the languages that your product supports(商品がサポートする言語を列挙してください)」
「Does your product currently use or plan to utilize any other Twitter APIs?(御社の製品にほかのTwitterAPIを現在使用していますか?または、今後、利用する予定がありますか?)」
「Do you license data from Twitter's Data APIs?(TwitterのデータAPIから取得したデータをライセンスの対象にしますか?)」
次に「Twitter広告API制約」です。
以下の項目はラジオボタンにチェックしてください。
- 「Yes, I agree to the terms of the Twitter Ads Products and Services Agreement.(はい、Twitter広告商品およびサービス契約書の条件に同意します。)」
- 「I acknowledge that by agreeing to this Twitter Ads Products and Services Agreement, I agree to the Twitter Privacy Policy, Terms of Service, Developer Agreement and Policy, Trademark and Brand Guidelines, and applicable Twitter Master Services Agreement.(このTwitter広告商品およびサービス契約書に同意することにより、Twitterプライバシーポリシー、利用規約、開発者契約およびポリシー、商標およびブランドガイドライン、および適用対象となるTwitterマスターサービス契約に同意することに同意いたします。)」
- 「I further acknowledge that by agreeing to this Twitter Ads Products and Services Agreement, I agree to the Twitter Ads policies, including those for Conversion Tracking and Tailored Audiences, and Twitter's Data Processing Addendum.(さらに、このTwitter広告商品およびサービス契約書に同意することにより、Twitter広告ポリシー(コンバージョントラッキングおよびテイラードオーディエンスのポリシー、Twitterのデータ処理補遺を含む)に同意することに同意いたします。)」
以下はどちらを選んでも問題ありません。
選択後は、「Submit」ボタンをクリックします。
- 「By clicking on Yes below, you agree to receive various marketing communications (like tech updates, version notifications, events) via email from Twitter. You may unsubscribe at any time.(以下で [はい] をクリックすると、Twitterからさまざまなマーケティング関連のメール(技術更新、バージョンの通知、イベントなど)を受信することに同意するものとします。購読登録はいつでも解除できます。)」
4.Twitterからの申請の承認メールが届きます。
■「Twitter広告APIを利用してキャンペーンを作ってみる 」シリーズ
- その1~TwitterAPI申請編~
- その2~TiwtterAPIのAPIキーとトークンの取得編~
- その3~TwitterAPIでツイート編~
- その4~Tiwtter広告APIのAPI申請編~ ←イマココ
- その5~Twitter広告APIでキャンペーン作成編~
- 投稿日:2020-09-18T14:10:30+09:00
サーバレスプラットフォームのCode Engine(IBM Cloud)を試してみた
IBM Cloud Code Engineのベータ版のリリースがアナウンスされました
これは、GCPで言うところのCloud Run
に似た機能を持っており、コンテナ上で稼働するアプリケーションをサーバレスで稼働させることができます。ベースとなっているのは、
- Kubernetes
- Knative
- Istio
- Tekton
等となっています。特徴的なのは
Code Engine ではソースコードをビルドパックと呼ばれるランタイム環境と組み合わせてコンテナを作成し、実行することもできるため、コンテナイメージがなくても利用が可能です。
と言うところですね。
ビルドを行うステップを飛ばしてデプロイすることができるので、きっとCI/CD周りの設定が少し楽になるのではないかな、と思います。とりあえず新しいものは触っておけ、と言うことでGetting started with IBM Cloud Code Engine (Beta)を参考に、
Node.js
でHello Worldを出してみます!
必要なのは、ソースコードのみ。コンテナイメージを使わないデプロイを試してみます!事前準備
IBM Cloud のアカウントを準備する。
ライトプランは不可みたいです。ご注意ください。(ちなみに、β版の間は課金は内容です。(用意されているのが無料プランだけでした。))
Container Registoryのnamespaceを用意する
下記のように好きな名前をつけてnamespaceを作っておきましょう。今回は
test-demo-code-engine
と言うnamespaceを用意しました。APIキーを取得する
画面上部の管理→アクセス(IAM)→APIキーをクリックして、APIキーを生成。生成されたキーをコピーして控えておいてください。
Code Engineを準備する
カタログから
Code Engine
を探して開きます。下記の画面がでたらRun your source code
を選択し、Start Creatingを押しましょう。プロジェクトを作成する
create
を押すと名称の入力ができます。現在、サポートされているロケーションはダラスだけのようですね。
プロジェクトを作成すると下記のような画面になります。
ビルドの詳細を設定する
Specify build details
を押して設定を進めましょうソースコードリポジトリを設定する
ブランチを設定することができます。重要なのは、
Context directory
です。実際に動かしたいソースコードが入っていディレクトリを指定してください。(デモの場合は、/hello
となります。※必ず/
から始まる文字列で指定してください)DockerFileの場所を指定する
デモをそのまま使う場合には、特に変更する必要はありません。
Context directory
配下のDockerFileを指定しましょう。また、使用するリソースもここで指定することができます。コンテナレジストリを指定する
Registry nameには準備の時に作成したコンテナレジストリのnamespaceを入れます。レジストリサーバは、コンテナレジストリのURLです。今回はダラスに作っているので、
us.icr.io
となっています。パスワードはAPIキーです。
Add
を押したら最後にリポジトリ名を入れましょう。今回はtest-code-engine
としています。tagは必要に応じてつけてください。デフォルトはlatest
です。デプロイ
ここまで来たら画面右下の
Deploy
を押しましょう動作を確認する
デプロイ後にはこのような
ダッシュボード
的な画面に遷移します。
右上の
Application URL
を押すと、該当のアプリケーションを開くことができます。下記のようにHello World
が出れば成功です!ちなみに、デモアプリケーションでは、
World
の部分が環境変数により変更可能となっています。
このようにTARGET
に指定した内容を反映することもできます。(変更を反映するためにはSave and Deployが必要です。)触ってみた感想
まだβ版と言うこともあり、機能としては最小限といったところでしょうか。(デプロイして動かすくらいしかできない)
今後は、コンテナイメージなしで動かせる利点を活かしてPipelines
との統合などに利便性を見出せるかもしれません。もちろん、リクエスト単位での課金なのでバックアップとして持っておくと言う選択肢もありそうです!(おまけ)Cloud Run(フルマネージド)との差分(9/18時点)
利点
- ソースコードだけでデプロイが可能!Dockerイメージを用意する必要がない
- Docker Hubからもデプロイ可能
- vCPUが0.01〜8まで選べるので選択肢が広い。(Cloud Runは1か2)
- メモリも128MiBから32GiBまで選べる(Cloud Runは4GiBが上限)→ただ、サーバレスでそこまで必要か?と言う気もする
足りない点(きっとこれから実装されるはず!)
- リビジョンごとのトラフィックの割合の変更が簡単にできない。リビジョン毎にURLが発行できるわけでもない
- コンテナのログがみられない
- リージョンがダラスしかないのでレイテンシが気になる
- 自動スケールするときの最大数が250(Cloud Runは1,000)
- Cloud Runで言うところの、
Serverless VPC Access Connector
がない。ローカルIPでDBなどにはアクセスしたい。- その他いろいろ。。。
- 投稿日:2020-09-18T14:03:39+09:00
Twitter広告APIを利用してキャンペーンを作ってみる その2~TiwtterAPIのAPIキーとトークンの取得編~
経緯
私が所属している会社では待ラノという小説投稿サイトを運営しています。
待ラノではオススメ小説のランキング上位5作を定期的にTwitterの公式アカウントで紹介しています。
紹介された小説をTwitter広告のキャンペーンを利用してプロモーションをしようってなりました。そもそもTwitter広告のキャンペーンって何?
Twitter広告のキャンペーンですが、簡単いうと1日にかける予算や期間内にかける総予算を指定して、Twitterに広告を出す機能です。
Twitter広告APIでキャンペーンを作る理由
1つのキャンペーンで複数のツイートをプロモーションする場合、1日にかける予算を一気に消化されてしまいます。
しかもどのツイートにどれだけ予算が消化されているかがわかりません。
そのため、1つのツイートに1キャンペーンを紐付けることで消化される予算の見える化を行うことになりました。ただ手動でTwitterの広告コンソールから、1ツイートに1キャンペーンを毎回作ることになると結構手間です。
というわけで、Twitter広告APIを利用して動的にキャンペーンを作成することになりました。Twitter広告APIでキャンペーンを作成するためには
以下の手順が必要です。
- Tiwtterアカウントを作成する(省略)
- Tiwtterアカウントにメールアドレスと電話番号を設定する(省略)
- TiwtterAPIの利用申請をする
- TiwtterAPIのAPIキーとトークンを取得する ←イマココ
- TiwtterAPIを利用してツイートをする
- Tiwtter広告APIの利用申請をする
- Tiwtter広告APIでを利用してツイートを使ったキャンペーンを作る
今回は4の【TiwtterAPIのAPIキーとトークンを取得する】について説明していきます。
1.Twitter Developerのページにアクセス
まずはTwitterにログインした状態で、Deeloperサイトへアクセスします。
2.「Create an app」ボタンをクリックします。
APIキーとトークンを取得するためにはTiwtter内でアプリを作成する必要があります。
3.英語でアプリの詳細を回答していきます。
「Application description(アプリの説明)」
「allow this application to be used to sing in with twitter(アプリの利用にはTwitterにサインインが必要か)」
今回は必要ではないので、チェックを「オフ」にします。
下記項目は必要に応じて記入します。
未記入でも問題はありません。「Callback URLs(コールバックのURL)」
「Terms of Service URL(利用規約ページのURL)」
「Privacy policy URL(プライバシーポリシーページのURL)」
「Organization name(企業名)」
「Organization website URL(企業のウェブサイトのURL)」
「Tell us how this app will be used(アプリの使用方法を説明してください)」
記入後、「Create」ボタンをクリックします。
4.デベロッパー規約を確認してから、再度「Create」ボタンをクリックします。
5.入力した内容が詳細として表示されるので「Keys and tokens」タブをクリックすます。
さらに「Access token & access token secret」の「Generate」ボタンをクリックするとトークンが出力されます。
今後必要になるのが以下の4項目になります。
- 「API key」
- 「API secret key」
- 「Access token」
- 「Access token secret」
■「Twitter広告APIを利用してキャンペーンを作ってみる 」シリーズ
- その1~TwitterAPI申請編~
- その2~TiwtterAPIのAPIキーとトークンの取得編~ ←イマココ
- その3~TwitterAPIでツイート編~
- その4~Tiwtter広告APIのAPI申請編~
- その5~Twitter広告APIでキャンペーン作成編~
- 投稿日:2020-09-18T09:11:56+09:00
Puppeteerの`waitFor`は`waitForTimeout`に書き換えた方がよいみたい(v5.3.0)
概要
警告が出たので調査
waitFor is deprecated and will be removed in a future release. See https://github.com/puppeteer/puppeteer/issues/6214 for details and how to migrate your code.結論
- Puppeteerのバージョンはv5.3.0
- 警告に表示されたリンクを見ただけ: https://github.com/puppeteer/puppeteer/issues/6214
- 単純に
waitFor
をwaitForTimeout
に置き換えれば良さそう- await page.waitFor(5000) + await page.waitForTimeout(5000)参考
詳しく書いてあるので詳細はGitHubのページを参照してください
- 投稿日:2020-09-18T07:07:20+09:00
discord.jsでapiの情報を取得する
すえきゅーですどうも
今回は discord.jsでapiから情報を取得して出力する方法をここに書こうと思います使うものApi Node fetch jsonを読む力この3つです
次にNode fetch
こいつがないとダメです
$ npm install node-fetch
こいつをターミナルで実行しましょう準備完了 コードをここに置きます
コードconst discord = require("discord.js"); const fetch = require("node-fetch"); const client = new discord.Client() client.on('ready', async () => { const msg = await client.channels.cache .get("送信したいチャンネルid") //チャンネルを取得 .send("Status"); //送信 setInterval(async () => { //任意のミリ秒ごとに繰り返す const res = await fetch("Api"); //取得 if (!res.ok) { //取得できなかったら console.log(await res.text()); //コンソールにメッセージを出力する return; } const json = await res.json(); //json msg.edit({ embed: { color: 0x00ff00, title: "thinking", description: "Api test", footer: { text: "thinkingbot", }, fields: [ { name: "fields", value: json.test.status, //Apiの情報を書く json.~~~~で行ける } ] } }) }, 1500); //1.5秒ごとに繰り返すこんな感じで出力出来ると思います
何か間違ってることや質問があるならこちらに参加して質問してください最後まで見てくれてありがとうございました
- 投稿日:2020-09-18T02:32:54+09:00
【npm】パッケージとモジュールの違いって何?
はじめに
普段、Node関連の記事を書いていたり、業務で説明をする時などに、曖昧になりやすい パッケージ と モジュール の違いについて公式のドキュメントをもとに簡単にまとめます。
npmにあるのはパッケージなのかモジュールなのか
The npm registry contains packages, many of which are also Node modules,
公式にはnpmレジストリーにはパッケージが含まれており、その多くはNodeモジュールです。
そもそもパッケージとは何なのか
A package is a file or directory that is described by a package.json file.
パッケージとは
package.json
によって記述されるファイルもしくはディレクトリのことを指します。そもそもモジュールとは何なのか
A module is any file or directory in the node_modules directory that can be loaded by the Node.js require() function.
モジュールとは、Node.jsの
require
機能によって呼び出すことができるnode_modules
内のファイルまたはディレクトリのことを指します。To be loaded by the Node.js require() function, a module must be one of the following:
・ A folder with a package.json file containing a "main" field.
・ A folder with an index.js file in it.
・ A JavaScript file.モジュールとして
require
機能によって読み込まれる為には、次のいずれかである必要があります。
package.json
を含むフォルダーであり、main
フィールドを含むファイルであること。index.js
というファイルが入っているフォルダであること。JavaScript
ファイルであること。結局のところ何が違うのか
npm経由でインストールされたパッケージは、ほとんどがファイルの中でロードされて使用されます。
つまり、これらはモジュールと言えるでしょう。
モジュールに該当しないパッケージもある
npm経由でインストールされるパッケージは、ほとんどがファイルの中でロードされる為、モジュールであると書きましたが、中にはターミナルなどのコマンドラインで実行するパッケージもあると思います。
このように
main
フィールドを持たないパッケージはモジュールとは言えません。まとめ
長々と書きましたが、簡潔にかくと以下のようになります。
ファイルの中で
require
して読み込みNode.jsが使用するmain
フィールドが含まれていればモジュールという認識でOK参考文献