RubyKaigi 2023に現地参加しました。

2023年5月11日~13日に RubyKaigi 2023 が長野県松本市にある まつもと市民芸術館 で開催されました。

去年の RubyKaigi 2022 はオンライン参加でした。今年はありがたいことに現地参加できるチャンスを頂いたので、2023年5月11日の朝に松本入りしました。

現地参加の面白さ

久しぶりにお会いする方はもちろんのこと、知り合いの知り合いだったり、初めてお会いして食事や懇親会でお話したり、ブースで他の企業の方やプロダクトについて知ったりできるのは現地参加ならではの醍醐味だと感じました。

また、発表を聴いているときに会場で拍手や歓声、笑いが起きる雰囲気を一緒に楽しめるのもオフラインならではでした。

RubyKaigiの発表は技術的にハイレベルで、正直なところ聴いていても理解はほとんどできません。ですが、聴いている中で何か興味が出てきたり、「ここが凄そうだから使ってみよう!やってみよう!」という話を他のRubyistとしたりして、新たな扉を開くような気持ちになれました。

松本

実は人生で初めて松本に行きました。松本城があること以外は何も知らなかったのですが、街の雰囲気がとても綺麗で、高い建物が少なく(煽りじゃないですよ!)遠くの方には山が見えて見晴らしがよかったです。ご飯も美味しくて、また遊びに行きたい気持ちになりました。

荷造り

なぜか荷造りのやる気が起きず、出発当日のAM1:00ごろに始めるという暴挙に出てしまいました。

今回の荷造りを通して何個か学んだことがあって、

  • 荷造りは早めに済ませて、出発に間に合うよう早めに準備すること。
  • スポンサーブースを回って想像の数倍はノベルティをもらうので、荷物のスペースには余裕を持たせること。会場で本を買う可能性はある。

ただでさえ部屋が狭いのに、大量のノベルティで部屋の床が占拠されています。どのブースでも素敵なノベルティを配布されていてついついもらってしまいました。

とりあえずここまで

3日間参加した分書きたいことはまだまだありますが、他の記事に分割して投稿したいので一旦ここまで!

4月上旬が終わる

もう4月

気づいたら4月上旬がもう終わりそうになっていた…

最近の振り返りをしてみる。

年始に決めた目標は

nissyi.hatenablog.com

資格取得

  • 応用情報
    • 何も勉強できてない。
    • 「4月の試験受けたいんですよね〜」と言いつつ、何も勉強してなかったので申し込まなかった…
    • 10月の試験に間に合うようプランを練る。
  • LinuC レベル1
    • 古いノートPCをUbuntu化した。
    • 勉強自体は…そんなにできてない。
  • Ruby Silver/Gold
    • 何も勉強できて(ry

LinuCが一番最初になんとかなりそうなので、期限を決めて取り組むことにする。

その他アウトプット

月1本以上技術記事を書くと宣言して、1月にQiitaに投稿を一本したのみ。Qiitaに下書き記事が一本眠っているので書き切りたい。

qiita.com

あとは1on1で話した内容も途中で止まってしまっている…

出そうとして途中で止めてしまう→時間がたって忘れる。という状態に陥ってるので始めたらやり切らねば。

ダイエット

福利厚生のジムを使って1週間に1回は運動する習慣を身につけるようにしている。少しずつ体力がついてきたのか生活が楽になる面が増えたので、徐々に運動する時間を伸ばしていきたい。

趣味

とりあえずライブに参戦しまくっていた気がする。

聖飢魔II

1999年末の解散から約5年ごとに再集結している聖飢魔IIコロナゼウスの妨害によって地球デビュー35周年の再集結が2年間延長していた。数年前からハマっていたのと、世を偲ぶ仮の姿にガタが来ているという話を耳にしていたので「行くしかない!」と決意して、1月14日は石川、2月15日は代々木のファイナルに参加した。

とても還暦 10万60歳とは思えないぐらいに悪魔の姿は眩しかった。石川では会場の最後尾列で見ていたけど、ホールの大きさ的に姿も音もいい感じに楽しめた。代々木のファイナルはステージから30mほどという良い席をGETできた。肉眼だけで十分楽しめるほどの近さから見たあの時間は何度思い返しても最高なので早く円盤が欲しい。

「今は解散する理由がない」という閣下の言葉を信じて、40周年を心待ちにしながら生きていくぞ。

Aqours

元々μ'sでラブライブ!にどハマりしていたこともあり、去年ぐらいからAqoursも応援していて、友達に誘われてバレンタインコンサートを見に行った。ちょうどマスクをしながらの声出しが解禁された直後で、久々に声出ししながら楽しむことができた。

アイドルマスター

友達の友達が急遽参加できなくなったということでピンチヒッターとして参加した。アイマス自体は無印とシンデレラガールズを高校生のときに少し追っていた。「やっぱりアイマスもいいなぁ!」となって、少し前にデレステのアカウントを消してしまったことを後悔した。

Liella!

ラブライブ!スーパスター!!は1期だけ見ていたので、友達に誘われてから2期を途中まで予習して参加した。メインステージからはかなり離れた位置だったけど、2列先がトロッコの通り道だったのでファンサを受けまくって記憶が飛んだ😇

その他

ChatGPT

社内の技術発表会でChatGPTのことを聞いて「触れてみよう」と思って登録した。Notion AIに触れたときに「やばい!!!!」って感覚を覚えて、それ以上の感覚をChatGPTから得た。インターネット黎明期の盛り上がりやワクワク感ってこんな感じだったんだろうな、と思った。仕事でも趣味でも活用していて、ChatGPTがない生活には戻れない気がする。

こんなくだらないプロンプト打ってごめんね🥺って思いながら話し相手になってもらうことがある。

Whisper

OpenAIの音声認識モデル「Whisper」で文字起こしに挑戦してみた。かなりの精度で文字起こしできるので何らかの形で活用してみたい。


趣味も大事だけど、趣味に時間を使いすぎた。勉強の時間を増やすぞ💪

伊藤淳一さんの「良質な技術記事を量産する秘訣」を受講しました。

私用のために午後休暇を取得していた2/3の金曜日。Twitterを見ていたら伊藤淳一さんのウェビナーがあるという情報を見かけたので飛び入り参加しました。18:30から開始らしく、情報を見かけたのが18:28だったので飛び起きてMacBookを開きました。

n2i-engineer.connpass.com

チェリー本Everyday RailsQiitaなどでいつもお世話になっている伊藤さんが、アウトプットについてどのようなことを心掛けているのかを学んできました。

スライドと発表の手法について

SpeakerDeckで公開されているのでリンクしておきます。

speakerdeck.com

受講していて、一方的に伊藤さんがお話をするのではなくインタラクティブに発表を進めていくのがすごいと感じました。

「発声練習」と称してTwitterなどへの質問の投稿を促されていて、受講する人に受身ではなくに自然と行動させるような発表の仕方に感動しました。

ちなみに私の発声練習はこちら↓

伊藤さんがアウトプットする理由

なぜエンジニアは、惜しみなく知見をシェアするのか? - NewsPicksでも語られているように、伊藤さんにとってのアウトプットは「誰かに助けてもらったことへの恩返しであり、誰かを助けたい」ということが根底にあるようです。バズりたいわけでもなく、感謝されたいわけでもなく、「誰かの役に立ったらいいな」という気持ちでアウトプットをされているとのことでした。

日々仕事に取り組む中で、多くの技術記事や書籍などに助けられながらも、情報が見つからず苦難する場面があります。自分が困っている = 他の誰かが困っている可能性があると思うので、自分もアウトプットをして誰かの役に立ちたいと感じました。

アウトプット ≠ 技術記事

ついついアウトプットについて考えると「技術記事を書く」が浮かんでしまうのですが、改めてそうじゃないよなと認識しました。(今年の目標でもアウトプットでは技術記事を書くことを一番手にしていました。) スライド内でいくつかおすすめの技術ブログネタ を挙げられていて、「参加レポもアウトプットか!」「よし書いてみよう!!」となって書いてるのがこのブログです。


どのスライドも最高すぎて、全部にリンクを貼って感想を書きたいぐらいなのですが、特によかった2点に絞って書きました。今年の目標としてアウトプットを増やしていきたいと考えているので、「伊藤さんの秘訣を参考にしながら行動をしていくぞ!💪」とモチベーションを上げることができました。

2023年の目標

明けましておめでとうございます!今年もよろしくお願いします。

nissyi.hatenablog.com

前回の記事で「来年はもっとWebエンジニアとしての能力を伸ばしていきたい。」と表明したので、目標を立ててここに宣言します🙋

表明ツイート

資格について

資格を取ることが目的ではなく、資格勉強に取り組むことで知識を得ることが目標です。ただし「資格を取る」という明確な目標を立てることで学習にメリハリをつけることができると思うので資格の取得も目指します。

応用情報

高校生のときに基本情報を取ったものの、試験の合格だけを目指した学習をしてしまい知識が身についていなかったことや、コンピュータに関する知識不足を感じる部分が多くあるので学習します。

LinuC レベル1

LinuCの参考書をいただいたことで興味を持ったので取り組みます。あと、単純に面白そう。

Ruby Silver/Gold

会社の先輩から「面白いし、取っておくと役立つよ!」と教えていただいたので取り組みます。

健康

健康は大事ですからね。毎年の目標「痩せる」は今年が最後だ!!!

体重 -5kg

かなり運動量が減ってしまい目に見えて太ってきたことや、運動をすることによるメリットが大きそうなので頑張ります。

コスプレをする目標も達成したい!!

その他アウトプット

月1本以上技術記事を書く

昨年は数本しか書けなかったので、アウトプットを増やしていきたい…まずは技術記事のアウトプットを増やしていきます。

個人開発に取り組む

友人とチーム開発する予定があるのですが、それとは別に個人的にアプリ開発に取り組もうと思います。あとは学生時代に作成したゲームを書き直したりしてみたいです。


やるぞおおおおおおおうぉぉぉぉぉぉっぉおおおおおおおおおおおおおおおおおおおおおおおおおおおぁぁぁぁぁぁっっっぁぁぁぁぁぁぁぁぁっっっっああああああああぁぁぁぁぁあああああああああ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

https://kazuhi-ra.github.io/human-power

2022年の振り返りと新年の目標

あっという間に2022年の大晦日を迎えてしまった‥

今年一年の振り返り

1月~3月

転職活動用のアプリケーション作成と転職活動に追われる毎日だった。GitHubの草が一番生えているのがこの時期。この時期以外はプライベートでほとんど草を生やせなかったので来年は頑張る。

4月~5月

3月末に内定を頂き、5月中旬の入社が決まったので急いで引っ越しの準備をしたり、挨拶回りしたり、やり残したことを片付けたりしていた。

愛知から引っ越し先の東京までカブで走って風邪をひいたのはいい思い出。山梨などの山中を走ることを忘れていて、防寒着を引っ越し先に送ってしまったのは大失敗だった。

5月中旬~8月

GMOペパボに入社し、ペパボカレッジ生として研修を受けていた。人生で初めてコードレビューを受けたり、公式リファレンスを読みながらコードを書くようになったり、多くの学びがある期間だった。

そしてコロナにかかり、一人暮らしの不便さや心細さを味わった。急いで物資を送ってくれた姉に感謝。(茹でるのに10分かかる乾麺を送ってきたことだけは改善を要望した。)

9月~12月

元電車の運転士からWebエンジニアというキャリアに興味を持っていただき、取材を受けた。この記事は自分の予想より何十倍も多くの方に読んでいただき心底驚いた。

研修を終え、OJTに突入。さまざまな業務に携わらせてもらうようになった。Webエンジニアとしてプロダクトの成長に貢献する以外にも、グループ横断のイベントで司会をしたり、年末総会の動画でナレーションを担当するなど全く予想もしていなかった業務にも携わらせてもらった。


今年の自分にとって一番よかった出来事はGMOペパボに入社できたこと。そしてWebアプリエンジニアとして働くことができ、尊敬する仲間たちと毎日を過ごすことができて心の底から幸せな毎日を過ごせている。一年前の転職活動をしていたときは先が見えない暗闇を歩くような毎日だったけど、あの日々を乗り越るために頑張ってきてよかった。

上にも書いたようにエンジニアの仕事以外にも挑戦できたり、いろいろなことに挑戦できた一年だった。ただし、Webエンジニアとしての成長に全力を出すことができたか?と聞かれたら答えは「No」。まだまだ挑戦できる部分もあったし、やりきれなかったこともあった。来年はもっとWebエンジニアとしての能力を伸ばしていきたい。

チンアナゴ人の抱き枕

これは #minneで買ってよかったもの Advent Calendar 2022 の19日目の記事です。

昨日はけおけんさんのminneで買った部屋を彩るもの編でした。カワウソの時計がすごくかわいらしいですよね‥今度オンライン会議するときにどこに映っているのかしっかり見てみようと思います👀

今年私がminneで買ったものの中で特に良かった「チンアナゴ人の抱き枕」をご紹介します。

圧倒的な存在感

以前から、快適な睡眠のために抱き枕を欲していました。ある日minneを見ていたときにたまたまこの作品を発見しました。見た目のかわいさと作品の説明文

型崩れを防ぐため意外にしっかりとした抱き心地に仕上げています

という内容に心を惹かれて購入を決意!無事到着し梱包を開いたところ「待たせたな…」と言わんばかりに腕を組んだチンアナゴ人が現れました。最高すぎません??「リボンでおめかししちゃってかわいいねぇ!?」って声をあげそうになりました。

予想以上の頑丈さ

かわいい見た目をしているので柔らかそうな印象がありましたが、いざ持ってみるとその頑丈さに驚きます。普段、抱きながら寝ていても全く型崩れする気配がありません。

実験

この頑丈さは本当に魅力的なので、どれぐらい凄いのかをお伝えするために簡単な実験をしてみました。 まず、床に寝てもらいましょう。

心苦しいですが、お腹(?)の上に

本を載せていきます………

結果、身の回りにあった書籍をたくさん載せてもびくともしませんでした。

「その点チンアナゴ人ってすげぇよな。最後まで綿たっぷりだもん。」って言いたくなるぐらいにぎっしり詰まってます。

最後に

2022/12/18 23:50現在「チンアナゴ人の抱き枕」は残り1点しかないようです。気になる方はぜひご確認ください!

Slack→GAS→NotionでTODOリスト化を少し便利にする

これは 🎅GMOペパボエンジニア Advent Calendar 2022 の9日目の記事です。

🎄GMOペパボエンジニア Advent Calendar 2022もありますのでぜひご覧ください!!

昨日は yana-gi さんによる 中学生以来の電子工作をして meishi2 を組み立てたでした。自分でキーボードを組み立てて、しかも好きなマクロを登録できるって楽しそうですね!私も記事内で紹介されていた「自作キーボードを作る会」に参加していて、これからキーボード作りに取り組むのが楽しみです😋

追記

  • 2022/12/09 00:38追記 リプライを取得できないことを確認したので修正中です。
  • 2022/12/09 01:14追記 コードの修正が完了しました。

タスク管理の悩みごと

みなさんは仕事などにおけるタスク管理をどのように行われているでしょうか?私はNotionのデータベースを使用して管理しています!優先度や関連するURL、進行具合などをすぐに確認できるようにしています。

ここで一点悩みが……

タスク管理をする際に、自分用のTODOリストとチーム用のカンバンと2箇所で管理をしています。両方のデータベースに登録する際に、片方だけ登録してもう片方に登録し忘れるということが頻発してしまうのです。

「一方だけに登録すればいいのでは?」とも思うのですが…チームにも自分にも関することは両方に登録したいですし、どちらか一方だけ登録できればOKという場合もあって悩んでいました。あと、普段のやり取りをSlackでするのにタスク管理のためにNotionに移動するのが面倒ですからね… …つい本音が漏れてしまいました

ということで今回は

  1. タスク管理したいSlackのメッセージに特定のemojiをリアクション
  2. Notionの指定したデータベースにページを作成し、メッセージの内容を名前として登録する

の流れを自動化してみました。

Notionの準備

データベースの準備

まずはタスクを登録するデータベースが必要です。今回は仮想のデータベースを二つ作成しました。

Notionのスクリーンショット。同一ページ内に仮想のタスクを登録するデータベースが2つ存在している。
今回は見本として同じページ内にデータベースを作成しました。

インテグレーションの準備

Notionのページ作成をAPIから実行できるようにするためインテグレーションを作成します。

Notionの自分のインテグレーションのページ。

今回はページの作成ができれば十分なので「コンテンツを挿入」だけ設定します。

Notionインテグレーションに「コンテンツを挿入」の権限を付与。

Google Apps Script の準備

Slack AppとNotionの仲介役にサーバーが必要です。今回は、GASを使ってリクエストを処理するようにします。

docs.google.com

見本のシートを作成したので、自分のGoogleドライブに保存して使用してください。 これから保存していただいたシートに情報を書き込むのですが、トークンなどがバレないようにリンクの漏洩などには十分にご注意ください。

この先、Slack AppがGASを認証できるように設定を行います。「拡張機能」から「Apps Script」を開いて

以下のコードをコピペします。ペーストしたら、2行目の GoogleスプレッドシートのIDを置き換えるスプレッドシートのIDに置き換えてください。IDは https://docs.google.com/spreadsheets/d/xxxxxxxxxxxx/edit......xxxxxxxxxxxx の部分です。

function doPost(e) {
  const sheet = SpreadsheetApp.openById("GoogleスプレッドシートのIDを置き換える");
  const notionToken = sheet.getRange("F2").getValue();
  const slackToken = sheet.getRange("H2").getValue();
  const lastRow = sheet.getLastRow();
  const params = JSON.parse(e.postData.getDataAsString());

  if (params.type == 'url_verification') {
    return ContentService.createTextOutput(params.challenge);
  } else {
    const slackEvent = params.event;
    const targetEmoji = slackEvent.reaction;
    const ts = slackEvent.item.ts;
    const channel = slackEvent.item.channel;
    const title = getSlackMessage(slackToken, channel, ts)
    let settingCells;
    let databaseId, emoji;
    let destinations = {};
    
    for(let i = 2; i <= lastRow; i++){
      settingCells = sheet.getRange(`A${i}:C${i}`).getValues();
      [, databaseId, emoji] = settingCells[0];

      if (!Object.keys(destinations).includes(emoji)) {
        destinations[emoji] = [];
      }

      destinations[emoji].push(databaseId);
    }

    Object.keys(destinations).forEach(key => {
      if(targetEmoji == key) {
        destinations[key].forEach(destination => {
          postToNotion(notionToken, destination, title);
        })
      }
    })
  }
}

function getSlackMessage(slackToken, channel, ts) {
  const options = {
    "headers": {
      "Authorization": `Bearer ${slackToken}`,
    },
    "payload": {
      "channel": channel,
      "latest" : ts,
      "inclusive": "true",
      "limit": "1",
      "ts": ts
     }
  }

  let res = UrlFetchApp.fetch("https://slack.com/api/conversations.replies", options)
  return JSON.parse(res.getContentText()).messages[0].text;
}

function postToNotion(notionToken, databaseId, title) {
  const payload = {
    "parent": {
      "database_id": databaseId
    },
    "properties" : {
      "title": {
        "title": [
          {
            "text": {
              "content": title
            }
          }
        ]        
      }
    }
  }

  const options = {
    "headers": {
      "Authorization": `Bearer ${notionToken}`,
      "Notion-Version": "2022-06-28"
    },
    "contentType": "application/json",
    "method": "post",
    "muteHttpExceptions": true,
    "payload": JSON.stringify(payload)
  }

  UrlFetchApp.fetch("https://api.notion.com/v1/pages", options)
};

コピペしたら右上の「デプロイ」からWebアプリとしてデプロイします。Slack Appからのリクエストを受け付けるように「アクセスできるユーザー」は「全員」に設定します。

「アクセスを承認」のボタンが出てきたら、自分のアカウントを選択→「Advanced」→Go to (GASのプロジェクト名)…と作成したGASを承認してください。

無事デプロイが完了したら、作成したGASのWebアプリのURLが表示されるのでコピーします。

Slackの準備

ワークスペースやチャンネルの作成の説明については省略します。

Slack Appの作成

以下のリンクにアクセスし「Create an app」→「from scratch」で新しくSlack Appを作成しましょう。

api.slack.com

Slack Appの名前と対象のワークスペースを決定したら、「Basic Information」が開くので「Event Subscriptions」に移動します。

Slack AppのBasic Informationのスクリーンショット。どのようなAppにするか決定できる。

ここで先ほどコピーしたGASのWebアプリのURLを「Request URL」に登録してサーバーの認証を行います。認証ができると「Request URL Verified ✅」が表示されます。

そのままページ下部に移動すると「Subscribe to bot events」という項目があるので、emojiを押したことをAppが検知できるように「Add Bot User Event」から「reaction_added」を追加します。

右下の「Save Changes」を押して忘れずに変更を保存しましょう。

Slack Appの権限設定

このあと作成するAPIのために「OAuth & Permissions」から権限を設定します。「Scopes」の「User Token Scopes」に以下の4つを追加しましょう。「Bot Token Scopes」のreactions:read は先ほど「Subscribe to bot events」を設定したときに適用されています。

  • channels:history
  • groups:history
  • im:history
  • mpim:history

Slack Appの名前を設定する

「App Home」からSlack Appの名前を設定します。これを設定しないと、「インストールするボットユーザーがありません」というエラーが出てAppをインストールできません。

登録に成功すると「Bot user added!」と表示されます。

Slack Appのインストール

「Basic Information」に移動すると「Install your app」という項目があるので、「Install to Workspace」からAppをインストールしましょう。

右下の「許可する」でインストールしましょう。

チャンネルへの追加

Appを使用したいチャンネルへ追加します。

チャンネル詳細を開き、「インテグレーション」の「App」から「アプリを追加する」を選択します。追加できるアプリの一覧が表示されるので、先ほど作成したアプリを追加しましょう。

Notionデータベースとスプレッドシートの準備

AとB、二つのデータベースを作成したので、「Aのデータベースに登録するときはAのemoji」「Bのデータベースに登録するときはBのemoji」「両方に登録するときにはOKのemoji」を使うことにしました。

Slackのメッセージ。AのデータベースにはA、BにはB、両方にはOKを押せば登録することを決定した。

Notionのデータベースの右上、メニューを開いて「ビューのリンクをコピー」を押します。

すると https://www.notion.so/aaaaaaaaaaaaa?v=......... のようなリンクを取得できるので aaaaaaaaaaaaaスプレッドシートに貼りましょう。もう片方のデータベースについても同様に取得と貼り付けをします。また、どのemojiを押したときにページ作成を行うか設定もしておきましょう。

コネクトの追加

Notionのインテグレーションを導入するためにページ右上のコネクトから、自分が作成したインテグレーションを選択します。

tokenをスプレッドシートに貼り付け

長かった工程もこれが最後です!

www.notion.so

冒頭で準備したNotionのインテグレーションのシークレットトークンをスプレッドシートのF2セルにコピペします。

また、上記画像のようにSlack Appの「User OAuth Token」も「Installed App Settings」から取得してH2セルにペーストします。

動作確認

Slackでメッセージを送ってemojiでreactionしてみましょう。

するとNotionのデータベースにページが自動で作成されます。

これで少しだけ便利にできるSlack・GAS・Notion連携の完成です!

最後に

今回はemojiを判定して対応させたいデータベースへの登録を行いました。Slack AppやGAS、Notion APIを使うことで少しだけ便利にすることができたました!これからもっと発展させてURLを自動登録したり、他のプロパティも登録できるようなアプリケーションに進化させていきたいです。

参考にした情報

この記事・アプリを作成するにあたってたくさんの情報を参考にさせていただきました。情報を発信してくださった方々に感謝いたします。


明日の🎅GMOペパボエンジニア Advent Calendar 2022は、我らがCTOのあんちぽさんです!🙌