func shutdownHook() {
	sigs := make(chan os.Signal, 1)
	signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
	<-sigs
	boltdb.Db.Close()
	logger.Close()
	fmt.Println("bye")
	os.Exit(0)
}
shutdownHook handles OS signals.
It catches SIGINT and SIGTERM to close resources and then exits the process.
package main
import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"os/signal"
	"runtime"
	"strings"
	"syscall"
	"time"
	. "github.com/daikikohara/enotify-slack/event"
)
var (
	config = NewConfig("conf.yml")
	logger = NewLogger(config.Logfile)
	boltdb = NewBolt(config.Boltdb.Dbfile, config.Boltdb.Bucketname)
)
func init() {
	runtime.GOMAXPROCS(runtime.NumCPU())
	SetTimezone(config.Timezone)
}
func main() {
	payload := make(chan *Payload)
	for provider, _ := range config.Provider {
		go getEvent(provider, payload)
	}
	go sendEvent(payload)
	shutdownHook()
}
func getEvent(provider string, payload chan *Payload) {
	api := GetApi(provider)
	for {
		events, err := api.Get(config.Provider[provider].Url, config.Keyword, config.Nickname, config.Place)
		handleError("Error on getting event from "+provider, err, payload)
		for _, event := range events {
			key := []byte(provider + ":" + fmt.Sprintf("%v", event.Id))
			if event.IsValid(config.Place, config.Taboo) && !boltdb.Exists(key) {
				value, _ := json.Marshal(event)
				boltdb.Put(key, value)
				payload <- ConstructSlackMessage(provider, &event, config)
			}
		}
		time.Sleep(time.Duration(config.Provider[provider].Interval) * time.Second)
	}
}
func handleError(pretext string, err error, errorMsg chan *Payload) {
	if err != nil {
		msg := pretext + "\n" + err.Error()
		logger.Println(msg)
		if config.ErrorToSlack {
			errorMsg <- ConstructSlackError(msg, config.Slack.Channel)
		}
	}
}
func sendEvent(payload chan *Payload) {
	for {
		p := <-payload
		data, err := json.Marshal(p)
		resp, err := http.Post(config.Slack.Url, "application/json", strings.NewReader(string(data)))
		if err != nil {
			logger.Println(err.Error())
		}
		defer resp.Body.Close()
		_, err = ioutil.ReadAll(resp.Body)
		if err != nil {
			logger.Println(err.Error())
		}
		time.Sleep(time.Duration(config.Slack.Interval) * time.Second)
	}
}