研究室Slack用の印刷Bot「sp-print」を作った

Go Wednesday, May 13, 2026

研究室Slack用に、PDFをそのままプリンターへ投げられるBotを作った。

名前は sp-print

研究室では、論文や資料のPDFをSlackに貼って共有することが多い。そこから印刷したいときに、いったんダウンロードして、印刷設定を開いて、プリンターを選んで、みたいな作業を毎回やるのが地味に面倒だった。

なので、SlackにPDFを投稿したら、そのままスレッド上で印刷までできるBotを作った。

使い方

使い方はかなり単純。

  1. 印刷したいPDFをSlackの対象チャンネルに投稿する
  2. Botが :printer: リアクションを付ける
  3. スレッド内に出てくる「印刷」ボタンを押す
  4. 部数、片面/両面、カラー、用紙サイズを選ぶ
  5. Botがプリンターにジョブを投げる

印刷状況も同じスレッド内で更新される。

Slack上でsp-print BotがPDFの印刷待ち状態を表示している画面

  • 受付
  • CUPSへ投入済み
  • 印刷完了
  • プリンター接続エラー
  • キュー待機中
  • キャンセル

みたいな状態をBotが返してくれる。

どう動いているか

構成は、Goで書いたサーバー + Slack Bot + CUPS。

Slack連携はSocket Modeを使っている。Goサーバー側からSlackへWebSocketで接続して、PDF投稿イベントやボタン操作、モーダル送信を受け取る。

最初はSlackからGoサーバーへHTTPリクエストを送ってもらう構成も考えた。ただ、研究室内で動かすサーバーを外向きに公開するのは面倒だし、ネットワーク的にも避けたい。Socket Modeなら、こちらからSlackへ外向き接続するだけで済む。

sp-print server -> outbound WebSocket -> Slack

外から研究室内のサーバーへ到達できるようにする必要がないので、今回の用途にはかなり相性がよかった。

PDFが投稿されると、Socket Mode経由でイベントを受け取り、Botが対象ファイルかどうかを判定する。

対象は今のところPDFのみ。許可したチャンネル以外では反応しないようにしている。

PDF投稿を検知したら、Botはすぐには印刷しない。まず投稿にリアクションを付けて、スレッド内に印刷ボタン付きのメッセージを出す。ユーザーがボタンを押して、モーダルで印刷設定を選んだら、SlackからPDFをダウンロードして lp コマンド経由でCUPSへ投げる。

初期版ではプリンターは1台固定にした。研究室用途なら、まずはこれで十分そう。

チャンネルをうるさくしない

最初は、PDFが投稿されたらBotがチャンネルに印刷ボタンを返す形にしていた。

ただ、Slackのスレッド返信はチャンネル側にも返信プレビューとして見えるので、Botの投稿が増えるとチャンネルがややうるさくなる。

最終的には、次の形にした。

  • PDF投稿にはBotがリアクションだけ付ける
  • 印刷ボタンはスレッド内に1つだけ出す
  • 受付、投入済み、完了、失敗などは同じメッセージを更新する

これで、チャンネル側にはPDF投稿とリアクションだけが見える。詳細な印刷状況はスレッドを開けば分かる。

Botは便利だけど、チャンネルに常駐するものなので、こういう見た目のうるささは意外と大事だと思った。

実装メモ

Goサーバー側では、主にこのあたりを実装した。

  • Socket Mode接続
  • Slackイベントの受信
  • ボタン操作、モーダル送信の受信
  • PDFファイル判定
  • 許可チャンネル判定
  • Slackからのファイルダウンロード
  • lp コマンドへの安全な引数マッピング
  • 印刷ジョブの状態通知
  • Slackイベントの短期重複排除

Socket Modeでは、Slackから届いたenvelopeに対してACKを返してから処理を進める。印刷やファイルダウンロードみたいな重い処理は、受信処理の中で抱え込まないようにしている。

印刷設定は、Slackのモーダルから受け取った値をそのままコマンド引数にせず、許可した値だけを lp のオプションに変換するようにした。こういうところは雑にやると危ない。

作ってみて

Slack BotはSocket Modeにすると外向き公開なしで動かせるので、研究室内のサーバーで運用するにはかなり扱いやすかった。

一方で、実際に使うBotとしては、Slack上でどこに何を表示するか、失敗したときにどこまで通知するか、二重実行をどう防ぐか、みたいな運用寄りの部分のほうが大事だった。

とりあえず研究室内で使うには十分なところまでできたので、しばらく使ってみる。

便利だったら、次は複数プリンター対応や、チャンネルごとのプリンター切り替えも入れてもいいかもしれない。