質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

91.03%

  • Google Apps Script

    572questions

    Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

  • ChatWork

    17questions

    業務の効率化を目的としたコミュニケーションツール。 グループチャット、ビデオ・音声通話、ファイル共有、タスク管理などの機能を備えています。マルチデバイス対応で、ブラウザだけでなくタブレットやスマートフォンでも利用可能です。

GASでFor文の入れ子がうまくいかない

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 329

普段はプログラミングとは全然関係のない仕事をしています。
調べながらGASを書いてみたのですが、うまくいきません。
下記、ヒントをいただけますと幸いです。

前提・実現したいこと

RSSの内容を、ChatWorkに流したいと思っています。

  • RSSは複数URLあり、下記のようにA列にURL、B列にサイト名の形でGoogleスプレッドシートに入っている。
A B
RSSのURL1 サイト名1
RSSのURL2 サイト名2
  • GASを使ってChatWorkに流したい

  • 最終的なアウトプットは、下記を目指している


<サイト名1>
ページタイトル1-1
URL1-1

ページタイトル1-2
URL1-2

<サイト名2>
ページタイトル2-1
URL2-1

ページタイトル2-2
URL2-2


発生している問題・エラーメッセージ

現在、出力はできているのですが、最終的に目指している形になっていません。
下記のように、1つ目のRSSのサイト名のみ出てきます。


<サイト名1>
ページタイトル1-1
URL1-1

ページタイトル1-2
URL1-2

ページタイトル2-1
URL2-1

ページタイトル2-2
URL2-2


また、RSSを直に見たときと、チャットワークにはき出されるURLの数も違います。

該当のソースコード

IDやトークンなどは念のためxxxxxで伏字にしております。

function sendNewsToChatwork() {

  //現在のスプレッドシートを取得
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  //現在のシートを取得
  var sheet = spreadsheet.getActiveSheet();
  //最後の行を取得
  var rowSheet=sheet.getDataRange().getLastRow();

  //チャットワークトークン
  var client = ChatWorkClient.factory({token:'xxxxxxxxxxxxxxxx'});
  //投稿するチャットルームのID
  var room_id = xxxxxxxx;

  //フィードからデータを取得
  for( var i=1;i<=rowSheet;i++ ) {
    //RSSのURL一覧が入っているセルを取得
    var range = sheet.getRange(i,1).getValue();
    //GoogleアラートのRSSフィード
    var feedURL = range;
    //サイト名取得
    var sitetitle = sheet.getRange(i,2).getValue();
    //サイト名を流す
    //   client.sendMessage({room_id: room_id, body: "<" + sitetitle + ">"});


  var atom = XmlService.getNamespace('http://www.w3.org/2005/Atom');
  var document = XmlService.parse(UrlFetchApp.fetch(feedURL).getContentText());
  var items = document.getRootElement().getChildren('entry', atom);


  //取得した件数分チャットワークへ投稿
  for(var j = 0; j < items.length; j++) {
    //サイトのURLを取得
    var link = items[j].getChild('link', atom).getAttribute('href').getValue();
    //サイトのタイトルを取得
    var title = items[j].getChild('title', atom).getText();
   //URLとタイトルを連結
  if (j == 0){
      var message = "<" + sitetitle + ">" + "\n" +  title + "\n" + link;
    }else{ 
      var message = title + "\n" + link;
    } 
  }

   //HTMLタグを除去してチャットワークへ投稿
    client.sendMessage({room_id: room_id, body: message.replace(/<("[^"]*"|'[^']*'|[^'">])*>/g,'')});
 }

  /*//テスト投稿
  client.sendMessage({room_id: room_id, body: range});*/
}

試したこと

現在【URLとタイトルを連結】の箇所に入っているサイト名をはき出す部分を【サイト名取得】の下にコメントアウトしてある部分を使って別にしてみたところ、下記のようにそれぞれのRSSの一つ目のURLのみ出るようになりました。


<サイト名1>
ページタイトル1-1
URL1-1

<サイト名2>
ページタイトル2-1
URL2-1


  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+2

普段はプログラミングとは関係無いお仕事に従事されつつも、業務改善の為に自らプログラミングをされる姿勢、感じ入った次第です。少しでも助けになればと思い、コードと動作を確認させていただきました。

何点か問題が見受けられました。ただ、質問者様が利用されているRSS/AtomフィードのURLが分からなかった為、こちらで適当なフィードを試した結果ですのでその点はご承知置きください。

まず始めに、

 //URLとタイトルを連結
  if (j == 0){
      var message = "<" + sitetitle + ">" + "\n" +  title + "\n" + link;
    }else{ 
      var message = title + "\n" + link;
    }

   //HTMLタグを除去してチャットワークへ投稿
    client.sendMessage({room_id: room_id, body: message.replace(/<("[^"]*"|'[^']*'|[^'">])*>/g,'')});


で、message 変数の宣言に問題があり、未初期化のmessage変数を
client.sendMessage({room_id: room_id, body: 省略
で使用するかたちになり停まってしまっていたケースがありました。また、ループ内でmesseageに適切に連結できていないように見受けられましたので、これも修正の必要があるように思いました。

次に、「1つ目のRSSサイトしか出ていかない」原因ですが、以下のコード
document = XmlService.parse(UrlFetchApp.fetch(feedURL).getContentText());
で受信するフィードの内容がXMLとして不完全で、JavaScriptの例外(Exception/要はエラー)が発生してしまい、その内容が処理されずにスキップ〜ChatWorkに送信する前に強制終了してしまうケースがありました。フィードの内容(XML)が不完全なのはコンテンツ提供側の問題なので、こちらではどうしようも無いと思います。これも

RSSを直に見たときと、チャットワークにはき出されるURLの数も違います。

の原因のひとつかと考えられます。上記を踏まえて修正、確認してみたコードが以下になります。

function sendNewsToChatwork3() {

    //現在のスプレッドシートを取得
    var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
    //現在のシートを取得
    var sheet = spreadsheet.getActiveSheet();
    //最後の行を取得
    var rowSheet = sheet.getDataRange().getLastRow();

    //チャットワークトークン
    var client = ChatWorkClient.factory({ token: '----------------' });
    //投稿するチャットルームのID
    var room_id =  '--------';

    //フィードからデータを取得
    for (var i = 1; i <= rowSheet; i++) {
        //RSSのURL一覧が入っているセルを取得
        var range = sheet.getRange(i, 1).getValue();
        //GoogleアラートのRSSフィード
        var feedURL = range;
        //サイト名取得
        var sitetitle = sheet.getRange(i, 2).getValue();
        //サイト名を流す
        // client.sendMessage({room_id: room_id, body: "<" + sitetitle + ">"});

        try {
            var atom = XmlService.getNamespace('http://www.w3.org/2005/Atom');
            var content = UrlFetchApp.fetch(feedURL).getContentText();

            // XmlService.parseで不正なXMLの為に例外が起きるケース有り。
            var document = XmlService.parse(content);
            var items = document.getRootElement().getChildren('entry', atom);

            // サイト名をあらかじめセットしておく
            var message = "<" + sitetitle + ">";
            //取得した件数分チャットワークへ投稿
            for (var j = 0; j < items.length; j++) {
                //サイトのURLを取得
                var link = items[j].getChild('link', atom).getAttribute('href').getValue();
                //サイトのタイトルを取得
                var title = items[j].getChild('title', atom).getText();
                //タイトルとURLを連結
                message += "\n" + title + "\n" + link;
            }

            //HTMLタグを除去してチャットワークへ投稿
            message = message.replace(/<("[^"]*"|'[^']*'|[^'">])*>/g, '');
            client.sendMessage({ room_id: room_id, body: message });
        } catch (e) {
            // XMLのパースが失敗した場合、例外
            Logger.log("excepton: " + e);
        }
    }
}


完全に質問者様の要望通りの送信内容になっているかは分かりませんが、よろしければお試しください。完成までもう少しだと思いますので、もう一息がんばってください。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/11/02 11:08

    ご回答ありがとうございます。
    いただいたコードを試してみたところ、考えていた通りの投稿になりました!
    ありがとうございました。
    理解できていない部分はもう少し調べて自分のものにしたいと思います。

    キャンセル

  • 2017/11/02 11:13

    早速お試しいただいたこと、並びにご報告どうもありがとうございます。お役に立てて良かったです。発展させると色々と面白いことができそうですね。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 91.03%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

  • 受付中

    GAS ドキュメント作成

    DocumentAppドキュメントを作成したいのですが、パスの指定方法がわかりません。 公式リファレンスで調べたところパスを指定するメソッドが見当たらないのですがどう指定すれば良

  • 解決済

    GoogleスプレッドシートからGASで文字列を検索する方法を教えてください

    Googleフォームの回答のスプレッドシートをGASでメールに送信するものを作っています。 質問 最終行の特定の列の文字列を同じ列から検索して、 条件分岐で、 すでに同

  • 解決済

    ChatWorkのtask一覧を取得したいです。

    こんにちは。  Windows10でアプリケーションを開発しています。  Visual Studio 2015 Communityを使っています。  前提・実現したいこと

  • 解決済

    Google Apps Script  query関数で読み込んだデータのGASでの取得

    前提・実現したいこと query関数で読み込んだデータを GASを使用して条件による色分けを行おうとしています。 発生している問題・エラーメッセージ query関数でデ

  • 解決済

    phpで謎の構文エラー

    どこがおかしいのか、いまいち掴めません、php詳しいかた、教えていただければ幸いです  やりたいこと phpでチャットワークのapiを叩いてphpに記述してある文字列をchat

  • 解決済

    GASのスプレッドシート 配列 高速化

    前提・実現したいこと ここに質問したいことを詳細に書いてください スプレッドシートにランダム関数を最終行まで(約3000個)、一列に並べるスクリプトを作りたい 発生している問題

  • 解決済

    LINE notify メッセーじが途中で切れてしまう

    ほんとうに初歩的なことだと思うのですが 自分なりにGoogleで検索をいろいろ掛けたのですがわからなかったので質問させていただきます。 前提・実現したいこと amazon・楽天

  • 解決済

    DelphiでChatWorkApiを用いたpost

    Delphiを用いて、ChatWorkへのメッセージ投稿をしようと考えています。 コンポーネントとしてIndyのIdHTTPを使用しようと思っています。 unit Unit1;

同じタグがついた質問を見る

  • Google Apps Script

    572questions

    Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

  • ChatWork

    17questions

    業務の効率化を目的としたコミュニケーションツール。 グループチャット、ビデオ・音声通話、ファイル共有、タスク管理などの機能を備えています。マルチデバイス対応で、ブラウザだけでなくタブレットやスマートフォンでも利用可能です。