yuorei blog

Python3 と SlackBotで請求書作成してみた

2024-12-01

Python3 と SlackBotで請求書作成してみた

Python3 と SlackBotで請求書作成してみた

この投稿はAizu Advent Calendar 2024 1日目の記事です。

明日はアト君です。

みなさんこんにちは。ユオレイです。

暇つぶしにSlackBotを作ってみたので、その紹介をします。

何をつくったか

請求書を作成するSlackBotを作成しました。

Slack画面

Slack bot にメンションを飛ばすと、請求書を作成してくれます。

@請求書bot @kashu 1240 2024/12/01 振込先 ユオレイ銀行ユオレイ支店普通1234567

このような請求書がPDFで作成されます。

請求書PDF

技術スタック

言語

今回はPDFを作成したかったので、そのGoでライブラリを探していたところいい感じに作成できるライブラリが見つからず、Pythonでいい感じに作れそうだったので採用しました。

ライブラリ

Python Slack SDKをSlackBotを作成するために使用しました。

ReportLabを使用してPDFを作成しました。

環境

ライブラリインストール

Python Slack SDKreportlabをpipでインストールします。

pip install slack_sdk
pip install reportlab

ReportLab

ReportLabはPythonでPDFを作成するためのライブラリです。

PythonでPDFを作成するためのライブラリはいくつかありますが、ReportLabは比較的使いやすいと思います。

以下に簡単なサンプルを記載します。

from reportlab.pdfgen import canvas

# PDFファイルを新規作成
c = canvas.Canvas("sample.pdf")


# テキストを描画
c.drawString(100, 700, "Hello, World!")
c.drawString(0, 0, "Hello2, World!")


# ページを確定し、PDFファイルを保存
c.showPage()
c.save()

drawString(x, y, text) メソッドは、PDF内の指定された (x, y) 座標にテキストを描画するために使用されます。ここでの座標 (100, 700) と (0, 0) は、PDFページの左下隅を基準にした位置です。 最初の drawString(100, 700, "Hello, World!") は、ページの左から100ポイント、上から700ポイントの位置に Hello, World! というテキストを描画します。 次の drawString(0, 0, "Hello2, World!") は、ページの左下隅に "Hello2, World!" というテキストを描画します。

PDF

このような感じで請求書のPDFを作成していきます。

今回請求書に入れた項目としては以下のものになります。

請求書のフォーマットとしては色々足らないですが、Slackから使う場合は引数が多くなりすぎて使いずらいので一旦はこのようにしています。 (そもその請求書をチャットボットから作るものではないかもしれないが)

基本的には位置と文字サイズを調整して気合いで頑張ります。

文字サイズについてはこのようにして変更します。

from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import A4, portrait
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.pdfbase import pdfmetrics

    pdfmetrics.registerFont(TTFont('IPAexGothic', '/usr/share/fonts/opentype/ipafont-mincho/ipam.ttf'))  #IPAゴシック

    # PDFファイルを新規作成
    c = canvas.Canvas("invoice.pdf", pagesize=portrait(A4))
    width, height = A4

    # タイトル: 請求書(中央に配置)
    c.setFont("IPAexGothic", 20)
    
        title = "請求書"
    title_width = c.stringWidth(title, "IPAexGothic", 20)  # 文字列の幅を取得
    c.drawString((width - title_width) / 2, height - 50, title)  # ページの中央に配置

IPAexGothicはubuntu にあったのでそれをそのまま使っています。お好きなのを使用してください。

A4サイズもついでに指定してあげます。

文字についてですが drawRightStringを使うと右寄せ、drawCentredStringを使うと中央寄せになります。

下線は簡単に引くことができます。

        # ご請求金額の下に下線
        c.line(50, height - 185, 200, height - 185)

振込先情報のテーブルについては以下のように記載します。色やフォント、罫線の太さなどを指定することができます。

            table_width = width - 100
            x_offset = 50
            y_offset = 350
            summary_data_2 = [
                [self.payment_method, self.payment_account]
            ]
            summary_table_2 = Table(summary_data_2, colWidths=[150, table_width - 150], rowHeights=45)

            summary_table_2.setStyle(TableStyle([
                ('BACKGROUND', (0, 0), (0, -1), colors.lightblue),
                ('TEXTCOLOR', (0, 0), (0, 0), colors.black),
                ('TEXTCOLOR', (1, 0), (1, -1), colors.black),
                ('ALIGN', (0, 0), (-1, -1), 'LEFT'),
                ('FONTNAME', (0, 0), (-1, -1), 'IPAexGothic'),
                ('BOTTOMPADDING', (0, 0), (-1, 0), 10),
                ('GRID', (0, 0), (-1, -1), 0.5, colors.black),
            ]))

            summary_table_2.wrapOn(c, table_width, height - y_offset - 250)
            summary_table_2.drawOn(c, x_offset, height - y_offset - 250)

これで請求書の生成は大体完成です。

        # PDFを保存
        c.showPage()
        c.save()

保存して終了です。

Slack Bot

Slack BotはPython Slack SDKを使用して作成しました。細かいところは公式ドキュメントや別の方の記事を参照してください。

Slack Botを作成するためには、Slack APIのトークンが必要です。 トークンを取得して、メッセージとユーザー情報とメンションを受け取れる権限を付与しておきます。

ファイルアップロードには files_upload_v2を使用しています。

response = self.client.files_upload_v2(
                file=invoice_filename,
                title=invoice_filename,
                channel=channel,
                initial_comment=sender_name + "さんが、"+user_id+"さんに請求書を送信しました。"
            )

これでSlack Botの作成は完了です。

まとめ

今回はPython3とSlackBotを使用して請求書を作成するBotを作成しました。Pythonを使ってPDFを簡単に作成することができました。今後はこれをLambdaに乗せて使うことも考えています。 最後まで読んでいただきありがとうございました。 Aizu Advent Calendar 2024 1日目は以上です。今後ともよろしくお願いいたします。