tekitoumemo’s diary

思ったことを書くだけ。長文版Twitter

ReactでYoutubeをテクニカルに扱う

https://www.tam-tam.co.jp/tipsnote/wpdata/wp-content/uploads/2014/04/6.YouTube-Player-API-690x362.jpg

ReactでIFrame Player APIを使う方法を軽く説明

IFrame Player APIって何かというとコレ↓を操作するAPIのことです。マシュメロの「Happier」です(今年一番おすすめ!)
youtu.be

全く使い道がなさそうなAPIですが、僕の場合は「音声のみ再生させたいなー」と思ったんで使ってみました。こんな感じになりました。
f:id:tekitoumemo:20181029220217p:plain

ReactでIFrame Player APIを使う場合はreact-youtubeというのを使います。ようはIFrame Player APIのwrapperです。
www.npmjs.com

インストール

npm i react-youtube

コンポーネント

<YouTube
  videoId={string}                  // defaults -> null
  id={string}                       // defaults -> null
  className={string}                // defaults -> null
  containerClassName={string}       // defaults -> ''
  opts={obj}                        // defaults -> {}
  onReady={func}                    // defaults -> noop
  onPlay={func}                     // defaults -> noop
  onPause={func}                    // defaults -> noop
  onEnd={func}                      // defaults -> noop
  onError={func}                    // defaults -> noop
  onStateChange={func}              // defaults -> noop
  onPlaybackRateChange={func}       // defaults -> noop
  onPlaybackQualityChange={func}    // defaults -> noop
/>

イベント毎にメソッドを指定すればいい感じです。

サンプル

import React from 'react';
import YouTube from 'react-youtube';
 
class Example extends React.Component {
  render() {
    const opts = {
      height: '390',
      width: '640',
      playerVars: { // https://developers.google.com/youtube/player_parameters
        autoplay: 1
      }
    };
 
    return (
      <YouTube
        videoId="2g811Eo7K8U"
        opts={opts}
        onReady={this._onReady}
      />
    );
  }
 
  _onReady(event) {
    // access to player in all event handlers via event.target
    event.target.pauseVideo();
  }
}

こんな感じっす。もう、まんま公式で申し訳ないのですがイベントと操作方法に関しては以下の公式サイトを
YouTube Player API Reference for iframe Embeds  |  YouTube IFrame Player API  |  Google Developers

playerVarsのパラメータは以下を参考にしてください。
YouTube Embedded Players and Player Parameters  |  YouTube IFrame Player API  |  Google Developers

一応上にないサンプルで、10秒早送りする場合

    var currentTime = event.target.getCurrentTime();
    event.target.seekTo(currentTime + 10);

Youtubeコンポーネント外で操作する
Jqueryなら以下のように利用出来ます。

var $playerWindow = $('#popup-YouTube-player')[0].contentWindow;
$playerWindow.postMessage('{"event":"command","func":"'+action+'","args":""}', '*');

ですが、ReactだとDom操作出来ないので(出来るけどダメ絶対)onReadyでStateにEventを入れて対応しました。

public _onReady(event: any) {
    this.setState({
        event: event
    });
}

onReadyは必ず通るので、Event入れてあとは使い回す方法です。これが良いのかどうかは不明。

音楽のみ再生する
これをやりたかったんですが、まともにやろうとするとめっちゃ違法で捕まるリスクがあります。以下に書いてありましたが、完全に違法ダウンロードです。やめましょう。
stackoverflow.com

ただ、YoutubeAPIを使って動画を再生させながら音源をダウンロードせずに流せば問題ないので色々試しました。

hiddenを使う
普通にHiddenを使うか、以下のように画面外に表示させて再生させます。

hidden{
    position:absolute;
    left:-10000px;
    top:-10000px;
    visibility:hidden;
}

が、これだと再生してくれません。IFrame Player APIでいうとずっとバッファリング中になってずっと再生されません。Youtubeはさすが対策してますね。

サイズを0にする
optsに渡すサイズを0にします。

  render() {
    const opts = {
      height: '0',
      width: '0',
      playerVars: { // https://developers.google.com/youtube/player_parameters
        autoplay: 1
      }
    };

これは再生できました。

iPhonesafariか不明)では、再生してくれません。XCodeのシュミレーターでも再現するので試す人は確認してみてください。

Youtube天才かよ。。

なので、音声のみは再生出来ません。あきらめましょう。

諦めきれないのでまだ試します。

サイズを1にする
optsに渡すサイズを1にします。

  render() {
    const opts = {
      height: '1',
      width: '1',
      playerVars: { // https://developers.google.com/youtube/player_parameters
        autoplay: 1
      }
    };

これは、iPhoneでも再生されます。当たり前ですね、動画を再生しているのですから。

もちろん、Youtubeではバックグラウンド再生が出来ないので画面遷移したら音楽が止まります。そこは潔くあきらめましょう。Audioタグはバックグラウンドでも再生出来るのですが、MP3などの音源を使わなければいけないので日本では使い物にならないですね。

普通に使うならreact-youtubeなんて必要ないですが、ちょっと小細工してみたい人がいたら使ってみてはいかがでしょうか。

Reactはこういうwrapperがたくさんあるのでかなり使いやすいですね。Jqueryで頑張っちゃったときの罪悪感がないのも素敵!

クソみたいな学歴のエンジニアでもわりとなんとかなると気づいた話

こんにちは

最近というかここ数年いろんなこと仕事をして気がついたことがあるのでつらつら書いてく。完全自分語りっす。

まず、僕というエンジニア

年齢 : 29歳
学歴 : 大卒(偏差値38だっけな?)
職歴 :
底辺SIer 3年
自社Webサービス 3年
フリーランス 半年
エンジニア歴 :
プログラムを書かないエンジニア歴 3年
C# 3年(プログラム組んでた時間は2年ぐらいなのかな?)
JS系 2年
資格 : Comptia(一番簡単なやつ)、基本情報
その他
既婚
ヘビースモーカー
趣味DIY、車いじり

ひどいなこれw

クソ大学生生活

https://3.bp.blogspot.com/-3roMAc1c1E8/V5aorett9MI/AAAAAAAA8yw/YKxrNwa_718SwNsD4yxjC8-KVzI-f8IiACLcB/s400/woman_nanpa.png

一応、情報系の大学だか偏差値38の大学ってマジでやばい。同じ学部のやつ8割やめたり、喫煙所で絡まれたり、お湯の入れたカップラーメン盗まれたり、逮捕されるやつが普通にいたり、とにかく劣悪な環境だった。俺も典型的なチャラ男みたいな感じの風貌でクソ調子に乗ってた。英語の授業とかやばすぎて、be動詞から始める。当然俺もbe動詞すらわかんない。それなのに単位がやばくて留年しそうだったからしょうがなく必修のC言語をやって、卒論のときは一週間ぐらい研究室止泊まってなんとか卒業した。卒論のくだりとか真面目にやってるじゃんと思えるが、泊まってることで誠意を見せつけて卒業させてもらう戦法なので、全く勉強頑張ってない。

終わってる就活

https://3.bp.blogspot.com/-8Mvjdk_wm48/VP6LoChPHqI/AAAAAAAAsME/uOV4pdWNN4g/s400/syukatsu_naitei_no_man.png

リーマンショックの次の年で東北の大地震がおきた年に4年になった。絶望モードがヤバかったけど、別に絶望なんかしないよね、就職出来たらラッキーぐらいでできなかったらフリーターやればいいし。普通に就活してても落とされるのに地震なんて起きたから全く連絡返ってこなかった。大学の就職センターに通ってたけど、泣いてるやつ必ず一人はいんのね。そんなやつを尻目に

「とりあえずどこでもいいんで、受かりそうな会社教えて下さい」

とお願いしてた。エンジニアなんて全く探してなかった。営業とかでもよかったけどなんか大学の卒業生がいっぱいいる会社でいかにも受かりそうだったから受けたら受かったwまぁ、普通のSIerでとりあえず派遣されまくる感じの会社。

底辺を受け止め決めた新卒

https://1.bp.blogspot.com/-KRLyWl-ZbQw/Vkcaj0ZmGAI/AAAAAAAA0dA/Qcqwu43TsjM/s400/shinsyakaijin_couple2.png

同期がなんと俺を含めた二人で、もう片方の同期は同じ大学の2年留年してるやつw。研修も適当だし、初めての仕事がXPでVB6。めっちゃダサいUIだし、プログラムも気合と根性みたいな感じで作られてるからプログラムの知識なんかつかんよね。なのにプログラムはこうしたらいいよーとか偉そうに言ってくる上司(この上司は好き)がいるからうるせぇ!、とりあえず動けばいいだろが!と思って自分でフリーソフト作った。気合と根性で作った結果、一生メンテ出来ないソフトになった。それがこれ↓

f:id:tekitoumemo:20170910172142j:plain
ITunEsTooL - あなたのiTunesを快適に
何だかんだ馬鹿にしてるけど、今となっては毎月それなりのディナーが食えるぐらいの収益あげてる

初の派遣と違和感

https://4.bp.blogspot.com/-msqv4Ef0eII/W5H_1hGda0I/AAAAAAABOwA/nZvREG9ZtPoskl4I7Rq1jSMmhqSl_rstQCLcBGAs/s400/fusagikomu_businessman.png

一年ちょいたって、官公庁に派遣される。言語はCobolでJCLとか触った。小泉進次郎とか普通に歩いてるレベルの官公庁で、上司にも「お前はすごいところ行くんだぞ!変なことするなよ!」と念を押される(この上司も好き)。やることといえば、1日一回問い合わせが来て調べるだけ。国家公務員の人って2年に一回異動があるから問い合わせ内容が過去にあるものばっか。早く回答するとたくさん問い合わせが来るので夕方まで外を眺めながら時間が過ぎるのを待つ。とりあえずクッソ暇で何も学びがない環境なんだけど、周りの奴らは

「〇〇省の仕事なんて普通の人じゃ出来ないからね」

って普通に言っててアホかと思った。なかなかの下請けに関わらず、何でこんなにプライド保てるのか不思議でしょうがなかったよ。一年半ぐらいいたんだけど、プロジェクトが長引いて違う現場にも行けそうになかったんで転職を決意。ちょうど三年以上付き合ってた彼女とも遠距離が原因で別れた。あのとき俺が良い企業に勤めてて故郷に帰るのを引き止めてたら結婚してたかもしれない。間違いなく今の嫁の方が良いので、あのときの弱気な俺グッジョブ!

やっと転職活動

https://3.bp.blogspot.com/-nT88MQKlQhw/VcMlV9c2AUI/AAAAAAAAwac/sHPLJJgdKCw/s400/fukidashi_tensyoku_man.png

「石の上にも三年」と言うことわざがあるように3年ぴったりで辞めてやろうと決意。転職先は「BtoCの自社サービス」と決めていたので名のある企業ばかり受けた。が落ちまくった。「自分でここまでサービスを作れるのはすごいね!」と褒めてくれるんだけど、普通に落ちたw、ふざけんなww。とりあえず、スキル的にもマッチして良さそうなサービスを運営してる会社にサービス愛を語りまくって合格した。同い年の奴らがMARCH以下がだれもいなかったのでそこも魅力で

「こいつらと同じように仕事すれば俺も1流になれる!」

と思ってた。このブログもここら辺から始めた。

転職してから

https://2.bp.blogspot.com/-5pWhkq5Iz8o/W1vhsZjWKWI/AAAAAAABNx0/OfFcxPh3fr89b65dmJpcZYrjmKHwjSCsgCLcBGAs/s400/rat_race_businessman.png

入社してからASP.NET MVCをやったがその時は生HTMLぐらいしか書いたことなかったので感動が半端なかった。C#のサービスで履歴書に嘘つきまくってC#やってました!とか言ったから全くわかんないw。全く理解出来てないけど、Googleっていうツールが俺にはある!と思って一生ググった。入社して3ヶ月でAngularJSやれと命令きたので余裕っしょと思って参考書片手にひたすらコーティングした。納期もきっちり守って(品質は全く守ってない)いろいろ作ったので入社して半年で抜擢昇進した。普通に

「この会社バカだろ、技術レベルもクソだし未経験にもほどがあるのに抜擢するか?」

と疑心暗鬼になって普通にテンション下がった。が給料は上がった。全くない技術力をあげたかったのに、サービスのリーダーとかやらされたもんだから嫌で嫌でリーダーとして何もやってなかったな。無能エンジニアコンプレックスがあったから技術力を磨きたいのに入社して半年でコーディングから遠ざかる日々。そんな中で一応リーダーなのでコンバージョンやら施策やらやらなきゃいけなく、目標達しないと罵倒されまくったんでエンジニアをやめようかと思ってた。まぁ俺は怒られても反省しないのでいつか「○ロス」と思ってたww。業績も特に上がらないので組織変更があり、BtoBのサービス事業部に異動。皮肉なことにBtoCのサービスよりもコーディングする量が増えたけど、技術負債を消していく日々。社内のバージョン管理をSVNからGitへ。Github移行もやったりした。それでも運用ばっかり増えて人もやめまくるからついにエンジニア以外の仕事をやったりしたw工場で生産した物をユーザーに届けるサービスだったので工場とのやりとりで1日が終わったりして「俺マジなにやってんのwwww」とか思った。リーダーもやってて工場とのやりとりもやってたからエンジニア業が全く出来なくて爆発した。

「俺、リーダーやらない!!」

と決意して他の人に担当してもらうように上司に説得。今の嫁にリーダーをやってもらってちょっとはエンジニア業もできるようになった。けど、運用ばっかり増えて下火なサービスだから業績も下がって全社員給料下がってと負の連鎖に陥った。転職かぁ、と思って転職先探してたら

「そもそも入りたい会社がねぇ!!」

と思って悩み続ける日々。

また転職?

https://2.bp.blogspot.com/--X2z5ldMf2A/WEOPX4Y31HI/AAAAAAABALg/pc0SbFkluPo4ImDnJxxQgGT2mq-96C9IACLcB/s400/neet_man2.png

転職するか迷ったけど、

「企業に入りたくねぇな、給料なんかたかがしてれるし」

と思ってたら「フリーランス」ってものがあるじゃない!全然技術力ないけど、やってみなきゃわかんねーじゃんと思いフリーランスになることを決意。フリーランスって言っても月単価で企業に勤めればいいからなんとかなる自信はあった。と思ったが、勤めてた会社が火の車で

「ここで辞めると逃げたやつみたいになってしまう」

という葛藤があったから決意してから1年も経ってしまった。会社的にもちょっと気の抜けた時期がやってきたので辞職を伝え、見事今年の3月末で退職。探した案件は経験年数5年以上!Angular経験必須(AngularJSはだめ!)とかなり厳しめの条件だったけど、誰でも名前の知ってる企業だし、どうせフリーランスだから2ヶ月(最初は1〜2ヶ月の契約)で捨てられてもいいや的な考えでそこに決める。案件決めるときに思ったのが、フリーランスだと切られても次探せばいだけなので自分が一番行きたいと思ったところを選べるということ。

フリーランスになって

https://2.bp.blogspot.com/-GrpQmuRjjII/Wq9-kNvTuPI/AAAAAAABK9o/XSlnWP5LbZksnOvHz3N9NFbQDd_Wx_4rQCLcBGAs/s400/kid_job_boy_programmer.png

フリーランスになって、Angular5と.Net Core 2.0の案件。「俺、.Net Core枠で入ったっぽいな」と思ってたら参画したときにはほぼサーバーサイドが出来上がっていて、90%の割合でAngular5をやる。

「いや、超絶むずいんだけどこれ!」

くっそムズイし、プロパーとか業務委託で来てる個人事業主のやつとかすげー優秀。同い年の個人事業主のやつなんかイかれてるレベルに優秀で

「世の中にはこんな優秀なやつがおるんだな〜」

と劣等感すら覚えないレベルで差を見せつけられたw。全然ついていけないから2ヶ月で終わるかなーと思ってたがちょうど2ヶ月目ぐらいからAngular面白くなっちゃったw。Angularはちょっと下火傾向が強いけど、かなりいいフレームワークじゃね?と今でも思えるのはこの案件のおかげだなと感じる日々。リーダーもかなり優秀すごい現場やなと実感してる。まぁ超絶冷たいけどねw。まだ同じ会社だけど違う現場になっちゃった。。けど、なんだかんだ1年ぐらいはお世話になるだろうなと予感。そろそろ技術変更したいから確定申告終わったら違う現場行こうかなと思ってるけど。

やっとWEBサービス作った

https://3.bp.blogspot.com/-2ZdFd1m_LcA/W4PKCybgncI/AAAAAAABOMU/IDcjpV3P5CMH3HH99Z9B0-ltI2rpPnd6QCLcBGAs/s450/sweets_baketsu_purin.png

フリーになったから気兼ねなく副業(本業?)できるし、みんな洋楽ランキングってサイトを作った。
mygkrnk.com
とりあえず飽きる前に作りたかったから作成初めてから実質1ヶ月で公開。急ぎすぎて.Net Frameworkで作成しちゃったから大失敗。MacBookを買ってWindows触れない環境を作って.Net Coreでフルリニューアル。最近はReactやサーバサイドもLinuxにするから完全にWindows離脱した。Windowsは嫌いじゃないんだけどOSクソだしVisualStudio重すぎ使いずらすぎなのでもう触りたくないまでもある。今の現場はVisualStudio使わなきゃいけないからそれが理由で現場変えたいと思っちゃう。このブログはなんだったのか。。。
tekitoumemo.hatenablog.com
技術的な話はここまでで、公開してから3ヶ月で1万PV、翌月には2万PVを超えてビビる。7月末から8月にかけてGoogleの変更の影響かわからんけど超絶にランクが下がる。狙ってるワード「洋楽ランキング」では50位ぐらいに下がっちゃったけどなんだかんた5000PVぐらいは平均してあるのでまぁ成功かな。これは勉強と趣味と自分の武器として作ってるサービスなのでそこまでPV(どれだけ使ってもらえるか)は気にしてなくてこのツールを使ってどんな動きが出来るか検証してる感じかな。でも洋楽好きだからアプリも作るよ!React Nativeの予定(xamarinやっぱだめや)

ブログ

https://1.bp.blogspot.com/-gT-GQZdgLs0/V9ppbFvONVI/AAAAAAAA9po/YiIqQRWL8iQHtvzWZLMejZqbZBLHZ0-rwCLcB/s400/computer_net_stalker_man.png

去年の年末からめっちゃ書いてるw。ちょっと技術ブログを書くのに抵抗があったんだけど、PVを見ると

「誰も見てねぇのになに渋ってんの俺wwww」

と思って適当に書きまくった。なんだかんだこの半年ぐらいの連鎖投稿で月200PVから月3000PVまで延びたw。適当なこと書いてて申し訳ない気持ちと1日100ちょいのPVはあるから一人ぐらい役にたってんだろ!と思うようになった。月30人の役にたつってボランティアを頻繁にやらないとできないレベルだから

「すごいだろ!!おらぁ!」

と自分に言い聞かせてる。

客観的に自分を見て

https://2.bp.blogspot.com/-F6aI0BMfaVg/Wqih-jYWc1I/AAAAAAABK3c/iVDJVFszr2cNr05QYphdJWkI-KlI35Y-ACLcBGAs/s550/network_people_connection.png

ここまで書いて

「仕事が全然出来ない人」

っていうのがわかってもらえたと思うが、意外に驚いた反応をもらうことが多い。今の現場では年上のプロパーに

「僕、技術的にわからないことが多いので本当に助かります(俺もわかんねぇから!)」

って言われたり勉強会(もくもく会)行くとプロダクトを持ってるから

「これつくってるんですか?すごい!いろいろ話聞かせてkwsk

って言われたり、Quitaで1000いいねをもらった人にTwitterで絡んだら

「ブログみてすごい参考になります!ずっと解決策悩んだたので参考にさせていただきます!」

とか俺、ぶっちゃけ技術的に興味がある方じゃないから全然すごいやつじゃないけど周りから見るとそれなりに悪い印象じゃないんだなと感じてる。お世辞かもしれないけど表に出る一歩は歩み始めてることは間違いないかなと感じる。やっぱ結構嬉しくて、自分のプロダクトを作るのがかなり大事なんだなと思う。

わりとなんとかなる

https://4.bp.blogspot.com/-DGriik1JKwI/VeJ-nHstE7I/AAAAAAAAxIQ/1ynD2OEy12M/s450/yowatari_jouzu.png

就職して6年ぐらい経つけど、いろいろ振り返って見るとなんだかんだ上手くいってると思う。別に努力とかしてるから上手くいったとかではなくて、適当に自分のやりたいことに向けて動いたら良い方向に向かっただけの話。ただ、これだけは言えるのは

「劣等感は絶対に持っちゃいけない」

自分の経歴から考えてずっと新卒で入った会社にいたら、、と思うとゾッとする。勘違いしないで欲しいのが、会社がダメなのではなく劣等感を持って仕事してる自分がダメで井の中の蛙で戦っていかなければいけないのでそれはさみしいよね。特に運がよくない人でも、動き次第で良い方向に向くので20代はやりたいことに向けて突き進んでよかったなと思う。あと1年で30代。まだまだやれることはある。学歴に関わらず劣等感を持ってる人たちは、そんなものを捨て去って自分の好きなことをやって欲しいと思います。

AzureでSendGridを扱う

https://sendgrid.kke.co.jp/blog/wp/wp-content/uploads/2016/09/SG_Logo_Blog.jpg

SendGridイイね!

Azure App Service on Linuxに移行する為にテストをしていたところ、メール送信に失敗するようになりました( ゚д゚)
tekitoumemo.hatenablog.com
色々調べてみるとAzureではメール送信を推奨していないことがわかりました。
Azure 上にメールサーバー/SMTP サーバーを構築する場合の注意事項 – Japan Azure IaaS Support Blog

Azure 上の VM から、外部ドメインに対して直接 SMTP 等を使ってメール送信することは、Azure プラットフォームとしてサポートをしておりません。

メールが失敗する原因がAzureのせいじゃないとは思うのですが、原因特定に力を使っても意味がないのでこの際Slackやらに通知する方法を考えていたのですが、「SendGrid使ってみたい!」と思ったのでSendGridにしました。stackoverflowに質問投げたのですが、ビビるほど音沙汰がないので知ってる人いたら教えて欲しいです(TLSで弾かれてるとこまではわかった)。
ja.stackoverflow.com

ということでAzureで動くまで説明します。

AzureでSendGridアカウントを作成する

SendGrid Accountsの[追加]を押下してアカウントを作成します。Resource Groupまで適当に入れてください。
f:id:tekitoumemo:20181017000439p:plain
pricing tierをクリックするとプランが出てきます。25000通まで無料(安杉)なのでFreeを選びました。
f:id:tekitoumemo:20181017000706p:plain
Contact Informationには、名前やら自分の情報を入れてください。
f:id:tekitoumemo:20181017000821p:plain
法律条例は[作成]を押下すると同意したことになるので同意しましょう。
f:id:tekitoumemo:20181017001005p:plain

SendGrid管理画面でAPIキーを発行

デプロイが完了したらリソースに移動して[Manage]を押下するとSendGridの管理画面に遷移します。
f:id:tekitoumemo:20181017001342p:plain
管理画面に移動したらメニューのSettingsを押下してApiKeyをクリックします。
f:id:tekitoumemo:20181017001504p:plain
Create API Keyを押下して、権限やらを設定します。発行したAPI Keyは一度しか見れないので厳重に保管しておいてください。
f:id:tekitoumemo:20181017001628p:plain

コード

C#用のSendGridライブラリがあるのでNugetから取ってきます。

dotnet add package Sendgrid --version 9.10.0

www.nuget.org

コードは以下です。

var apiKey = "{発行したAPI Key}";
var client = new SendGridClient (apiKey);
var msg = new SendGridMessage () {
    From = new EmailAddress ("{メールアドレス}"),
    Subject = "Hello World from the SendGrid CSharp SDK!",
    PlainTextContent = "Hello, Email!",
    HtmlContent = "<strong>Hello, Email!</strong>"
};
msg.AddTo (new EmailAddress ("{メールアドレス}"));
var response = await client.SendEmailAsync (msg);

response.StatusCodeで送信出来たか確認できます。

あとは管理画面でメールが送信されたか確認出来ます。

感想

SendGridは知ってましたが、一休のブログとか見てると大規模サービスに使われるクラウドぐらいの感覚でしかなかったのですが
25000通まで無料なので気軽にいじれてよかったです。
user-first.ikyu.co.jp
日本語の情報が多く、値段も手頃なのでかなり気に入りました。
f:id:tekitoumemo:20181017003657p:plain

最近の記事で気になったこと

日本語の検索結果を排除する設定にせざるを得なくなってる

すごいなこれ。技術ブログを書くのに億劫になってる人ってこういうやつがいるからなんだろうな。好きに書きなさいよまったく。っか記事の絶対数が少なすぎるだけで、外国人は仕事中に書いてるから多いんだろ!羨ましい!


同意。俺も勉強会きらいー。勉強会に行く人は、技術オタクか無駄に意識高い系か出会い厨(異性を探す以外に人脈増やしたがる人も含む)しかいないんで、一部の人にあたったのかなーと。っか仕事終わって勉強会行く人謎。家帰って寝っ転がりながらパソコン開いてる方がよっぽど楽なのに。



これ、何年議論されてんのか謎。

これも。

「だからここら辺はまじめに勉強するのが嫌いなんだよねー。」



seo系の記事ってなんでちゃんと内容書いてくれないのか。その過程を知りたいんだが。普通にseo困ってんのにこの記事見てスマホカチ割りそうになった


結論「学歴は関係ない」

嬉しいね、こういう記事。

結論「クッソ勉強すれば高学歴と同じレベルもしくは超えられるよ」

は?結局勉強しなきゃいけないの?


この人は前提でしっかりツッコミどころをなくしているのでこの記事は良い記事だな。知り合い経由で転職はちょっと微妙だけど

結論

記事に対して物申す人はクソ(え

Azure Logic Appsを試す

https://azure.microsoft.com/svghandler/logic-apps?width=600&height=315

Azure Logic Appsを導入しました。なぜ導入したかと言うと以前に書いたAzure Schedulerが2019年9月で終了するからです。
tekitoumemo.hatenablog.com
こんなメールきてびっくりしました。Azure Scheduler作った時に教えてよ!って感じですがまぁ良いです。
f:id:tekitoumemo:20181011223709p:plain

Azure Logic Appsとは

AzureのサービスやいろんなAPIやらを組み合わせてサービス作れるよってやつです。

業務上重要なアプリやサービスを Azure Logic Apps に接続して、コードを 1 行も書かずにワークフローを自動化します。

が謳い文句ってやつでしょうか。
azure.microsoft.com

導入方法

AppServiceから「Logic App」とフィルタかけると見つかります。
f:id:tekitoumemo:20181011224334p:plain

トリガーを作る

「ロジック アプリ デザイナー」から作ります。
f:id:tekitoumemo:20181011224529p:plain

あまり説明するところはないのですが、スケジュール決めてあとは好き勝手にHTTPやらAzureやらいろんな物を組み合わせてくサービスです。最近流行ってるRPAツールですね。

スケジュール

f:id:tekitoumemo:20181011224933p:plain

HTTP

f:id:tekitoumemo:20181011225001p:plain

なんかいっぱいある

f:id:tekitoumemo:20181011225039p:plain

値段

僕の場合は3(アクション)×24(毎時)×30(日)で2160(アクション)回動かすので以下でした。
f:id:tekitoumemo:20181011225602p:plain
6円?安くね?ほんとこれ?ちょっと疑問はありますがまぁ値段かかってから確認します。

よくわかってない

トリガーってAppServiceごとにしか作れないのだろうか?
まぁいつか調べます(絶対調べない)

感想

AzureのサービスはAzure Schedulerみたいな微妙なサービスがいっぱいあるのでおそらくここに統合されたサービスがいっぱいあると思います。なのでAzure Logic Appsをみて物足りなかったら他を探すでいいかなと思いました。Azure Schedulerとか1500円したので高杉。

後日

1週間でかかった値段
f:id:tekitoumemo:20181017215857p:plain
ひと月8円かかる計算(安杉
トリガーも複数設定できるみたいなのですが、デザイナーからは出来ないようです。

Azure App Service on Linuxで.Net Coreアプリを公開

https://msdnshared.blob.core.windows.net/media/2017/05/1-TryAppLinuxLanding.png

.Net Coreアプリ作ったのならLinuxで公開したい!って思ったものの、あまり必要性が感じられなかったので手付かずだったのですが値段見たらまぁびっくり!

Linux

f:id:tekitoumemo:20181010214208p:plain

3000円近くも変わるじゃん!前はほぼ値段変わらなかったのになぜにこんな差が。。まぁそんなこんなでみんなの洋楽ランキングLinuxサーバに移行計画を立てました。PaaSだからGithubブランチ指定してすんなり行くと思いきや、まったくダメで情報も全然無くて結構大変だったので丁寧に書いておきます。

Web Appをたてる

OSはLinux、公開はコード、ランタイムスタックは.Net Core 2.1で。Dockerの方が値段安いっぽいけどちゃんと調べてないから次回へ(たぶんやる)。しかも今ならB1インスタンスが1ヶ月無料なのでやりたい放題っす。
f:id:tekitoumemo:20181010215008p:plain

Githubのブランチからデプロイ

Github、Bitbucket、その他もろもろから合ったものを選んでください。
f:id:tekitoumemo:20181010221240p:plain
ブランチにPushされたら勝手にデプロイされます。

エラーが出る

f:id:tekitoumemo:20181010221727p:plain
はい、ダメでした。原因を探ります。失敗したところをクリックすると以下の画面が表示されます。ログを表示をクリックします。
f:id:tekitoumemo:20181010222118p:plain
f:id:tekitoumemo:20181010222210p:plain
「Object reference not set to an instance of an object」とでます。おなじみのメッセージですが、意味不明です。これはプロジェクトにsln(ソリューション)ファイルを含めるとkuduが解析出来ないのでダメみたいです。slnを消してプロジェクトを一つにすれば問題ないのですが、テストやライブラリなど複数のプロジェクトがあることが多いのでプロジェクトを一つにする方法はイケてませんし、マルチプラットフォームの意味がないですね。みんなの洋楽ランキングもDapperの自作拡張ライブラリ、定期更新系のAPIライブラリ、テストなどプロジェクトが分かれているので一つにする選択肢はありません。これを回避する方法があります。

ちなみにkuduとは

f:id:tekitoumemo:20181010223638p:plain
Kudu is the engine behind git deployments in Azure App Service.
Kuduは、Azure App Serviceのgitデプロイメントの背後にあるエンジンです。(翻訳ママ)

.deploymentファイルとCustom Deployment Scriptを設置する

Custom Deployment Scriptを準備

deploy.shファイルのWebApplication1はプロジェクトに合わせて変えてください。deploy.shはシェルスクリプトなんで名前はなんでもよいです。

#!/bin/bash

# ----------------------
# KUDU Deployment Script
# Version: 1.0.13
# ----------------------

# Helpers
# -------

exitWithMessageOnError () {
  if [ ! $? -eq 0 ]; then
    echo "An error has occurred during web site deployment."
    echo $1
    exit 1
  fi
}

# Prerequisites
# -------------

# Verify node.js installed
hash node 2>/dev/null
exitWithMessageOnError "Missing node.js executable, please install node.js, if already installed make sure it can be reached from current environment."

# Setup
# -----

SCRIPT_DIR="${BASH_SOURCE[0]%\\*}"
SCRIPT_DIR="${SCRIPT_DIR%/*}"
ARTIFACTS=$SCRIPT_DIR/../artifacts
KUDU_SYNC_CMD=${KUDU_SYNC_CMD//\"}

if [[ ! -n "$DEPLOYMENT_SOURCE" ]]; then
  DEPLOYMENT_SOURCE=$SCRIPT_DIR
fi

if [[ ! -n "$NEXT_MANIFEST_PATH" ]]; then
  NEXT_MANIFEST_PATH=$ARTIFACTS/manifest

  if [[ ! -n "$PREVIOUS_MANIFEST_PATH" ]]; then
    PREVIOUS_MANIFEST_PATH=$NEXT_MANIFEST_PATH
  fi
fi

if [[ ! -n "$DEPLOYMENT_TARGET" ]]; then
  DEPLOYMENT_TARGET=$ARTIFACTS/wwwroot
else
  KUDU_SERVICE=true
fi

if [[ ! -n "$KUDU_SYNC_CMD" ]]; then
  # Install kudu sync
  echo Installing Kudu Sync
  npm install kudusync -g --silent
  exitWithMessageOnError "npm failed"

  if [[ ! -n "$KUDU_SERVICE" ]]; then
    # In case we are running locally this is the correct location of kuduSync
    KUDU_SYNC_CMD=kuduSync
  else
    # In case we are running on kudu service this is the correct location of kuduSync
    KUDU_SYNC_CMD=$APPDATA/npm/node_modules/kuduSync/bin/kuduSync
  fi
fi

if [ "x$DEPLOYMENT_TEMP" = x ]; then
    DEPLOYMENT_TEMP=/tmp/`date +%s`
    CLEAN_LOCAL_DEPLOYMENT_TEMP=true
fi

if [ "x$CLEAN_LOCAL_DEPLOYMENT_TEMP" = xtrue ]; then
    rm -rf "$DEPLOYMENT_TEMP"
    mkdir "$DEPLOYMENT_TEMP"
fi
##################################################################################################################################
# Deployment
# ----------

echo Handling ASP.NET Core Web Application deployment.

# 1. Restore nuget packages
dotnet restore "WebApplication1/WebApplication1.csproj"
exitWithMessageOnError "dotnet restore failed"

# 2. Build and publish
dotnet publish "WebApplication1/WebApplication1.csproj" --output "$DEPLOYMENT_TEMP" --configuration Release
exitWithMessageOnError "dotnet publish failed"

# 3. KuduSync
"$KUDU_SYNC_CMD" -v 50 -f "$DEPLOYMENT_TEMP" -t "$DEPLOYMENT_TARGET" -n "$NEXT_MANIFEST_PATH" -p "$PREVIOUS_MANIFEST_PATH" -i ".git;.hg;.deployment;deploy.sh"
exitWithMessageOnError "Kudu Sync failed"


##################################################################################################################################
echo "Finished successfully."
.deploymentファイルを準備

.deploymentファイルはデプロイ時に実行されるスクリプトを記述するファイル(正直よくわかってない)で先ほど準備したCustom Deployment Scriptを指定します。フルパスにしないとNot Foundが出るのでちゃんと指定します。

[config]
command = /home/site/repository/deploy.sh

準備が出来たらPushしてください。

Custom Deployment Scriptは以下を参考に
github.com

再度デプロイする

次はデプロイが成功するはずなので、サイトを見に行きます。
f:id:tekitoumemo:20181010230041p:plain
そうするとサイトが立ち上がりません。
f:id:tekitoumemo:20181010230126p:plain
MVCテンプレ作ってデプロイしたらちゃんと動いたので、謎です。

スタートアップ ファイルを指定する

[アプリケーションの設定]からスタートアップ ファイルを指定します。ここで重要なのは、各フレームワークによって指定の仕方が違います。.Net Coreは以下の通りです。こんな記述方法知らんがな。

dotnet <myapp>.dll

ここにフレームワーク毎の指定方法が書いてあります。
docs.microsoft.com

サイトを確認する(二度目)

f:id:tekitoumemo:20181010230857p:plain
はい。動いたけど動いていません(え
心折れそうになったんですが、一つ心当たりが合ったのでそれを実施しました。

.Net Coreのバージョンを下げる

以前の記事で.Net Coreのバージョンを2.1.5にあげました。
tekitoumemo.hatenablog.com
公式ではApp Service反映してるよ!って言ってたのですがエラーの内容から怪しいのでバージョン指定なしでプロジェクトファイルの内容を変更します。

<PackageReference Include="Microsoft.AspNetCore.App" Version="2.1.5" />
↓
<PackageReference Include="Microsoft.AspNetCore.App" />

何も指定しないと2.1.1になるみたいです。
f:id:tekitoumemo:20181010232833p:plain
はい、確認しましょう。

サイトを確認する(三度目)

f:id:tekitoumemo:20181010233033p:plain
よっしゃー!ざっと見た感じ、Reactも動いてるしいい感じですね!もうちょっと動作確認したり、Coreのバージョンを下げたのでそれに伴ってNugetのバージョンを下げる必要がありそうです。また、移行する時間、告知、メンテナンス中のページとか作らなきゃいけないですので今月いけるかな〜?って感じです。

さいごに

記事では流れで書いているので簡単そうに見えますが、昨日の夜から今日も仕事でしたが適当にタスク2つぐらい終わらせてあとはずっと調べてました(クビ。開発もMacでやってるしWEBサーバーもマルチプラットフォームで実現出来たのでサービス開始から5ヶ月でようやく完全マルチプラットフォーム化実現しそうです。一応、Windowsでも動くような構成にしてるので(Windows機ないからわかりませんが)どの環境からも開発できるようになりました。.Net CoreのリリースノートにApp Serviceも反映したよって書いてあったのですがAzure App Service on Linuxは完全別物なんですね。3000円浮くし、application insightsとかゆくゆくはKubernetesとか試して見ようかなと思います。最後に参考になったサイトのリンクを貼っておきます。

Deploying ASP.NET Core to App Service on Linux – Honza's Blarg
Azure web app on linux deployment failed on deploy.ssh - Stack Overflow
Azure App Service on Linux の FAQ | Microsoft Docs

ASP.NET MVCにおけるモデル検証について

https://4.bp.blogspot.com/-NZWVQX1HeY0/W4tss_UVZmI/AAAAAAABOQ0/xBD5M6o3HAs82NfznQPvkgoxCHtO1RDHQCLcBGAs/s450/fashion_model_woman.png

かなり一般的なネタですが、以外に実装されている現場が少なく、色々処理した後にエラーチェックしてバグる現象が発生していることが多い気がするので備忘録として。以下に書いているコードは.Net Core2.1です。Frameworkでもほぼ一緒なので参考になるかなと思います。

モデル検証って言うとなんか小難しく感じるのですが、要はエラーチェックです。公式はこう言ってます。

アプリでは、データベースにデータを格納する前に、データを検証する必要があります。 データにセキュリティ上の脅威がないかどうかを確認し、種類とサイズが適切に設定されていることを検証しなければなりません。また、ご自身のルールに準拠している必要もあります。

で、ASP.NETだと簡単にできるよって言ってます。

検証を実装するのは冗長で面倒な場合がありますが、必要不可欠です。 MVC では、検証はクライアントとサーバーの両方で発生します。
さいわい、.NET では検証が検証属性に抽象化されています。 これらの属性には検証コードが含まれているため、開発者が記述しなければならないコードの量は少なくて済みます。

まぁ、他のフレームワークでもあるよねって感じですが。

本題に入ります。

モデル

Personというモデルがあり、名前と年齢が定義されています。

public class Person {

    public string Name { get; set; }

    public int Age { get; set; }

}

名前は10文字まで、年齢は99歳までというバリデーションをつける場合はAttributeをつけます。

[Display (Name = "名前")]
[MaxLength (10)]
public string Name { get; set; }

[Display (Name = "年齢")]
[Range (0, 99)]
public int Age { get; set; }

これで条件通りのバリデーションをつけれますが以下のようなエラーが出力されます。

"The field 名前 must be a string or array type with a maximum length of '10'."

これだとアプリ毎に適切なメッセージじゃないのでメッセージをつけます。

[Display (Name = "名前")]
[MaxLength (10, ErrorMessage = "{0}は10文字まで")]
public string Name { get; set; }

[Display (Name = "年齢")]
[Range (0, 99, ErrorMessage = "{0}は99歳まで")]
public int Age { get; set; }

これで以下のようなメッセージが出力されます。

"年齢は99歳まで"
"名前は10文字まで"

バリデーションはいろんな種類があるので以下を参考にしてください。
docs.microsoft.com

次にアプリ独自の検証は必ず必要なので、CustomValidationAttributeで検証します。今回はsaitoって名前で29歳(僕)だったらエラーにします。

public class Person {

    [Display (Name = "名前")]
    [CustomValidation (typeof (Person), "CheckName")]
    public string Name { get; set; }

    [Display (Name = "年齢")]
    public int Age { get; set; }

    public static ValidationResult CheckName (string value, ValidationContext context) {
        var model = (Person) context.ObjectInstance;
        if (model.Name == "saito" && model.Age == 29) {
            return new ValidationResult ("この人はダメです。");
        }
        return ValidationResult.Success;
    }
}

上記のコードでモデルを取得して組み合わせ技で検証出来るのでだいたいは事足りるかなと思います。

コントローラ

次にコントローラー側の検証します。

WEBAPIなどに使われるApiControllerAttributeを指定している場合はコントローラ側に来る前に以下のエラーを吐きました。ちょっと独自のエラーを返したい場合はどうするのかよくわかりません。いつか調べます(絶対調べない)

{
    "Age": [
        "年齢は99歳まで"
    ],
    "Name": [
        "名前は10文字まで"
    ]
}

MVCの場合は以下のように検証します。ModelState.IsValidはモデルにエラーがあるか判定するフラグでfalseだったらエラーがあるってことです。

[HttpPost]
public string Post ([FromBody] Person person) {

    if (!ModelState.IsValid) {
        // ここでエラーチェック
    }
    return "Success";
}

独自のエラーモデルなどを使っている場合はModelStateからエラーメッセージとプロパティを取得できます。

// プロパティ毎のエラーを保持
ModelState.Values
// 一番最初のプロパティのエラーを保持
ModelState.Values.First ().Errors
// 一番最初のプロパティのエラーの最初のメッセージ(エラーが複数ある場合)
ModelState.Values.First ().Errors.First ().ErrorMessage
// エラーがあるプロパティの名前
ModelState.Keys

いろいろ書きましたが、これだけ覚えていればだいたいのエラーチェックがAttributeで済むと思います。エラーチェックは作り込んでから直すと結構大変なんでここら辺は習得しておく必要があるかなと思います。いつものごとく雑ですが、githubにあげましたので参考になればと思います。個人の趣味ブログなのですげーテキトーにコード書いてますのでご注意を。
github.com