毎年冬に半年ほど具合が悪くなるというのがもう数年続いていた。 今年こそは少しはマシにしたいと思い、比較的体調が安定する夏の間に色々できることはやろうと思っていた。近くのジムにも通い始め、電車に乗るのではなく自転車で移動するようにしたりして体を動かすようにしていた。
生理による体調の不安定も軽減しておきたかった。 一時期血栓ができやすくなり普通の低容量ピルが使えなくなっていたが、血栓リスクのないピルもあるようだったので試してみようとした。 多分これがいけなかったのだと思う。 薬が合わずに二週間ほどで飲むのをやめた。 やめてから程なくしてだるさが続くようになった。 この時はあまり気がついていなかったが外に出るとめまいがして気分が悪くなるようになっていた。
また精神的なものかと思い病院にも行った。 気がついたら全く仕事に集中できなくなっており、数日間休みをとった。 寝る時に急に気分が悪くなり飛び起きる日が続いた。 怖くなって実家に連絡をとりしばらくそちらで寝泊まりすることにした。 周りに人がいると少し安心し、数日の休みでとりあえず仕事に復帰した。 少し体調が良くなったみたいだねと言われることもあったが、特に良くなっていたわけではなかった。
ずっとめまいがした。 この辺でおそらく自律神経がいかれたのだと思ったので、この目眩は脳貧血によるものでありそうということがわかった。 外を歩くことができない、風呂で体を温めてもだめ、満腹になるほど食べてはダメ、寝ようとすると気持ち悪くなることもある、たいていは座っておとなしくしていれば大丈夫だったがひどい時はただ座って話しているだけでも気分が悪かった。 元々ひどかったが輪をかけて首や肩のこりがひどかった。
いろいろな病院に行って検査をしたけど結局どこも悪くなかった。 何をしたら良くなるのかもよくわからなかった。 それでも暑さが和らぐにつれて少しずつよくなり、毎日少しずつ散歩する距離を伸ばした。 仕事は何度も長期で休もうか時短勤務のような形にしようか迷ったが結局なぁなぁになったまま続けていた。 自分がいつもよりもパフォーマンスが出ていないこともわかっていたし、周りにフォローしてもらうのも申し訳ない気持ちがどんどん募っていったが、この状態を正確に他人に共有することはなかなか難しいことのようだった。
初めに体調を崩したのは8月。11月初めにはだいぶよくなって自分のマンションに帰ってきていたが、次の週に急に寒くなりまた体調が逆戻りした。 今このへん。 という感じです。
自律神経のバランスを崩したこと、ありますか。 外を少し歩くだけで気持ちが悪くなってどこにもいけないこと、それがいつまで続くかわからないことにはなかなかに絶望しました。 ただ、何年か前に妹が同じような症状になっており、2年ほどかけてほぼ完治したと聞いたので少しだけ前向きになれました。 今は調子が良い時は電車にも乗れるし、商業施設に買い物に行くこともできるが、でもあまり長時間は厳しいし、調子が悪い時は特に夕方や夜に何もしていなくても気持ちが悪くて不安が強くなる、そういう波をくり返しています。 症状はある程度薬で抑えることはできますが、あまり何度も飲んでいい薬ではない。 お酒も飲めないし、飲み会やカンファレンスなど全くいけないし、勉強どころではなく、本も読んでない。何も話すことはない。少し長く外を歩けたら、それがうれしい。
仕事は続けていくしかないから、できるだけ見放されないようにしたい。 ご迷惑をかけている皆様、申し訳ありません。
]]>一月の試験が終わって間も無く、大学が春休みの間は何をしようかなと考えていた矢先に、また動悸がはじまりました。引っ越しで環境を変えた甲斐なく、今年も冬季うつのような状態になってしまったということです。
第一には気持ちが不安定になるのですが、それに加えて熱もないのに寒気がするほど体が冷えてだるくて動けなくなったり、体が冷えるのですぐ膀胱炎になったり、自炊をするのも億劫な上、食欲は増すので食費が激増したりします。
仕方がないので少し落ち着いた時にまた病院を探して、行って、もらった薬を飲んで出勤(概念)し、仕事してました。仕事はなんとかできるけど、それ以外にできることはほぼありません。当然勉強することもままならない、というか、何かしなければと思って悪化することを一番避けたいので、例年のごとく私は全てを放棄しました。何もしなくても百点。
しかし、私は気になっていたことがありました。前期の授業で出てきた「エニグマ」のことです。第二次世界大戦でドイツが用いた最強の暗号…戦後何十年も秘匿されたその暗号を打ち破った事実…それに関わった数学者の運命…。教科書にはサラッと紹介されていただけだけど、こんなのあまりにも気になりすぎますよね。また、今期の授業ではRSA暗号の計算方法まで知って新しい驚きがあったので、大学の休み中は何かしら暗号について調べたいなと思っていました。
初めは技術書も読もうと思っていたのですが、無理だったので映画から入って少しずつ本を読みました。
見ての通り、二ヶ月の間、私はチューリングの追っかけを楽しんでいたというわけです。読書を通して、いつかブレッチリー・パークへも行ってみたいと思うようになりました。また、エニグマについての本にもチラチラと出てきますが、暗号の解読にはたくさんの女性たちも関わっていた史実があり、コード・ガールズ 日独の暗号を解き明かした女性たちも読みたいと思っています。
読書自体も楽しめたのですが、大学の授業をきっかけに興味を広げて楽しめている、ということ自体にも嬉しさを感じました。昔大学生だった頃は学校のお勉強の延長線だと思い込んでいた節があって、あまりこういう楽しみ方をしなかったような記憶があります。大人になってから大学行くの、良いですね。
また、チューリングのことを調べていたらゆるコンピューター科学ラジオなるyoutubeにたどり着きました。今年のうつ期間は、このチャンネルとその姉妹番組であるゆる言語学ラジオに救われたと言っても過言です。何もできない多くの時間はこれらのチャンネルを聴きながらマイクラして過ごしました。普段は音声コンテンツが好きで、youtubeは全く見ないので、音声だけでも聴けるようにしてくださっていたのが幸いでした。いい時代だ。
しんどいうつ期間でしたが、楽しみを見つけられてよかったです。しかしそろそろいい加減Webの勉強しないといけないのでまたぼちぼちやっていこうかなと思っています。
]]>何回書いても自分のブログを読み返すとなんでこんなテンションで書いたんだろう…って気持ち悪くなります。 何か人に見られるということで必要以上に気張ってしまうのかもしれないですね。 素直でポジティブでエモくないといけない、という空気を勝手に過剰に感じて気にしてしまうのかもしれないです。 人は別にそうでなくても生きていけます。淡々と書いていきたい。
先月に四国某所から関東某所に引っ越しをしました。 四国には特に縁もゆかりもなく、家賃が安いので前職を辞めてからもなんとなく住み続けていたのですが、対面で人と話す機会が激減して一年以上。精神的にも調子が良くない状態が続き、友人たちに相談したのをきっかけに、関東に戻ることにしました。 親しい人たちが偶然近くに住んでいたのでその間くらいに住むことにしました。 興味がなかった町ですが、私の好きな商店街が適度に栄えていて意外に住み心地は良さそうです。 今のところ楽しくやっています。
精神的に調子が良くないと言えば、エンジニア関連で持っていたTwitterアカウントも消してしまいました。 色々と試行錯誤?してみたのですが、もともとプライベートで多用していたツールなので、仕事とプライベートが地続きになってしまうのがどうしてもストレスになり、やめることにしました。 連絡用に残しておいてもいいかなと思ったのですが、アカウントがあること自体がダメみたいです。 特に私に用がある人もあまりいないと思いますが、連絡手段はメールかDiscordなどでお願いします。 最近コミュニティにあまり行かなくなってしまったのは、そういうのとは別で、完全に朝型になり夜集中力を保つのがつらくなってきたからです。 ちょっとバランス考えたいです。
去年は年明けから初めて案件に入り、一年間バタバタしながらなんとかやってきた感じなんですけども、個人的にはあまり何かがすごくできるようになったな、という感覚がなくて、今年はもっと良いコードをかけるようになっていきたいなぁと思っています。 でもそのために具体的にどうしていったらいいか、というのは人に相談しても明確な答えが返ってくることが少なく… 手始めに11月にRuby Goldを取得してみました。これは本当に勉強してよかったなと思っています。 試験があるとある程度まとまった知識を無理やり頭に入れることになるので、手始めにっていうのも間違ってなかった気がします。 今後も自分なりに考えて、体力ないのでちょっとずつですが、RubyやRailsに関する知識を得る時間をとっていきたいです。 これは特にRubyやRailsのコードの書き方を学びたい、というか、RubyやRailsでコードの書き方を学びたいという感じなのかなと思っています。 幸にも今、複数の言語に同時に触れる環境にいるので、言語特有の良い書き方だ、と思っていたことは別にそうでないということも勉強させてもらっているのかもしれないなと思います。
去年は後半に、思ったよりJavaScript方面でたくさんキャッチアップしなければいけないことがあって、割とそっちに時間を割いていました。 弊社のエンジニアが新しいことをやるときはとりあえず5冊とか本を買って全部読む、みたいなことを言っていたので、そのとき私も、どの本がいいとかもう考えるのめんどくさいから全部読めばいいや、と思って目についたもの全部買って必要そうなところだけ全部ざっと目を通す、ということをしました。結局、知識というものは何度も違う方向から同じ知識を入れることで定着していくというものだと思っているので、あぁこれでいいんだなと思いました。 放送大学でも別々の授業で何度も何度も同じ領域についての話題が繰り返し出てくるようになっているので、自然とそういうことをやっているんだなと思います。
まずは年明け1月に大学の試験があります。器用でないのでほぼ一ヶ月くらいは引越しのことしか考えておらず、何もしていなかったので、間に合うか心配です。せっかく自分でお金を払っているんだからもっとじっくり向き合いたいと思うのに結局こんなことになってしまう…。 でも引っ越したことによって今年はより良い環境で仕事も勉強も進めていけるのだろうなと期待しています。 今年もよろしくお願いします。
]]>前期から科目履修生としてお試しで授業を取っていたりしてたんだけど、割と自分にあってるなと思ったので。
去年の10月、晴れてエンジニアとして就職できたので、これから長くこの仕事を続けていく上でプログラムを書くっていうだけじゃなくて広く基礎的な知識を身につけたいなっていうのは思っていまして。でも一人で本探して読んで…っていうのは大変じゃないですか。基本情報とかもなんか浅く広くで面白くないから寝ちゃうし。だからなんかいい方法ないかなって探してました。
それと、私は課題があって手を動かしたり問題あって解いたりするほうが頭に入るので、本読むとかだけだと嫌になって勉強習慣が絶えるなって思って。本当はまだ基本的な知識よりプログラムの書き方とか勉強したほうがいい段階だと思うんだけど、とにかく勉強やめちゃうほうが怖い。
ということで色々探してたんですが、放送大学は別に今期で何単位取らなきゃいけないとか、取らないと留年とかないので自分のペースで好きな科目を取れるのがいいんですよ。初めは取る科目を少なめにして仕事に慣れてきたら増やすとか、今期は今やってる仕事に関係のありそうな科目をとるとか、調整できるんでこれはいいなーと思って。
あと、私は普通に大学がすきなんですね、多分。取れるなら学位もほしいし。情報コース以外の科目も面白そうで目移りしちゃう。アカデミア苦手って人もいそうだけど、体系的に学べてクオリティも高いし、何勉強したらいいかわからなくてあれこれ手を出すより普通にいい選択だと思うんですよ。スクール否定することないじゃんってのと同じで。
注意なのは放送大学でとれるのはどのコースでも教養の学士なんですよね。でも、学位授与機構っていうのがあって、必要単位あれば申請すると規定の学位をくれるシステムがあり、それを使ってがんばれば情報工学の学位も取得できそうです。詳しくは参考リンクの記事を。そこまで目指したいなー。
前期は科目履修生(半年だけ在籍できる)のお試しで、
の4つ取ってみました。や、4つっていっても結構ボリュームあった。就職したばっかだし。ちょっとナメてた。
情報学へのとびらは情報学とはなんぞやなオムニバス授業、情報ネットワークはほぼマスタリングTCP/IP、初歩からの数学は高校数学ざっくり復習って感じです。普通に見いやすいし、内容も充実していて、いっこいっこ授業を消化していくっていうのは結構勉強のペースを掴みやすくてよかったです(深夜2時までレポート書いてたのに…?)。
情報ネットワークの授業はマスタリングTCP/IPより基本的なところをかなり丁寧にやってくれていたので、その後復習として本を読んだけど読みやすかった。多分いきなり読んでたら途中でやめてたと思いますね。よかったね!久しぶりに一冊通して読めて!
来期は計算の科学と手引き、Webのしくみと応用、情報セキュリティ概論の三科目を受講しようかなーと思っております。今の所仕事にできるだけ近そうなところの科目でって感じで選んでるんですけど、データサイエンスとか自然言語処理とかの授業も充実してるみたいなので、ゆくゆくはそういう科目を取って知識をつけたいんですよー。職場でそういうお仕事をしている人もいるので。話わかるようになりたい。あと統計。私、生態学やってた割に統計をあんまりやってなくて恥ずかしいのでこの期にちゃんとできるようになりたいんです。今だからこそあの時より興味を持ってやれるってこともあるよね。分子系統学を理解してえな。
参考にさせてもらった記事!
文系パパエンジニアが放送大学等でコンピュータサイエンス・数学を学んで理系学士を取りに行く話
文系出身の若手SIer社員が放送大学で情報学を勉強してレベル上げした話
授業の内容!
]]>他の受講生の方もBot作りに挑戦してみてくれる方が出てきて、良い流れのような気がしています。プラクティスだけだとどうしてもずっと勉強という感じで実際自分が使いたいものを作って楽しむ機会ってあまりなくなってしまうのですが、Discord botは実際にサーバーのメンバーに使ってもらえて達成感もあるしちょうど良いのかもしれないですね。
ただ、やっぱりRubyでDiscord APIを扱う情報がかなり少ないのが大変なところなのかなと思いました。私もはじめの理解に結構時間かかりましたし、あまり時間に余裕がない方には勧めにくいかもしれません。お手軽感はないかもしれないですけど、何もわからないところから一生懸命ドキュメントを読んだりしたことは、すごく良い勉強になったなーと私は思っています。
さて、私の作ったサービスも早速ミスや改善した方がよいことが出てくるもので、最近その修正をしたのでそれも記事に残しておこうと思います。
これ、必要だろうなと思いつつ実装してなくて(え)、やっぱり不具合出たので即修正しました。すいません。
Discordのサーバーから取得しているユーザー情報は今のところ、ユーザーネーム、#以降の4桁の数字(discriminator)、アイコン画像のurl、なんですけども、これらをDsicord上で変更してもサービス上ではそれが反映されるようになっていなかったために画像が非表示になってしまったりしました。
メンバー情報が変更された時のイベントを取得できるので、そのイベントが発生した時にこれらの情報が更新されていたら変更する、というコードを追加しました。
class DiscordBot
def initialize
@bot = Discordrb::Bot.new token: ENV['DISCORD_BOT_TOKEN']
end
def start
settings
@bot.run
end
def settings
# banや脱退などサーバーからメンバーがいなくなったらそのユーザーを消去
@bot.member_leave do |event|
user_id = event.user.id
user = User.find_by(uid: user_id)
user&.destroy
end
# メンバーのusername, discriminator, avatarの更新を反映する
@bot.member_update do |event|
uid = event.user.id
updated_member = JSON.parse(Discordrb::API::User.resolve("Bot #{ENV['DISCORD_BOT_TOKEN']}", uid))
name = updated_member['username']
discriminator = updated_member['discriminator']
avatar = avatar_url(uid, updated_member['avatar'], discriminator)
user = User.find_by(uid: uid)
if user
user.update!(name: name) if user.name != name
user.update!(avatar: avatar) if user.avatar != avatar
user.update!(discriminator: discriminator) if user.discriminator != discriminator
end
end
end
private
def avatar_url(uid, avatar_id, discriminator)
if avatar_id
Discordrb::API::User.avatar_url(uid, avatar_id)
else
Discordrb::API::User.default_avatar(discriminator)
end
end
end
ついでにクラスの構成もちょっと変えてます。member_update
でメンバー情報の変更イベントを取得できるんですけど、eventに入ってくるユーザー情報は変更前のものだったので、そこで取得したユーザーIDからもう一度ユーザー情報を取得して、変更があったものを更新するようにしてます。
ユーザーアイコンの情報(avatar)はidだけが取れるのでそこからDiscordrb::API::User.avatar_url(uid, avatar_id)
でurlを作っています。また、Discord上のアイコン画像が未設定、つまりavatarがnilの場合はDiscordのデフォルト画像urlが取得できるメソッドがあったのでそれでurlを作るようにしました。discriminatorで色が決まってたんですね。
member_update
ってドキュメントにSent when a guild member is updated. This will also fire when the user object of a guild member changes.
とあるけど、どの情報の更新まで入るのかなぁ。
上の修正をしててDiscordのデフォルトアイコンurl、取れるんじゃんって気が付いたんですね。私はDiscordのアイコンが未設定の場合は用意したデフォルト画像が表示されるように書いていました。ですが、それもomniauth-discordの挙動をちゃんと確認していなくて、思うような挙動にならないコードになっていたので修正しました。
元々、アイコン画像のurlはavatar = auth_hash[:info][:image]
で取得していました。このimage
がアイコン画像が未設定だったらnilになると思っていたのですが、無効なurlができるような仕様になっていました。
そこで、avatar = auth_hash[:extra][:raw_info][:avatar]
でavatarのidを取得して先ほどのようにurlを作るようにしました(以下のコードの部分)。こちらだとアイコン画像が未登録の時はnilが入ってくるのでうまくいきます。
def avatar_url(uid, avatar_id, discriminator)
if avatar_id
Discordrb::API::User.avatar_url(uid, avatar_id)
else
Discordrb::API::User.default_avatar(discriminator)
end
end
この変更でDiscordのデフォルト画像を利用するようになり、こちらで用意したデフォルト画像を使わなくなったので、環境変数IMAGE_URL_HOST
を設定する必要がなくなりました。
このomniauth-discordの挙動はちょっとおかしいのでは?と思ったらissueがたっているようですね。対応はされてないけど…。
今後もなにか不具合や、Discord APIの勘違い等ありましたら報告してくださると嬉しいです。
]]>フィヨルドブートキャンプは現在完全にフルリモートでスクールが運営されおり、メンターや生徒同士のコミュニケーション手段としてDiscordを利用しています。
新しく入ってきてくれる受講生が増えていく中で、オンラインで積極的にコミュニケーションをとっていくきっかけがなかなか掴めないな、という人もいると思います。サーバー内でコミュニケーションのきっかけになるBotがあると良いなという声があったので、最終課題として作ることにしました。
具体的には、サービス上に色々な質問を用意しておいて、サーバーのメンバーに好きな質問に答えてもらい、その回答をBotがDiscordに自動投稿するというようなものです。
簡単に構成をかくとこんな感じです。githubのリポジトリはこちら↓
https://github.com/misosoup160/discord-bot-f
今回はフィヨルドブートキャンプというプログラミングスクールで使うということに特化した方が面白くなっていきそうだなと思ったので、利用者は特定のサーバーに限定するような仕様にして、フィヨルドブートキャンプ専用サービスとして作りました。
ユーザーは、SKIPボタンで答えたい質問を選んで、それに対する回答を入力できます。
Botによって毎日指定したチャンネルにランダムに選ばれた回答が投稿されます。 サービスへのリンクとランダムに一つ選ばれた質問が例として同時に送信されます。 チャンネルと一度に送る回答の数は環境変数で指定し、投稿時間はHeroku Schedulerで設定しています。
過去の回答は、自分以外のものはDiscordに投稿済みのもののみ、自分のものは未投稿も含め確認することができます。未投稿の回答は編集削除ができます。
サーバーの管理人(サーバーを作った人)は、サービスの管理者として登録されます。管理者は、任意のユーザーを管理者にすることができます。また、質問の登録・編集・削除ができます。
退会するなどでDiscord側のサーバーからいなくなった場合は、こちらのサービス側からもそのユーザーが自動削除されるようになっています。
DiscordのBotや連携サービスをrubyやrailsで書いてる例が少ない気がしており、今回のサービスを作成するにあたって一番苦労したところでもあるので、Discord APIを利用した部分について少し詳しく書いておこうと思います。まだまだ初学者なので情報あやしいところあったらぜひコメントください。今回はWebhookは利用していないので、そちらの話は省略します。
Discord APIには大きく分けて二つのレイヤーがあって、一つはHTTPリクエストを送ってレスポンスとしてDiscordサーバーの情報が返ってくるもの(HTTP API)、もう一つは、リアルタイムのイベントに対して反応できるWebSocketベースの接続で、例えばキーワードを含む発言をするとBotが反応してくれたりするような機能の実装に利用できるものです(Gateway API)。
HTTP APIの方でどんな情報が取れるのかはDiscordのDeveloper Potalから見れるドキュメントのResourcesのところ、WebSocketベースのGateway APIでどんなイベントをキャッチできて、どんなオブジェクトが返ってくるのかはTopicsのGatewayのところあたりを見ていくのかなと思います。必要に応じて、Botに権限を持たせないといけないものもあります。
Discord APIにはそれぞれの言語でいい感じに書けるようにしたラッパーが各種あります。rubyはDiscordrbというgemがあるのでそれを使っています。こちらのドキュメントをDiscordのドキュメントと照らし合わせながら見て書いていきました。
APIを使うにはまずBotを作ってサーバーに招待しないといけないですがここはいろいろなサイトで紹介されていると思うので省略します〜。
今回Discord関連でやりたかった実装は以下の4つ。
2〜4はHTTP API、5はGatway APIを利用しています。
オーナー(owner)というのはDiscordの用語でサーバーを作った人(管理人)のことです。この人だけとりあえずサービスの管理者としたかったために、ログイン時にオーナーかどうか確認するようにしました。
HTTP APIで取得できるサーバー情報の中にowner_id
という項目があります。これがオーナーのユーザーIDです。Discord認証でログインさせるときに取得できるuidがこれと一致すればその人がオーナー。
DiscordのサーバーはDiscordrbだとserverだけど、Discordのドキュメントだとguild(ギルド)です。たまに用語が違うのでややこしい。
guild_info = Discordrb::API::Server.resolve("Bot #{ENV['DISCORD_BOT_TOKEN']}", ENV['DISCORD_SERVER_ID'])
owner_id = JSON.parse(guild_info)['owner_id']
これはどういう方法でできるかなーと考えた結果、Discord認証でログインさせるときに取得できるuid(ユーザーID)を利用して、そのIDを持つユーザー情報を取得するリクエストを送り、それが成功するかどうかでそのサーバーにいるユーザーかどうか確かめる、という方法で実装しました。
Discordrb::API::Server.resolve_member("Bot #{ENV['DISCORD_BOT_TOKEN']}", ENV['DISCORD_SERVER_ID'], uid)
これを認証のコードの間に書いておいてリクエストが失敗するとエラーでログインできなくしました。
みんなが質問に回答してくれたものをサーバーに送りたい。今回はHTTP APIの方で実装しました。ドキュメントにあるようにBotを作成するときにPermissionsのSendMessagesを許可しておかないといけません。
まずどんな感じのメッセージを送るか考える。
こんなふうに埋め込み(embed)を使ってみたかったので、こちらのembed visualizerを使ってとりあえず構成を考えました。
それをrake taskにします。例えばこんな感じ…?実際中身はもっと長くなったのでモデル以下にファイルを作ってそこにコードを移しています。
namespace :discord_bot do
desc 'send message to discord guild'
task send_messages: :environment do
Discordrb::API::Channel.create_message(
"Bot #{ENV['DISCORD_BOT_TOKEN']}",
ENV['DISCORD_CHANNEL_ID'],
'こんにちは!こちらは毎日サーバーのメンバーのことを紹介するBotです!',
false,
{
title: '好きな寿司ネタはなんですか?',
description: '質問に回答するにはここにアクセスしてね。'
}
)
end
end
メッセージを毎日同じ時間にDiscordに送信したいので、このタスクをHeroku Schedulerに登録しました。
これはGatway APIの方を利用して、メンバーがサーバーから去るイベント(脱退、追放、BAN)をハンドルしています。
このようにメンバーの変更イベントを監視するタイプのものは、デフォルトでは制限がかかかるようになっているらしいので、Botを登録する画面にあるSERVER MEMBERS INTENTをONにしていないと利用できない…はずです。多分(この辺ちょっと理解があやしい)。
bot = Discordrb::Bot.new token: ENV['DISCORD_BOT_TOKEN']
bot.member_leave do |event|
user_id = event.user.id
user = User.find_by(uid: user_id)
user&.destroy
end
bot.run
bot.run
でBotが起動されますが、サーバーのメンバーが去るイベントを常に監視するためにずっと起動状態(Discordの画面でいうとオンライン状態)にしといてあげないといけない。そのために、これをrake taskにして、Procfileという名前のファイルを作り、そこに適当なプロセス名とこのタスクのコマンドを書いておきます。
bot: rails discord_bot:start
デプロイしたらHerokuのDynosにこのプロセスが表示されるのでONにしてあげるとBotが起動します。
ただ、Herokuの無料枠で使ってるので30分間サービスにアクセスがないとスリープしてしまい、Botもオフライン状態になってしまうようなのでHeroku Schedulerで10分毎に叩き起こすようにしています。
Discord APIを使ったところはこんな感じでやりました〜。
Discord BotはpythonかJavaScriptで作っている記事が多いのかなと思います。rubyでDiscord Botを作っている例が検索してもあまり出てこないし、Discord APIを理解して、何がどういうふうにできるから、アプリの仕様をどうしたらいいか?と考えるところで結構時間がかかったなーと思います。RailsとBotを別スレッドで同時に立ち上げておくみたいなところが一番分かってなかったかもしれない。また、API関連のテストを書くところでかなり助けてもらいました。難しかったー。
実際にフィヨルドブートキャンプで欲しい!という声が多かったものを作ったので、ちゃんと完成させれば実際にこのコミュニティの人たちに使ってもらえるんだというのは、自分にとってはモチベーションになったと思います。
実際仕様を考えるところは、メンターの方を利用者としてヒアリングして、検討しながら進めていたのですが、それも面白い経験でした。今回はその側面はそんなに大きくなかったかもですが、やっぱり問題や需要に対してどういう対処ができるのか、というのを考えていくのは自分が楽しいと思ってる部分なんだなぁと思います。
あとは、フィヨルドブートキャンプのプラクティスで、最小限の機能に限ってつくる、小さいサイクルで回していく、というアジャイルやスクラムの考え方についても勉強していたので、それをなんとなく意識して進めていけたのも良かったかなと思います。はじめにAPIについて調べて仕様を考えるのに2週間くらい、そのあと一気に完成までに必要なissueを登録して見通しを立て、初めの一週間で大まかな画面を全て作り、次の一週間で抜けているところを埋めていき、三週目で完成度を上げていく、という感じで進めました。Discord APIのことがわかってくるといろいろ他にも機能をつけたくなってくるんですが、そこは堪えてとりあえずみんながちゃんと使える状態のものを一度完成させようと思ってカリカリ書きました。
やってみたいなという機能としては、一度に投稿する回答の数やチャンネルをコマンドなどで変更できるようにするとか。Discordサーバー側でついているロールの変更もリアルタイムで取得できるようなので、ロールを取得、記録してそれを用いて管理者権限を変えたり質問を分けて管理したりなどできても面白いかなと思っています。
また、フィヨルドブートキャンプの中でもまだ他にDiscordに欲しいなという機能がちらほらあるように思うので、これを機会にDiscord Botや連携サービスが色々作られていくと楽しいなと思っています。
]]>ブートキャンプアプリはacts-as-taggable-onというgemを使っていて、私が担当したissueではそのgemが絡むことが多かったので、ちょっと困ったところや調べたところをメモしておこうと思います。
gemの導入方法とかはさておき、とりあえずこのgemを入れると、taggingsとtagsの二つのテーブルができます。tagsテーブルの方はid、name、taggings_countの3つのカラムがあって、そのタグが登録されている数がtaggings_countに入っている。はずです。
tagsテーブル | taggingsテーブル |
---|---|
id | id |
name(タグの名前) | tag_id(タグのid) |
taggings_count(そのタグが登録されている数) | tag_type(モデル名) |
taggable_id(登録されているもののid) | |
tagger_type | |
tagger_id | |
context | |
create_at |
だけど、初めてリポジトリクローンして立ち上げて開いたら画面上ではタグがあるのに、テーブルでは全てのタグのカウントがゼロになっていてえ???ってなってしばらく悩んでしまいました。
fixtureで登録されているタグのカウント数はテーブルのtaggings_countには反映されないです。(これは先人に教えてもらった)
でも手動?で登録すればちゃんと反映されるので本番の方では大丈夫です。数はちゃんと入ってます。ただ、ちょっと問題がある。
タグは複数のモデルで付けられます。ただし、別々のモデルで同じ名前のタグを登録した場合taggings_countのカウントが混ざる。「猫」とタグ付けされた人が3人いて、「猫」とタグ付けされた記事が2本あったら、tagsテーブルでは「猫」のカウントが5となるだけで、gemのメソッドを使ってもこれを分けて取ることができません。
ActsAsTaggableOn::Tag.most_used
ActsAsTaggableOn::Tag.least_used
例えばこれはタグの中で登録数が多いもしくは少ない順にタグを取得できるメソッドですが、この数も全モデルでの数になるので、ユーザーが登録しているタグの中で数が一番多いタグが欲しい、といった場合は使えない。多分どのメソッドもこれは考慮されていないと思われます。
じゃあどうやって取得するの?ということで、これはgemのissueにも上がっているようです。(これも先人に教えてもらった)
https://github.com/mbleigh/acts-as-taggable-on/issues/719#issuecomment-172490087
ActsAsTaggableOn::Tag
.joins(:taggings)
.select('tags.id, tags.name, COUNT(taggings.id) as count')
.group('tags.id, tags.name, tags.taggings_count')
.where(taggings: { taggable_type: 'User'})
taggable_typeはモデルの名前が入っているので、taggingsテーブルを連結してそれで絞り込めば数が取れるということですね。bootcampのコードもこれをアレンジして使っています。このgemのメソッドでどういうSQLが発行されているのかはチェックしたほうがいい感じだと思われる。
余談だけど、こうやって取得したタグの数だけ欲しくて、.pluck(:count)
ってやったらできなくて、.pluck('COUNT(taggings.id) as count')
か、.map(&:count)
でやるしかなかった。pluckは元々あるカラムしかカラム名指定することができないんですね〜。
READMEにもあるとおり、タグはこんな感じでtag_list
に配列として登録されるんですが、
@user.tag_list.add("awesome") # add a single tag. alias for <<
@user.tag_list.remove("awesome") # remove a single tag
@user.save # save to persist tag_list
@user.tag_list # => ["awesome"]
コンソールでユーザーの中身を見るとtagは登録されていてもいなくても常にnilになっています。
#<User id: 1234, name: "yamada", tag_list: nil>
user.tag_list?
はいつもfalseです。
それをやりたかったところは、私はuser.tag_list.empty?
ていう形で書きました。
これもissueが上がっていました。バージョンアップしてもそのままな気がする…。
https://github.com/mbleigh/acts-as-taggable-on/issues/1024
ユーザーを全部取得してユーザーごとに登録しているタグを表示したいなーなどと思った時
controller
def index
@users = User.all
end
view
<% @users.each do |user| %>
タグ:<%= user.tag_list.join(', ') %>
<% end %>
こうやって書くとですね、毎回2回ずつSQL発行されててN+1問題が発生しています。
bootcampではbulletを入れているのでN+1問題が発生しているとメッセージが表示されて、この場合taggingsをincludeしてね!という表示がでます。ただ、tagginsをincludeするとこの警告は消えるんですけど、確認すると実はまだ毎回1回ずつSQLが発行されていました。
https://github.com/mbleigh/acts-as-taggable-on/issues/91#issuecomment-168273770
これもissueに上がっていて、tagsをincludeしてmapでtagの名前だけ取るのだ、という解決策があるみたいです。
上のを修正するとこんな感じ。
controller
def index
@users = User.all.preload(:tags)
end
view
<% @users.each do |user| %>
タグ:<%= user.tags.pluck(:name).join(', ') %>
<% end %>
他の記事を参考にpreloadとpluckを使っています。bootcampのアプリでは今のところ私が担当した部分だけこれで書いてみています。パフォーマンスが結構変わるなら全部書き直したほうがいいのかなぁ。
includeではなくpreloadとeager_loadを使用する方がいいのかなという参考記事はこちらとか。
これもSQL確認しといた方がいいよ〜、て感じでしょうか。
個人的には、tagsやtaggingsテーブルへのデーターの登録が全部gemの中で行われているので、それをgemのメソッドを使わないでアレンジしないといけない時に、どこのモデルやコントローラーに書くのがいいのかっていうのがちょっと悩みました。いろいろ勉強になりました。
]]>前に進捗を書いた12月からしばらく体調を崩していた時もあったのですが、最近やっと最終課題に差し掛かりました。書き並べてみるとすごく長くなってしまいましたね。現在はシステム開発の後半で、webサービス作成も徐々に準備し始めているところです。
システム開発は実際に自分たちが利用しているブートキャンプのシステムの開発に携わるのですが、課題をひとつづつ解決していくのが結構楽しいです。今までは深く調べてみたいけどわからないことも多くて見通しが悪いのでとりあえず進めてみよう、と思って進めてきたところがあるのですが、課題を解決しながら気になったところを時間をかけて調べたり復習したりして知識がつながっていくと嬉しいです。まだ全然足りないなぁ、もっと勉強したいなぁと思います。
でもそろそろ就職活動のことも考えないとね。私は勉強の方が気が楽なので、どうしてもこれずっとやってたいなーと思ってしまいます。
フィヨルドブートキャンプは最近チャットツールがSlackからDiscordに移行して、そこで分報を書くことがはじまったりしました。それによって受講生同士もそうですが、卒業生やメンターさんなどとの距離もまた近くなった気がしますし、ボイスチャンネルに入っている人数がわかるようになって、質問タイムなどを利用するハードルが下がった人もいるんじゃないかなーと思います。
メンターさんたちがオンラインでもコミュニケーションをとりやすくなるような手段を色々考えてくださっているので、自立した学習環境がありながらも、サポートも手厚い、より良い感じの方向に進んでるんじゃないでしょうか。
最近パーフェクトRuby on Railsの輪読会にも参加するようになりました。多分みんなが言っていることだと思うんですが、人と一緒に読むと自分が知らない知識が得られてすごく勉強になるなぁと思います。最後の方のプラクティスがjavascriptなのでちょっと様子見てしまってたんですが、もっと前から参加しても良かったかも。
輪読会もそうですし、雑談のボイスチャンネルでお話ししたりする機会もあって、最近突然人と話す時間が増えたなぁと思います。ずっと静かにひとりでひきこもって勉強していたのですが、これから就職活動もしなければいけないので、人と話す機会を増やしてちょっと慣れとかないとなーと思っています。Rubyのコミュニティとかにもちょこちょこ参加するようにしたいです。
最近はそんな感じでしたー。
]]>フィヨルドブートキャンプに入って3ヶ月くらい経ちました。こんにちは、Misosoupです。 そういえば、みそすーぷって読みにくいかなと思っているのですが、Misosoupは英語表記(?)なのでみそしるでも。ちなみに元のあだ名は「みそ」で、最近友人に「しる」って呼ばれました。よろしくお願いします。
フィヨルドブートキャンプではアウトプットのためにブログを書こう!ていうのがあります。このブログは独学期間に勉強のために作ったもので、せっかくだから引き続き使いたかったのですが、コメント欄がないとかGitがよくわからんとか、いろいろと力不足で放置していました。最近がんばってやっと準備できたかなと思うので、こちらでアウトプットしていけたらなーと思っています。
今回はこのブログを作るのに使ったツールの簡単な紹介と、フィヨルドのアウトプット用に使用できるように追加した機能の作業メモを書きました。
このブログは、JekyllというRuby製の静的サイトジェネレーターを使い、GitHub Pagesで公開していました。今はGitHubのリポジトリをNetlifyで公開する形にしています。Netlifyのことはこちらで書きました。
Jekyllはヘッダーとかのパーツを共通化して書けて、HTMLを生成してくれるツールで、データベースを使わないブログとかウェブページが作れます。記事はマークダウンでかけます。
Rubyの開発環境があれば、Jekyllのgemをインストールして、以下のコマンドを実行するだけで、my-site
ディレクトリにブログとして構成されたファイルたちが勝手に出来上がります。
jekyll new my-site
デザインはデフォルトでminimaというテーマが使われています。
一度buildしたときのディレクトリ構成は以下のような感じで、_posts
ディレクトリにマークダウンでかいた記事を入れていくと、_site
ディレクトリにhtmlファイルとして生成されるという感じです。あとは_config.yml
でブログの名前とか自分の情報を書き換えていけばとりあえず形になります。
my-site
├── 404.html
├── Gemfile
├── Gemfile.lock
├── _config.yml
├── _posts
│ └── 2020-12-03-welcome-to-jekyll.markdown
├── _site
│ ├── 404.html
│ ├── about
│ │ └── index.html
│ ├── assets
│ │ ├── main.css
│ │ ├── main.css.map
│ │ └── minima-social-icons.svg
│ ├── feed.xml
│ ├── index.html
│ └── jekyll
│ └── update
│ └── 2020
│ └── 12
│ └── 03
│ └── welcome-to-jekyll.html
├── about.markdown
└── index.markdown
また、テーマはテーマを配布しているサイトがいくつもあり、それを使うこともできますし、このデフォルトテーマを少しずつアレンジしてもいいし、jekyll new-theme
というコマンドを使うと、全て空の最小限のディレクトリ構成で立ち上がるので自分で一からテーマを書くこともできます(私はこれでやったので無限に時間がかかりましたが…)。
静的サイトジェネレーター自体はいろいろな種類があるみたいですが、当時ぺーの私が出来そうなのがこれしかなかったのでJekyllを選択しました…。作った頃は全くRubyは知らなかったので、Rubyあんまり知らなくてもなんとかできる…と思います(ほんとか?)。gemくらいは知っときたかったけどな。
今回確認したらデフォルトテーマではfeedは元から入ってるし簡単な設定でコメント欄もonにできるようになってるみたい…。くっ…。
GitHub Pagesはリポジトリにpushするだけで無料でサイトを公開できるサービスです。独自ドメインも使えるよ。
詳しくは公式サイトをみていただきたいのですが、静的ファイルを置いたリポジトリのSettingsのGiHub Pagesのところでブランチを指定するとそれでもう公開できてしまいます。JekyllはGitHub Pagesでサポートされているので、さっきのmy-site
ディレクトリをリポジトリにおいてその設定をすればいいです。
私はとにかく何か物を作ってみたくてこのブログを作りました。 何か作って公開してみたいなーって思ったら、これらのツールでちょっと遊んでみても良いのでは?という簡単な紹介でした。Gitに草も生えるよ。でもそれなりにちゃんとやろうと思うといろいろと調べないといけないので時間は無限に溶けます。ははは。
以下はコメント機能とfeed機能を追加したときの主に自分用の作業のメモです。しらんよという方はとばしてください〜。
Jekyllは静的ページしか作れないので、本来はコメント機能とかは実装できないのですけど、今回はDisqusというサービスを使って簡単に機能を追加しました。フィヨルドのブログでも使ってますかね?Disqusは書き込む人も何かしらのアカウントがないとできないようですが、逆にそれくらいの方が良いんじゃないかな?と思いました。
まずはトップページの「GET STARTED」から、会員登録します。 「I want to install Disqus on my site」を選択。必要情報を入力します。 プランは今回Basicを選択しました。 利用するプラットフォームでJekyllを選択します。すると、そのプラットフォームごとの設定方法の説明がでてきますので、それを参考にページの設定をします。
Disqusはページごとにコメント機能を追加するかどうか設定できるみたいです。機能をつけたいpostページのymlフロントマターに以下のように書けば設定されます。
---
comments: true
---
あとはコメント機能を入れたいレイアウトファイルのhtmlに指定されたコードをコピペすればよい。
{% if page.comments != false %}
<div id="disqus_thread"></div>
<script>
/**
* RECOMMENDED CONFIGURATION VARIABLES: EDIT AND UNCOMMENT THE SECTION BELOW TO INSERT DYNAMIC VALUES FROM YOUR PLATFORM OR CMS.
* LEARN WHY DEFINING THESE VARIABLES IS IMPORTANT: https://disqus.com/admin/universalcode/#configuration-variables*/
/*
var disqus_config = function () {
this.page.url = PAGE_URL; // Replace PAGE_URL with your page's canonical URL variable
this.page.identifier = PAGE_IDENTIFIER; // Replace PAGE_IDENTIFIER with your page's unique identifier variable
};
*/
(function() { // DON'T EDIT BELOW THIS LINE
var d = document, s = d.createElement('script');
s.src = 'この辺がオリジナルになっているはず';
s.setAttribute('data-timestamp', +new Date());
(d.head || d.body).appendChild(s);
})();
</script>
<noscript>Please enable JavaScript to view the <a href="https://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
{% endif %}
公式サイトでは、{% if page.comments %}
と{% endif %}
で囲んでね!とありますが、いちいちフロントマターに書くのがめんどくさいので、{% if page.comments != false %}
にしてみました。これでfalseじゃなければ常に追加されるはず。
コメントアウトされている部分を使うと、テーマを配布したいときなどにユーザーが設定ファイルに必要な項目を書き込むだけで一括設定できるようにしとけるみたいです。公式テーマのコード見たらそうなっていた。
これでコメント機能が使えるようになった!簡単だ!Disqusでこんな設定しておくといいよみたいなのがありましたら教えてください〜。
Feedって実を言うと使ったことがなかったんですが、この前「Webを支える技術」も読んだことだし、機能を付けてみることにしました。そこで、まずはユーザーとなるべくfeedlyに登録してみました。Jekyllへの機能追加は公式サイトと公式テーマとかを参考に進めます。
今回はjekyll-feed
っていうgemを使いました。Gemfileに書いてインストール。
_config.yml
に以下の情報を書き加えます。
plugins:
- jekyll-feed
サイトのURLと著者情報が必要みたいなので一応これも_config.yml
に書いてあるか確認しておきます。
url: https://mssp160.netlify.app
author:
name: Misosoup
email: hotmisosoup160@gmail.com
headタグ内にフィードのタグ{% feed_meta %}
を追加します。例えばこんな感じ。
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>{{ page.title }}</title>
<link rel="stylesheet" href="/assets/css/styles.css">
{% feed_meta %}
</head>
<body>
{{ content }}
</body>
</html>
公開する前にjekyll build
します。普段はjekyll serve
でローカルでページを確認しながら作ってそのままあげてしまいますが、そうするとfeed.xmlファイル内のドメインが、「http://localhost:4000」になっちゃうみたいです。ただ、Netlifyを使っていればそこでbuildされるのでよい。
buildすると_siteフォルダにfeed.xmlができていて、headのリンクはこんな感じでできています。
<link type="application/atom+xml" rel="alternate" href="https://mssp160.netlify.app/feed.xml" title="MSSP" />
ついでにヘッダーにfontawesomeでフィードアイコンを作ってみました。これって目印なだけなのかな?
<li class="social-link__item">
<a href="{{ 'feed.xml' | relative_url }}">
<i class="fas fa-rss"></i>
</a>
</li>
最後にfeedlyで確認したら一応できるようになっていました!feedlyのリンクを作ることもできるみたいですね〜。
はい、お役立ち情報というより自分のメモですいませんでした。来年はちょっとずつこういうメモをこっちでも書いていきたいなという気持ちです。日記とか全然書かないので初めはすごく違和感があったのですが、フィヨルドの日報でだいぶ慣れてきたような気がしています。あと、意外と何したか覚えてないのでたまに過去のメモ見るなって思って。書いとこ、って思いました。
このブログでまだしたいのは、表のCSSを書いてないので(えっ)それと、読んだ本リストにopenBDていうAPIを使ってるんですが、技術書の情報が乏しいような気がするのでなんとかしたいなぁと思っています。記事が増えてきたらTagページもなんとかせな…。僕はまだあんまりわかってないのですが、Rubyがもっとわかると自分でもっといじれることが増えるんだろうなーと思います。
]]>こんにちは、Misosoupです。私は今webプログラマーになるための勉強をしています。 本格的に勉強をはじめようと思ったのが去年の年末ころだったと思うので、あれから丁度1年が経ちました。今回は最近のまとめと思ったことを書きました〜。
初めは独学していたのですが、現在はフィヨルドブートキャンプというところで勉強をしています。9月の頭から始めたので、今3ヶ月くらいたったところですが、その間にやったことを並べてみました。11月中は太字になっているところあたりをやっていて、12月に入った今もRailsの勉強の途中です。
独学でやってた頃のイメージよりも、コードをごりごり書いている時間は少ないなと思います。それよりWeb周りの知識、LinuxとかデータベースとかRESTの考え方とか、コードを書く上で必要になる周辺の知識を勉強していた時間が長かったかな。でもこういう知識が必要なんだということ自体が、自分でやっててわからなかったことなので、参加してちゃんと勉強できてよかったなぁと思っています。
フィヨルドのカリキュラムはまだまだあって、この後もテスト技法、オブジェクト指向の書き方、Javascript、Vue.js、最後には開発…と続いていきます。全部でだいたい1000時間分くらいあると言われていて、プログラミング未経験者が最低限必要だと言われてる(?)勉強時間分くらいになってます。目標は今年度中の卒業かなぁ〜。でもこの先が重そうです。がんばります〜。
ところでこの1000時間という勉強時間は長すぎてつらいとか金銭的にもしんどいとか、フィヨルド内でも先日そういう話になりました。しかもフィヨルドは授業とかはなくて、本とか資料とか読んで課題やってみてね、わかんなかったら聞いて、って感じなので、自由に時間が使える反面、人によって卒業までにかかる時間はかなり違ってきます。
このシステムに関しては、私は人にやり方を強制されたり干渉されたりするのが嫌いなので、めちゃくちゃ好きで、家族もいなくて過度なプレッシャーもなく、大学で鍛えられたので人に質問するのも何の抵抗もないし、一人でもくもくと勉強しているのが性に合っているのか、割と毎日超ハッピーで一生やってたいって感じなのですが(働け)、人それぞれ性格や事情があるから辛くなったり焦ったりのもわかります。
この前Twitterでちょうどこんなツイートを見かけました(詳しくはツリーで続いています)。
スウェーデンで解雇になった知り合いのほとんどが大学や専門学校で新しい分野の勉強を始めてる。旅行業やってた友人はデータサイエンスを学んでるとか。2年後にはプログラム終えて職につくプラン。なお学費はかからず、返済不要の給付金も国からもらえる。こうしてこの国は再び持ち直す。
— 両角達平🇸🇪若者政策の研究員 (@tppay) November 26, 2020
私も別分野ではあるけど、ずっと専門職をやってたので、専門職につきたいなら、ある程度時間をかけて知識と経験を積み上げていくことは最低限必要なことだと思うんですよね。
ただ、できるだけ再チャレンジがしやすいような社会ではあって欲しいと思うんですよ。今、日本だと、一度躓いてしまったら、やっぱりそれなりにお金と時間に余裕がある人しか再チャレンジできない。だからみんな学ぶことに焦るしプレッシャーを感じたりするんじゃないかなぁ。
私もハラスメントを受けてはじめの仕事を辞めたときは、親に、おまえなんかもうろくな仕事にはつけない、家に帰ってこないで欲しいとまで言われたし、あの頃はそれなりに間に受けてしまいました。
いつでも何度でも学び直すことがもっと当たり前の社会になって欲しい。本当はツイートみたいに学ぶことに対して金銭的な援助とかがもっとあるといいですよね。特に女の人にとってはすごく助けになると思います。
この業界の方々を見ててすごくいいなと思ったのは、みんな当たり前にずっと勉強されているところです。フィヨルドでもTECHPLAY女子部でも、あたらしく勉強始めましたという人を絶対に馬鹿にしたりしない。転職するのも結構普通。今そういう場所にいるのがとてもうれしいし、社会にもっと広がっていって欲しいな〜と思っています。
]]>