I made a Twitter Bot with Go x Qiita API x Lambda

Introduction

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.

architecture

It's a structure that you can understand even if you explain it in sentences, but I made an architecture diagram. architecture.png

--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.

code

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

Finally

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

I made a Twitter Bot with Go x Qiita API x Lambda
I made a Twitter BOT with GAE (python) (with a reference)
I made a LINE BOT that returns parrots with Go
I made a stamp substitute bot with line
I made a Twitter fujoshi blocker with Python ①
I made a LINE Bot with Serverless Framework!
I made a Mattermost bot with Python (+ Flask)
I made a Python Qiita API wrapper "qiipy"
I tried to make "Sakurai-san" a LINE BOT with API Gateway + Lambda
I made a household account book bot with LINE Bot
I made a vim learning game "PacVim" with Go
I made a bot to post on twitter by web scraping a dynamic site with AWS Lambda (continued)
I made a LINE BOT with Python and Heroku
I made a discord bot
[AWS] I made a reminder BOT with LINE WORKS (implementation)
I made a wikipedia gacha bot
I made a fortune with Python.
I made a daemon with Python
I wrote a script to create a Twitter Bot development environment quickly with AWS Lambda + Python 2.7
I made a Twitter bot that mutters Pokemon caught by #PokemonGO
I tried ChatOps with Slack x API Gateway x Lambda (Python) x RDS
I made a character counter with Python
I made a Hex map with Python
I made a life game with Numpy
I made a stamp generator with GAN
Let's make a Twitter Bot with Python!
I made a roguelike game with Python
I made a simple blackjack with Python
I made a configuration file with Python
I made a WEB application with Django
I made a neuron simulator with Python
I tried to delete bad tweets regularly with AWS Lambda + Twitter API
Create a Twitter BOT service with GAE / P + Tweepy + RIOT API! (Part 1)
Create a Twitter BOT service with GAE / P + Tweepy + RIOT API! (Part 2)
I wrote a Slack bot that notifies delay information with AWS Lambda
I made a music bot using discord.py and Google Drive API (tested with Docker → deployed to Heroku)
Tweet regularly with the Go language Twitter API
I made a competitive programming glossary with Python
I tried hitting the Qiita API from go
I made a weather forecast bot-like with Python.
Make a Twitter trend bot with heroku + Python
I made a GUI application with Python + PyQt5
I made my dog "Monaka Bot" with LineBot
[Python] I made a Youtube Downloader with Tkinter.
LINE BOT with Python + AWS Lambda + API Gateway
I made a simple Bitcoin wallet with pycoin
Steps to create a Twitter bot with python
I made a random number graph with Numpy
I made a bin picking game with Python
I made a QR code image with CuteR
I made a LINE BOT that returns a terrorist image using the Flickr API
Try implementing a Cisco Spark bot with AWS Lambda + Amazon API Gateway (Python)
I tried to make a castle search API with Elasticsearch + Sudachi + Go + echo
I made a twitter app that decodes the characters of Pricone with heroku (failure)
〇✕ I made a game
I made a ready-to-use syslog server with Play with Docker
I made a Christmas tree lighting game with Python
I made a window for Log output with Tkinter
I made a net news notification app with Python
[Life hack] Women's Anna support bot with Twitter API
[Piyopiyokai # 1] Let's play with Lambda: Get a Twitter account