2023-03-18 SappoRo.R #10 での発表スライドです。
積もってく会議メモをどうにかしたかったSappoRo.R #10kazutan2023-03-18
View Slide
はじめに2 / 39
はじめに自己紹介名前/アカウント前田和寛(Maeda Kazuhiro)@kazutanTwitterGitHubQiita, r-wakalang, etc...3 / 39
はじめに書籍4 / 39
はじめに所属LINE Fukuoka株式会社Data ScientistDataLabs - Senior ManagerData Science TeamMachine Learning TeamData Engineering & Solution TeamLINE株式会社CDO Office5 / 39
はじめに今回のお話日々の困りごとをRで解消しようとしたお話API便利系関数のつくり方がメインコードが多めになりますAgenda降り積もる会議memo要件定義Confluenceへの投稿Trelloへの登録Solution6 / 39
降り積もる会議メモ7 / 39
最近の私会議がめっさ増えた1日平均で8-12本いろんなプロジェクト関わるようになったためヘッドセット装着しっぱなし骨伝導を導入したMeeting Driven何をしてるか?会議メモを書くあくまで個人用(議事録は別の人が担当)TODOやNext Actionを書き出すあくまで個人用タスク管理ツールに登録メモを保管8 / 39
何が起こったか?会議メモがあふれた実はVS Code上にMarkdownで書いてたちなみにpreviewとかrenderとかはしてない会議が連続するので、「保存する余裕がない」そして つい未保存のまま放置また次の会議でもメモを作成以下繰り返しタスク登録されないメモが書き捨て状態にそんな状態なので、タスク登録にまで至らないこのままではいけないだから解決しよう、Rで9 / 39
要件定義10 / 39
求めているものmarkdownでメモを書くシンプルにしたいどこかにpublishしてストックしときたい業務なのでconfluenceがいいどうせならタスク登録したいTrelloにスッと起票できるようにしたいできれば関数一発でできるとうれしいよね11 / 39
Confluenceへの投稿12 / 39
line/ConflrRmdファイルをConfluenceに投稿する関数を提供しているパッケージ詳細は以下のページを参照https://line.github.io/conflr/index.htmlinteractiveモードとbatchモードがある設定は .Renvironに登録すればOKRmdのYaml Front Matterにいろいろ書いておくと楽13 / 39
こんな感じでOKTrelloというセクションに、trelloへ送る設定を書くこれを test_0.Rmdとして進めます会議メモのフォーマット14 / 39
会議メモの実装res_confl <- conflr::confl_create_post_from_RmdでOKif (file.exists(Rmd_file)) {res_confl <- conflr::confl_create_post_from_Rmd(Rmd_file, interacmessage(paste("The memo was created at", res_confl))} else {stop("This Rmd file is not found. Please check this path.")}後述する「一発で全部やる関数」の中に組み込む15 / 39
Trelloへの登録16 / 39
TrelloにはREST APIが提供されているhttps://developer.atlassian.com/cloud/trello/rest/Trelloのほぼ全ての要素が扱えそう各種APIについては今回の発表では省略ドキュメントがしっかりしているkey/tokenがあれば利用可能API Call制限などはそれぞれで確認してください管理者により制限されている場合がありますTokyo.R #100で話したプレゼンを参照https://speakerdeck.com/kazutan/rniguan-li-saretemiruTrello Rest API17 / 39
RからTrelloにアクセスする関数たち認証系低水準系CURD関数高水準系具体的なアクションをする関数(いくつか今回用に関数を追加しました)18 / 39
認証系set_trello_auth_infos(force_update = FALSE)https://github.com/kazutan/trelloR/blob/master/R/api.R#L23-L56認証情報はkeyringパッケージを利用することに対話的にkey/tokenをセットするのでRのログに残らないすでに登録してある場合、強制的にupdateしたい場合は引数で指定check_trello_auth_infos(key = NULL, token = NULL,null_return = NULL)https://github.com/kazutan/trelloR/blob/master/R/api.R#L71-L107認証情報がすでにあるかどうかをチェックすでにあるならそれを持ってくる19 / 39
CRUD系関数GETget_trello_apiPUTput_trello_apiPOSTpost_trello_apiDELETEdelete_trello_api20 / 39
CRUD関数(低水準関数) - GETget_trello_api(base_url, path, verbose = FALSE, content = TRUE,query = list(), key = NULL, token = NULL)https://github.com/kazutan/trelloR/blob/master/R/api.R#L136-L166base_url, pathでAPIの行き先を指定queryでクエリパラメータを指定verboseを出すかどうかを指定可能content = TRUEで、outputに httr::content()を当てたものを返すkey, tokenはNULLならローカルのkeyringへ探しに行くbatch処理をする場合は、ここにSecretで渡せばOK21 / 39
CRUD関数(低水準関数) - PUTput_trello_api(base_url, path, verbose = FALSE, content = TRUE,query = list(), body = NULL,encode = c("multipart", "form", "json", "raw"),key = NULL, token = NULL)https://github.com/kazutan/trelloR/blob/master/R/api.R#L173-L206get_trello_api()とほぼ一緒body, encodeについては ?httr::PUTを参照22 / 39
CRUD関数(低水準関数) - POSTpost_trello_api(base_url, path, verbose = FALSE, content = TRUE,query = list(), body = NULL,encode = c("multipart", "form", "json", "raw"),key = NULL, token = NULL)https://github.com/kazutan/trelloR/blob/master/R/api.R#L213-L246put_trello_api()とほぼ一緒23 / 39
CRUD関数(低水準関数) - DELETEdelete_trello_api(base_url, path, verbose = TRUE,key = NULL, token = NULL)https://github.com/kazutan/trelloR/blob/master/R/api.R#L253-L275get_trello_api()とほぼ一緒ただし、verbose = TRUEをデフォルトに24 / 39
高水準関数 - メンバー情報取得get_member_infos(base_url, member = "me",post_path = NULL, query = list(),verbose = FALSE, content = TRUE,key = NULL, token = NULL)https://github.com/kazutan/trelloR/blob/master/R/get.R#L13-L46メンバー情報を取得する関数memberユーザー名もしくはメンバーIDを指定長さ2以上のベクトルで与えた場合、purrr::mapでまとめて実行するmeは自分自身を指定する意味となるpost_pathはさらに対象を指定するときに利用詳細はTrello APIリファレンスを参照25 / 39
高水準関数 - ボード情報取得get_board_infos(base_url, board_id,post_path = NULL, query = list(),verbose = FALSE, content = TRUE,key = NULL, token = NULL)https://github.com/kazutan/trelloR/blob/master/R/get.R#L56-L89ボード情報を取得する関数board_idボードIDを指定あとは get_member_infos()と同様26 / 39
高水準関数 - カード作成create_card(base_url,board_id = NULL, list_id = NULL, list_name = NULL,card_name = "Untiled", card_body = list(), query = list(verbose = FALSE, content = TRUE,key = NULL, token = NULL)カードを作成する関数list_idを指定すれば、そのリストのところにカード作成わからなくても、board_idを指定すれば作成可能board_idと list_nameを指定すれば、アクセスしてlist_idを取得して実行できるcard_bodyに、リストでCardの内容を突っ込めばOK27 / 39
高水準関数 - カードにコメントを追加add_new_comment(base_url,card_id, text,verbose = FALSE, content = TRUE,key = NULL, token = NULL)カードにコメントを追加する関数card_idは必須textにコメント内容を書き込むTrelloはmarkdown記法を受け付ける(重要)28 / 39
Solution29 / 39
会議メモのR Projectパッケージ化はいまのところ予定なしまだ作りかけで、運用してみてから考えるRmd_sandboxここに会議メモのRmdを作っていくtrello_profileここにtrelloの設定をyamlで保存しておくいまのところは base_urlとlist_id30 / 39
build_mtg_memo(長いので、分割して貼り付けてます)# 実行プロセス系の関数build_mtg_memo <- function(Rmd_file, add_trello = FALSE, trello_prof# post to confluenceif (file.exists(Rmd_file)) {res_confl <- conflr::confl_create_post_from_Rmd(Rmd_file, interacmessage(paste("The memo was created at", res_confl))} else {stop("This Rmd file is not found. Please check this path.")}31 / 39
続き(2枚目)# trello processif (add_trello) {# check and get trello profileif (is_null(trello_profile)) {stop("There is no trello profile. Please check again.")} else {trello_setting <- yaml::read_yaml(trello_profile)}# catch trello section from Rmdrmd_raw <- readLines(Rmd_file)# get trello contexttrello_context <- rmd_raw[str_which(rmd_raw, "^# Trello"):length(rmd_raw)]# get memo contentsmemo_contents <- rmd_raw[(str_which(rmd_raw, "^---")[2] + 1):(str_which(rmd_raw, "^# Trello")# create trello contentstrello_content <- list(# TODO: ここを必要に応じて追加title = str_extract(str_subset(trello_context, "^title:"),"^title:(.+)",group = 1)) 32 / 39
続き(3枚目)# add confl_memo url to commentadd_new_comment(trello_setting$base_url,card_id = card_obj$id,text = paste(memo_contents, collapse = "\n"))# modify Rmdrmd_modified <- c(rmd_raw, "\nTrello Card", card_obj$url)write(paste(rmd_modified, collapse = "\n"), Rmd_file)# messagemessage("The card was created. Plase check Trello.")}} 33 / 39
手順1. Rmd_sandboxディレクトリに、Rmdファイルを作成2. メモを書く1. メモの最後にTrelloを作る3. build_mtg_memo("kosaki.Rmd", add_trello = TRUE, trello_profile ="kosaki.yml")Rで解決しました34 / 39
35 / 39
36 / 39
さいごに37 / 39
なければ作る、でも効率よく要件を整理しようそれはissueに基づいていますか?あるならそれを使おう大事なのはachievement組み合わせることが大事そのために設計を意識しようみんなでRを書いて楽になろう38 / 39
Enjoy!39 / 39