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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Slack

Slackは、Tiny Speckという企業からリリースされたコミュニケーションツールです。GoogleDriveやGitHubなど、さまざまな外部サービスと連携することができます。

Q&A

1回答

2099閲覧

node.jsを利用してSlackの各チャンネルの最終投稿を全て取得したい

sasagar

総合スコア15

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Slack

Slackは、Tiny Speckという企業からリリースされたコミュニケーションツールです。GoogleDriveやGitHubなど、さまざまな外部サービスと連携することができます。

0グッド

0クリップ

投稿2017/02/18 05:05

編集2017/02/20 02:28

###前提・実現したいこと
node.jsを利用し、複数のチームのSlackからチャンネル情報を取得して、
全チャンネル(絞り込みは追って対応するとして)の最終投稿を取得したいと考えています。
それらを選別・整形し、最終的にはHTMLで出力することを想定しています。

###試したこと
asyncを利用して書いたりした物の、どうしてもforforEachが発生し、
同期処理と非同期処理(で良いもの)が入り乱れ、
何をどうしたら正しく処理が進むのか解らなくなってきてしまっています。
APIの取得は完了を待たねばならず、その辺りの解消法が一番重要だと思っています。

個別に質問をして解消を...と思った物の、
複数のAPI呼び出しが1つのネックになっている事も踏まえ、まとめた形で改めて質問を
することにしました。

理想の流れとしては、

// ここからtokenの数だけ繰り返し [API] 該当チームの情報取得 [API] 該当チームの全てのチャンネル情報を取得(プライベートチャンネルのみで良いのでgroupsが対象) // ここからチャンネルの数だけ繰り返し [API] 各チャンネルの最終投稿を取得 [API] 最終投稿のユーザ名などを取得 受け取ったユーザ名と投稿内容の結合 チャンネル情報と投稿の情報の結合 // ここまで // ここまで 全てのデータの結合(やもすれば、繰り返しの中でpushする?) 該当のデータ絞り込み作業 HTMLに整形

だと思っています。
外部APIを利用するため、酷く躓いている気がするのですが、教えていただけたら幸いです。


2017/02/20追記

どこまでやってみたかという部分なのですが、
結局の所、繰り返した実行結果をループの外側に持ち出すことで問題が起きている印象です。

若干混乱しており、何が何だか...という状態になっていることも否めないのですが、
一番外側の繰り返しについては、取得結果を繰り返し利用することも無く、無事に取得して、次の処理に渡す事はできています。

問題は、その取得したグループ情報を1つずつやりくりし、全ての結果を拾って1つの配列にまとめるという部分かと思っています。

うまくお伝えできているかわからず恐縮ですが、コレで、少し伝わったでしょうか...。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ezaki

2017/02/18 14:32

前回のご質問も拝見しまして、非同期処理周りでお困りなのかな…と思いますが、どのような回答をお求めなのかがイマイチ掴みきれません。「ここまでできたがここからが分からない」ということを明確にすることは可能ですか?
guest

回答1

0

追記ありがとうございます。
頂いた内容を元に、やりたいと考えられているであろう内容を回答いたします。

配列データに対して非同期処理を回し、結果を配列にして返す

それぞれのグループ情報に対して非同期処理(今回はAPIを叩いてデータを取得する)を行い、
全ての結果を配列として格納するということなので、

javascript

1 2var async = require("async"); 3var https = require("https"); 4 5var group = [ 6 {"id":"hoge"}, 7 {"id":"fuga"}, 8 {"id":"piyo"} 9]; 10 11// 配列のそれぞれのデータが data に格納される 12async.map(group, (data, next) => { 13 // API を叩く 14 https.get("https://example.com/", (res) => { 15 16 var body = ""; 17 18 res.on("data", (chunk) => { 19 body += chunk; 20 }); 21 22 res.on("end", () => { 23 var json = JSON.parse(body); 24 // 各データについて、結果を格納 25 next(null, body.data); 26 }); 27 }); 28}, (err, result) => { 29 // next の第二引数で渡した値が、配列になって result に入ってくる 30 console.log(result); 31}); 32

 こんな感じになるのではと思います。

async を使用されているということですので、 async.map を使用しました。
これは、第一引数の配列データをそれぞれ第二引数の関数に渡し、
全てのデータに対して next が実行された時点で
第三引数の result にデータを配列にして入れてくれる、というものです。

今やりたいと思われていることと一致するのではないでしょうか。

非同期処理を直列に配置する

非同期処理と同期処理が混ざって混乱されている部分もあるようですので、
その部分についても私なりの解決法を提案いたします。

こちらも async を利用されていますので、
async.waterfall を使用されるのが良いかと思います。

javascript

1 2var async = require("async"); 3 4var group = [ 5 {"id":"hoge"}, 6 {"id":"fuga"}, 7 {"id":"piyo"} 8]; 9 10async.waterfall([ 11 (cb) => { 12 // 非同期処理 13 async.map(group, (data, next) => { 14 next(null, data.id); 15 }, (err, result) => { 16 cb(null, result) 17 }); 18 }, 19 (arg, cb) => { 20 // 同期処理 21 var sync = arg.map((data) => { 22 return data + "!!!"; 23 }); 24 cb(null, sync); 25 } 26], (err, arg) => { 27 console.log(arg); // [ 'hoge!!!', 'fuga!!!', 'piyo!!!' ] 28}); 29

async.waterfall は直列につなげた関数のコールバックに渡されたデータを、
次の関数で使用できる特徴があります。

ここで注意したいのは、(当然のことですが) async.waterfall 内での処理は
非同期処理を行う関数でなくとも良い点です。

それぞれの処理を(非同期・同期処理関係なく)関数にまとめて、
return の代わりにコールバックを呼び出す形にすることで
簡単に直列に繋ぐことができ、見通しもよくなるのではと思います。

すでに流れとして、動作を部品ごとに分ける作業はされているようですので、
あとはそれぞれを async.waterfall で繋ぐことで
期待する処理がかけるのではないでしょうか。


この回答で、お役に立てましたでしょうか。
もし、イメージされていることと異なっている場合は改めて追記いただくか、
新しく記事を立てていただけるとありがたいです。

投稿2017/02/20 08:13

ezaki

総合スコア204

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問