ゆるふわ技術日誌

エンジニア見習いの悪戦苦闘日記

社員を選択できるフォームをつくってよ!と言われたのでAirtableでハックしてみた話

会社で全社イベントの運営っぽいことをしているのですが、その事務作業の一環で社員一覧から一人を選択でき、かつその社員に紐づく情報を入力するフォームみたいなものを作りたいという要望が出てきました。

フォームを作るというと、思いつくのはOffice365やGoogleのフォームなのですが、残念ながら大量の選択肢から何か一つを選ぶというフォーム部品は用意されておらず実現するのは難しそうということでどうしたものかちょっと悩んでおりました。

いろいろ考えた末、Airtableというサービスを使ってそれっぽいことをできたのでやり方を共有。ちなみに、「社員を選択する」という超具体的なケースについて書いてますが、大量の選択肢が用意されたフォームみたいなものを作りたい全ての場合に応用できると思うので、ぜひ。

(注意: この記事は将来同じことしたくなった時に思い出すためのメモ書きなのでちょいちょい端折ってる箇所があるかもしれません。)


Airtableについて

airtable.com

最近流行りのサービスで、一言で言うとだれでも簡単に扱えるデータベース的なものをイメージしてもらうと良さそうです。
Notionを使ったことがある人にとっては、Notionのデータベース・テーブル機能を抜き出して高機能化したもの、というとわかりやすいかも。

ノーコードの文脈でよく触れられたりする気がします。今回はこのサービスを使っていきます。ちなみにFreeプランありで、この記事の内容程度の使い方であれば無料のままでいけます。

できあがったもの

f:id:uutarou:20210518225426p:plain

f:id:uutarou:20210518225442p:plain
「対象者」をクリックすると社員名簿が出てきて一人を選択できる

例として社員名の他に、文字列を入力できる箱を用意しましたが、他にもGoogleFormsでサポートしているような部品は一通りあります。

つくりかた

社員名簿を手に入れる

いきなりですが、フォームの選択肢の基になる社員名簿を手に入れてください。

Airtableは標準でCSVからのimportに対応しているのでExcel形式とかで存在していれば、CSVとして書き出したりしてください。

自分は社員名簿手に入れるのが面倒だったので(?)SlackAPIを使って社員が所属しているチャンネルのメンバー情報を引っこ抜きました。SlackのAPI的に、チャンネルに所属するメンバーのIDだけを取ってくるAPI(conversations.members)と、メンバーのIDからメンバー情報を取得するAPI(users.info)の二つを組み合わせる必要があるので、適当にコードを書いて引っこ抜きます。(自分はGolangを使って書きましたがシェル芸がお得意な方は多分curlとjqとかで同じようなことができるんじゃなかろうかと思います。僕はチャレンジして2分で諦めてGo書きました)

だいたいこんな感じ。

package main

import (
    "fmt"
    "github.com/slack-go/slack"
    "sync"
)

const (
    token = "insert your api token"
    channelId = "insert target channel id"
)

func main () {
    api := slack.New(token)

    members, _, _ := api.GetUsersInConversation(&slack.GetUsersInConversationParameters{
        ChannelID: channelId,
        Cursor:    "",
        Limit:     1000,
    })

    wg := sync.WaitGroup{}

    fmt.Printf("\"%s\",\"%s\",\"%s\"\n", "name", "slackId", "email") // ヘッダー行を出力しておく。Airtableに取り込んだ時に使われる。
    for _, memberId := range members {
        wg.Add(1)
        go func(id string) {
            user, _ := api.GetUserInfo(id)
            if !user.IsBot {
                fmt.Printf("\"%s\",\"%s\",\"%s\"\n", user.RealName, user.ID, user.Profile.Email)
            }
            wg.Done()
        }(memberId)
    }

    wg.Wait()
}

ちなみに上記コードは極めて雑です。エラー処理をしていないのはもちろん、rate limitやメンバーが1000人以上いた時の考慮(conversations.membersは1回で1000人までしか取得できない。それ超える場合は、cursorを載せて再度リクエストして続きを取得する必要がある。)なども一切していないのでガチ用途の時は気をつけてください。

で、これを実行するとカンマ区切りで名前・SlackのID・メアドが吐き出されます。ファイルにリダイレクトするとかしてCSVとして保存しておいてください。

ちなみに1列目を名前などフォームで表示したい値にしておいた方が良いっぽいです。あとは適宜必要な項目があれば取得する感じで。(自分は一意に特定して何かしたくなったりした時のためになんとなくSlackのIDとメアドを取るようにしてみた。それ以上の理由は特にないです)

Airtableに名簿を取り込む

無事に名簿を手に入れたら、Airtableに登録してもらって適当にbaseをつくります。base = Excelでいうブックだと思います。(たぶん。雰囲気でAirtable触っているので詳しくはわかってない)

baseを作ったら、上の方のタブ?のところにある「Add or import」を開き「CSV file」を選択します

f:id:uutarou:20210518231401p:plain

さっき錬成したCSVファイルをアップロードするとこんな感じになるので、データの切れ目がおかしくなってるところがないかなどをざっと確認しつつImport

f:id:uutarou:20210518231632p:plain

これで新たテーブル(Excelでいうところのシート)が作られて、名簿が取り込まれます。ちなみにテーブル名ダブルクリックで名前変更できるので、わかりやすい名前に変えておきましょう。

フォームの入力を受け付けるテーブルをつくる

次にフォームの入力が溜まっていくテーブルを作ります。

さっきの「Add or import」のところを再びクリックし、今度は「Create empty table」というのを選択します。名前は適当に。

f:id:uutarou:20210518232223p:plain

するとこんな感じになります。最終的にフォームを作った時、列が回答項目になります。(Googleフォームの結果をスプレッドシートに吐き出した時をイメージしてもらうとわかりやすいです。結果を入れるスプレッドシートを先に作って、それに対応するフォームが後から作られるイメージ)

列は「+」ボタンから作れるので任意の項目を足してあげてください。(たとえば文字列での入力が必要ならSingle line textやLong textなど)

f:id:uutarou:20210518232526p:plain
これだけでもすでにGoogleフォームとかよりいろんな選択肢があっていい感じ。

で、肝心の社員を選択する項目はどう作るかというと、↑の図一番上にある「Link to another record」をクリック。

するとさっきCSVから取り込んだテーブルがあるはずなので選択。

f:id:uutarou:20210518232743p:plain
ちょっとテストで色々作ったりしてたのでとっ散らかってますが気にせず。

f:id:uutarou:20210518232825p:plain

「Allow linking to multiple records」を選んでおくと複数人が選択できるようになり、外しておくと単一の選択になります。

設定が済んだら「Create field」を。

f:id:uutarou:20210518232956p:plain

こんなやつも出てきますがあとから足せるので一旦スキップで大丈夫かと思います。(選ばれた人に紐づく情報を横に出すかどうかが選べる)

フォームをつくる

ここまできたらフォームの形にするだけです。先程と同じテーブルで左下にある「Form」をクリックしてForm viewをつくります。(Airtableにはviewという概念があって、同じテーブルを複数の見方で見られる。さっき作った表をFormという見方で見るよ、という意味でviewです)

f:id:uutarou:20210518233259p:plain

f:id:uutarou:20210518233348p:plain

この時点ですでにあるフィールドは全て含まれた状態のフォームが出来上がってます。Googleのやつと同じようにマウスのドラッグ&ドロップで順番を入れ替えたりもできますし、タイトルの変更などもできます。無料プランでは✨マークのついている項目のカスタマイズはできません。それが嫌ならお金を払うかフルスクラッチでフォームを作りましょう😇

ちなみにいらない項目(フォームで収集しない項目)があれば、フォーム部品をクリックして右上のボタンから消しちゃうこともできます。

f:id:uutarou:20210518233604p:plain

フォームを共有する

最後にフォームを実際に配って書いてもらうためには、左上にある「Share form」を。

f:id:uutarou:20210518233729p:plain

こんな感じの画面で共有用のURLを取得できます。

そればかりではなく、「Restrict access with a password」を選ぶと事前に決めておいたパスワードを知っている人でないとフォームを開けないようにすることもできたりします。これはなかなか嬉しい。

おわり

という感じでサクッとメモ書きするつもりが、結構ガッツリになってしまった。

Airtable、有料プランだと結構いいお値段しちゃうので個人でゴリゴリ使っていくイメージはあんまりもてなくて触ってなかったのですが、実は結構いろんなことができて楽しいなと思いました。

NotionのDatabaseにも言えることなのですが、英語なのと、若干DB設計に対する理解みたいなものを必要とするので、普段そういうのをやらない事業職の人たちとかからはもしかするととっつきづらさがあるのかもしれないなとは思いつつ、みんなで使いこなせたら幸せになれるんじゃないかとも思いましたとさ。おしまい。