paizaのアルバイトが好き勝手開発できるスペースを作りたい

この記事は[paiza Advent Calendar 2020](https://adventar.org/calendars/5435) 21日目の記事です。
20日目は弊社CTOの [2020年で変わったこと・変えたことを振り返る | My Notion Blog](https://notion-blog-five-blue.vercel.app/blog/2020%E5%B9%B4%E3%81%A7%E5%A4%89%E3%82%8F%E3%81%A3%E3%81%9F%E3%81%93%E3%81%A8%E3%83%BB%E5%A4%89%E3%81%88%E3%81%9F%E3%81%93%E3%81%A8%E3%82%92%E6%8C%AF%E3%82%8A%E8%BF%94%E3%82%8B)
22日目はpaizaラーニングの上司の [「クリスマス休戦」 100年前のクリスマス](#) です。

---

もじゃです。paizaラーニングで勤務中に安達としまむらを見ています。今のところまだクビになってはいません。

今日は安達としまむらの話を書こうかと思っていたんですが、一人で一ヶ月分の記事が必要になりそうなのでpaizaラーニングチーム内で行っている取り組みの話にしておきます。

# timelineという取り組み

paizaでは現在リモートワークを行っています。
朝起きなくてよかったり、終わり次第即寝れたりと基本的には最高ですが、チーム内のコミュニケーションがどうしても希薄になりがちです。
業務上必要なコミュニケーションについてはSlackやZoomによるミーティングで事足りますが、「業務上必要でない」コミュニケーションが発生しにくくあります。

私が入社したばかりの頃はピークでも6人くらいで構成されていましたが、今やpaizaラーニングチームのアルバイト戦士も増え何人いるのかすらよくわかってません。10は超えてる気がします。

そこで最近paizaラーニングチームでもtimelineという取り組みが始まりました。
個々人のスペースであるTLに業務に関係あるなし問わずに自由に投稿ができ、それらの投稿を1つのtimelineチャンネルへ集約して一覧できる仕組みです。
もともとはエンジニアチームの取り組みだったものを弊チームに導入した形です。
詳細は[こちら](https://paiza.hatenablog.com/entry/2017/05/05/SlackとHubotで開発チームの分報を集めるBotを作ってみた)

要するにクローズドなSNSみたいなものを用意して、気軽に業務外のコミュニケーションを取ったりしようというものです。

## paizaラーニングチーム特有の問題

これはSlack上で運用されていますが、paizaラーニングチームに取り込む上で一つ大きな課題がありました。
弊チームのアルバイト戦士たちはマルチチャンネルゲストのアカウントでslackを運用しており、自由に各チャンネルに出入りできない制約があります。

そのため、1人をtimelineに追加するためには権限を持った社員による

1. 個人用TLチャンネルを作成し、timelne参加者全員を追加する
2. 集合timelineチャンネルへ新たなメンバーを追加する

という作業が必要になります。
これは人数が増えるほど作業コストが多くなり、具体的には2(n+1)の作業コストが発生します。
この作業は変色したブロッコリーみたいなアイコンの社員さんに毎回行っていただいていましたが、流石にしんどそうなのでこれを改善したいというのがきっかけです。

↓変色したブロッコリーみたいなアイコンの人のアドベントカレンダーの記事
[料理はしたくないけど健康は気になる](https://paiza.io/projects/Yq8_xm9TnbyHFZ8GTiEykA)

## バイトの遊び場が欲しい

上記の制約により、slackに自由にチャンネル追加やbot追加が行えなかったり、APIを叩けなかったりするので、遊び感覚でアプリケーション開発を行ったりのコミュニケーションがなかなか発生しません。
いっそのことバイト戦士含めた有志で好き放題アプリ開発が行える場があれば楽しそうだなあと常々思っていました。

そのため、いっそのことバイト戦士同士の非業務コミュニケーションの場を外へ切り出してしまい、バイト主体で好き勝手できる遊び場を作ってしまおうということでtimelineごとDiscordへ切り出すことにしました。

もちろん開発を強要するわけではなく、単純にプライベートなコミュニティとしての役割も持っています。現時点でも何故かおすすめのイラストレーターさんのpixiv投稿を張り合ったりしています。何これ。

![](https://i.imgur.com/nwjTb8M.png)

現時点では走りとしてtimelineが主な機能ですが、このアプリケーションに対して誰でもが自由に機能追加を行い、業務効率化やエンタメとしての趣味開発空間になればよいなと思っています。

## warriors bot

そんなこんなでリポジトリを作りアプリケーション開発を始めました。
現時点ではまだスタートアップ段階で開発基盤が整っていないので、私と同じくバイト戦士のKJさんとの2人で開発しています。
https://github.com/paiza-learning/warriorsbot

さっさと基盤やドキュメントを整えて解放していきたい。

### 開発環境

#### 言語
開発言語にはtypescriptを採用しました。

https://www.typescriptlang.org

* バイト戦士や非エンジニアが気軽に参加できる形にしたいので学習コストが低めの言語がいい
* 多数の人が開発に参加する想定なので、静的型付による秩序が欲しい
* ライブラリのドキュメントが整っていてコミュニティが活発なライブラリが良い

という理由でtypescript + discord.jsという組み合わせを用いています。
当初はgolangも選択肢にありましたが、ライブラリのドキュメントであるgodocを慣れてない人が読み解くのはしんどそうだねという理由で選択せず。

#### ホスティング先
herokuを採用しました。

https://jp.heroku.com

選定理由は

* コストが抑えられる
* デプロイが容易

です。

herokuでは1アカウントあたり1000h/monthの無料インスタンス時間が用意されています。なおクレジットカードが登録されていないアカウントは550hです。
また、worker dyno（webリクエストを待ち受けないインスタンス）のみで構成されたアプリケーションの場合は無料枠であっても無停止稼働が可能です。

さらに、github連携を行うと特定ブランチにpushが発生した場合に自動でデプロイを行う設定ができるので、難しいことを考えずにデプロイができます。
このリポジトリはgit-flowで運用しており、productionリリースであるmasterブランチが更新された場合に自動デプロイが行われます。
これによって複雑なデプロイプロセスを理解せずとも誰でもデプロイが行えます。

![](https://i.imgur.com/YB4aNj2.png)


#### デプロイ

ただし、heroku側で用意されているnode.jsアプリケーション用のstackを利用するとビルド環境と実行環境を分離できません。
typescriptで開発しているため実行前にjsへのトランスパイルが必要ですが、本番環境に動作に必要がないファイル（tsの元コードなど）が含まれてしまうのは好ましくありません。

そのため、dockerでのデプロイを行うことにしました。

herokuではインスタンスのstackをcontainerに設定することでdockerでのデプロイが可能です。

![](https://i.imgur.com/TN4ql9J.png)

また、heroku.ymlという設定ファイルを用意することである程度柔軟にビルドを行うことができたり、リリース前フェーズとしてDBのマイグレーションなどを走らせることが可能です。

これとgithub連携を利用することで、masterブランチに変更があった場合にプロジェクトに含まれるDockerfileをもとに本番ビルドが行われ、heroku上にデプロイされる仕組みを導入しました。

```dockerfile
FROM node:14 as builder

ENV NODE_ENV=development
WORKDIR /usr/src/app

COPY package.json .
COPY yarn.lock .
RUN yarn 


COPY . .
RUN yarn build

# ------------------------- #

FROM node:14 as production

ENV NODE_ENV=production
WORKDIR /usr/src/app

COPY package.json .
COPY yarn.lock .

RUN yarn

COPY --from=builder /usr/src/app/dist ./dist

CMD ["yarn", "start"]
```

### 機能概要

#### timeline

現時点ではこれしか機能がありませんが、今後開発に参加する方のアイディア次第で無法地帯になっていくとよいなと思います。

Discordのメッセージイベントを取得し、 `times_*` と命名されたチャンネルからのイベントだった場合にイベントに含まれる情報を再構成して webhook で 特定のチャンネルに投げています。

```typescript
// TODO: times_*に対する処理
if (channel.name.match(DiscordConstants.TIMES_NAME_PATTERN)) {
  const { text, options } = Bots.TimeLineBot.buildTimePost(msg);
  timeLineWebhookClient.postToTimeLine(text, options);
}
```

Discordでは簡単に特定チャンネル向けのwebhookを構成でき、post時のbodyに特定パラメータを含むことで「投稿者」「アイコン」などを変更することができます。
この仕組みを用いて、まるで「本人がtimelineに投稿している」かのように表現しています。

元投稿
![](https://i.imgur.com/jy6ezZ1.png)

転記
![](https://i.imgur.com/FpQOpjb.png)


もちろん添付ファイル等も転記しています。

ただしtimelineに集約してしまうと各tlで発生した会話もマージされてしまうので、話の流れがわからなくなってしまいます。
また、その会話に言及したい際に一々該当のtlを探すのも大変です。
なので、timelineに転記する際には該当のtlへのリンクを含む様にしています。

当初は普通にテキストリンクを追加していましたが、結構主張が激しくて邪魔なので、チャンネルトピックに設定した任意の項目で代替できる仕組みを実装しました。
上のスクショでは、:peach: をクリックするとオリジナルの投稿まで遷移します。

これで各tlの会話を追いつつ、目的の投稿へワンクリックで遷移ができます。

さらにこの投稿を閲覧専用に社Slackに転記する機能も実装予定ですが、まだ手をつけていません。

# 今後の展望
現時点ではまだ開発基盤が整っていないのでオープンな活動にできていません。そもそもまだ既存のslack timelineに参加できていない新規バイト戦士の方々も居ます。

なのでさっさとドキュメントを整備したり開発環境構築の手順を共有したり、足回りを整えて新規参入するスタッフを呼び込める体制に持っていきたいです。

まだまだ実装予定で手をつけてない思いつき機能がたくさんあるので、これらのIssueを気になった人や思いついた人が手を出して実装していける仕組みにしていこうと思います。

この記事を読んでいるアルバイトスタッフの皆様。逃がさんからな。

---

timelineの開発段階で末尾に任意の絵文字でリンク付与できるようにしたらなんかえっちな感じになった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204734/6375a18e-1537-6b6c-b780-04c67e9440e7.png)