bubbleでFor文(繰り返し処理)を実行する方法と使用例
どうも、けいです(https://twitter.com/NoCoder_K)
最近あまりnoteでの発信ができていませんでしたが、久しぶりに書いてみようと思います。NocodeCamp内での質問や、あとは公式Forumでも質問が結構上がってるのをみて、あまり知られてない方法なんだなと感じていたので、今回は題名にもある通りbubbleで繰り返し処理を行う方法を解説します。
また、解説の後には実際の例を紹介します。この方法をマスターすればかなり処理の幅が増えるはずです。今回紹介するのは、
・メール送信で複数宛先に個別送信
・新規レコードの複数追加
・動的リスト数のJSON文の作成(需要ないので排除)
・週末料金が変わる設計をしてるホテルの予約時の決済料金の計算
この4つです。
最後に、この処理を行うときに躓く重要ポイントをまとめておきます。
これまでも繰り返し処理はできた
bubbleの標準機能であるバックエンド処理の1つ、Schedule API Workflow on a listというアクションを使用すれば、繰り返しの処理は可能なんですが、このバックエンド処理は有料プランでないと使用できなかったり、文字通りバックエンドなのでユーザーの画面上で変更を行うことや、また、処理の終了をトリガーに次の画面に遷移するなどといった動作をさせることができません。
これらを解決する方法を紹介します。つまり、無料で行えて、フロント側の処理で、処理が完了した時のトリガーも呼び出せます。
処理の繰り返し数の負荷などについては、最後に書いておくので最後までご覧ください(結構重要)
設定方法
この繰り返し処理を実行するにあたり、1つプラグインを入れます。プラグインタブに行き、
List Shifter Karma-Ware
というプラグインをインストールしてください。
このプラグイン、できることが多すぎて自分も使いこなせていないので詳しくはご自身でお調べください。
では、デザインタブに戻り、List Shifter KWというエレメントをページ上に配置します。
List Shifter KWエレメントは、Visual Elementないとしてありますが、実際にプレビュー画面では非表示のエレメントになるのでどこに配置しても問題ありません。
このエレメントの設定するべき箇所は2つです。これから扱うデータの型と、繰り返し処理で利用するデータのリストです。
例えば後ほど詳しく解説するメール配信の例で言うと、Typeは"User"。その下のList to shiftは、対象のユーザーデータ(Do searchでもいいし、Repeatingに表示されてるリストでもいいし、Custom stateに保存してあるユーザーリストでもなんでもOK)です。
一連の繰り返し処理の時に、1ループずつ利用するデータのリストを設定します。
今回は1つ目の使用例であるメール送信システムを例にして解説します。
複数の宛先に個別のメールを配信する方法
bubbleの標準のメール送信アクションであるsend emailは、Toの箇所やBCCに複数のユーザーメールを指定することで、簡単に一斉送信を配信することいが可能なんですが、あまり多くのBCCをつけると迷惑メール扱いされたり、また、1つ1つのメール本文などに記述する相手の名前を変更することができません。これらを解決します。
プラグインの設定
List Shifter KWの設定は下のようにします。TypeはUser。List to ShiftはDo search for Userで、特に今回は条件はつけていません。
ワークフローの設定
上の図のようにボタンを1つ配置し、クリックをトリガーにアクションを追加します。アクションは、下の写真の"BEGIN ITERATE ListShifterKW A"を選択します。日本語で言うと、"繰り返し処理を開始"です。
このアクションで、指定したデータリストが1つ1つループする処理の中に送られます。
次に、トリガーをもう一つ追加します。
下の写真の"ListShifterKW A Iterate from List Shifter"です。このトリガーの中に、各ループ処理の中身を作成します。
今回は、単にメールを送信するだけなので "send email"アクションを追加します。
Toの宛先には、現在のループのユーザーのemailを指定するので、"This List Shifter KW's current Iteration Item's email"と設定します。
Current Iteration Itemが、全体のデータリストの中から現在のループ処理で受け取っている1つの特定のデータ。"Item"は指定したデータの型なので、Userという意味です。このほかにも上の図のように何ループ目なのか、というデータも取得することができます。
これと同様に、Body部分には、"Current Iteration Item's name様"といった具合に指定することで、各ユーザー個別のメール内容を配信することができます。
これで、繰り返しの設定は完了です。
ここにさらに、全ての繰り返しが終了したのをトリガーにアラートを出すとかポップアップでメッセージを表示するなどのアクションを行いたい場合は、"ListShifterKW A Iteration Complete"というトリガーをさらに追加することで可能なので試してみてください。
これまでの一連の流れをおさらいすると、デザインタブでShifterエレメントを配置し、データの型と繰り返し処理したいデータリストを指定。
繰り返し処理を開始し、それぞれの処理の中身のアクションを作成。完了した際にも別途アクション追加可能。
これを図に表したのが下です。赤文字がトリガーです。
これをイメージしながら構築していきます。
ほかにもこの繰り返し処理を用いた、よくある事例を解説します。
新規レコードの複数追加
今回は、入力したタグを全て別々のデータとして"create new thing"アクションを一気に行う方法です。下のようなUIを用意して、inputとbuttonとrepeatingをシンプルに置いたものです。
ボタンをクリックしたのをトリガーに、custom stateを設定します。indexにtextのリスト型のcustom stateを作成し、プラスしていきます。
Custom stateについて理解できていない方は、こちらの記事も参考にしてください
そして、最後にRepeating Groupの設定は下の図のようにしています。
これで、inputに入力して追加ボタンを押したデータのリストがrepeatingで表示できます。
1つ目の例と同様に、List Shfter KWエレメントをデザインタブに配置します。
今回の設定は、下のように型をtext、データリストを、index's tags(これはcustom state)とします。
この時、データリストをrepeating group's list of texts と指定しても、全く同じデータを指定しているのでお好みで(下図)
次の操作としては、1つボタンを配置して、繰り返し処理を開始するアクションを追加します。"BEGIN ITERATE ListShifterKW A"を呼び出し、トリガーに"ListShifterKW A Iterate from List Shifter"を追加し、その中でcreate new thingアクションを作成します。その設定はこちら↓
これで、repeating Grpupに表示されているtext型のデータをそれぞれ別々に保存していくことができます。
週末料金設定してる場合の予約料金計算
次は、これもやりたいという意見が多い、予約システムで活躍する手法です。月から金曜日までは利用料1,000円で、土日は3,000円などとした場合、ユーザーが 木曜~月曜を予約した際の料金の計算を行うにはどうしたらいいでしょうか?
これも、繰り返し処理で解決していきます。
まず、toolboxというプラグインをインストールしてください。
次にデザインタブに移り、下のようにDate/TimePickerを2つ配置し、予約の開始日と終了日を選択できるようにします。
さらに、toolboxプラグインを入れることによって追加された、"ListofNumbers "エレメントも配置してください。
【ListofNumbers は超便利】
このListofNumbersは非常に便利で、始まりと終わりの数字、その間隔を指定することで数字のリストを作成してくれます。例えばdropdownで1~12月の選択肢を作りたい場合に、わざわざstatic dateで1から12を作らなくても、このListofNumbersを使えば Start numberを1、Length of listを12、incrementを1に設定し、dropdownではdynamic dataからこのListofNumbersを選択するだけです。ほかにも時間や分も、staticで作成するのは非常に面倒なのでこれらを活用します。
今回の設定では、下の図を参考にしてください。Start numberを1、Length of listには、予約終了日から予約開始日の日数を引いたものに、1を足しています。incrementは1です。
例えば開始日が3月1日で、終了日が3月3日の場合、ListofNumbersは、[1,2,3]という数字のリストを作成してくれます。
ホテルの予約などの場合、宿泊料金がかかるのは3月1日と2日の2日間だけなので、+1をする必要はありませんね。
これで繰り返し処理に送る数字のリストができたので、List ShifterKWの設定を、型をnumberにし、List of ShfitにListofNumbers's listを指定します。
今回の繰り返しのトリガーは、予約ボタンではなく、Date/TimePickerの値が変更されたこととします。ユーザーが日数を変更するたびに計算を行うためです。(これはサービスの設計によると思います)
ワークフロータブにいき、Element ⇨An input's value is changedとします。
この時、このトリガーにOnly whenの設置をします。date time pickerが開始も終了も入力されている時だけ、という設定です(下図参照)
このトリガー内にBEGIN ITERATE ListShifterKW Aのアクションを追加します。と言いたいですが、今回はその前に1つcustom stateの初期化を行います。料金の計算結果の値を0にしておきます。
ListShifterKW A Iterate from List Shifterのトリガーを追加し、先ほど初期化したamountに料金を足し算していきます。
少し複雑なので、詳しくみてみます。この場合、月〜金までは1,000円、土日は3,000円を足していくので、条件を分ける必要があります。
まず、現在の繰り返し処理がどの日付を扱っているのかをは、予約開始日(Date/TimePickerの開始側)に、1を引いて、現在の繰り返しnumberを足す。という計算で求めることができます。
例えば、3月1日〜3日までの時、listNumberで1~3を送ります。
1順目:3月1日 + day(-1)で2月28日。そこに、1順目ということで+ day(1)で結果3月1日。
2順目:3月1日 + day(-1)で2月28日。そこに、2順目ということで+ day(2)で結果3月2日。
3順目:3月1日 + day(-1)で2月28日。そこに、3順目ということで+ day(3)で結果3月3日。
次に、何曜日かの判定を行います。
それが、formatted asの箇所です。このコマンドによって、date型のデータの表示方法を指定します。 Format typeをcustomにし、Cusomt formatをdddと指定します。
この、dddとは、曜日を示す形式で、この他の形式については今回は直接関係ないのでスルーでいいですが、興味のある方はこちらをご覧ください
ただ、このツイートの最後にも書いている通り、bubbleのバグでdddの前に半角空白が混ざってしまうことが判明しているので、これを次のコマンドを繋ぐことで空白を削除します。
それが、下の図です。find & replace を繋げて、text to findには半角空白を、replace byには何も入力しないそのままを設定します。
find & replaceは、指定した文字列の中から特定の文字列を調べてきて、別のものに置き換える操作をしてくれます。
bubble ⇨find & replaceで
text to find:e
replace by:y
⬇︎
bubbly
のような使い方。bubblyってなんだろ。きっとあれのこと。
で、今回は空白をなくす操作をしました。
ここまできて、ようやく現在の繰り返し処理が何曜日なのかを特定したので、条件として、 "is 土"と繋げると、これが土曜日の場合。という条件を作成できました。
この時、"is 土"と書いた時に本当に土曜日として判定されるためには、bubbleのアプリの言語設定を日本語にしておく必要があります。
方法は、SettingタブのLanguageから行います。
細かい日本語の設定に関しては、こちらも参照ください。
話を戻して、Only whenの設定が終わったら、custom stateのValueのところには、index's amount + 3000とすることで、繰り返されるたびに料金を追加していきます。
さて、これを日曜日も同様に作成します。面倒ですが、ここからさらに、or を繋げて全く同じ条件文を書いていきます。
これで、土曜日もしくは日曜日は3000円と設定できました。
次に、平日料金についてです。
これは、1つめのアクションをクリックして選択した状態でctrl + c、続いてそのままCtrl + vをしてアクションを複製します。(右クリックでも可能)
そして、複製した2つめのアクションのonly whenを少し修正します。
1. 先ほど、"is 土" としていた箇所を、"is not 土"に変更。
2. 先ほど、"is 日" としていた箇所を、"is not 日"に変更。
3. orで結んでいたものをandに変更
これで、土曜日と日曜日以外の曜日。と言う意味になります。
さらに、Valurを index's amount + 3000から、index' anount + 1000に変更します。
はい。。これで終了、疲れた。お疲れ様です。
こんな感じで、簡単に(簡単じゃないけど)bubbleでもfor文と条件分岐をさせたif文の処理を実現することが可能です。
この処理の数についてですが、自分が行った限りでは300件ほどのメール配信には耐えられました。
あまりに1000件などのバッチを行う場合は、bubbleのプランにもよると思いますが、おそらく処理の負荷か大きくて止まります。また、初めにも触れましたが、バックエンドではなくユーザー側での処理になるので、処理中にユーザーが画面を閉じたとかがあると、途中で処理は止まってしまします。
さらに、ループ処理は同時に処理されるわけではなく、1順目が終われば2順目・・・・と続いていくので、1つの中の処理が複雑になるほどループの時間も長くなっていきます。
これらのデメリットも頭に入れておいて、実装するようにしましょう。
BEGIN actionをページ読み込み時に作動させる場合の注意
これまで複数のパターンを用意しましたが、どれもトリガーは page loadではありませんでした。
実はこのプラグインのBEGINアクションは、page load時に使うとうまく作動しません。エラーですかね。
そこで対策として、page loadではなく"Do when condition is true"をトリガーにします。このトリガーは、読み込み時のみでなくある条件を満たす場合に何度でもトリガーを起こすためのものです。
設定は、下の写真のように、Run this をEvery timeに。Only whenを Page loaded (entire) is yesに変更します。
理論上はこれで問題なく動作するんですが、なぜかうまくならない時もあります。なので保険を取ってStep 1で、"Add a pause before next action"で1000ms(1秒)置いてから Step2でBEGINを開始するなどの工夫を行うとうまく行く場合もあります。
以上、bubbleで繰り返し処理を行う方法でした。
今後もnoteの発信は重要なこと&他に誰も発信していない情報を中心にやっていくので、お楽しみに!
Twitterは毎日発信してるのでフォローがまだの方はお待ちしています!