はじめに
どうも、たにあんです。今回もmakeの話です。
12月にmakeを初めて触り、なんやかんや継続してmakeを弄っています。実装していく中でつまずいたポイントやmakeの仕様に関わる話をまとめておこうと思った今日この頃です。
makeを触ったら1回はぶち当たるであろう壁みたいなポイントがいくつかあるので、解説していきたいと思います。他のiPaaSは知ってるけどmakeは知らん、makeでこれから自動化したいでーみたいな人向けだと思っています。
Sample Scenario
以下のScenarioをベースに後述するポイントを説明していくので、Scenarioの概要を記載しておきます。
簡潔に説明すると、「自分宛のメンションメッセージのうち、スレッドに返信できていない投稿を検出する」Scenarioになっています。


ポイント
複数のBundleの実行順を理解しよう
まず、BundleとはmakeのModuleで実行された結果(OUTPUT)を受け取る際のデータの基本単位です。makeが自動で「Bundle」というデータ単位に分けてくれます。
このとき、Bundle毎に後続Moduleが実行されます。
※ 正直、他のiPaaSではどのように取り扱われているのか分かりませんので、もしかしたら当たり前かもしれません。
以降で具体例を見ていきます。
今回作成したScenarioだと、Slack「Search for Message」を用いて特定ワードでSlackメッセージを検索した結果、左下画像のようなOUTPUTを受領することになります。
仮にOUTPUTとしてBundle1, 2の2つを受領したとすると、後続のModuleは右下画像のような順番で処理されます。Bundleが増えたとしても、Bundle2が完了したら同様にBundle3が実行されて…という流れで続いていきます。


さらに、今回の例では「Search for Messages」が実行されたら、「List Replies」というModuleが実行されます。Slackの特定スレッドについて、スレッドのメッセージをごっそり取得するためのModuleであり、スレッド内に複数のメッセージが存在したら左下画像のようにBundleが分かれます。
仮に、前述の「Search for Messages」でBundle1, 2を取得し、Bundle1が実行された結果、「List Replies」ModuleでBundle1-1, 1-2を取得したことを想定すると右下画像のようになります。Bundle1-2の処理が終了したら、Bundle2のデータが「List Replies」Moduleに渡され、OUTPUTのBundle数に応じて後続の処理が順次実行されます。


Bundleが多くなってくると、どういう順番で実行されるかによって、条件(Filter)の作り方や処理そのものが変わってくる可能性もあるのでご注意を。
Set variable / Get variableは気にするな
makeの有料プランにおいて、変数はいくつかの種類がありますが、Scenario内で変数の設定ができる「Set variable」Moduleに限った話です。
makeの変数についてはこちら:make Help Center – Variables, make Help Center – Tools
「Set variable」で設定できる変数は、基本的にJavaScriptにおけるconst
に近しい存在です。x += 1
といったこともできないので、プログラミング言語で呼ばれているような変数ではないです。ただ、「Set variable」Moduleで同じ変数名を設定すると上書きはできます。つまずきポイント(ぼくはめっちゃつまずきました)。
そんなVariableにも使えるシチュエーションはありそうです(参考までに画像も貼っておきます)。
- 1つ前のBundleで実行された値を保持しておく。
- 別の分岐上で実行された「Set variable」の値を取得する。
- Bundleが特定の条件に一致した場合、ある値を保持しておく。

こんなこと書いてますが、後述のコラム1でバリバリ使って処理を作りましたので、全然使い道あります。
Bundle(配列)間のデータの処理はData Storeを使おう
ここまでのポイントで勘の良い方はお気づきかもしれませんが、Bundleを跨いで値を取得することが基本的に難しいです。1つ前のBundleで実行された値や、特定の位置に存在するBundleのとある値を「Set Variable」で取得することは可能ですが、動的に変化するシチュエーションでは極めて使いにくいです。Bundleのみならず配列(Array)でも同様です。
例えば、「List Replies」Moduleで以下のようなデータを取得したとします。画像にはBundle2までしか映ってませんが、3つ以上でも構いません。

「List Replies」のレスポンスデータ全体からAさんとBさんの投稿それぞれについて、一番新しいMessage ID(timestamp)
のメッセージを取得したい場合、どのような処理をしたらよいでしょうか。
プログラミング的な思考でいくと、「Slack User IDが特定の値」かつ「timestampの中から一番大きい数値を取ってくる」といった処理が一番ピンとくると思います。
特に「timestampの中から一番大きい数値を取ってくる」の判断は、Bundleを跨いでデータ全体で比較する必要がありますが、なんとなく複雑な処理になることはご想像いただけると思います。そんな複雑さをmakeのData Storeで解決します。
- Data Storeに「List Replies」から取得した操作対象のデータを保存
- どのような値を取得するか「Search records」で設定し、最新のtimestampの投稿のみ取得
- ownMessages:自分の投稿がターゲット
- mentionedMessages:自分宛のメンションメッセージを確認(参考:右下画像)


Data Storeを使うメリットは以下のような点だと考えています。Data Storeに保存さえされていれば、比較的使い勝手がよいです。
- Data Storeの「Search Records」により、柔軟な条件で値を取得することができる。
- 配列や表形式のデータと同じような形で取り扱えるので、直感的にわかりやすい。
- 「Search records」Moduleの検索結果をSortできる。
- データを再利用できる。取得やデータのアップデートなど。
Bundleの位置を上手に使おう
以下の画像で赤枠で囲っている通り、BundleにはTotal number of bundles
やBundle order position
という値が必ず含まれます。OUTPUTがBundle1つだけであれば両方とも1
として返ってきます。

Scenarioが実行されるたびに処理件数が変化するような状況下で、最後の処理が実行されたときに特定の処理を動かしたいケースでは、Total number of bundles
とBundle order position
が一致していることを条件にFilterを設定してあげると実現できます。
今回のScenarioでは最後の処理が完了したタイミングで通知されるように、Filterで「Search for Message」と「List Replies」ともに最後のBundleが実行されたら、という条件を指定しています。

コラム1:Variableを使用した別の実装方法
本記事を書きながら思いついてしまったので、供養しておきます。
Data Storeを使う必要もなく、Variableで以下のように実装できます。細かい動作は確認していないですが、「自分宛のメンションメッセージのうち、スレッドに返信できていない投稿を検出する」を満たすだけであれば恐らく大丈夫です。

「Variableは気にするな」と書いておきながら、Variableを使うという…矛盾に塗れてますが、Bundleの処理順とVariableの挙動を理解していないと思いつかない処理方法なので仕方ないです。ただ、同じことを2つのアプローチで実装できるんやで、ということを理解できていると、実装の幅も広がると思いますし良いことの方が多いと考えてポジティブにいきます。
また、Data Storeのメリットも無視できるものではないので、ケースバイケースでどの実装が良いかは各自判断していただければと思います。
コラム2:Search for Messageの挙動に注意
makeではなく、Slack APIの話ですがメモがてら残しておきます。
メンションを検索する際に、<@${slackUserId}>
の形式で検索させているのですが、なぜかSlackユーザーの表示名(メンションするときに表示される名前)にも反応してしまいます。
たとえば、私の表示名はryosuke
なのですが、この文字列にも反応してしまい、メンションではないテキストの記載にも反応してしまいます。回避策としてはマイナス検索があるのですが、表示名そのものをマイナスするとメンション自体も除かれてしまいます。完全に回避できるわけではないので諦めましょう。
おわり
いろいろとmakeにおける細かいポイントを解説しました。
恐らく、iPaaSで自動化をしたい方にとって割と序盤でつまずくであろうポイントが含まれているのではないかと思います。我も初心者ゆえ。iPaaSあるあるかもしれませんが、参考になれば幸いです。