tag:crieit.net,2005:https://crieit.net/tags/SendGrid/feed 「SendGrid」の記事 - Crieit Crieitでタグ「SendGrid」に投稿された最近の記事 2021-11-17T09:36:55+09:00 https://crieit.net/tags/SendGrid/feed tag:crieit.net,2005:PublicArticle/17765 2021-11-17T09:36:55+09:00 2021-11-17T09:36:55+09:00 https://crieit.net/posts/102949946b0e6197f103d453a781a1fc 数日で有料サービスをリリースしてみた話 <p>有料サービスを2,3日位で作ってリリースしてみました。多分計10時間ほど? 急にぱっと思いついて次の日の夜くらいにはだいたい完成していました。作ったのは下記のHand Refactorerというプログラムのコードを手動的にリファクタリングしてくれるサービスです。</p> <blockquote class="twitter-tweet"><p lang="ja" dir="ltr">130円でプログラムのコードを手動的にリファクタリングしてくれるサービスをリリースしました。プログラミングを始めたばかりの方にはもしかしたら役立つ場合もあるかもです。よろしければお試しください!!<a target="_blank" rel="nofollow noopener" href="https://t.co/bHlNXJFbTh">https://t.co/bHlNXJFbTh</a> <a target="_blank" rel="nofollow noopener" href="https://t.co/VhPI80a6Cl">pic.twitter.com/VhPI80a6Cl</a></p>— だら@Flutterもやってる (@dala00) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/dala00/status/1459816338050859008?ref_src=twsrc%5Etfw">November 14, 2021</a></blockquote> <p>ちなみにこれ自体は単に自動的じゃなくて手動かよというツッコミがほしいだけのために作ったネタクソアプリです。</p> <p>色々やるべきことを削ったりなどで考えたりしたので書いておきます。</p> <h2 id="サービスの流れ"><a href="#%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9%E3%81%AE%E6%B5%81%E3%82%8C">サービスの流れ</a></h2> <p>そもそもサービスの流れですが、まずユーザーがリファクタリングしてほしいコードを入力して登録します。</p> <p>それを僕が人力でリファクタリングし、回答として登録するとユーザーがそれを確認できる、という形です。</p> <h2 id="課金関連の開発を極限まで削る"><a href="#%E8%AA%B2%E9%87%91%E9%96%A2%E9%80%A3%E3%81%AE%E9%96%8B%E7%99%BA%E3%82%92%E6%A5%B5%E9%99%90%E3%81%BE%E3%81%A7%E5%89%8A%E3%82%8B">課金関連の開発を極限まで削る</a></h2> <p>課金となると、結構色々考えなければなりません。ユーザー登録し、そのユーザーに対して課金ログを保存し、購入履歴などを用意する必要があります。ただそこまでするとどうしても工数がかかってしまいます。そのため下記のようにして開発事項を削りました。</p> <h3 id="オーソリを使う"><a href="#%E3%82%AA%E3%83%BC%E3%82%BD%E3%83%AA%E3%82%92%E4%BD%BF%E3%81%86">オーソリを使う</a></h3> <p>オーソリというのは、仮売上です。即課金確定するのではなく、注文が確定した時にキャプチャという処理を行って決済を確定させる方法です。ユーザーが注文してきた時に仮売上とし、僕が処理を行って納品でき、ユーザーがそれを意図的に閲覧した場合に納品確定としキャプチャを行うようにしました。</p> <p>この方法には色々メリットがありました。</p> <h4 id="ユーザーの心理的不安を取り除ける"><a href="#%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E3%81%AE%E5%BF%83%E7%90%86%E7%9A%84%E4%B8%8D%E5%AE%89%E3%82%92%E5%8F%96%E3%82%8A%E9%99%A4%E3%81%91%E3%82%8B">ユーザーの心理的不安を取り除ける</a></h4> <p>個人サービスですので、そこに課金するのにはちょっと不安があります。ただ、ちゃんと納品が行われないと課金が確定しないということが事前にわかっていればその不安をある程度取り除くことができます。</p> <p>確定する場合には、ユーザーに回答画面のURLが貼られたメールが送られます。ここでも実際に見て課金を確定するかどうかをユーザーが意図的に選ぶ事ができます。興味がなければ見ずに終わらせればいいですし、お金を払ってでも見たいと思っていれば閲覧して確定できます。</p> <h4 id="運営側の不安も取り除ける"><a href="#%E9%81%8B%E5%96%B6%E5%81%B4%E3%81%AE%E4%B8%8D%E5%AE%89%E3%82%82%E5%8F%96%E3%82%8A%E9%99%A4%E3%81%91%E3%82%8B">運営側の不安も取り除ける</a></h4> <p>個人サービスで課金機能を提供するのは、運営者としてもなかなか気持ち的に不安になることが多いです。うまくサービスを提供できなかったらどうしよう、大きなミスに気づかず迷惑をかけてしまったらどうしよう、など。</p> <p>しかしオーソリを利用してユーザーがお金を払って結果を見たいと確信して行動する時に初めて課金が行われるようにすれば、なかなか間違えたり問題が起こる可能性は低くなります。そうなると運営側としても問題が発生しにくく安心です。</p> <p>また、最悪僕が怠けたりなにか急なトラブルで全然手を付けられず放置したとしても一切課金されることはありません。また、そんなにリファクタリングすることがないコードであれば確定しないことでキャンセル扱いにすることもできます。</p> <p>このようにしてお互いの不安をなるべく少なくすることでユーザーは購入を、運営はリリースをしやすい気持ちにできるようにしました。これができなければ色々と複雑なテストをしたり入念にいろいろな機能をつくったりしてなかなかリリースはできなかったでしょう。</p> <h3 id="チェックアウトを使わない"><a href="#%E3%83%81%E3%82%A7%E3%83%83%E3%82%AF%E3%82%A2%E3%82%A6%E3%83%88%E3%82%92%E4%BD%BF%E3%82%8F%E3%81%AA%E3%81%84">チェックアウトを使わない</a></h3> <p>Stripeにはチェックアウトというプログラムを書かなくても商品を売れる機能があります。すごく簡単なのですが今回はそれは使いませんでした。というのも売上の結果を知るためにWebhookでチェックする必要があり、ちょっとそれが面倒でした。プログラムで決済してしまえば登録時に一緒にやってしまえばすべてが終わるためそちらの方が処理的にもわかりやすくテストもしやすかったためです。</p> <h2 id="メールアドレスを使う"><a href="#%E3%83%A1%E3%83%BC%E3%83%AB%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%E3%82%92%E4%BD%BF%E3%81%86">メールアドレスを使う</a></h2> <p>メールアドレスを使うことでログイン機能を削りました。ユーザー登録をすると、やはり離脱率は上がります。ちょっと投稿して利用するだけのサービスでユーザー登録は面倒くさいです。</p> <p>また、ログイン機能を作るとそれはそれで結構面倒です。Next.js と Firebase を使っているのですが、それで認証を入れるとFirestoreのセキュリティルールも設定しなければなりませんし、その状態だとNext.jsのサーバーサイドレンダリング時にエラーが発生することもあり、結構確認事項が増えます。ログイン機能を作らずメールアドレスのみの照合とすることでそれら全ての開発を削りました。</p> <p>メールアドレスだけでは勝手に決済されて危険なのでは? と思われるかもですが、クレジットカード自体は操作している人自身のものを入れなければならないためなりすましは難しいですし、できたとしても結局オーソリまでしか進めないため、利用者が最後まで進まないとお金は一切動きません。</p> <p>またこれにより結果のURLはメールで本人しか知ることができないため漏洩の心配などもありません。</p> <p>最初はユーザーもメールアドレス登録するのはいやかな…とも思ったのですが、そもそも大量の依頼がくるとそれはそれで僕のスケジュールがパンクしてしまうのである意味抑制になっていいかなと思っています。</p> <h2 id="極限までハードルを下げる"><a href="#%E6%A5%B5%E9%99%90%E3%81%BE%E3%81%A7%E3%83%8F%E3%83%BC%E3%83%89%E3%83%AB%E3%82%92%E4%B8%8B%E3%81%92%E3%82%8B">極限までハードルを下げる</a></h2> <p>このハードルというのはユーザー、運営者両方のことです。</p> <p>まず費用は130円という自販機でジュースを買うのと同じ(?)ような料金にしました。また、説明分にはレジャー感覚で使ってほしいということ、意図した結果が帰ってくるとは限らないということを書いておき、運営者的にもちゃんとした結果をださなければ、という不安をなくし、利用者としてもさほど結果に期待しない状態を作っておきました。</p> <p>ハイクオリティになったり、ハードルの認識の齟齬があると開発もそれに対処するためにちょっとやることや考えることが増えたりなど、すぐにリリースはできません。とにかくすぐに作るレベルのサービスに連動したクオリティの商品をそれに見合った低価格で提供することによってリリース時の負担を下げました。</p> <h2 id="管理機能を公開しない"><a href="#%E7%AE%A1%E7%90%86%E6%A9%9F%E8%83%BD%E3%82%92%E5%85%AC%E9%96%8B%E3%81%97%E3%81%AA%E3%81%84">管理機能を公開しない</a></h2> <p>リファクタリング結果の送信ですが、Firestoreのダッシュボードだけではできません。そのためそこは返答用の画面を作ってあげる必要がありました。</p> <p>しかし前述の通り認証もありませんし、URLを作ってしまうと万が一アクセスされてしまった時に情報が漏洩してしまいます。</p> <p>そのため管理画面は公開せず、別プロジェクトとして作り、ローカルのデバッグ実行だけでできるようにしました。絶対に他の人にアクセスされることもありませんので安全です。また、作っていたプログラムをコピーするところから始めたのでベース部分はまるまる流用でき、特に大変でもありませんでした。</p> <h2 id="Firebaseクライアントを使わず全部APIのみにする"><a href="#Firebase%E3%82%AF%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%B3%E3%83%88%E3%82%92%E4%BD%BF%E3%82%8F%E3%81%9A%E5%85%A8%E9%83%A8API%E3%81%AE%E3%81%BF%E3%81%AB%E3%81%99%E3%82%8B">Firebaseクライアントを使わず全部APIのみにする</a></h2> <p>前述の通り、セキュリティルールを設定するのが面倒だったためFirebaseのクライアントはアクセス解析にしか使っていません。セキュリティルールは全部のデータへのアクセス不許可にしています。</p> <p>普通に単なるAPIとしてfirebase-adminを利用してサーバーサイドのDBのようにして作っています。なにもかんがえることもなく非常に楽です。勝手に変なデータにアクセスされてしまうこともありません。</p> <p>また、Firestoreを使うことによってデプロイする場所を選ばなくてもよいようにもなっています。</p> <h2 id="Cloud Runにデプロイ"><a href="#Cloud+Run%E3%81%AB%E3%83%87%E3%83%97%E3%83%AD%E3%82%A4">Cloud Runにデプロイ</a></h2> <p>今回はCloud Runにデプロイしました。前述の通りDBはFirestoreなのでどこにでもデプロイできます。本来はVercelが一番楽なのですが、この無料プランは個人的な利用のみに限られますので、今回の場合は利用できません。ということでCloud Runを使いました。GitHubにpushしたのに連動して自動的にデプロイもできますし。Herokuでも良いと思いますが頻繁に利用されるサービスではありませんし、あまりアクセスして遅いのもあれかなと思いCloud Runにしました。</p> <p>せっかくなのでDockerfileを使わないでデプロイできるBuildpackというものを試してみたかったというのがあったのですが、どうもビルド無しで実行されてしまうようでエラーになったので今回は諦めてDockerfileを使うことにしました。だいたいDockerfileならどっかーにあると思いますので。</p> <p>今回は下記を使いました。<br /> <a target="_blank" rel="nofollow noopener" href="https://zenn.dev/kazumax4395/articles/427cc791f6145b">【Node.js/Next.js】Cloud Runで動作する軽量なDockerを構築してみた</a></p> <p>これの真ん中のやつでだいたいデプロイに8分ほどかかります。それほどパフォーマンスが必要ではないので一番最初の簡易的なやつでも良かったのかもしれません。なんにしろVercelよりはやはりどうしても遅くなってしまいますね。</p> <p>あと日本リージョンにしたのでちょっとネットワーク料金がかかります(アクセスがちょっと多ければ月何十円とか100円とか?)</p> <h2 id="CSSも使わない"><a href="#CSS%E3%82%82%E4%BD%BF%E3%82%8F%E3%81%AA%E3%81%84">CSSも使わない</a></h2> <p>今回はChakra UIを使いました。とにかくデフォルトのデザインパーツで、カスタマイズは全部Chakraコンポーネントのプロパティのみで、ぶわっと作りました。非常に楽です。</p> <h2 id="DIFFの表示"><a href="#DIFF%E3%81%AE%E8%A1%A8%E7%A4%BA">DIFFの表示</a></h2> <p>リファクタリングということで、DIFFを表示したほうがわかりやすいかなと思いました。</p> <p>React Diff Viewerというのを使いました。<br /> <a target="_blank" rel="nofollow noopener" href="https://github.com/praneshr/react-diff-viewer">https://github.com/praneshr/react-diff-viewer</a></p> <h2 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h2> <p>最初に書いたとおりクソアプリですので、ものすごい依頼が増えない限りは特にアップデートする予定はありません(依頼がきたらちゃんと対応します。リファクタリングは結構好きなのでわりと楽しんでやっています)。</p> <p>ただ数日で作れたので、これを機に低価格で同じように自分で提供できることを売るのも面白いかなとは思います。どうしても手がかかるので規模が大きくなるとスケールもしないし限界がありますので、あくまでも今回のようにジョーク交じりかつすごく負担の少ない作業だけになるとは思いますが。</p> <p>逆に言うと、低価格でちょっとなにか提供できる、というひとはたくさんいると思いますので、みんながこういうサービスを各々作れたら面白いのにな、とも作ってる途中に思いました。例えば小説の手直し、絵の手直し、もしくはちょっとした絵を書いてあげたり、サービスの感想を伝えてあげたり、なにか写真をとってあげたり、ロゴをつくってあげたり。皆自分の得意なことを提供して少しでもお金になれば楽しいのでは、と思いました。</p> <p>もちろんそういうモール的なサービスはいくつかあると思いますが、あくまでも自分の個人商店的な感じで運用するのも面白いと思います。</p> <p>自分でみんながそういうことを提供できるサービスを作ればよいのでは、とも一瞬思ったのですが、やはり価格的に運営者に入るお金はかなり薄利になり、儲けを出すにはかなり大量に集客しないといけませんし個人だと逆に大変なことが多そうなので、無理かなと思いました。Skebのもっと安くて気軽バージョン的な感じかもです。</p> <p>なので可能な方は是非同じ様なサービスを作ってなにか提供してみると面白いのではないかと思います。</p> だら@Crieit開発者 tag:crieit.net,2005:PublicArticle/16425 2020-12-26T12:11:54+09:00 2020-12-26T12:11:54+09:00 https://crieit.net/posts/EXCEL-VBA-SendGrid-WebAPI EXCEL VBAからSendGrid WebAPI経由でメール送信 <h1 id="はじめに"><a href="#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">はじめに</a></h1> <p>(Qrunch からの移管記事です)</p> <p>タイトルの通り、EXCEL VBAからSendGridのWebAPI経由でメール送信をする方法を記載。<br /> 「WebAPIとか全然わからない」の状態から頑張って送信までできるようにしました。</p> <p>普通はCDO.MessageでSendGridへSMTP通信すればいいだけですが、<br /> ネットワーク構成の都合上「外部へのSMTP通信は不許可、HTTP/HTTPSはOK(ただし認証プロキシあり)」という環境化だったので、WebAPIを利用せざるをえませんでした。<br /> ⇒むしろSendGridにWebAPIがあってよかった。</p> <p>同じような境遇の人がいたら参考にしてください。(いるか?)</p> <h1 id="参考URL"><a href="#%E5%8F%82%E8%80%83URL">参考URL</a></h1> <p>1.VBAでのWEB API<br /> <a target="_blank" rel="nofollow noopener" href="https://qiita.com/haseshin/items/4acf31db9a672ed691df">https://qiita.com/haseshin/items/4acf31db9a672ed691df</a><br /> 2.VBAでのWEB API & JSON<br /> <a target="_blank" rel="nofollow noopener" href="https://qiita.com/MakotoIshikawa/items/be902e6bd3fa2e5c5fe5">https://qiita.com/MakotoIshikawa/items/be902e6bd3fa2e5c5fe5</a><br /> 3.SendGridのリファレンス<br /> <a target="_blank" rel="nofollow noopener" href="https://sendgrid.kke.co.jp/docs/API_Reference/index.html">https://sendgrid.kke.co.jp/docs/API_Reference/index.html</a></p> <h1 id="事前作業(SendGridの認証について)"><a href="#%E4%BA%8B%E5%89%8D%E4%BD%9C%E6%A5%AD%EF%BC%88SendGrid%E3%81%AE%E8%AA%8D%E8%A8%BC%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%EF%BC%89">事前作業(SendGridの認証について)</a></h1> <p>「SendGirdのユーザ名とパスワードをどこかで指定するんだろうなぁ」<br /> と思ってたのですが、不要でした。</p> <p>SendGridのポータルサイトからAPIキーを発行してください。<br /> 発行したAPIキーが認証情報になります。</p> <h1 id="実装コード"><a href="#%E5%AE%9F%E8%A3%85%E3%82%B3%E3%83%BC%E3%83%89">実装コード</a></h1> <ul> <li>Sample</li> </ul> <pre><code>Private Sub SendMail() Dim objHTTP As Object Dim json As Variant json = "{""personalizations"":" _ "[{""to"": [{""email"": ""[email protected]""}],""subject"": ""Mail Title""}]," _ """from"": {""email"": ""[email protected]""}," _ """content"": [{""type"": ""text/plain"",""value"": ""Mail Body""}]}" Set objHTTP = CreateObject("MSXML2.ServerXMLHTTP.6.0") With objHTTP .Open "POST", "https://api.sendgrid.com/v3/mail/send", False .setRequestHeader "Content-Type", "application/json; charset=UTF-8" .setRequestHeader "Authorization", "Bearer xxxxYourApiKeyxxxxxxxxxxxxxx" .setProxy 2, "proxyhost.com:9293" .setProxyCredentials "proxyUser", "ProxyPassword" .setOption 2, 13056 .send json If .ResponseText <> "" Then MsgBox .ResponseText Else MsgBox "OK" End If End With End Sub </code></pre> <ul> <li><p>流れ<br /> ・JSON形式でメール設定を定義(細かい内容はリファレンスの「V3 Mail Send API概要」参照)<br /> ・MSXML2.ServerXMLHTTP.6.0オブジェクトの生成<br /> ・POSTメソッドでSendGridのMail Send APIをオープン<br /> ・ヘッダ設定。Content-TypeにJsonの指定。<br />  AuthorizationヘッダにAPIキーをセット。Bearerの指定をお忘れなく。<br /> ・プロキシ設定。setOptionの記述はSSL認証に関するエラー回避。<br /> ・送信。エラーの際にはResponseTextにエラー内容が入っているはず。</p></li> <li><p>補足<br /> ・「xxxxYourApiKeyxxxxxxxxxxxxxx」がAPIキーです。<br /> ・プロキシを経由しない環境であれば「setProxy」、「setProxyCredentials」、「setOption」は省略してください。</p></li> </ul> <h1 id="VBAでのJSONファイルの取り扱い"><a href="#VBA%E3%81%A7%E3%81%AEJSON%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E5%8F%96%E3%82%8A%E6%89%B1%E3%81%84">VBAでのJSONファイルの取り扱い</a></h1> <p>JSONファイルをVBAでまじめに取り扱うのであれば「VBA-JSON」の利用なども検討してください。<br /> ⇒参考URL3の記事に詳しく記載されています。</p> <h1 id="所感"><a href="#%E6%89%80%E6%84%9F">所感</a></h1> <p>・VBAでのWebAPI利用なんてサッパリだ、の状態からなんとか実現できました。<br /> ・以外にVBA&REST APIの情報がネットに転がっていて助かった…</p> ANA tag:crieit.net,2005:PublicArticle/14565 2018-10-10T19:35:48+09:00 2018-10-26T08:28:47+09:00 https://crieit.net/posts/Wordpress-S3-SendGrid-Heroku-Composer Wordpressを無料でS3、SendGrid、Heroku、Composerでデプロイする <p><a href="https://crieit.now.sh/upload_images/3e0a99d4c9d3bf6999aa40837f8a26475bbdd5cd82288.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/3e0a99d4c9d3bf6999aa40837f8a26475bbdd5cd82288.png?mw=700" alt="logo-composer-transparent5.png" /></a></p> <p><a target="_blank" rel="nofollow noopener" href="https://github.com/PhilippHeuer/wordpress-heroku">https://github.com/PhilippHeuer/wordpress-heroku</a></p> <p>こちらのGithubにある「Deploy to heroku」ボタンをクリックすることでも構築できるのですが、画像やプラグインを永続的に維持するためにはローカルに構築してcomposer updateしてから差分をgit pushし、同じソースコードをherokuにデプロイする必要があるのでした。</p> <p>いろいろいじってやってみたところ、なんとかできたので、この後もいろいろ試したいと思う。</p> <p>一番苦労した点は、英語版Wordpressを日本語化する方法だった。</p> <p>ローカルでWP CLIを使って日本語化ファイルをダウンロードし、git pushしたらできた。</p> <p><code>wp core language install ja --activate</code></p> <p>参考URL<br /> <a target="_blank" rel="nofollow noopener" href="https://upd.world/wordpress-cloud9/">https://upd.world/wordpress-cloud9/</a><br /> <a target="_blank" rel="nofollow noopener" href="https://qiita.com/miya0001/items/96a684e2f819f9d8b4a4">https://qiita.com/miya0001/items/96a684e2f819f9d8b4a4</a><br /> <a target="_blank" rel="nofollow noopener" href="https://qiita.com/fuwamaki/items/8684003bb47197336645">https://qiita.com/fuwamaki/items/8684003bb47197336645</a></p> fk2000 tag:crieit.net,2005:PublicArticle/14472 2018-06-20T08:12:23+09:00 2019-02-28T16:25:32+09:00 https://crieit.net/posts/WEB-5b298dd7398c4 WEBサービスの通知機能実装が面倒すぎるので困った <p>先日Crieitにコメント機能を付けました。そうなると必要になってくるのが、通知機能です。</p> <p>記事を投稿した人はコメントがついたら通知が欲しいでしょうし、コメントした人も自分のコメントに返信が来たり、同じ記事にコメントがついた場合にはすぐに見たいと思いますので通知が欲しいはずだからです。</p> <h2 id="通知機能の選択肢"><a href="#%E9%80%9A%E7%9F%A5%E6%A9%9F%E8%83%BD%E3%81%AE%E9%81%B8%E6%8A%9E%E8%82%A2">通知機能の選択肢</a></h2> <p>WEBサービスに通知機能を実装する場合、現在だと大まかにふた通りのやり方があると思います。</p> <h3 id="メール通知"><a href="#%E3%83%A1%E3%83%BC%E3%83%AB%E9%80%9A%E7%9F%A5">メール通知</a></h3> <p>昔からある一般的な方法です。一番無難な方法でもあると思います。通知メールを残しておけば何の通知だったかあとでも確認できますし、メール通知機能さえあれば必要最低限はまかなえると思います。</p> <h3 id="PUSH通知"><a href="#PUSH%E9%80%9A%E7%9F%A5">PUSH通知</a></h3> <p>FCMを利用したPUSH通知です。メールとは違い、端末に通知が来て直接アプリケーションの画面が開けるため、スピード感がありWEBサービスには向いています。</p> <h2 id="どちらがいいのか?"><a href="#%E3%81%A9%E3%81%A1%E3%82%89%E3%81%8C%E3%81%84%E3%81%84%E3%81%AE%E3%81%8B%EF%BC%9F">どちらがいいのか?</a></h2> <p>最終的には両方の通知機能を実装することでしょう。ただ、個人でWEBサービスを作っている場合や、スタートアップなどがスモールスタートする場合などは何でもかんでも最初から実装しておけばいいというわけではありません。</p> <p>サービス的に両方絶対必要、ということであれば仕方ないですが、時間に限りがありますし通知機能の実装は非常に面倒ですので、絶対必要でなければどちらかの通知機能に絞った方が良い場合もあると思います。</p> <p>どちらにどういうメリットがあり、どちらがどれだけ面倒か考えていきます。</p> <h2 id="メール通知"><a href="#%E3%83%A1%E3%83%BC%E3%83%AB%E9%80%9A%E7%9F%A5">メール通知</a></h2> <p>メール通知のメリットは前述の通り、とりあえず作っておけば最低限大体のことは満たせるということです。ただ、実装方法は色々ありますが、結構面倒な点もあったりします。</p> <h3 id="サーバー上のメールサーバーを用意する場合"><a href="#%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E4%B8%8A%E3%81%AE%E3%83%A1%E3%83%BC%E3%83%AB%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%82%92%E7%94%A8%E6%84%8F%E3%81%99%E3%82%8B%E5%A0%B4%E5%90%88">サーバー上のメールサーバーを用意する場合</a></h3> <p>Postfix等を使えば特に外部サービスを利用しなくてもメールを送信することができます。ただ、自分で設定をしなければならないので面倒です。一回くらいなら自分で頑張って設定しようかと言う気にはなるのですが、もしもう1台増やすか、ということになった時などにまた同じ設定をしなければならないのかと思うとうんざりします。</p> <p>僕は仕事上インフラ周りも触ることはありますが、メールサーバーは正直必要最低限は最初から送信できたりすることもあり、WEBサーバーやDBの設定に比べて扱う頻度が低く、大体次触る頃にはほとんど設定方法を覚えていません。そのためネットで調べながら設定することになり、時々つまづくこともあるのでかなり面倒です。</p> <p>特に普段サーバー環境構築をしない人からするともっと大変だと思います。例えば下記の記事に設定が書いてありますが、長い設定画面が出てきたあたりで読む気すら起こらなくなると思います。<br /> <a target="_blank" rel="nofollow noopener" href="https://qiita.com/mizuki_takahashi/items/1b33e1f679359827c17d">Ubuntuでメールサーバー構築</a></p> <h3 id="メール送信サービスを利用する場合"><a href="#%E3%83%A1%E3%83%BC%E3%83%AB%E9%80%81%E4%BF%A1%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9%E3%82%92%E5%88%A9%E7%94%A8%E3%81%99%E3%82%8B%E5%A0%B4%E5%90%88">メール送信サービスを利用する場合</a></h3> <p>上記の理由から、SendGridやMailgunメールサービスをつかってメール通知を実装するともっと楽になります。色々と機能もついており非常に便利です。ただ、これはこれでいくつか問題があったりします。</p> <h4 id="送信数制限"><a href="#%E9%80%81%E4%BF%A1%E6%95%B0%E5%88%B6%E9%99%90">送信数制限</a></h4> <p>送信数制限があるため、多く送ると費用がかかるようになります。例えばSendGrid等は現在月12000通です。</p> <p>さすがにそれなら超えないんじゃないか? と思いますが、1サービスではなく1アカウント毎の制限になりますので、いくつもサービスを作っていて、ある程度メールを送信するしている場合はわりと超えてしまうのではないかと思います。</p> <p>今は良いけど今後サービス新しく作る場合にどうしようか? と悩むこともあると思います。</p> <h4 id="リレー方式の場合はダメな場合がある"><a href="#%E3%83%AA%E3%83%AC%E3%83%BC%E6%96%B9%E5%BC%8F%E3%81%AE%E5%A0%B4%E5%90%88%E3%81%AF%E3%83%80%E3%83%A1%E3%81%AA%E5%A0%B4%E5%90%88%E3%81%8C%E3%81%82%E3%82%8B">リレー方式の場合はダメな場合がある</a></h4> <p>僕が愛用しているGCEもそうですが、ポートに制限がかかっている場合があり、リレー方式の送信方法だとブロックされてしまい送信できません。マニュアルはありますがこれもちょっとうんざりする系です。<br /> <a target="_blank" rel="nofollow noopener" href="https://cloud.google.com/compute/docs/tutorials/sending-mail/using-sendgrid">SendGrid でのメールの送信</a></p> <h4 id="API方式がいい"><a href="#API%E6%96%B9%E5%BC%8F%E3%81%8C%E3%81%84%E3%81%84">API方式がいい</a></h4> <p>API方式は良いです。一番簡単だと思います。ただ、言語によってはなぜかリレー方式しか使えないライブラリがあったりするので、このあたり気をつけないとローカル環境では動いたのに本番では送信できないとなりますので気をつけましょう。</p> <p>あとはどの方式にも言えますが、DNSでSPFの設定をちゃんとやっておく必要があります。これをやっておかないとスパムメール扱いされてしまう事が多いです。メールサービスであればマニュアルに書いてあることも多いと思います。</p> <h3 id="WEB PUSH"><a href="#WEB+PUSH">WEB PUSH</a></h3> <p>FCMを利用したWEB PUSHによる通知です。スマホなどで通知を受け取り、すぐに目的のURLにアクセスできるため、サービスにユーザーを頻繁に呼びこむのに優れています。</p> <p>単にユーザーに通知を送るだけでなく、トピックを作っておいて、そこにユーザー端末を登録してトピックに通知を送ると登録されているユーザー全員に通知を送ることができる、などもあり、非常に便利です。(もちろん、そのあたりの登録、解除の仕組みなどもちゃんと作らないといけません。自前のDBに保存しておく必要もあります)</p> <h4 id="通知の履歴が残らない問題"><a href="#%E9%80%9A%E7%9F%A5%E3%81%AE%E5%B1%A5%E6%AD%B4%E3%81%8C%E6%AE%8B%E3%82%89%E3%81%AA%E3%81%84%E5%95%8F%E9%A1%8C">通知の履歴が残らない問題</a></h4> <p>通知の履歴が残らないため、通知を消してしまったり、通知からサービスにアクセスしても一旦どうでもよくて離脱し、再度気になった時にアクセスできない、といった問題が出てきます。(実際にはスマホには履歴が残っているのですが、見るのも面倒で知らない人も多いと思います)</p> <p>そのためサービス側に独自の通知履歴を作らなければなりません。</p> <h2 id="独自の通知の実装"><a href="#%E7%8B%AC%E8%87%AA%E3%81%AE%E9%80%9A%E7%9F%A5%E3%81%AE%E5%AE%9F%E8%A3%85">独自の通知の実装</a></h2> <p>独自の通知の実装ですが、これがまた面倒です。というのも、通知というのは色々なところで発生します。例えばフォローしているユーザーやカテゴリに何かが投稿されたり、自分の投稿にコメントがついたり。</p> <p>つまりDBの構造として単純なbelongsToで作ることができません。通知自体はあまり他のところで使われるものでもないのでpolymorphicであれば割とシンプルに困ることなく作れるかもしれません。何にしろ条件分岐にしろ、関連モデルに共通のメソッドを用意するにしろ、やることは増えるので面倒なのは面倒です。</p> <p>元はといえば単にユーザーに最低限の通知をしたかっただけのはずなのに…。</p> <h3 id="フロントとの連携の問題"><a href="#%E3%83%95%E3%83%AD%E3%83%B3%E3%83%88%E3%81%A8%E3%81%AE%E9%80%A3%E6%90%BA%E3%81%AE%E5%95%8F%E9%A1%8C">フロントとの連携の問題</a></h3> <p>単に通知一覧を実装するだけであれば問題ないのですが、WEBサービスのヘッダ部分に新着通知アラートをだしたりすることになるとまた面倒なことになります。どこまで閲覧済みかという情報を保存しておかなければならないからです。</p> <p>フロントエンドと連携する場合、ユーザーの確認とDBの更新のタイミングが必ずしも同じではなくなるため、適当に作ったりするとまだ確認していないのにある一瞬のタイミングで全ての通知を確認済みにしてしまって新着通知が消えてしまったり、逆にフロント側では新着確認済みになったのにリロードするとまた新着が復活してしまう、ということが発生したりします。</p> <p>Facabookもこの不具合が多く非常に困ったため、Fluxを提唱したという話をどこかで見ました。ほんとに通知機能というのはやっかいなシロモノです。</p> <p>個人のWEBサービスなら良いのですが、もし仕事でするとなると仕様策定側が便利にしたいと思ってあれこれ勝手に決めてしまうこともあるので大変そうです。</p> <h2 id="周辺機能の実装"><a href="#%E5%91%A8%E8%BE%BA%E6%A9%9F%E8%83%BD%E3%81%AE%E5%AE%9F%E8%A3%85">周辺機能の実装</a></h2> <p>通知を作るとなると、周辺にも色々と機能を実装する必要が出てきます。これも非常に面倒です。元はといえば単にユーザーに最低限の通知をしたかっただけのはずなのに…。</p> <ul> <li>トピックやユーザーなどにウォッチ機能、もしくは通知解除機能を実装する必要がある</li> <li>ユーザーの個人設定に一般的な通知許可設定を実装する必要がある、もしくはここにも分類毎の許可設定が必要</li> </ul> <h2 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h2> <p>こんな感じで、単に通知機能を作りたいだけのはずなのですが、周辺部分も含めると結構工数がかかってしまい、なかなか厄介です。考えれば考えるほど、こだわればこだわるほど色々できてしまう箇所ですので、いかに絞って仕様を策定するかは非常に重要になると思います。<br /> (メールサービス関連はざっと調べただけですので誤っている情報もあるかもしれません。検討される際は実際に確認してください)</p> <p>記事を書きつつ気持ちを落ち着けて考えてみましたが、CrieitとしてはとりあえずSendGrid等のAPI送信で試そうかなと思います。一応公式のライブラリの方はAPI方式っぽいので。(SendGrid公式のLaravelやRailsのサンプルはリレーっぽいのでなんか不親切な感じがします)</p> <p>…と決めたら決めたでまた悩む…。</p> <p>追記)<br /> FCMにする。</p> <p>追加)<br /> 結局メール(API)も入れました。</p> だら@Crieit開発者