Elixirでスクレイピング&DiscordBotを動かそう！

#Elixirって？
Elixir (エリクサー) は並行処理の機能や関数型といった特徴を持つ、Erlangの仮想マシン (BEAM) 上で動作するコンピュータプログラミング言語である。([Wikipedia参照](https://ja.wikipedia.org/wiki/Elixir_(%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E8%A8%80%E8%AA%9E))）

**Elixirちょっと触ってみたいって人は@piacerexさんの[この記事](https://qiita.com/piacerex/items/6714e1440e3f25fb46a1)をどうぞ！**

#Discordって？
Discord（ディスコード）は、Windows・macOS・Linux・Android・iOS・Webブラウザで動作する、ビデオ通話・音声通話・VoIPフリーウェアである。([Wikipedia参照](https://ja.wikipedia.org/wiki/Discord_(%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2)))

Lineのグループチャットのようなものです。
僕も普段からよくお世話になっております。

#さっそく作ってみよう！
**今回は、qiitaの各言語のトレンドがdiscordでコマンドを打つだけで見れるものを作ろうと思います**
・`!qiita elixir`的な感じで取得します
*Elixirのインストール方法やdiscordbotのアカウント作成等はさらっと、他の記事にぶん投げます！

##まずはElixirのインストール

[ここだよ！](https://elixir-lang.jp/install.html)
Elixirのバージョン管理したいなら@nishiuchikazumaさんの[この記事かな！]
(https://qiita.com/nishiuchikazuma/items/b9d319732ddb540fd990)

*僕は[exenv](https://github.com/exenv/exenv)を使っているのですが、おそらく、たぶん、いや絶対上記の記事のバージョン管理が簡単な気がする。


##DiscordBotの設定
@1ntegrale9さんの[この記事かな！](https://qiita.com/1ntegrale9/items/cb285053f2fa5d0cccdf)

##準備ができたら作っていきましょい!
今回は@madoramaさんの[こちらの記事](https://qiita.com/madorama/items/b8d1d1fb8a6e457e30b2)を参考にさせていただきました！

###あらためて今回の目標
![Screen Shot 2021-02-11 at 3.06.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327052/d7a9da74-360d-dc99-b09a-004c93971b7d.png)
**上記の画像のトレンドのaタグをスクレイピングして、下記の画像のようにDiscordBotを用いて表示させます！**
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327052/5477115f-38e4-076d-d564-02bee653f74b.png" width=60%>


###プロジェクト作成
``` 
mix new qiita_discord_bot --sup 
```
`qiita_discord_bot`は自分の好きなプロジェクト名に変えてください。
なんか色々ファイルとかフォルダが作られると思うので`cd プロジェクト名`で移動してください。

*`--sup`オプションが必須なのかが分からない、、(誰か教えてください)
###ライブラリの導入
`mix.exs`の中にこちらを追加

```elixir:mix.exs
defp deps do
  [
    {:alchemy, "~> 0.6.7", hex: :discord_alchemy}
  ]
end
```
追加したら

```
mix deps.get
```
を実行してライブラリを取得
###configファイルを作ろう
Elixir1.9からconfigファイルが[自動で生成されなくなった](https://dev.to/gumi/elixir-elixir-1-9-1dmp)ので`config/config.exs`を作ってください。

```
mkdir config
cd config
touch config.exs
```
次に`config.exs`にbotのトークンを書きます。

```elixir:config.exs
config :qiita_discord_bot,
  discord_token: "bot token"
```
###Bot界のHelloWorld!?
は[こちら](https://qiita.com/madorama/items/b8d1d1fb8a6e457e30b2#ping%E3%81%95%E3%82%8C%E3%81%9F%E3%82%89%E8%BF%94%E4%BA%8B%E3%81%99%E3%82%8B)をみてください。（~~書いてたんですけど、誤ってページ飛んだら保存されてないじゃないか、なにがじどうほぞんd~~）

###気を取り直して、qiitaをスクレイピングしてdiscordに表示させましょう！
えー、まずは[HTTPoison](https://github.com/edgurgel/httpoison)(httpクライアント)と[Floki](https://github.com/philss/floki)(httpパーサ)を追加しましょう。(~~あ〜ここもちゃんと書いてたのになぁ~~）

```elixir:mix.exs
defp deps do
  [
    {:alchemy, "~> 0.6.7", hex: :discord_alchemy},
    {:httpoison, "~> 1.8"}, # <-追加
    {:floki, "~> 0.29.0"} # <-追加
  ]
end
```
追加したら

```
mix deps.get
```
を実行!

###実際にコードを書いてく
はい、それではコードを書いていきましょう。
`https://qiita.com/tags/*****`の`*****`の部分を引数にしてやればそれぞれのタグのトレンドが取得できます。
ちなみに、`Cogs.def コマンド名(引数) do`となっているのでそこを利用します。
以下コードの全体です。

```elixir:application.ex
defmodule QiitaDiscordBot.Application do
  use Application

  defmodule Commands do
    use Alchemy.Cogs

    Cogs.def ping do # <- bot界のhelloworld
      Cogs.say "pong!"
    end
   # 今回したかったやつ
    Cogs.def qiita(key) do 
      key = String.downcase(key) # <- 大文字が入るとうまくいかなかったので全て小文字に変換
      Cogs.say "#{key}の先週のトレンド"
      target_url = "https://qiita.com/tags/" <> key
      HTTPoison.get!(target_url).body # <- htmlのbodyを取得
      |> Floki.find("a.css-eebxa") # <- トレンドの部分のクラスを取得
      |> Floki.attribute("href") # <- 属性を取得
      |> Enum.each(&(Cogs.say(&1))) # <- それぞれ表示
    end
  end


  def start(_type, _args) do
    opts = [strategy: :one_for_one, name: QiitaDiscordBot.Supervisor]
    Supervisor.start_link(children, opts)

    token = Application.get_env(:qiita_discord_bot, :discord_token)
    run = Alchemy.Client.start(token)
    use Commands
    run
  end
end
```
###実行

```
mix run --no-halt
```
はい、discord開いて`!qiita elixir`って打ってみたら、elixirのトレンドの記事が出てきますよ〜！
間違って、`!qiita EliXIr`なんて打っても大丈夫ですからね〜！
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327052/5477115f-38e4-076d-d564-02bee653f74b.png" width=50%>

###終わりに
たった数行でスクレイピングできたりdiscordにつぶやけたり、elixirってすごいですね！
今回のプロジェクトは[github](https://github.com/daikiyamane)にも載せてますので何かご不明な点などありましたら、コメントお待ちしております！

######本当の終わりに
誰か雇ってもろてもええですか？(就活生）