- 投稿日:2020-11-20T22:59:03+09:00
YouTubeの配信・動画のコメント(トップレベルコメントのみ)を取得するnode.jsのツールを作成
概要
- 気になる事があったので、配信のコメントを取得するツールを作成した。
- トップレベルコメントのみ(コメントへの返信は取得していない)
- APIキーは伏字。log4jsでログ出力しているので(いないとは思いますが)流用する場合は各々の出力方法に変換してください。
引数
- 動画ID(watch?v=XXXXXXXXXXXのXXXXXXXXXXX部分)
実行結果
以下を出力する。
- 投稿者表示名(items.snippet.topLevelComment.snippet.authorDisplayName)
- 投稿者チャンネルID(items.snippet.topLevelComment.snippet.authorChannelId.value)
- 表示メッセージ(items.snippet.topLevelComment.snippet.textDisplay)
- いいね数(items.snippet.topLevelComment.snippet.likeCount)
- 投稿日(items.snippet.topLevelComment.snippet.publishedAt)
- 詳細はAPIドキュメントを参照備考
YouTubeの利用規約としては、個人を特定する情報を収集・取得するのは駄目、とありますが、
APIで取得できる情報が規約的に駄目ならAPIを使っては駄目なのでは、という話になりかねないので
とりあえず取得できるものは見ていい(DBには保存しない)というスタンスで扱います。ソース
const ApiKey = "key=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; const UrlCommentThreads = "https://www.googleapis.com/youtube/v3/commentThreads?" + ApiKey + "&part=snippet&maxResults=100&videoId=" var logger = require('../modules/logger'); var axios = require("axios"); let targetVideoId = getTargetVideoId(process.argv); if ( targetVideoId == undefined || targetVideoId.length == 0 ) { logger.info("video comment require arg... video id.") return; } // call main main(targetVideoId); function getTargetVideoId(argv) { if ( argv.length <= 2 ) { return ""; } return argv[2]; } // main async function main(videoId) { logger.info("video comment start"); var itemArray = new Array(); logger.info("get video comment, videoId[" + videoId + "]"); await outVideoComment(itemArray, videoId, ""); logger.info("video comment end"); }; // out video comment async function outVideoComment(itemArray, videoId, pageToken) { var nextPageToken = ""; var docs = undefined; let requestUrl = UrlCommentThreads + videoId + "&pageToken=" + pageToken; logger.debug(requestUrl) await axios.get(requestUrl) .then(function(res) { nextPageToken = res.data.nextPageToken; docs = res.data.items; }) .catch(function(err) { docs = undefined; logger.error("axios error!"); logger.error(err); }); if ( docs != undefined && docs.length > 0 ) { for ( let key in docs ) { let topLevelCommentSnippet = docs[key].snippet.topLevelComment.snippet; let comment = { authorDisplayName: topLevelCommentSnippet.authorDisplayName, authorChannelId: topLevelCommentSnippet.authorChannelId.value, textDisplay: topLevelCommentSnippet.textDisplay, likeCount: topLevelCommentSnippet.likeCount, publishedAt: topLevelCommentSnippet.publishedAt } logger.info(comment); } } else { logger.debug("no docs"); } if ( nextPageToken == undefined || nextPageToken == "" || nextPageToken.length == 0 ) { logger.debug("no next page"); return; } await outVideoComment(itemArray, videoId, nextPageToken); }
- 投稿日:2020-11-20T17:30:11+09:00
【エラーコード別解説】Twitter の Account Activity API の Webhook URL が登録できないときの解決法
はじめに
Twitter の Account Activity API を使う機会があり、こちらの記事 を参考に Webhook URL を登録しようとしたのですが、なかなか登録できず、丸一日ほど費やしてしまいました。
Webhook の登録はかなり罠があり、調べても解決法が全然出てこなかったため、この記事では、発生するエラーコードを紹介し、その原因と解決法について解説します。参考になりましたら幸いです。
正しい設定方法だけ見たい
事前準備
Webhook URL を登録する際には POST リクエストを Twitter に送る必要があります。そのリクエストを送るために、本記事では Postman を利用します。あらかじめアカウント登録し、デスクトップ版アプリをインストールしておいてください。
cURL でもできる気がしますが、罠が多すぎていちいちパラメータをいじるのがめちゃくちゃ大変だったので Postman の使用をおすすめします。
アカウント登録
アカウントを持っていない場合は こちら からアカウントを作成してください。
アプリのインストール
アカウント登録またはサインイン後に
Workspaceに行き、画面右下のDesktop AgentからDownload desktop agentをクリックしてダウンロードしてください。
または、macOS をお使いの方は Homebrew Cask からインストールすることもできます。
$ brew cask install postmanその後、アプリを起動し、サインインしてください。
アプリをインストールする必要がありますか? ブラウザではダメですか?
Postman は Web 版で使用することもできます。しかし、ブラウザで検証したところ、CORS の制約に引っかかってしまいリクエストを送信することができませんでした。そのためアプリ版を使用する必要があります。
目次
発生したエラーコードの解説だけ知りたい方は以下の目次をご活用ください。
エラーコード 32
エラーメッセージは
Could not authenticate youです。「認証できませんでした」ということなのですが、理由が全く書かれていないためこれだけではわかりません。{ "errors": [ { "code": 32, "message": "Could not authenticate you." } ] }公式のトラブルシューティング を見ても「リクエストの認証データに問題がある」ということしかわからず、認証データの「どこ」に問題があるかはわかりません。
ネットで調べてみると、このエラーで苦しんでいる人が多くいるようでした。何を隠そう、自分もこのエラーで苦しみました。
原因
このエラーが発生する原因として考えられるのは、Webhook URL をクエリパラメータとして設定していること です。つまり、リクエストの URL を、以下のように指定しているためです。
https://api.twitter.com/1.1/account_activity/all/:ENV_NAME/webhooks.json?url=https%3A%2F%2Fyour_domain.com%2Fwebhook%2Ftwitter
:ENV_NAMEには、設定した Dev environment label が入ります。何を意味しているかわからない場合は「エラーコード 200」の解説をご覧ください。公式ドキュメント にはクエリパラメータとして Webhook URL を指定する例が載っているのでこれが正しそうな気がしますが、なぜかこれではうまくいきません。
解決方法
これの解決方法は、POST リクエストの Body にこのパラメータを入れること です。つまり、
↑ こうではなく
↑ こうしてください。
Bodyタブを開きx-www-form-urlencodedを選択して、KEYにurl、VALUEにあなたの Webhook URL を指定してください。このときの注意点として、Webhook URL はパーセントエンコーディングしてはいけません。上記の例で説明すると、
https%3A%2F%2Fyour_domain.com%2Fwebhook%2Ftwitterではなくhttps://your_domain.com/webhook/twitterと記載してください。エラーコード 261
エラーメッセージは
Application cannot perform write actionsです。書き込み権限がないというエラーです。{ "errors": [ { "code": 261, "message": "Application cannot perform write actions. Contact Twitter Platform Operations through https://help.twitter.com/forms/platform." } ] }エラーメッセージに「Twitter プラットフォームオペレータに連絡してください」とありますが、アカウントが凍結したりアプリが停止処理を受けていない限りは連絡しても解決しません。そもそもまだ Webhook URL の登録すらできていないのでアプリが停止処理を受けているなんてことはふつうありえません。
原因
このエラーが発生する原因として考えられるのは、アプリに書き込み権限を与えていないこと です。
解決方法
Twitter Portal Dashboard にアクセスし、アプリの権限を変更してやります。
左カラムの
Projects & Appsのタブを開き、使用しているプロジェクトまたはアプリを開き、App permissionsを確認します。ここがRead onlyになっている場合は右上のEditをクリックして権限を変更します。
一番下の
Read + Write + Direct Messagesを選択して保存します。
DM の権限がいらない場合は、おそらくRead and Writeでも問題ないかもしれませんが、試していません。少なくともReadではダメです。次に、
Keys and tokensのタブをクリックし、Access token & secretの権限を確認します。先ほどApp permissionsでRead onlyになっていた場合は、権限修正後もここがRead onlyになっているかと思います。その場合はRegenerateをクリックしてトークンを再発行します。
トークンが変わるので、再度 Webhook URL 登録のリクエストを送る際に忘れずにトークンを変更してください。エラーコード 89
エラーメッセージは
Invalid or expired tokenです。トークンが無効か期限切れであるというエラーです。{ "errors": [ { "code": 89, "message": "Invalid or expired token." } ] }原因
おそらくこれは先ほどのエラーコード 261 の解決法の手順でトークンを変更したのを忘れていた場合に発生すると思います。
解決方法
Regenerateを実行したあとはキーやトークンが変わるので忘れずに変更してください。エラーコード 200
エラーメッセージは
Forbiddenです。これまたシンプルなメッセージですね。シンプルすぎて原因が不明です。{ "errors": [ { "code": 200, "message": "Forbidden." } ] }原因
このエラーが発生する原因として考えられるのは、Account Activity API の Dev environment label を、認証しようとしているアプリに紐づけていないためです。何を言っているのかわからないかと思いますのでスクリーンショットで解説します。
解決方法
左カラムの
Productsのタブを開き、Dev Environmentsを開きます。すると 3 つの環境をセットできる画面が表示されます。そのうちのAccount Activity API / Sandboxの項目を見てください。まだ何も設定していない場合はNOT SET UPと表示されているはずです。その場合はSet up dev environmentをクリックし、環境をセットアップしてください。
Dev environment labelとAppを設定するダイアログが表示されます。Dev environment labelには任意の名前、Appは使用しているプロジェクトまたはアプリを選択します。
Dev environment labelは任意と言いましたが、URL の一部となるため、わかりやすい名前にするのが良いです。本番環境で使用するつもりのアプリならprodやproduction、開発環境で使用するつもりならdevやdevelopmentなどです。とりあえずテストで使うなら
testとしても良いですが、一度設定してしまうと、あとから環境を作り直しても同じ Dev environment label 名は使用することができない そうなので十分注意してください。そして、ここで設定した Dev environment label を、Webhook URL を登録する POST リクエストの URL の
:ENV_NAMEの部分に当てはめます。https://api.twitter.com/1.1/account_activity/all/:ENV_NAME/webhooks.jsonたとえば Dev environment label を
prodcutionとした場合、https://api.twitter.com/1.1/account_activity/all/production/webhooks.jsonとしてください。
エラーコード 357
エラーメッセージは
url: queryParam is requiredです。Webhook URL が設定されていないのが原因です。原因
このエラーが発生する原因として考えられるのは、主に Webhook URL を指定し忘れているか、指定するキーが間違っていることです。
解決方法
Postman を使用している場合は、Webhook URL のパラメータにチェックが入っていることと、
KEYを間違えていないことを確認してください。正しいKEYはurlです。
エラーコード 34
エラーメッセージは
Sorry, that page does not existです。ページが存在しないというエラーです。{ "errors": [ { "message": "Sorry, that page does not exist", "code": 34 } ] }原因
これはおそらく URL の
:ENV_NAMEの部分をそのままにしているパターンです。
解決方法
:ENV_NAMEには Dev environment label を指定します。詳細は「エラーコード 200」の解説を確認してください。エラーコード 131
エラーメッセージは
Internal errorです。その名の通り内部エラーです。エラーが発生してエラー内容が「内部エラー」って何かのとんちですかね?{ "errors": [ { "message": "Internal error", "code": 131 } ] }原因
これはおそらく Webhook URL をサンプルのまま書いているパターンです。
解決方法
https://your_domain.com/webhook/twitterはあくまで例なので、実際に自分が用意した Webhook URL を使用してください。エラーコード 214
エラーコード 214 は原因によって 4 種類のエラーメッセージが発生しました。一つずつ解説します。
Unable to connect during CRC GET request
エラーメッセージは
Unable to connect during CRC GET requestです。「こちらが指定した Webhook URL に Twitter が GET リクエストを送信したところ、GET リクエストが送信できなかった」というエラーです。{ "errors": [ { "code": 214, "message": "Unable to connect during CRC GET request." } ] }原因
これの原因として考えられるのは、Webhook URL が間違っていて Webhook 先のサーバにアクセスできないということです。Postman で Webhook URL として指定した URL をコピーしてその後ろに
?crc_token=fooとつけてブラウザでアクセスしてください。たとえば以下のような URL です。https://your_domain.com/webhook/twitter?crc_token=fooこのときブラウザでは以下のように表示されることが期待されます。
{"response_token":"sha256=2rzGn72Vut3ALp+QtkkTgnQ/dE3tmn/HXT+XThpve4B="}もし Web サイトにアクセスできなかった場合はこのエラーメッセージに該当するはずです。ドメインが間違っていたり、DNS の設定がまだ反映されていなかったり、自分で設定した Webhook 先のサーバがダウンしていたりなどが原因として挙げられます。
Non-200 response code during CRC GET request (i.e. 404, 500, etc)
エラーメッセージは
Non-200 response code during CRC GET request (i.e. 404, 500, etc)です。「こちらが指定した Webhook URL に Twitter が GET リクエストを送信したところ、200 OK ではない HTTP ステータスが返ってきた」というエラーです。{ "errors": [ { "code": 214, "message": "Non-200 response code during CRC GET request (i.e. 404, 500, etc)." } ] }Unable to connect during CRC GET request と同じように Webhook URL の後ろに
?crc_token=fooとつけてアクセスした際に 404 Not Found や 500 Internal Server Error などが表示されるはずです。原因
おそらくこれは Nginx などの Web サーバの設定が間違っているか、Webhook を受け付けるスクリプトの実装が間違っているかです。どちらもサーバのログを見てエラー内容を調べる必要があります。
参考スクリプト
ぼくが使用した Node.js のスクリプトを載せておきます。Node.js で実装しましたが、他のプログラミング言語でも問題ありません。参考にしてみてください。
index.jsrequire('dotenv').config(); const express = require('express'); const app = express(); const port = 5000; const crypto = require('crypto'); app.get('/webhook', (req, res) => { console.log('GET /webhook'); const hmac = crypto.createHmac('sha256', process.env.CONSUMER_SECRET).update(req.query.crc_token).digest('base64'); res.send('{"response_token":"sha256=' + hmac + '"}'); }); app.listen(port, () => { console.log(`App listening at http://localhost:${port}`); });.envCONSUMER_SECRET=<YOUR_CONSUMER_SECRET>command$ npm init $ npm install express --save $ npm install dotenv --save $ node index.js事前に Express.js や dotenv のインストールが必要です。また、
http://localhost:5000を Nginx 等でリバースプロキシする必要があります。Webhook URL does not meet the requirements
エラーメッセージは
Webhook URL does not meet the requirementsです。Webhook URL が要件を満たしていないというエラーです。{ "errors": [ { "code": 214, "message": "Webhook URL does not meet the requirements. Please use HTTPS." } ] }原因
主な原因としては 2 つ考えられます。
HTTPS 対応していない
エラーメッセージに
Please use HTTPSと書かれていることからもわかる通り、Webhook URL は HTTPS でなければなりません。もし HTTPS になっていない場合は Let’s Encrypt などを使用して HTTPS 対応をしてください。Nginx + Let’s Encrypt での対応方法については以前に記事にまとめていますので参考にしてください。
Nginx+リバースプロキシ環境でWebサーバを停止させずに Let's Encrypt (Certbot) のSSL証明書を自動更新するURL の指定方法が間違っている
有効な URL が指定されていないとこのメッセージが表示されます。ご丁寧にも
Please use HTTPSと書かれているのが逆にややこしいですが、http://になっているだけでなく、それ以外の無効な URL だった場合も同様のメッセージなので、正しい URL かどうかを確認してください。よくありがちなのは、パーセントエンコーディングしてしまっている場合です。「エラーコード 32」のときにも書きましたが、POST リクエストの Body に Webhook URL を含める際に、パーセントエンコーディングしてはいけません。
Too many resources already created
エラーメッセージは
Too many resources already createdです。すでに Webhook URL の登録が完了しています。おめでとうございます ?{ "errors": [ { "code": 214, "message": "Too many resources already created." } ] }補足しておくと、無料版1では 1 つしか Webhook URL を設定することができません。
2 つ以上の Webhook URL を登録したかったら 有料版を契約する 必要がありますが、有料版は一番安くても $339 / month (約 35,000 円 / 月)2なので一般人には手が出せませんね……。おそらくこれは企業向けだと思います。
なので、遊びで複数のサービスやアプリを作りたくて、なおかつ Account Activity API を使用する場合は、一つの Webhook URL を使い回すことになります。登録した Webhook URL に Twitter からアクティビティがリアルタイムで届くので、それを受け取るスクリプトを用意しておいて、受け取ったデータを各サービスやアプリにパススルーするような実装になると思います。
正しい設定方法
正しい設定方法でまとめると、以下のようになります。以下は Postman での設定例です。
Authorization
まず
Authorizationタブを開きます。そして以下の通りにパラメータ等を指定します。
番号 値 補足 ① POST② Dev environment label に設定した値 詳しくは「エラーコード 200」の解説を参照 ③ OAuth 1.0④ Request Headers⑤ Signature Method は HMAC-SHA1を指定なお、
Consumer KeyとConsumer Secretというのは Twitter Developer Portal の画面でいうAPI key & secretのことです。View Keysをクリックすれば見ることができます。
Access token & secretは一度だけしか表示されずあとから見ることができませんので、忘れてしまった場合はRegenerateで再発行してください。Headers
次に
Headersタブを開きます。そして以下の通りにパラメータを指定します。
KEY VALUE Content-typeapplication/x-www-form-urlencodedこれは設定しなくてもうまくいくかもしれません。うまくいかなかったら設定してみてください。
Body
最後に
Bodyタブを開きます。そして以下の通りにパラメータ等を指定します。
番号 値 補足 ⑥ x-www-form-urlencoded⑦ KEY に url⑧ VALUE に Webhook URL https://your_domain.com/webhook/twitterではなく、自分の Webhook URL を設定すること終わりに
結構罠があって大変でしたがなんとか Webhook URL を登録することができたと思います。エラーコードで調べてもあまり大した情報がないということと、Twitter のトラブルシューティングやドキュメントページが丁寧なようでいまいちよくわからない内容だったということがあって原因を解決するのに時間がかかりました。
特に罠だと思ったのが、公式ドキュメント にはクエリパラメータとして Webhook URL を指定する例が載っているのにこれではうまくいかないという点ですね。
それから、Twitter のアプリを登録するページの UI や URL が昔とだいぶ変わっていて、現在の UI で紹介されている記事がほとんど見つからなかったのも地味に戸惑ったポイントでした。
この記事が参考になりましたら幸いです。
参考サイト
- 投稿日:2020-11-20T17:17:47+09:00
Box UI Elementsを自前でホスティングする方法
Box UI Elementsを自前でホスティングする方法
BOX UI Elements は、React.jsを使っていない場合、CDNからJSファイルとCSSファイルをダウンロードして利用します。
これらのリソースをCDNを使わずに自前でホスティングする方法をメモしておきます。まとめ (TL;DR)
1. box-ui-elements をCloneして、CSSがフォントを直接参照してる部分を書き換える。
変更するファイルはこれ。
https://github.com/box/box-ui-elements/blob/v12.0.0/src/elements/common/fonts.scss
ビルドする前に、https://cdn01.boxcdn.netとなってる4箇所を、http://localhost:3000 などに書き換えておきます。
マシなやり方あればおしえてください。2. box-ui-elemensをビルドする。
全ロケール、React.js有り無しパターン生成yarn release:cdnまたは、
ja-JPとReact入りのみyarn setup; LANGUAGE=ja-JP REACT=true yarn build:prod:dist3. box-content-preview をビルドする
yarn install && yarn build:i18n && yarn build:prod4. Font、box-ui-elements、box-content-preview をホストする
1でダウンロードしておいたFontと、3、4で生成したものをホストします
5. box-ui-elementsの利用時に、optionsに、
staticHostとpreviewLibraryVersionを指定する
staticHostは自前のホストサーバーpreviewLibraryVersionはBUIEが指している単体のPreviewとバージョンが違うときだけ指定contentExplorer.show(folderId, token, { container: ".container", staticHost: "http://localhost:3000", previewLibraryVersion: "2.58.0" });Box UI Elementsの構成
前提知識として、Box UI Elementsの注意点を書いておきます。
BOX UI Elements(以降BUIEと表記)に関する詳細は、以下のガイドをまずは参照してください。BOX DevのUI Elementsガイド
https://ja.developer.box.com/guides/embed/ui-elements/BUIEはPreviewの中身が別プロジェクト
BUIEは、ガイドにあるように、6個のエレメントでできています。
このうち、BUIEのContent Previewは、Preview機能を単体で提供する、box-content-previewのラッパーです。Github: box-ui-elements
https://github.com/box/box-ui-elementsGithub: box-content-preview
https://github.com/box/box-content-previewBUIEガイドのインストールの箇所で、CDN版のURLが、Content PreviewだけURLのフォーマットとバージョンが違うのは、
実はbox-ui-elementsのContent Previewではなく、box-content-previewのPreviewを向いています。
なぜガイドがこのようになっているのかは不明ですが、BUIEのContent Previewで問題なく動作します。BUIEのPreviewじゃないとサイドバーがでない
このPreviewの2つの大きな違いは、BUIEの方だとサイドバーが出せるということです。
box-content-previewのPreviewだとサイドバーを出せません。ガイドには書かれていませんが、CDNからインストールするときのURLも、BUIEのPreviewを使いたいときは、その他のElementと同じ形で以下のように指定して取得可能です。
https://cdn01.boxcdn.net/platform/elements/11.0.2/en-US/preview.jsガイドに書いてある以下のURLは、単体のPreviewのインストールURLとなります。
https://cdn01.boxcdn.net/platform/preview/2.34.0/en-US/preview.jsまた、グローバル変数の下に作られるオブジェクト名も以下のように変わります。
BUIE Preview: Box.ContentPreview
単体 Preview: Box.Preview両者の使い方はほとんど同じですが、受け取るパラメータに少し違いがあります。
具体的な使用方法は、ガイドのBUIE Sidebarのページの、Sidebar with Content Preview のCodePenのコードを読んでもらうとわかりやすいです。
https://developer.box.com/guides/embed/ui-elements/sidebar/#sidebar-with-content-previewこのサンプルを乗せている以上、BUIE ContentPreviewは使って問題無いはずなのに、手動インストールのURLには乗せていないのでガイドが少しバグってます。
単体のPreviewがBUIEのPreviewからどのように参照されているか
BoxのCDN(https://cdn01.boxcdn.net/) には、BUIEと単体Previewとその他いくつかのものがホストされています。
おそらく以下のような構成です。https://cdn01.boxcdn.net/ ├── fonts │ └── (1.0.2 のようなバージョン番号) │ └── lato └── platform ├── elements │ └── (11.0.2 のようなバージョン番号) │ ├── (ja-JP のようなロケール名) │ └── ... └── preview ├── (2.58.0 のようなバージョン番号) │ ├── (ja-JP のようなロケール名) │ └── ... └── third-party ├── doc ├── media ├── model3d ├── swf └── textCDN経由でインストールされたBUIEは、/platform/elements/11.0.2/ja-JP/xxx を読み込みます。
BUIE Content Previewは、コードの中から強制的にscriptタグを作成し、/platform/preview/2.58.0/ja-JP/preview.js の読み込みを行います。
これは、React.jsを利用している際にNPM経由でインストールしても、この方法でpreview.jsを読み込んでいます。
なぜこのようにしているかは不明ですが、おそらく、preview以下に依存するファイルが大量にあり、相対パスで一括で取り込んでしまいたいという意図があるような気がします。これをおこなっているのが、以下の箇所になります。
BUIE Preivewが単体のPreviewを呼び出すためにスクリプトタグを埋め込む箇所
https://github.com/box/box-ui-elements/blob/1803655c777493c34ccc32ae339445f88cdb1e20/src/elements/content-preview/ContentPreview.js#L466単体のPreviewが、グローバル変数にPreviewオブジェクトを露出させる箇所
https://github.com/box/box-content-preview/blob/83d687ec9ea7f9ff17380c0590e72a947df9ac73/src/lib/Preview.js#L1944BUIE Preivewが、グローバルの単体Previewを読み込む箇所
https://github.com/box/box-ui-elements/blob/1803655c777493c34ccc32ae339445f88cdb1e20/src/elements/content-preview/ContentPreview.js#L787Fontの指定が絶対URLになっている
自前でホスティングしようとした場合、BUIEと単体 Preview以外にも、CDNを直接参照しているものがあります。
それが、BUIEのCSSのFontの指定です。自前でホスティングするためにやらないといけないこと
ここまでをまとめると、BUIEをセルフホスティングしようとしたら、以下のことを行わなければならないということです。
- フォントを絶対URLで指定している箇所を変更する
- BUIEをビルドして、生成されたファイルをホストする
- 単体のPreviewをビルドして、生成されたファイルをホストする
- BUIEのPreviewがコードから単体のPreviewを読み込むので、これを自前のホストに振り向ける
セルフ・ホスティングを行う
さて、本題です。
ここからホスティングを行う準備をしていきます。フォントを絶対URLで指定している箇所を変更する
https://github.com/box/box-ui-elements からCloneします。
以下のファイルを開き、ホストの部分を書き換えます。
https://github.com/box/box-ui-elements/blob/v12.0.0/src/elements/common/fonts.scssfonts.scss@font-face { font-weight: normal; font-family: 'Lato'; font-style: normal; src: local('Lato Regular'), local('Lato-Regular'), url('https://cdn01.boxcdn.net/fonts/1.0.2/lato/Lato-Regular.woff2') format('woff2'), url('https://cdn01.boxcdn.net/fonts/1.0.2/lato/Lato-Regular.woff') format('woff'); } @font-face { font-weight: bold; font-family: 'Lato'; font-style: normal; src: local('Lato Bold'), local('Lato-Bold'), url('https://cdn01.boxcdn.net/fonts/1.0.2/lato/Lato-Bold.woff2') format('woff2'), url('https://cdn01.boxcdn.net/fonts/1.0.2/lato/Lato-Bold.woff') format('woff'); }ここでは、
https://cdn01.boxcdn.netとなっている4箇所を、http://localhost:3000などに書き換えておきます。
運用環境に合わせて変更してください。
イケてないですね・・ ほかにいいやり方あれば教えてください。
利用するときにCSSで上書きできる気もするのですが・・
( @font-faceで名前を変えて定義し、font-familyを!importatで上書きしてみましたがうまくいきませんでした・・・ )
CDNのフォントはホストできるようにダウンロードしておいてください。BUIEをビルドして、生成されたファイルをホストする
BUIEのCDN版のビルド方法は、ガイドに説明はのっていませんが以下のコマンドで行えます。
yarn release:cdnこのコマンドは、package.jsonを見てもらうとわかりますが、/scrips/prod.jsを実行します。
準備されているロケールに対して、Reactが入ってるものと入っていないものをそれぞれ生成します。
この実行は非常に時間がかかり、私の環境では2時間近くかかりました。
もしも日本語用でReactを含んだものだけを生成したい場合、以下のコマンドでクイックに生成可能です。yarn setup; LANGUAGE=ja-JP REACT=true yarn build:prod:distこのコマンドを実行すると、/distフォルダ以下に以下がつくられます。
0.0.0-semantically-released というのは、package.jsonのversionの値です。
おそらくCIで、12.0.0のように適切なバージョンに置き換えて生成してるものと思います。. └── 0.0.0-semantically-released └── ja-JP ├── explorer.css ├── explorer.js ├── openwith.css ├── openwith.js ├── picker.css ├── picker.js ├── preview.css ├── preview.js ├── sharing.css ├── sharing.js ├── sidebar.css ├── sidebar.js ├── uploader.css └── uploader.js単体のPreviewをビルドして、生成されたファイルをホストする
次に、単体のPreviewをビルドします。
Content PreviewのSelf Hostingパッケージの作り方はこちらに説明があります。(ちょっと間違ってます・・・汗)正しくは以下です。
yarn install && yarn build:i18n && yarn build:prodこのコマンドを実行すると、/distフォルダに以下が作られます
バージョン番号 2.58.0の下にロケール別のフォルダや、third-partyというフォルダが作られます。. ├── 2.58.0 │ ├── bn-IN │ ├── (... 省略:サポートされているロケール毎のフォルダ) │ └── zh-TW └── third-party ├── doc │ ├── 1.17.0 │ ├── ( ... 省略 ) ├── media │ ├── 0.127.0 │ ├── (... 省略) ├── model3d │ ├── 1.10.1 │ │ └── WebVR │ │ ├── (... 省略) │ ├── (...省略) ├── swf │ └── 0.112.0 └── text ├── 0.112.0 └── 0.114.0あとで解説しますが、ここで生成した2.58.0のようなバージョンは、フォルダ名に反映されますが、このフォルダ名はBUIEのPreviewが指定してきます。
BUIE Previewと単体Previewを連動させるため、バージョンをあわせる必要があります。
BUIE Previewが指定しているバージョンの単体Previewを元に生成するか、指定の単体Previewのバージョンをパラメータで変更します。サンプルコードを作って動作確認
Express.jsで動作する簡単なサンプルをつくってみます。
雛形を作ります。
mkdir sample cd sample npm init -y npm i express touch app.js mkdir lib以下がフォルダ構成です。
libフォルダ(名前は何でも・・)以下に、生成されたファイルを置いてください。. ├── app.js ├── lib │ ├── fonts │ │ └── 1.0.2 │ │ └── lato │ │ ├── Lato-Bold.woff │ │ ├── Lato-Bold.woff2 │ │ ├── Lato-Regular.woff │ │ └── Lato-Regular.woff2 │ └── platform │ ├── elements │ │ └── 12.0.0 │ │ └── ja-JP │ └── preview │ ├── 2.58.0 │ │ ├── bn-IN │ │ ├── ... │ └── third-party │ ├── doc │ ├── media │ ├── model3d │ ├── swf │ └── text └── package.json
app.jsはこんな感じです。app.jsconst path = require("path"); const express = require("express"); const app = express(); const HOST = "http://localhost:3000"; const ACCESS_TOKEN = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; //開発者トークンを利用 const oneHour = 1000 * 60 * 60; app.use( "/platform", express.static(path.join(__dirname, "lib", "platform"), { maxAge: oneHour }) ); app.use( "/fonts", express.static(path.join(__dirname, "lib", "fonts"), { maxAge: oneHour }) ); app.get("/explorer", async (req, res) => { res.set("Content-Type", "text/html"); res.send( ` <!DOCTYPE html> <html lang="en-US"> <head> <meta charset="utf-8"/> <title>BUIE Self Hosting Sample</title> <script src="${HOST}/platform/elements/12.0.0/ja-JP/explorer.js"></script> <link rel="stylesheet" href="${HOST}/platform/elements/12.0.0/ja-JP/explorer.css"/> </head> <body> <div class="container" style="height:600px"></div> <script> const folderId = "0"; const token = "${ACCESS_TOKEN}"; const contentExplorer = new Box.ContentExplorer(); contentExplorer.show(folderId, token, { container: ".container", staticHost: "${HOST}", previewLibraryVersion: "2.58.0" }); </script> </body> </html> ` ); }); app.get("/preview", async (req, res) => { res.set("Content-Type", "text/html"); res.send( ` <!DOCTYPE html> <html lang="en-US"> <head> <meta charset="utf-8"/> <title>BUIE Self Hosting Sample</title> <script src="${HOST}/platform/elements/12.0.0/ja-JP/preview.js"></script> <link rel="stylesheet" href="${HOST}/platform/elements/12.0.0/ja-JP/preview.css"/> </head> <body> <div class="container" style="height:600px"></div> <script> const fileId = "727216965561"; const token = "${ACCESS_TOKEN}"; const ContentPreview = new Box.ContentPreview(); ContentPreview.show(fileId, token, { container: ".container", staticHost: "${HOST}", previewLibraryVersion: "2.58.0" }); </script> </body> </html> ` ); }); const PORT = process.env.PORT || "3000"; app.listen(PORT, () => { console.log("Express Server started on port: " + PORT); });BUIEのPreview、Explorerがコードから単体のPreviewを読み込むので、これを自前のホストに振り向ける
BUIEのShowメソッドにわたすオプションで、
staticHost、previewLibraryVersionを指定しています。
これにより、BUIE Content Previewや、BUIE Content Explorerのように、コードから単体のPreviewを読み込む箇所での、CDNのURLを変えることが可能です。動作確認
このコードは
node app.jsで実行すると、
以下のURLでBUIEの動作確認が可能です。http://localhost:3000/explorer,
http://localhost:3000/preivewブラウザにChromeをお使いであれば、検証 → Networkから、ダウンロードされるリソースがすべてCDNでなくローカルから落ちてきていることが確認可能です。
- 投稿日:2020-11-20T15:11:39+09:00
LINEの絵文字・スタンプメッセージ送信メモ
これはうまくいくけど、
let text_length = pushText.length; pushText += "$" // チャンネルに登録されている方たちに連絡 client.broadcast([{ type: "text", text: pushText, "emojis": [ { "index": text_length, "productId": "5ac1bfd5040ab15980c9b435", "emojiId": "002" } ] }]).then(data => console.log(data))こっちのスタンプはうまくいかんのなんでやろ。指定の仕方がまちがってるのか?
client.broadcast([{ type: "sticker", packageId: "11537", stickerId: "520027451" }]).then(data => console.log(data)) .catch(e => console.log(e))追記⇒ただのIDのコピペミス!!「520027451」の最後の1がいらなかった。見たところ、他のも全部8桁や。
- 投稿日:2020-11-20T13:43:08+09:00
タスクランナーで作ったサイトをHerokuでデプロイする
npm-scriptsやgulpで静的サイトを作った際にHerokuをテストサーバにしたい時の手順です。
前提
npm-scriptsやgulpで静的サイトを作った場合、管理の都合で、静的サイトはgitigoreしていることが多いと思います。
同じリポジトリのまま、Herokuへデプロイする手順です。手順
(1) Heroku上でnodeでサーバを立ち上げるファイルを作る
# Procfileを作る echo 'web: node server' >> Procfile # expressをインストール npm i express # server.jsを作成する touch server.js(2) Herokuでサーバーを立ち上げるserver.jsを編集
server.jsvar express = require('express'); var app = express(); var user = process.env.USER; var pass = process.env.PASS; app.set('port', process.env.PORT || 3000); if (user && pass) { app.use(express.basicAuth(user, pass)); } app.use(express.logger('dev')); app.use(express.compress()); app.use(express.static(__dirname + '/dist')); app.listen(app.get('port'), function() { console.log('Server listening on port %s', app.get('port')); });
/distをルートディレクリとしてサイトを作成している想定です。必要に応じて編集してください。(3) package.jsonへheroku環境でサイトをビルドするスクリプトを入力
package.json{ "scripts": { "postinstall": "gulp build" } }Heroku上でpackageのインストールが完了したあとにpostinstallが実行されます。
postinstallにはサイトをビルドするスクリプトを記入してください。(4) デプロイする
# アプリーケーション heroku create # デプロイ git push heroku master # アプリケーションを開く heroku open
heroku create アプリ名でアプリ名を指定することもできます。

















