I'm studying Go, but when I go looking for information from myself, it's natural, but I can only get the information I want. I think it is necessary to read various articles in order to expand the overall knowledge, but it is quite heavy. So, I created a Twitter bot that tweets articles with Qiita's Go tag!
@BotQiita ↑ Follow me.
It's a structure that you can understand even if you explain it in sentences, but I made an architecture diagram.
--Get articles with Go tag with Qiita API --Authentication & Tweet with Twitter API --lambda is written in Go and runs regularly on cloudwatch every hour
It is like that.
First of all, from Twitter authentication. I used https://github.com/ChimeraCoder/anaconda.
package auth
import (
"os"
"github.com/ChimeraCoder/anaconda"
)
type Credentials struct {
ConsumerKey string
ConsumerSecret string
AccessToken string
AccessTokenSecret string
}
// GetTwitterAPI gets twitter client
func GetTwitterAPI() *anaconda.TwitterApi {
creds := Credentials{
ConsumerKey: os.Getenv("CONSUMER_KEY"),
ConsumerSecret: os.Getenv("CONSUMER_SECRET"),
AccessToken: os.Getenv("ACCESS_TOKEN"),
AccessTokenSecret: os.Getenv("ACCESS_TOKEN_SECRET"),
}
anaconda.SetConsumerKey(creds.ConsumerKey)
anaconda.SetConsumerSecret(creds.ConsumerSecret)
api := anaconda.NewTwitterApi(creds.AccessToken, creds.AccessTokenSecret)
return api
}
Then hit the Qiita API to get the article. Click here for Qiita API specifications → https://qiita.com/api/v2/docs#%E6%8A%95%E7%A8%BF
package qiita
import (
"encoding/json"
"errors"
"io/ioutil"
"net/http"
"net/url"
"time"
)
type Client struct {
Endpoint string
CreatedAt string
Tag string
}
type Article struct {
Title string `json:"title"`
URL string `json:"url"`
CreatedAt time.Time `json:"created_at"`
}
//Create url
func createUrl(u *url.URL, c *Client) string {
q := u.Query() //Generate a map type of query parameters
q.Set("page", "1") //Set query parameters
q.Set("per_page", "10")
q.Set("query", "tag:"+c.Tag+" created:>="+c.CreatedAt)
u.RawQuery = q.Encode() //Encode query parameters
return u.String()
}
func (c *Client) GetQiitaArticles() (*[]Article, error) {
e, err := url.Parse(c.Endpoint) //Parse url
if err != nil {
return nil, err
}
u := createUrl(e, c) //Url after setting query parameters
req, err := http.NewRequest(http.MethodGet, u, nil) //Set method, url, body
if err != nil {
return nil, err
}
resp, err := http.DefaultClient.Do(req) //Request issuance
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, errors.New(resp.Status)
}
body, err := ioutil.ReadAll(resp.Body) //Read the response
if err != nil {
return nil, err
}
var articles []Article
if err := json.Unmarshal(body, &articles); err != nil {
return nil, err
}
return &articles, nil
}
reference
-[Introduction to Go] Parsing and generating URLs with the net / url package
Finally it is main. Since the lambda function is executed every hour, it gets the time one hour ago each time and tweets if the retrieved article is later than that.
package main
import (
"fmt"
"os"
"time"
"github.com/Le0tk0k/qiita-twitter-bot/auth"
"github.com/Le0tk0k/qiita-twitter-bot/qiita"
"github.com/aws/aws-lambda-go/lambda"
)
var tag = "go"
func post() {
c := qiita.Client{
Endpoint: "https://qiita.com/api/v2/items",
CreatedAt: time.Now().Format("2006-01-02"),
Tag: tag,
}
api := auth.GetTwitterAPI()
articles, err := c.GetQiitaArticles()
if err != nil {
fmt.Fprintln(os.Stderr, "Error:", err)
os.Exit(1)
}
t := time.Now().Add(time.Duration((-1) * time.Hour))
for _, i := range *articles {
if i.CreatedAt.After(t) {
_, err = api.PostTweet(i.Title+"\n#golang\n"+i.URL, nil)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
}
}
func main() {
lambda.Start(post)
}
That's it for the code. After that, generate a zip file with the following command and upload it to the lambda function.
$ GOOS=linux GOARCH=amd64 go build -o post
$ zip handler.zip ./post
Actually, it was my first time on AWS, but it was surprisingly smooth! I want to study little by little from now on.
Please follow us! @BotQiita
Recommended Posts