Skip to content

Commit

Permalink
chore: initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
otaviotech committed May 9, 2023
0 parents commit 3f53c9a
Show file tree
Hide file tree
Showing 18 changed files with 1,778 additions and 0 deletions.
47 changes: 47 additions & 0 deletions .github/workflows/cd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: CI

on:
push:
branches:
- main

permissions:
id-token: write
contents: read

env:
AWS_REGION: us-east-1

jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: "1.20"

- name: Install dependencies
run: go get .

- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
with:
role-to-assume: ${{ secret.ROLE_TO_ASSUME }}
role-session-name: samplerolesession
aws-region: ${{ env.AWS_REGION }}

- name: Setup Terraform
uses: hashicorp/setup-terraform@v2
working-directory: deployments/terraform
run: terraform init

- name: Deploy
working-directory: deployments/terraform
run: terraform apply -auto-approve



26 changes: 26 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# If you prefer the allow list template instead of the deny list, see community template:
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
#
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib

# Test binary, built with `go test -c`
*.test

# Output of the go coverage tool, specifically when used with LiteIDE
*.out

# Dependency directories (remove the comment below to include it)
# vendor/

# Go workspace file
go.work

# Compiled artifacts
bin

deployments/terraform/.terraform
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Smiles BOT

## What it does?

It checks the active promotions page to see if any of the promotions meet some (regex) criteria. If so, it notifies the user via email.
57 changes: 57 additions & 0 deletions cmd/lambda/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package main

import (
"context"
"log"
"net/http"
"os"

"github.com/aws/aws-lambda-go/lambda"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/ses"
"github.com/otaviotech/bot-smiles/internal"
)

func run(ctx context.Context, event interface{}) error {
logger := log.Default()

logger.Println("Started crawling.")

c := buildCrawler()

err := c.Crawl(ctx, internal.CrawlInput{
PromotionsURL: os.Getenv("PROMOTIONS_URL"),
UserAgent: os.Getenv("USER_AGENT"),
EmailToNotify: os.Getenv("EMAIL_TO_NOTIFY"),
Regexes: []string{os.Getenv("REGEXES")},
})

if err != nil {
logger.Printf("Error crawling: %s", err.Error())
}

logger.Println("Finished crawling.")

return err
}

func main() {
lambda.Start(run)
}

func buildCrawler() internal.Crawler {
sess, _ := session.NewSession(&aws.Config{
Region: aws.String("us-east-1")},
)

sesClient := ses.New(sess)

sesEmailNotifier := internal.NewSNSEmailNotifier(sesClient)

return internal.NewCrawler(
&http.Client{},
&internal.GoQueryHTMLInspector{},
&sesEmailNotifier,
)
}
62 changes: 62 additions & 0 deletions deployments/terraform/.terraform.lock.hcl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 18 additions & 0 deletions deployments/terraform/event_bridge.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
resource "aws_cloudwatch_event_rule" "lambda_trigger" {
name = "everyday_at_10am_and_16pm"
description = "run everyday at 10am and 16pm (Brasilia time)"
schedule_expression = "cron(0 13,21 * * ? *)"
}

resource "aws_cloudwatch_event_target" "lambda_target" {
arn = aws_lambda_function.function.arn
rule = aws_cloudwatch_event_rule.lambda_trigger.name
}

resource "aws_lambda_permission" "allow_trigger_execution_from_cloudwatch" {
statement_id = "AllowExecutionFromCloudWatch"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.function.function_name
principal = "events.amazonaws.com"
source_arn = aws_cloudwatch_event_rule.lambda_trigger.arn
}
67 changes: 67 additions & 0 deletions deployments/terraform/iam.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
resource "aws_iam_role" "lambda" {
name = "AssumeLambdaRole"
description = "Role for lambda to assume lambda"
assume_role_policy = data.aws_iam_policy_document.assume_lambda_role.json
}

data "aws_iam_policy_document" "allow_lambda_logging" {
statement {
effect = "Allow"
actions = [
"logs:CreateLogStream",
"logs:PutLogEvents",
]

resources = [
"arn:aws:logs:*:*:*",
]
}
}

data "aws_iam_policy_document" "allow_lambda_send_email" {
statement {
effect = "Allow"
actions = [
"ses:SendEmail",
"ses:SendRawEmail"
]

resources = [
"*",
]
}
}

data "aws_iam_policy_document" "assume_lambda_role" {
statement {
actions = ["sts:AssumeRole"]

principals {
type = "Service"
identifiers = ["lambda.amazonaws.com"]
}
}
}

resource "aws_iam_policy" "function_logging_policy" {
name = "AllowLambdaLoggingPolicy"
description = "Policy for lambda cloudwatch logging"
policy = data.aws_iam_policy_document.allow_lambda_logging.json
}

resource "aws_iam_policy" "function_ses_policy" {
name = "AllowLambdaSESPolicy"
description = "Policy for lambda to use SES"
policy = data.aws_iam_policy_document.allow_lambda_send_email.json
}

resource "aws_iam_role_policy_attachment" "lambda_logging_policy_attachment" {
role = aws_iam_role.lambda.id
policy_arn = aws_iam_policy.function_logging_policy.arn
}

resource "aws_iam_role_policy_attachment" "lambda_ses_policy_attachment" {
role = aws_iam_role.lambda.id
policy_arn = aws_iam_policy.function_ses_policy.arn
}

47 changes: 47 additions & 0 deletions deployments/terraform/lambda.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
resource "null_resource" "function_binary" {
triggers = {
always_run = "${timestamp()}"
}

provisioner "local-exec" {
command = "go build -o ${local.binary_path} ${local.src_path}"
environment = {
GOOS = "linux"
GOARCH = "amd64"
}
}
}

data "archive_file" "function_archive" {
depends_on = [null_resource.function_binary]
type = "zip"
source_file = local.binary_path
output_path = local.archive_path
}

resource "aws_lambda_function" "function" {
function_name = "bot-smiles"
description = "Smiles bot"
role = aws_iam_role.lambda.arn
handler = local.binary_name
memory_size = 128

filename = local.archive_path
source_code_hash = data.archive_file.function_archive.output_base64sha256

runtime = "go1.x"

environment {
variables = {
PROMOTIONS_URL = "https://smiles.com.br/promocao"
USER_AGENT = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36"
EMAIL_TO_NOTIFY = "otaviotech@gmail.com"
REGEXES = "^Transferir\\sPontos$"
}
}
}

resource "aws_cloudwatch_log_group" "log_group" {
name = "/aws/lambda/${aws_lambda_function.function.function_name}"
retention_in_days = 7
}
6 changes: 6 additions & 0 deletions deployments/terraform/locals.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
locals {
binary_path = "../../bin/bot-smiles"
archive_path = "../../bin/bot-smiles.zip"
src_path = "../../cmd/lambda/main.go"
binary_name = "bot-smiles"
}
25 changes: 25 additions & 0 deletions deployments/terraform/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
}
archive = {
source = "hashicorp/archive"
}
null = {
source = "hashicorp/null"
}
}

required_version = ">= 1.3.7"
}

provider "aws" {
region = "us-east-1"

default_tags {
tags = {
app = "bot-smiles"
}
}
}
Loading

0 comments on commit 3f53c9a

Please sign in to comment.