投稿

ラベル(ソフト開発)が付いた投稿を表示しています

[GAS] 唐突にException: Bandwidth quota exceeded: {URL}. Try reducing the rate of data transfer. と言うエラーが発生

Bloggerや小説家になろうへの投稿をXにフィードするために、一年半ほど前にGoogle Apps Scriptでプログラムを作り、動かしてきました。 が、それが、4月の下旬になって、突然 Bandwidth quota exceeded と言うエラーを吐いて動かなくなる事象が発生。 いつものように記事を投稿しようとした時に、予告も無しにエラーが発生しため、少し焦りました。 調べた所、どうやら UrlFetchApp.fetch() を呼び出す間隔が短いと発生する物らしいと分かり、fetch()について、4~7秒の間隔を開けるようにコードを見直した結果、エラーの発生が止まりました。 一年以上も動かしていたのに何故、と思いましたが、何かの理由でGASでのfetch()の利用に制限が追加、あるいは制限が強化されたのだろうと考えています。 fetch()を間断なく呼んでいるコードを書いていると引っ掛かる可能性があるので、要注意です。 なお、GoogleのAIによる回答では、以下でした。 A "Bandwidth Quota Exceeded" error in Google Apps Script (GAS) means your script has exceeded the daily or temporary data transfer limits (upload/download) permitted by Google . This usually occurs when using UrlFetchApp to process large amounts of data, frequent API calls, or high-volume scraping.  送受信するデータサイズは小さくても発生しているので、frequent API callsで引っ掛かったのだと思います。 ではでは。

(テストです) タイトル中のアンド記号(&)はAtomでどう表現されるのか?

小説家になろうのサイトの活動報告のタイトルにアンド記号(&)を使ったところ、Xの方に&で表示されてしまいました。 調べると、活動報告の記事一覧のAtomのtitle欄に、HTMLエスケープされた状態で収められていて、それがそのままGASのプログラムに渡ったようです。 では、Bloggerだとどうなるのか?この記事で試してみました。 結果、こちらの記事のAtomにおいても、アンド記号(&)は&で表現されていましたので、そこは共通だと考えて、title取得時にHTMLエスケープを外す処理を追加したのでした。

[GAS] ATOMを読み取ってGoogle Spreadsheetに書き込む

イメージ
残念なことに、dlvr.itの無料プランが無くなると言うことで、ブログの記事をXにフィードするには自前で何とかするしかなくなりましたね。 そんなわけで、GASを初めてX APIを調べ始めたわけです。 で、一応、Xへの投稿ができることは分かったので、次はブログの記事の確認方法を調べていきます。 そもそもdlvr.itを設定するにあたって、ブログのAtomは調べてあったので、そのAtomを拾って解析すれば良いよね、と考えました。 拾ったAtomは保存することになります。保存先は何かと考えれば、まあ、Google Spreadsheetですよね。 なので、まずは、新しいGoogle Spreadsheetを作ります。 Googleドライブの画面で、ファイルの表示されているところで右クリックし、でてきたメニューから「Googleスプレッドシート」を選択。 その画面で、「拡張機能」→「App Script」を選んで、Google App Scriptの画面を出します。 そこで、コード.gsの中身を以下で置き換えます。 function fetchAtomFeedTsuretsu() { // AtomフィードのURL const url = 'https://tsuretsu.blogspot.com/feeds/posts/default'; // ネームスペース const ns = XmlService.getNamespace('http://www.w3.org/2005/Atom'); const ns_media = XmlService.getNamespace('http://search.yahoo.com/mrss/'); // Atomフィードを取得 let response = UrlFetchApp.fetch(url); let xml = response.getContentText(); // XMLデータをパース let document = XmlService.parse(xml); let root = document.getRootElement(); // エントリーを取得 let entries = root....

[GAS,X API] GASでX APIを使ってメッセージを投稿する

イメージ
GASを使おうと思ったのは、はい、X APIを使いたかったからです。 XのAPIを叩く方法は、調べてみると幾つかありそうでした。 その中で、自分でサーバを運用しなくてよくて、定期的にブログなどの状態を見てX側に投稿する仕組みを作るのに良さそうな環境は、GASみたいだなと思ったのです。 で、GASの使い始めは 昨日の記事で書いている ので、今回はX APIの使い方について。 詳しく書くと、とても分量が多くなるので、超絶簡単に参考にした記事と、それに対する補足を並べていこうかと思います。 (1) X開発者プラットフォームへの登録 これには、以下の記事を参考にしました。 「 Twitter API v2(X API Free)の使い方・移行(2024年)【GAS】 」(Qiita: 外部リンク)  プロジェクト画面を開くまで、詳細に書かれています。 開発者ポータル( https://developer.x.com/ja )、最初の表示は以下です。 未登録だと、右上にメニューの横三本線(「三」みたいな表示)があるので、そこを押して、 出てきたメニューから「開発者ポータル」を押します。 あとは、ログインして、登録して...ですね。それでプロジェクトの画面が出ます。 無料のアカウントですと、プロジェクトは一つしか作れませんから、最初に作られたプロジェクトで話を進めます。 で、ここでいくつかの情報を入手しないといけません。 API KeyとAPI Secret Access TokenとそのSecret Client IDとClient Secret これらのうち、前者二つはOAuth1の認証で利用し、最後の一つはOAuth2で使います。 かつ、前記記事にあるように、Client IDとClient SecretはフィードバックのURLを設定することで得られます。 (2) さてどうして、OAuth1とOAuth2の両方の情報が必要かと言えば、X APIで画像付きのメッセージをポストするには、OAuth1(X API V1.1)を使って画像をアップロードし、OAuth2(X API v2)を使ってメッセージを投稿しないといけないからです。 逆に言えば、画像無しのテキストの投稿ならOAuth2の情報のみで大丈夫です。 そして、それの実例が以下の記事で示されています。 「 OA...

[GAS] Google Apps Scriptを始めよう

イメージ
唐突ですが、Google Apps Script (GAS)を使い始めました。 その動機については後にして、簡単な使い方を備忘録的にまとめておきます。 GASは、言語仕様としてはJavaScriptに準拠していますが、ライブラリは異なります。 また、独立したプロジェクトとして動作させることもできますが、Google Spreadsheetなどと連動して動作させることもできます。 独立したプロジェクトの場合には、GASのトップから、開始します。 GASのトップのURLは検索すればすぐにわかると思いますが、以下です。 https://www.google.com/script/start/   (文章の続きは画像の後) GASのトップ画面から、右上の"Start Scripting"を押せばプロジェクトの画面に移ります。 一方、Google Spreadsheetと連動させる場合は、Google Spreadsheetの画面の中で、「拡張機能」から「Apps Script」を選ぶと、GASのプロジェクト画面に移ります。 プロジェクトの初期画面では、空の関数が書かれた「コード.gs」が出来ているのではないかと思います。 例えば、自分宛にテストメールを送信してみるなら、このmyFunctionの定義を消して、以下のようなコードを書きます。 // メール送信サンプル function testMailToMyself() { let subject = "テストメール"; let body = "これはテストです。"; let name = "スクリプトから送信"; sendMailToMyself(subject, body, name); } /** * (自分のアカウントへの)メールの送信 * * @param {string}subject メールのタイトル * @param {string}body メールの本文 * @param {string}name 発信者名 */ function sendMailToMyself(subject, body, name) { // パラメータ無しで呼び出したときにメール発信しないように防御 if (...