$30 off During Our Annual Pro Sale. View Details »
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Discord botにScrumの Discord botにScrumの手伝いをしてもらう手...
Search
Takashi Makino
February 26, 2021
Programming
0
410
Discord botにScrumの Discord botにScrumの手伝いをしてもらう手伝いをしてもらう
使った技術
- discord.py
- gspread
- Backlog API
Takashi Makino
February 26, 2021
Tweet
Share
More Decks by Takashi Makino
See All by Takashi Makino
あなたの知らないスクラムの世界
makky0620
0
67
Flutterでもテスト駆動したい
makky0620
0
340
A_アルゴリズム高速化を目指して
makky0620
0
1.4k
Other Decks in Programming
See All in Programming
Navigation 3: 적응형 UI를 위한 앱 탐색
fornewid
1
170
ローターアクトEクラブ アメリカンナイト:川端 柚菜 氏(Japan O.K. ローターアクトEクラブ 会長):2720 Japan O.K. ロータリーEクラブ2025年12月1日卓話
2720japanoke
0
700
[堅牢.py #1] テストを書かない研究者に送る、最初にテストを書く実験コード入門 / Let's start your ML project by writing tests
shunk031
12
7k
WebRTC と Rust と8K 60fps
tnoho
2
1.9k
TypeScriptで設計する 堅牢さとUXを両立した非同期ワークフローの実現
moeka__c
6
2.9k
30分でDoctrineの仕組みと使い方を完全にマスターする / phpconkagawa 2025 Doctrine
ttskch
3
750
TUIライブラリつくってみた / i-just-make-TUI-library
kazto
1
320
20 years of Symfony, what's next?
fabpot
2
320
AIコーディングエージェント(NotebookLM)
kondai24
0
140
目的で駆動する、AI時代のアーキテクチャ設計 / purpose-driven-architecture
minodriven
11
4k
開発に寄りそう自動テストの実現
goyoki
1
580
Rediscover the Console - SymfonyCon Amsterdam 2025
chalasr
2
140
Featured
See All Featured
Build The Right Thing And Hit Your Dates
maggiecrowley
38
3k
Git: the NoSQL Database
bkeepers
PRO
432
66k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
249
1.3M
Writing Fast Ruby
sferik
630
62k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
26
3.2k
RailsConf 2023
tenderlove
30
1.3k
Unsuck your backbone
ammeep
671
58k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
61k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
46
2.6k
Building a Scalable Design System with Sketch
lauravandoore
463
34k
A Modern Web Designer's Workflow
chriscoyier
697
190k
The Power of CSS Pseudo Elements
geoffreycrofte
80
6.1k
Transcript
Discord botにScrumの 手伝いをしてもらう Makino Tommy Takashi @TechBash
ストーリーポイントを Backlogに反映 ベロシティの計算と記録 ベロシティの可視化 やったこと
discord.py discord gspread Backlog API 使ったものたち(概要)
使ったものたち(パッケージなど) • discord.py:discordを操作するやつ • gspread:スプレッドシートを操作するやつ • requests:httpリクエストを送るやつ • pandas:表や時系列データを操作しやすいやつ •
matplotlib:グラフとか作るやつ • oauth2client:Google APIの認証周りをやってくれるやつ • PyYAML:yamlを操作するやつ [補足] • heroku:デプロイする場所として使ったやつ • poetry:pythonプロジェクトを管理するやつ
なぜやろうと思ったのか 背景 • 私のプロジェクトはスクラム(スクラムマスターいないけど…)をしている • プロダクトバックログはSpread SheetでスプリントバックログはBacklogで管理 • ベロシティの計測周りが手作業だった •
最近はちゃんとチェックしなくなっていた →自動でやってくれたらいいなぁ+みんな見てくれるかなぁ
Discord.py Cogが便利 よくある書き方 with event import discord token = ‘token’
client = discord.Client() @client.event async def on_ready(): print(‘botがログインしました ’) @client.event async def on_message(msg): if (msg.content == ‘!ping’): await msg.channel.send(‘pong!!’) client.run(TOKEN) pros - 手っ取り早くかける cons - 新たなコマンドを増やしたいときは on_message()内の条件分岐を 増やしていく →どんどん増えて煩雑になる
Discord.py Cogが便利 よくある書き方 with command from discord.ext import commands token
= ‘token’ bot = commands.Bot(command_prefix=’!’) “”” ctx: Context 呼び出しについてのコンテキストのメタデータが含まれている e.g. チャンネル, 送信者など “”” @client.event async def on_ready(): print(‘botがログインしました ’) @client.command async def ping(ctx): await ctx.send(‘pong!!’) bot.run(TOKEN) pros - 条件でなく関数名でコマンドが表現で きる cons - コマンドを意味のまとまりに分けること ができない e.g.: - 挨拶系:ping, hello - 時間系:timer, reminder
Discord.py Cogが便利 よくある書き方 with Cog from discord.ext import commands from
greeting import Greeting from timer import Timer token = ‘token’ client = commands.Bot(command_prefix=’!’) @client.event async def on_ready(): print(‘botがログインしました ’) client.add_cog(Greeting(client)) client.add_cog(Timer(client)) client.run(TOKEN) # greeting.py from discord.ext import commands class Greeting(commands.Cog): def __init__(self, bot): self.bot = bot @commands.commands async def ping(self, ctx): await ctx.send(‘pong’) @commands.commands async def hello(self, ctx): await ctx.send(‘world’) # timer.py from discord.ext import commands class Timer(commands.Cog): def __init__(self, bot): self.bot = bot @commands.commands async def timer(self, ctx): # TODO @commands.commands async def reminder(self, ctx): # TODO コマンドを意味のまとまりに分けることができる!
そんなこんなでのファイル構成 root |- main.py |- cog | |- scrum_master_cog.py |-
service | |- scrum_master_service.py | |- backlog_service.py | |- discord_service.py | |- sheet_service.py |- repository |- backlog_repository.py |- sheet_repository.py ここでCogを定義する scrum_master_cogで呼ぶメソッドたち undoneの課題一覧の取得、milestone情報の取得など discordに返すための値を作成など spreadsheetの更新など
gspread (Sheets API)とpandasの相性が良い pandasの便利なところ import pandas as pd import maplotlib.pyplot
as plt # 読み込み df = pd.read_csv(‘velocity.py’) # 絞り込み df = df[df.total >= 30] # -> totalが30以上の行が抽出できる # 図を作成 df.plot(x=’sprint’, y=’total’) # -> 横軸sprint, 縦軸totalの折れ線グラフができる # 統計値を計算 df.describe() “”” 要素数, 最頻値, 平均, 標準偏差, 最小値, 最大値, 中央値などが計算され る “”” sprint start end jack cocoa total 140 2020-07-02 2020-07-08 5 8 13 141 2020-07-09 2020-07-15 14 40 54 142 2020-07-16 2020-07-29 7 8 15 143 2020-07-30 2020-08-05 5 8 13 144 2020-08-06 2020-08-12 5 7 12 145 2020-08-13 2020-08-19 0 35 35 146 2020-08-20 2020-08-26 18 0 18 147 2020-08-27 2020-09-02 2 21 23 148 2020-09-03 2020-09-09 26 26 52 149 2020-09-10 2020-09-16 6 24 30 150 2020-09-17 2020-09-30 16 13 29 velocity.csv
sprint start end jack cocoa total 140 2020-07-02 2020-07-08 5
8 13 141 2020-07-09 2020-07-15 14 40 54 142 2020-07-16 2020-07-29 7 8 15 143 2020-07-30 2020-08-05 5 8 13 144 2020-08-06 2020-08-12 5 7 12 145 2020-08-13 2020-08-19 0 35 35 146 2020-08-20 2020-08-26 18 0 18 147 2020-08-27 2020-09-02 2 21 23 148 2020-09-03 2020-09-09 26 26 52 149 2020-09-10 2020-09-16 6 24 30 150 2020-09-17 2020-09-30 16 13 29 gspread (Sheets API)とpandasの相性が良い spreadsheetをpandasのDataFrameとして扱える velocity spreadsheet import gspread import pandas as pd # 認証部分は省略 # 読み込み sheet = gspread_client.open(‘velocity spreadsheet’).sheet1 df = pd.DataFrame(sheet.get_all_values()) csvを扱う時と同じ処理ができる ※numpyとして読み込むことも可能
Backlog APIのいけてないところ - 課題一覧取得 - マイルストーンの条件が当てはまらない場合は、全ての結果が返ってくる - マイルストーン一覧の取得 - マイルストーン単体で調べる
API がない - 一覧取得の際に名前でフィルターできない 今度もうちょっとまとめます
余談:設定値をyamlで管理しておいた discord: token: discord token scrum-master: channel-ids: [どこかのトピックのid, どこかのトピックのid] backlog:
api-key: BacklogのAPIキー base-url: BacklogのBase URL sheet: credentials: ./code/configs/credential.json product-backlog: バックログ用のスプレッドシートの名前 velocity: ベロシティを保存するようのスプレッドシートの名前