Skip to content

Commit

Permalink
Merge branch 'develop' for release v0.2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
daikikohara committed May 19, 2015
2 parents cff8011 + 6faa365 commit 8880910
Show file tree
Hide file tree
Showing 28 changed files with 618 additions and 213 deletions.
6 changes: 5 additions & 1 deletion Godeps/Godeps.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

47 changes: 15 additions & 32 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,54 +4,37 @@ enotify-slack
[![Build Status](https://drone.io/github.com/daikikohara/enotify-slack/status.png)](https://drone.io/github.com/daikikohara/enotify-slack/latest)
[![Coverage Status](https://img.shields.io/coveralls/daikikohara/enotify-slack.svg)](https://coveralls.io/r/daikikohara/enotify-slack?branch=master)

This is a tool to get event information and send the information to a channel in [Slack](https://slack.com/).
The event information is provided by event support sites such as [Connpass](http://connpass.com/).
Currently this tool only gets event information provided by Japanese event support sites.
Although the following part of this document is written in Japanese, Godoc and comments in the source code are written in English.


## 概要
日本語の紹介記事は[こちら](http://qiita.com/kiida/items/373446edd2fb09da82ca)

イベント支援サイトから勉強会の情報を取得してSlackに通知するためのツールです。
イベントのタイトルか説明にキーワードが含まれている場合、または指定したユーザが開催(または参加)しているイベントの情報をSlackの指定のチャネルに通知します。
もう少し詳しい紹介は[こちら](http://qiita.com/kiida/items/373446edd2fb09da82ca)に書きました。
## Summary

![キャプチャ](https://raw.github.com/wiki/daikikohara/enotify-slack/images/capture01.png)
This is a tool to get event information and send the information to a channel in [Slack](https://slack.com/).
The event information is provided by event provider's site such as [Meetup](http://www.meetup.com/) and [Eventbrite](https://www.eventbrite.com/)(the others are mainly Japanese sites).
The event information will be sent to Slack if the title or description contains keyword specified in the configuration file.

## 使い方
![screenshot](https://raw.github.com/wiki/daikikohara/enotify-slack/images/capture01.png)

[バイナリ版](https://drone.io/github.com/daikikohara/enotify-slack/files)はLinuxのみ動作確認しています。<br>
バイナリ版を使う場合は以下の「取得」の項は不要です。設定ファイル(conf.yml)はバイナリと同じディレクトリに配置してください。
## How to use

* 取得
```
go get github.com/daikikohara/enotify-slack
cd /path/to/enotify-slack
godep restore
go build
```
* 設定<br>
conf.ymlを必要に応じて編集して下さい。<br>
設定方法はconf.ymlのコメントを参照して下さい。
* 起動<br>
nohupを付けるかscreen/tmuxのセッションの中で起動して下さい。
```
nohup ./enotify-slack &
```
* Get binary and conf.yml from [release](https://github.com/daikikohara/enotify-slack/releases) and place them in the same directory.
* Configure conf.yml. Comment in the file is descriptive enough.
* Run the binary with `nohup` like `nohup ./enotify-slack &` or run it in screen/tmux session.

## Thanks

以下のAPIを利用させて頂いております。
ありがとうございます。
enotify-slack uses api shown below.

* イベント情報サイト
* Event provider's site
* [ATND](http://api.atnd.org/)
* [Connpass](http://connpass.com/about/api/)
* [Doorkeeper](http://www.doorkeeperhq.com/developer/api)
* [Eventbrite](http://developer.eventbrite.com/docs/)
* [Meetup](http://www.meetup.com/meetup_api/)
* [Partake](https://github.com/partakein/partake/wiki/PARTAKE-Web-API)
* [StreetAcademy](http://www.street-academy.com/api)
* [Zusaar](http://www.zusaar.com/doc/api.html)
* Slack通知
* Slack
* [Slack](https://api.slack.com/)

## License
Expand Down
14 changes: 8 additions & 6 deletions conf.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ import (

// Config represents configurations defined in a yaml file.
type Config struct {
Keyword string
Nickname string
Place []string
ErrorToSlack bool `yaml:"error_to_slack"`
Provider map[string]struct {
Keyword string
Nickname string
Taboo string
Place []string
Provider map[string]struct {
Url string
Color string
Interval uint32
Expand All @@ -29,7 +29,9 @@ type Config struct {
Dbfile string
Bucketname string
}
Logfile string
Logfile string
Timezone string
ErrorToSlack bool `yaml:"error_to_slack"`
}

// NewConfig constructs Config using a yaml file passed as the argument.
Expand Down
91 changes: 58 additions & 33 deletions conf.yml
Original file line number Diff line number Diff line change
@@ -1,26 +1,31 @@
# タイトルとイベント説明文の中にこれらの単語が含まれているものを通知します。
keyword: golang,slack,anotherkeyword
# イベントオーナーまたはイベント参加者に以下の参加者が含まれているものを通知します。
# イベントにkeywordが含まれていなくてもnicknameが含まれていれば通知します。
# atnd,connpass,zusaarのみ対応しています。
nickname: nickname1,nickname2
# 場所にこれらの単語が含まれているもののみ通知します。
# If event title/description contains 'keyword', the event will be sent to Slack.
keyword: golang,slack,anotherkeyword,etc

# If the owner or participants contains 'nickname', the event will be sent to Slack.
# 'nickname' is OR'd with keyword.
# 'nickname' only works for Atnd, Connpass and Zusaar.
nickname: nickname1,nickname2,etc

# If event title/description contains 'taboo', the event will Not be sent to Slack even if the other conditions are satisfied.
taboo: taboo1,taboo2,etc

# Event will be sent if 'place' is included in the event address.
# 'place' is AND'd with 'keyword' or 'nickname'.
place:
- 東京
- 神奈川
- 埼玉
- 千葉
- 未定
- 調整中
# イベント取得でエラーが発生した場合にslackに通知します。
# ネットワークが不安定になると頻発することがあるのでデフォルトはログファイルのみです。
error_to_slack: false
# イベント提供サイトごとの設定を記載します。
# urlはAPIのURLです。
# colorはSlackで表示される際の色です。
# intervalはAPIを実行する間隔(秒)です。負荷をかけ過ぎないよう注意して下さい。
# また、通知時のアイコンはイベント提供者名(例えば:atnd:)としています。
# 事前にアイコンに対応した絵文字を登録しておかないとそのまま文字として表示されます。
- "San Jose"
- "Santa Clara"
- "Sunnyvale"
- "Mountain View"

# Event provider specific configuration.
# url: url for the API. API key for meetup and eventbrite must be set using your key.
# color: color to be displayed on Slack.
# interval: interval in second to execute the API.
# Keep the value moderate to avoid overloading the event provider.
# Comment some provider's name(,url color and interval) out, if you don't want to get event information from them.
#
# NOTE: Icon in Slack message is shown as :providername: (like ":meetup:").
# Please set the icon for your Slack in advance or you'll see the name as text.
provider:
atnd:
url: https://api.atnd.org/events/?count=50&format=json&
Expand All @@ -34,6 +39,14 @@ provider:
url: http://api.doorkeeper.jp/events/?sort=published_at&locale=ja&
color: "#00D0A0"
interval: 600
eventbrite:
url: https://www.eventbriteapi.com/v3/events/search/?token=your_api_token_here&
color: "#FFaa33"
interval: 600
meetup:
url: https://api.meetup.com/2/open_events?key=your_api_key_here&
color: "#F00000"
interval: 600
partake:
url: http://partake.in/api/event/search?sortOrder=createdAt&maxNum=50&query=
color: "#AAAAAA"
Expand All @@ -46,23 +59,35 @@ provider:
url: http://www.zusaar.com/api/event/?count=50&
color: "#0000FF"
interval: 600
# Slack通知の設定です。
# pretextはイベント情報の前に付与する文字です。
# urlはSlackのincoming-webhookのURLです。環境に合わせて記載して下さい。
# channelは通知するチャネル名です。
# shortは表示方法です。falseにすると整形されて表示されtrueにすると詰めて表示されます。
# 詳細はincoming-webhookのページを参照してください。
# intervalはSlackに通知する間隔(秒)です。初回起動時やイベントが大量に登録されたときに
# Slackのrate limit(1message/sec)に達してしまうのでインターバルを入れてます。

# Slack configuration.
# pretex: text to be displayed before event details.
# url: url for your your Slack incoming-webhook. modify the token.
# channel: name of Slack channel that event is sent to.
# short: if true, event details are displayed side-by-side.
# interval: interval in second to send event to Slack.
# This prevent reaching rate limit when many events are registered in a short period.
slack:
pretext: "ヒャッハー!"
pretext: "New Event Arrived!"
url: https://hooks.slack.com/services/YOUR/TOKEN/HERE
channel: "#event-notify"
short: false
interval: 3
# 過去に通知したイベントの情報を保持するboltdbというKVSの情報です。基本的には変更不要です。

# timezone
# The time of event sent to Slack is shown as time in this time zone.
timezone: "America/Los_Angeles"

# db file configuration.
# This usually does not need to be modified.
boltdb:
dbfile: enotify-slack.db
bucketname: enotify-slack
# ログファイル名です。

# log file name.
# This usually does not need to be modified.
logfile: enotify-slack.log

# If 'error_to_slack' is true, error messages are sent to Slack when error occurs.
# Recommended to leave this false since lots of messages are sent when network error occurs.
error_to_slack: false
2 changes: 1 addition & 1 deletion conf_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
)

var (
validConf = "keyword: keyword1,keyword2\nnickname: person1,person2\nplace:\n - Tokyo\n - Kanagawa\nerror_to_slack: true\nprovider:\n connpass:\n url: http://connpass.com/api/v1/event/?order=3&count=50&\n color: \"#D00000\"\n interval: 300\nslack:\n pretext: slackpretext\n url: https://test.slack.com/services/hooks/incoming-webhook?token=tokenname\n channel: \"#notify-channel\"\n short: false\n interval: 3\nboltdb:\n dbfile: it-event.db\n bucketname: it-event\nlogfile: ./enotify-slack.log\n"
validConf = "keyword: keyword1,keyword2\nnickname: person1,person2\nplace:\n - Tokyo\n - Kanagawa\nerror_to_slack: true\nprovider:\n connpass:\n url: http://connpass.com/api/v1/event/?order=3&count=50&\n color: \"#D00000\"\n interval: 300\nslack:\n pretext: slackpretext\n url: https://test.slack.com/services/hooks/incoming-webhook?token=tokenname\n channel: \"#notify-channel\"\n short: false\n interval: 3\nboltdb:\n dbfile: it-event.db\n bucketname: it-event\nlogfile: ./enotify-slack.log\ntimezone: Asia/Tokyo\n"
// slice for invalid conf contents
invalidConf = []string{
// invalid slack interval data
Expand Down
49 changes: 20 additions & 29 deletions event/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"io/ioutil"
"log"
"net/http"
"strings"
"time"
)

Expand All @@ -15,8 +14,23 @@ type Api interface {
Get(baseurl, keyword, nickname string) ([]Event, error)
}

// timeFormat holds time format.
// Currently it only supports "2006-01-02 15:04" style format.
const timeFormat = "2006-01-02 15:04"

// timezone holds timezone such as "Asia/Tokyo"
// This can be set via configuration file.
var timezone *time.Location

// SetTimezone sets timezone specified in the configuration file.
func SetTimezone(t string) {
l, err := time.LoadLocation(t)
if err != nil {
panic(err.Error())
}
timezone = l
}

// GetApi is a factory function.
// GetApi returns an implementation of Api which gets actual events provided by each event provider.
func GetApi(provider string) Api {
Expand All @@ -33,8 +47,12 @@ func GetApi(provider string) Api {
return new(Zusaar)
case "strtacademy":
return new(Strtacademy)
case "meetup":
return new(Meetup)
case "eventbrite":
return new(Eventbrite)
default:
log.Fatalln("Invalid api name:" + provider + "\ncheck conf file.")
log.Panic("Invalid api name:" + provider + "\ncheck conf file.")
}
return nil
}
Expand All @@ -58,30 +76,3 @@ func GetJson(url string) (interface{}, error) {
}
return result, nil
}

// format formats date format for the common format used for Slack message.
func format(date string) string {
t, err := time.Parse(time.RFC3339Nano, date)
if err != nil {
return date
}
return t.In(time.FixedZone("Asia/Tokyo", 9*60*60)).Format(timeFormat)
}

// contains checks if keyword is contained in either title or description.
func contains(title, description, keyword string) bool {
for _, q := range strings.Split(keyword, ",") {
if strings.Contains(strings.ToLower(title), strings.ToLower(q)) || strings.Contains(strings.ToLower(description), strings.ToLower(q)) {
return true
}
}
return false
}

// trim returns first 50 characters of string passed by the argument.
func trim(s string) string {
if len([]rune(s)) > 50 {
return string([]rune(s)[:50]) + "..."
}
return s
}
Loading

0 comments on commit 8880910

Please sign in to comment.