A Golang bot to count down the best day of your life - the holidays
Luis Gustavo Macedo
Posted on July 6, 2023
Returning with my desire to share knowledge and experience, today i will show a very cool project that i built in the last year.
At the time, I was in the middle of my degree. Although I liked the university and thought that academia is very important for the education of a great software developer (but not mandatory), the holidays are a time that every university student looks anxiously.
The Idea ๐ก
Then, at the time as I already my studies in Go, and I have a idea, why not make a bot for twitter?๐ค To learn more about golang and make a cool project.
A bot that makes a tweet every day telling how many days are left until college holiday, for me and people at my university accompany.
Repository of project -> https://github.com/Luisgustavom1/go-twitter-bot
Today that's what I want to show, I'll show the simple code of bot and how I built the infra in AWS to automate this process, obviously using the free tier๐ค.
Before start I have divided it into 4 main steps ๐:
- Create a main function that must receive a date and return how many days are left until this date.
- Connect with twitter to make a tweet.
- Configure the function in AWS Lambda.
- Give a way of execute lambda function every day.
1. The function
The code of this feature is very simple.
I have a function to format date and another to subtract the date.
package main
import (
"log"
"math"
"time"
)
type DaysRemaining int
func main() {
VACATION_DATE := "2023/06/29 23:00:00 -03"
vacationDateFormatted, err := getVacationDateFormatted(VACATION_DATE)
if err != nil {
log.Fatal(err)
}
daysToVacation := getDaysRemaining(vacationDateFormatted)
log.Println("tweet", daysToVacation)
}
func getVacationDateFormatted(date string) (time.Time, error) {
const shortFormat = "2006/01/02 15:04:05 -07"
// Format date to this format and timezone ๐๐
dateParsed, err := time.Parse(shortFormat, date)
if err != nil {
return dateParsed, err
}
return dateParsed, nil
}
func getDaysRemaining(date time.Time) DaysRemaining {
today := time.Now()
duration := date.Sub(today)
// Subtract today from vacation date
return DaysRemaining(math.Ceil(duration.Hours() / 24))
}
The main logic is basically that, in another post we can explore more about golang and its powers, but today i just want to give an overview of the code.
2. Connect with twitter
At the time I used this client library to abstract the twitter API, but unfortunately it is deprecated๐ญ
So today maybe it is not the best option. You can venture into twitter api.
In this step I had to generate api keys and access tokens. Every time I get to this part to integrate with third party, I get lost where get this secrets, so here are the ones from twitter api key and access token.
package main
import (
"log"
"math"
"time"
"os"
"github.com/dghubble/go-twitter/twitter"
"github.com/dghubble/oauth1"
)
func main() {
//...
// Initial config to oauth 1.0a
config := oauth1.NewConfig(
os.Getenv("API_KEY"),
os.Getenv("API_KEY_SECRET"),
)
token := oauth1.NewToken(
os.Getenv("ACCESS_TOKEN"),
os.Getenv("ACCESS_TOKEN_SECRET"),
)
// Create a http client with oauth 1.0a method
httpClient := config.Client(oauth1.NoContext, token)
// Create the client to access twitter api methods(endpoints)
client := twitter.NewClient(httpClient)
//...
daysToVacation := getDaysRemaining(vacationDateFormatted)
messageToTweet, err := generateMessageToTweet(daysToVacation)
if err != nil {
log.Fatal(err)
}
// Method to publish a tweet
client.Statuses.Update(messageToTweet, nil)
}
3. Create the Lambda Function
At the time I only knew the concept about lambda functions so it would be one more tech that I would learn with this simple project.
Let's create lambda function.
- Choose
Author from scratch
. - Put the name of your bot.
- Select the language and architecture.
Now, to work with Lambda using go, we have to change the code a little bit and use this official aws tool.
So we import the package, rename main
function to Handler
and create a new main
that will execute the .Start()
method, of aws tool.
The Handler
function is method that manipulate the events. The main
function is required, is the entry point where aws lambda will run our code.
package main
import (
// ...
// Import the package
"github.com/aws/aws-lambda-go/lambda"
)
type DaysRemaining int
func main() {
// The `main` should start the Handler function
lambda.Start(Handler)
}
// Out function that contains the logic
func Handler() {
VACATION_DATE := "2023/06/29 23:00:00 -03"
config := oauth1.NewConfig(
os.Getenv("API_KEY"),
os.Getenv("API_KEY_SECRET"),
)
// ...
}
If you want developing something more complexity, with multiply events and features, you can access the event name and work with context in Handler function, see more.
After finishing the code, don't forget of upload the code to AWS lambda, either by uploading the .zip file or by configuring an s3 bucket, and add the twitter keys in the environment variables (Configuration
> Environment variables
).
4. Running every day
Someone once told me that
"Developers are the laziest, because they want to automate everything"
Sice obviously I won't execute manually the lambda every day, we can use the AWS CloudWatch Events to trigger the function at the specific time.
- Select
EventBridge (CloudWatch Events)
. - Check
Create a new rule
. - Check
Schedule Expression
. - Put the cron expressions.
For my bot I use this cron cron(00 09 ? * * *)
, It will run every day at 09:00 UTC, that is, 06:00 in GTM-3.
If when creating your lambda function, you kept these configs checked (the default configs):
Permissions
>Change default execution role
>Create a new role with basic Lambda permissions
. You won't have to worry with the IAM role for lambda access the cloud watch, the AWS already create the role for you, lambda permissions.
That's it, see the bot perfil in twitter.
Hope you are enjoying.
Follow me on social networks:
Posted on July 6, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.