RubyでSlack通知

以前シェルでSlack通知のスクリプトを書いていたのだけど、この間書いたRubyプログラムの、

Nokogiriを使ってみる
あるサイトでは、電子書籍で発売した漫画の一覧を観ることができる。 そのサイトを見るのが日課だったのだけど、正直毎日確認するのが...

これでSlack通知させたくて、Rubyでも書いてみた。

require 'dotenv'
require 'slack/incoming/webhooks'

  Dotenv.load
  slack = Slack::Incoming::Webhooks.new ENV["APIKEY"]
  
  attachments = [{
    color: "#483D8B",
    fields: [
      {
      title: "今日の書籍一覧",
      value: "#{str}",
      }
    ],
  }]
  
  slack.post "", attachments: attachments

APIKEYをGithubで管理しないために、dotenvで.envに書いたAPIKEYを読むようにした。
しかし、他の方々はどうしてるのだろう?

ちなみにシェルスクリプトはこれ。

#!/bin/bash

if [ -n $? ];then
  echo "Usage: ./slack.sh IPaddress"
  exit 1;
fi

url='webhookのAPIで取得したURLをここに記載する。'
username='ユーザー名として名乗る名称を記載する。なんでもOK'
to="#チャンネル名を記載する"
subject="`hostname` : $1"
emoji=':bell:'   <-絵文字。なんでもOK
#message="${subject}"
message2="$2"

payload="payload={
     \"channel\": \"${to}\",
     \"username\": \"${username}\",
     \"text\": \"${subject}\",
     \"icon_emoji\": \"${emoji}\",
     \"attachments\": [
     {
       \"text\": \"${message2}\"
     }
     ]
}"

curl -m 5 --data-urlencode "${payload}" $url

今となってはなんでこれを書いたか覚えてないけど、なんとくなく監視用っぽいスクリプトな気がする。
curlでAPIKEYにJSON形式で情報を渡している。

Slackで通知を集約できるのは思った以上に便利だった。
今までとりあえず雑にメールで通知させていたものは、全てSlackで良くなった。
SkypeからSlackへ移行した理由もこの辺が強いと思う。

反面、通知が流れていくと他の人は追いづらくなってしまうのでバランスよく通知させていきたい。

上記通知部分が作成できたので、自宅サーバーのcronにセットすることで、毎日新しい漫画の一覧が取得できるようになった。
便利機能でもなんでもないけど、作ろうと思ってたものができたのは良かった。

次は何書こうかな。

Nokogiriを使ってみる

あるサイトでは、電子書籍で発売した漫画の一覧を観ることができる。
そのサイトを見るのが日課だったのだけど、正直毎日確認するのが面倒くさいと思ってた。
そこで、いい感じに一覧を取得できないか調べたところ、いわゆるスクレイピングなどでよく使われるNokogiriを使ってみることにした。

実際に書いたコードはこちら。

require 'yaml'
require 'open-uri'
require 'nokogiri'

list = YAML.load_file("list.yaml")

list['siteurl'].each do | url |
  doc = Nokogiri::HTML(open(url).read)
  puts "=== Info === "
  p doc.title
  doc.xpath('//h2[@class="entry-title"]').each do | node |
    puts node.text
  end
end

見て分かるように大変シンプルなコードで簡単に取得できた。

取得できた情報はこんな感じ。

=== Info ===
絢爛たるグランドセーヌ 第01-06巻 [Kenrantaru Grande Seene vol 01-06]
Ultraman 第01-08巻
ディメンションW 第01-10巻 [Dimension W vol 01-10]
ねじ巻き精霊戦記 天鏡のアルデラミン 第01巻 [Nejimaki Seirei Senki – Tenkyou no Alderamin vol 01]
生徒会副会長矢上さゆりは頑張っている! 第01巻 [Seitokai Osayagami Sayuri wa Ganbatte Iru! vol 01]
黒崎くんの言いなりになんてならない 第01-07巻 [Kurosaki-kun no Iinari ni Nante Naranai vol 01-07]
ソードアート・オンライン プログレッシブ 第01-05巻 [Sword Art Online – Progressive vol 01-05]
木根さんの1人でキネマ 第01-02巻 [Kine-san no 1-ri de Cinema vol 01-02]

頻繁にアクセスしてバンされたら嫌だなぁと思って、サイトURLはyamlでリストを管理することにした。
最初ソースを全部取得するのはすぐにできたのだけど、その後にどのように書いたら特定のタグの値を取得できるかがわからなかった。
このソースを見て分かるように、xpathというメソッドで指定している。
pathは”//”で指定して書いてくので、ちょっと独特だなと感じたけど、理解すればそこまででも無い。
このままだとサイトにアクセスしてるのと同じレベルなので、次はSlack通知するようにしたい。

atcoder041のABCを解いた

いつもやってるatcoderの問題シリーズ。

今回は最新のabc041を解いてきた。

問題はこちら。

A問題の回答

s, i = STDIN.read.split(?\n)
i = i.to_i - 1
puts s[i]

改行コード区切りで縦に並んだ文字列をそれぞれ変数に入れる。
iという数字を整数の型にセットして、1引く。
文字列sのi番目を表示させる。

B問題の回答

A, B, C = STDIN.gets.split(" ").map(&:to_i)
X = A * B * C
Y = (10**9) + 7
puts X % Y

スペース区切りで変数にセットし、整数の型にセットする。
AとBとCを積算する。
Yは指定された数字10の9乗足す7を計算している。
そして最後にX割るYの余りを出している。

C問題の回答

N = STDIN.read.split("\n").map(&:to_s)
hash = {}
i = 1.to_i
N[1].split(/ /).each do | val |
  hash[i] = val.to_i
  i = i + 1
end
 
A = Hash[ hash.sort_by { | _, v | -v } ]
 
A.map { | key, value | puts key }

改行区切りで縦に変数に文字列としてセットする。
hashを宣言する。
iに1を整数としてセットする。
変数Nの2行目の値をスペース区切りで、hashにセットする。その際にkeyは整数で1から足していく。
hash.sort_byを使って、valueをsortする。※配列をソートすると、順番が変わるのでkeyを並べることはできない。結果は123のようになってしまう。
最後にhashのkeyだけを取り出している。

いつもこの手の文字列の変数セットに悩む。

S
A1,A2,A3... An

このような標準入力があって、Anを配列に入れたい場合はみなさんどうしているのだろうか。
上記方法以外になにかあるのだろうか。なんかこう1行目だけを無視して、2行目をいきなりhashに入れるみたいなことができないのだろうか。
私は分からずに、いつも一旦変数に入れて、string関数で抽出するようにしている。最近はこれが定着しつつあるけど正しいのかわからない。

来週のRubyの勉強会で聞いてみよう。
もし教えたくてムズムズした人がいたら是非教えてほしいです。