爆速でBubbleのプラグインを作って公開してみた!
はじめに
弊社ispecでは、スピード感をもったプロトタイプ開発を提供するために、Bubbleというノーコードツールを活用しています。
その中で、プラグインを開発する機会があったので、その手順や注意点をまとめました!
今回作成したプラグインは、下記で公開しています!
よかったら使ってください!🥳
プラグイン開発のきっかけ
Bubbleでは、様々な個人や団体が開発したプラグインが公開されています。Bubbleの基本機能では求める体験が実現ができない場合、これらのプラグインを組み合わせて実装します。
今回、録音のできるプラグインを探していたのですが、スマホでは長時間の録画に対応していなかったり、求めるファイル形式で出力できなかったりと、なかなか理想のプラグインが見つからなかったため、自作することにしました。
今回開発したプラグイン
以下の機能を持ったシンプルなプラグインを開発しました。
- 録音の開始、停止ができる
- 録音の一時停止、再開ができる
- 録音した音声を、WebM形式で出力できる
- 出力した音声ファイルを、File Managerに保存できる
- 出力した音声ファイルのURLを、プロジェクト側で参照できる
1. プラグインの箱を作成する
早速、プラグインを作っていきます!
- ログインした状態で、プラグインページにアクセスします
- 画面右上の「Create a plugin」をクリックします
- プラグインの名前を入力してください。今回は「WebM Audio Recorder」にしました
2. Elementを作成する
Bubbleのキャンバス上に表示される要素を作成します。
今回、表示する情報は特に無いのですが、Elementがないと、プロジェクト側から呼び出すアクションやステートを定義できないので作成します。
- 画面左のサイドメニューで「Elements」をクリックします
- 「Add a new element」をクリックします
- Elementの名前を入力してください。今回はプラグイン名と同じ「WebM Audio Recorder」にしました
作成すると、以下の画面が表示されます。
上の方ではElementの表示に関する設定を行なえますが、そのままでも問題ありません。
今回は、表示する情報の無いElementなので、プロジェクト側で1x1で画面の端に置いておけるよう、Bubble Properties > Resizableだけチェックしました。
3. 各種アクションやステートを定義する
ここでは、あくまでアクションやステートの名前と型を定義するだけです。
実際の値の挿入やイベントの発火は、次のセクションで実装します。
Fields
プロジェクト側からプラグインに、設定値などを渡すことができます。
今回は使用しませんが、ここで定義した項目は、以下のよく見るモーダルに表示されます。
Exposed states
プラグインから、プロジェクト側に値を渡すことができます。
プロジェクト側では、${Element名}'s ${定義したステート名}
で参照できるようになります。
今回は、audioUrl
というステートを定義して、録音した音声ファイルのURLを参照できるようにします。この場合、プロジェクト側ではWebMAudioRecorder A's audioUrl
で参照できます。
Events
任意のタイミングでイベントを発火することができます。
プロジェクト側のWorkflowで、これをトリガーにして処理を実行することができます。
今回は、uploaded
というイベントを定義して、録音したファイルをFile Managerにアップロードできたタイミングで発火するようにします。
Element actions - triggered in workflows
プロジェクト側から呼び出せるアクションを定義します。
今回は、Start
、Stop
、Pause
、Resume
の4つを定義します。
4. プラグインの動作を実装する
画面を下にスクロールしていくと、先程定義したアクションのJavaScriptの関数が用意されています。ここに、各アクションが呼び出された際の処理を書いていきます。
function(instance, properties, context) {
// instance.data.hogeで、他の関数と値を共有することができます
instance.data.audioChunks = []
navigator.mediaDevices.getUserMedia({
audio: true,
video: false,
}).then(stream => { // async/awaitでは、エラーになり動作しませんでした
instance.data.stream = stream
instance.data.mediaRecorder = new MediaRecorder(instance.data.stream)
instance.data.mediaRecorder.ondataavailable = (e) => {
instance.data.audioChunks.push(e.data)
}
instance.data.mediaRecorder.start()
}).catch(err => {
// エラー時の対応は、今後アップデートしていきたいです
console.error('録音が許可されませんでした: ', err)
})
}
function(instance, properties, context) {
if (
!instance.data.mediaRecorder ||
!instance.data.audioChunks ||
!instance.data.stream ||
instance.data.mediaRecorder.state === 'inactive'
) {
console.error('録音を開始してから停止してください')
return
}
const onFileUploaded = (err, url) => {
if (err) {
console.error('オーディオファイルのアップロードに失敗しました: ', err)
} else {
// 事前に定義したステートに値を入れることができます
instance.publishState('audiourl', url)
// 同様に、定義したイベントを発火することができます
instance.triggerEvent('uploaded', () => {})
}
}
const onFileLoaded = (e) => {
// 以下のリンク先に詳細がありますが、splitしないと正しくファイルが作成されません
// https://forum.bubble.io/t/important-information-about-context-uploadcontent/198088
const dataUrl = e.target.result.split(',')[1]
const timeStamp = Date.now()
context.uploadContent(
`audio${timeStamp}.webm`,
dataUrl,
onFileUploaded
)
}
instance.data.mediaRecorder.onstop = () => {
const audioBlob = new Blob(
instance.data.audioChunks,
{ type: 'audio/webm' },
)
const reader = new FileReader()
reader.readAsDataURL(audioBlob)
reader.onload = onFileLoaded
}
instance.data.mediaRecorder.stop()
instance.data.stream.getTracks()
.forEach(track => track.stop())
}
function(instance, properties, context) {
if (
!instance.data.mediaRecorder ||
instance.data.mediaRecorder.state === 'inactive'
) {
console.error('録音を開始してから一時停止してください')
return
}
instance.data.mediaRecorder.pause()
}
function(instance, properties, context) {
if (
!instance.data.mediaRecorder ||
instance.data.mediaRecorder.state === 'inactive'
) {
console.error('録音を開始してから再開してください')
return
}
instance.data.mediaRecorder.resume()
}
5. 動作を確認する
デバッグしてみましょう!
画面左のメニューに「App to test the plugin」という項目があるので、試したいBubbleのプロジェクト名を入力して、「Go to test app」をクリックしてください。
すると、指定したプロジェクトが開き、今回作成したプラグインが(testing)という名前付きで表示されています。ここからはBubbleでいつもやっているように、このElementとボタンをキャンバスに配置し、Workflowでボタンにアクションを割り当てることで、デバッグができます。
6. プラグインを公開する
正常に動作することが確認できたら、プラグインを公開しましょう!
1. 必須項目を入力する
- General > Primary information > Public name
- General > Primary information > Public logo
今回は、ChatGPTに作成してもらいました😙 - General > Additional information > Plugin categories
- General > Additional information > Description
2. ライセンスを設定する
Settings > Publishing and license > Plugin distribution license で「Open source (MIT)」を選択します。
3. 変更内容を入力して公開する!
「Submit a new version」をクリックして、変更を内容を入力したら、公開完了です!🎉
4. Public pageを確認する
公開ができたら、プラグインのPublic pageを確認して、情報に間違い等がないか確認しておきましょう。
さいごに
今回はじめてBubbleのプラグインを開発したのですが、思ったより簡単に作成、公開ができました。プラグインを作ることで、自分が関わるプロダクトだけでなく、他の多くのプロダクトにも貢献できるので、積極的に開発してけたらなと思いました!
ispecでは、Bubbleなどのノーコードツールを使用したプロトタイプ開発を主導していただける、エンジニアやPdMの方を絶賛募集中です!興味のある方は、こちらから!
Discussion