Slide 1

Slide 1 text

積もってく会議メモをどうにかしたかった SappoRo.R #10 kazutan 2023-03-18

Slide 2

Slide 2 text

はじめに 2 / 39

Slide 3

Slide 3 text

はじめに 自己紹介 名前/アカウント 前田和寛(Maeda Kazuhiro) @kazutan Twitter GitHub Qiita, r-wakalang, etc... 3 / 39

Slide 4

Slide 4 text

はじめに 書籍 4 / 39

Slide 5

Slide 5 text

はじめに 所属 LINE Fukuoka株式会社 Data Scientist DataLabs - Senior Manager Data Science Team Machine Learning Team Data Engineering & Solution Team LINE株式会社 CDO Office 5 / 39

Slide 6

Slide 6 text

はじめに 今回のお話 日々の困りごとをRで解消しようとしたお話 API便利系関数のつくり方がメイン コードが多めになります Agenda 降り積もる会議memo 要件定義 Confluenceへの投稿 Trelloへの登録 Solution 6 / 39

Slide 7

Slide 7 text

降り積もる会議メモ 7 / 39

Slide 8

Slide 8 text

最近の私 会議がめっさ増えた 1日平均で8-12本 いろんなプロジェクト関わるようになったため ヘッドセット装着しっぱなし 骨伝導を導入した Meeting Driven 何をしてるか? 会議メモを書く あくまで個人用(議事録は別の人が担当) TODOやNext Actionを書き出す あくまで個人用 タスク管理ツールに登録 メモを保管 8 / 39

Slide 9

Slide 9 text

何が起こったか? 会議メモがあふれた 実はVS Code上にMarkdownで書いてた ちなみにpreviewとかrenderとかはしてない 会議が連続するので、「保存する余裕がない」 そして つい未保存のまま放置 また次の会議でもメモを作成 以下繰り返し タスク登録されない メモが書き捨て状態に そんな状態なので、タスク登録にまで至らない このままではいけない だから解決しよう、Rで 9 / 39

Slide 10

Slide 10 text

要件定義 10 / 39

Slide 11

Slide 11 text

求めているもの markdownでメモを書く シンプルにしたい どこかにpublishしてストックしときたい 業務なのでconfluenceがいい どうせならタスク登録したい Trelloにスッと起票できるようにしたい できれば関数一発でできるとうれしいよね 11 / 39

Slide 12

Slide 12 text

Confluenceへの投稿 12 / 39

Slide 13

Slide 13 text

line/Conflr RmdファイルをConfluenceに投稿する関数を提供しているパッケージ 詳細は以下のページを参照 https://line.github.io/conflr/index.html interactiveモードとbatchモードがある 設定は .Renviron に登録すればOK RmdのYaml Front Matterにいろいろ書いておくと楽 13 / 39

Slide 14

Slide 14 text

こんな感じでOK Trelloというセクションに、trelloへ送 る設定を書く これを test_0.Rmd として進めます 会議メモのフォーマット 14 / 39

Slide 15

Slide 15 text

会議メモの実装 res_confl <- conflr::confl_create_post_from_Rmd でOK if (file.exists(Rmd_file)) { res_confl <- conflr::confl_create_post_from_Rmd(Rmd_file, interac message(paste("The memo was created at", res_confl)) } else { stop("This Rmd file is not found. Please check this path.") } 後述する「一発で全部やる関数」の中に組み込む 15 / 39

Slide 16

Slide 16 text

Trelloへの登録 16 / 39

Slide 17

Slide 17 text

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-saretemiru Trello Rest API 17 / 39

Slide 18

Slide 18 text

RからTrelloにアクセスする関数たち 認証系 低水準系 CURD関数 高水準系 具体的なアクションをする関数 (いくつか今回用に関数を追加しました) 18 / 39

Slide 19

Slide 19 text

認証系 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

Slide 20

Slide 20 text

CRUD系関数 GET get_trello_api PUT put_trello_api POST post_trello_api DELETE delete_trello_api 20 / 39

Slide 21

Slide 21 text

CRUD関数(低水準関数) - GET get_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-L166 base_url , path でAPIの行き先を指定 query でクエリパラメータを指定 verboseを出すかどうかを指定可能 content = TRUE で、outputに httr::content() を当てたものを返す key , token はNULL ならローカルのkeyringへ探しに行く batch処理をする場合は、ここにSecretで渡せばOK 21 / 39

Slide 22

Slide 22 text

CRUD関数(低水準関数) - PUT put_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-L206 get_trello_api() とほぼ一緒 body , encode については ?httr::PUT を参照 22 / 39

Slide 23

Slide 23 text

CRUD関数(低水準関数) - POST post_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-L246 put_trello_api() とほぼ一緒 23 / 39

Slide 24

Slide 24 text

CRUD関数(低水準関数) - DELETE delete_trello_api(base_url, path, verbose = TRUE, key = NULL, token = NULL) https://github.com/kazutan/trelloR/blob/master/R/api.R#L253-L275 get_trello_api() とほぼ一緒 ただし、verbose = TRUE をデフォルトに 24 / 39

Slide 25

Slide 25 text

高水準関数 - メンバー情報取得 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

Slide 26

Slide 26 text

高水準関数 - ボード情報取得 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

Slide 27

Slide 27 text

高水準関数 - カード作成 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の内容を突っ込めばOK 27 / 39

Slide 28

Slide 28 text

高水準関数 - カードにコメントを追加 add_new_comment(base_url, card_id, text, verbose = FALSE, content = TRUE, key = NULL, token = NULL) カードにコメントを追加する関数 card_idは必須 text にコメント内容を書き込む Trelloはmarkdown記法を受け付ける(重要) 28 / 39

Slide 29

Slide 29 text

Solution 29 / 39

Slide 30

Slide 30 text

会議メモのR Project パッケージ化はいまのところ予定なし まだ作りかけで、運用してみてから考える Rmd_sandbox ここに会議メモのRmdを作っていく trello_profile ここにtrelloの設定をyamlで保存しておく いまのところは base_url とlist_id 30 / 39

Slide 31

Slide 31 text

build_mtg_memo (長いので、分割して貼り付けてます) # 実行プロセス系の関数 build_mtg_memo <- function(Rmd_file, add_trello = FALSE, trello_prof # post to confluence if (file.exists(Rmd_file)) { res_confl <- conflr::confl_create_post_from_Rmd(Rmd_file, interac message(paste("The memo was created at", res_confl)) } else { stop("This Rmd file is not found. Please check this path.") } 31 / 39

Slide 32

Slide 32 text

続き(2枚目) # trello process if (add_trello) { # check and get trello profile if (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 Rmd rmd_raw <- readLines(Rmd_file) # get trello context trello_context <- rmd_raw[str_which(rmd_raw, "^# Trello"):length(rmd_raw)] # get memo contents memo_contents <- rmd_raw[(str_which(rmd_raw, "^---")[2] + 1):(str_which(rmd_raw, "^# Trello") # create trello contents trello_content <- list( # TODO: ここを必要に応じて追加 title = str_extract( str_subset(trello_context, "^title:"), "^title:(.+)", group = 1) ) 32 / 39

Slide 33

Slide 33 text

続き(3枚目) # add confl_memo url to comment add_new_comment( trello_setting$base_url, card_id = card_obj$id, text = paste(memo_contents, collapse = "\n") ) # modify Rmd rmd_modified <- c(rmd_raw, "\nTrello Card", card_obj$url) write(paste(rmd_modified, collapse = "\n"), Rmd_file) # message message("The card was created. Plase check Trello.") } } 33 / 39

Slide 34

Slide 34 text

手順 1. Rmd_sandboxディレクトリに、Rmdファイルを作成 2. メモを書く 1. メモの最後にTrello を作る 3. build_mtg_memo("kosaki.Rmd", add_trello = TRUE, trello_profile = "kosaki.yml") Rで解決しました 34 / 39

Slide 35

Slide 35 text

35 / 39

Slide 36

Slide 36 text

36 / 39

Slide 37

Slide 37 text

さいごに 37 / 39

Slide 38

Slide 38 text

なければ作る、でも効率よく 要件を整理しよう それはissueに基づいていますか? あるならそれを使おう 大事なのはachievement 組み合わせることが大事 そのために設計を意識しよう みんなでRを書いて楽になろう 38 / 39

Slide 39

Slide 39 text

Enjoy! 39 / 39