yoshiislandblog.net
元営業の駆け出しアラサーSEが、休日にMACと戯れた際の殴り書きメモ。日々勉強。日々進歩。

この記事は3年以上前に書かれた記事で内容が古い可能性があります

golangでbot作成

2017-09-12

兎にも角にもgoに慣れよう、とのことで、slack botをgoで作ってみた。

以下の記事を大変参考にしました。
今更やけど、Go言語でSlack APIを使ってみた!!

動きとしては、とあるキーワード(今回は#golang)のtweetsを拾ってslackにポストするもの。

# go get anaconda

tweet apiを使うにはanacondaがいいらしい。

% go get github.com/ChimeraCoder/anaconda

# GOPATH/GOROOTの定義

% export GOPATH=""

# goのファイル構造

ファイル構造はこんな感じに。

.
├── bin
├── pkg
│   └── darwin_amd64
│   └── github.com
└── src
├── github.com
│   ├── ChimeraCoder
│   ├── azr
│   ├── dustin
│   └── garyburd
├── main.go
└── passwordlist
│   └── passwordlist.go

実行ファイルはsrcの下に置くのがお決まり
Goコードの書き方

Goコードはワークスペース内に置いておく必要があります。ワークスペースはルートに以下の3つのディレクトリを持つディレクトリ階層です。

srcはパッケージに構成された(1ディレクトリに1パッケージ)Goのソースファイルを含み、
pkgはパッケージオブジェクトを含み、
binは実行形式コマンドを含みます。

# 実行ファイルの用意

package main

import (
    "encoding/json"
    "io/ioutil"
    "net/http"
    //"fmt"
    "net/url"
    "github.com/ChimeraCoder/anaconda"
    "passwordlist"
)

func twitter_search() []string {
    anaconda.SetConsumerKey(passwordlist.ConsumerKey)
    anaconda.SetConsumerSecret(passwordlist.ConsumerSecret)
    api := anaconda.NewTwitterApi(passwordlist.AccessToken, passwordlist.AccessTokenSecret)

    v := url.Values{}
    v.Set("count", "10")
    searchResult, _ := api.GetSearch("#golang", v)

    twtlst := make([]string, 10)
    for i, tweet := range searchResult.Statuses {
        twtlst[i] = "\n\n" + tweet.CreatedAt + " " + tweet.Text + "\n\n"
        _ = twtlst //avoiding error
        //fmt.Printf("[%s] %s\n", tweet.CreatedAt, tweet.Text)
    }
   return twtlst
}

var (
    IncomingUrl string = passwordlist.Incomingurl
)

type Slack struct {
    Text        string `json:"text"`
    Username    string `json:"username"`
    Icon_emoji  string `json:"icon_emoji"`
    Icon_url    string `json:"icon_url"`
    Channel     string `json:"channel"`
}

func main() {

    output_text := ""
    output_text_2 := ""
    for _, ot := range twitter_search() {

      output_text_2 = output_text + ot
      output_text = output_text_2
      _ = output_text
    }

    //fmt.Print(output_text)

    params, _ := json.Marshal(Slack{
        output_text,
        passwordlist.Username,
        passwordlist.Icon_emoji,
        passwordlist.Icon_url,
        passwordlist.Channel})

    resp, _ := http.PostForm(
        IncomingUrl,
        url.Values{"payload": {string(params)}},
    )

    body, _ := ioutil.ReadAll(resp.Body)
    defer resp.Body.Close()

    println(string(body))
}

# 変数を他パッケージから読み込む

先ほどの引用、よく見ると「1ディレクトリに1パッケージ」と書いてある。

srcはパッケージに構成された(1ディレクトリに1パッケージ)Goのソースファイルを含み、

素直に、src配下にディレクトリを作成して変数を収めるファイルを配置

変数を収めるコードの冒頭にパッケージ名を定義する(goファイルはどれもパッケージの必要)

package passwordlist

var ConsumerKey = "ホゲホゲ
...

この時、変数の冒頭は必ず「大文字」で記述する!

じゃないとこうなる

./main.go:10: imported and not used: "passwordlist"
./main.go:15: undefined: consumerKey

読み込むファイルでは、packageとしてimportすること、
「パッケージ名.変数名」で記載することを忘れない

import (
    "passwordlist"
)

var (
    IncomingUrl string = passwordlist.Incomingurl
)

# 実行

これで問題なく動くはず

% go run main.go


意味はわからないがtweetは拾えている。