LoginSignup
1
1

More than 3 years have passed since last update.

【Lambda×Kotlin×SendGrid】自分にメール配信する機能を作ってみた

Last updated at Posted at 2019-11-10

1 はじめ

何か自分の欲しい情報を定刻に毎日配信してくれるものはないかな~
そうだ作ろう、という感じでスタート

構成

ざっくり
CloudWatch Eventsで定刻にLambdaを実行
Lambdaはどこからか情報を取得/編集、SendGridで結果をメール配信
image.png

LambdaでKotlinを使用する方法は過去に書いたこの記事を参照
KotlinでAWS Lambdaを書く!

SendGridはクラウドメール配信サービスです。
登録後審査があるのですぐ使用開始!、とはいかないのですがFreeプランもあり良いサービスです。
※私の場合は1営業日ほどで認可されました。
SendGrid

各言語のSDKもあります。
https://github.com/sendgrid/sendgrid-java#usage

何を配信しよう??

とりあえずQiitaの日間トレンドを取得してみようか。
トレンドを取得するAPIはないようなので自分で取得します。

ライブラリにはjsoupとgsonを使用しています。
div[data-hyperapp-app=Trend]の中のattr("data-hyperapp-props")を取得すればトレンドが取ってこれますね。
以前Rubyで同じことをしてる方の記事を見て同じ方法を使わせていただきました。
※こんなやり方をしてるのは実際のページをF12ツールで解析すればあぁ。。とわかります。

Qiita.kt
class Qiita : Source {
    override val connection = QiitaConnection()

    //記事へのURL
    //https://qiita.com/{{name}}/items/{{uid}}
    override val information_list: MutableList<String> = mutableListOf()

    override fun run(): MutableList<String> {
        val documents = connection.getDocumentData()
        this.information_list.add("------ Qiita Daliyトレンド記事 ------${LINE_SEPARATOR}")

        documents?.forEach {
            this.information_list.add("タイトル:${it.node?.title}" + LINE_SEPARATOR)
            this.information_list.add("URL    :https://qiita.com/${it.node?.author?.urlName}/items/${it.node?.uuid}" + LINE_SEPARATOR)
        }

        this.information_list.add("-----------------------------------$LINE_SEPARATOR")
        return this.information_list
    }
}
QiitaConnection.kt

//    const val QiitaDailyTrend = "https://qiita.com/"
class QiitaConnection : Connection(SourceList.QiitaDailyTrend) {

    override fun getDocumentData(): List<Edge>? {
        val element = super.html.select("div[data-hyperapp-app=Trend]")
                                .attr("data-hyperapp-props")

        val data = gson.fromJson(element, DailyTrend::class.java)
        return data.trend?.edges
    }

}

gsonのPOJOの生成には以下のサイトを使用
私はここで作ったソースをIDEなどでKotlinに変換して使いました。
http://www.jsonschema2pojo.org/

余談なのですが、Gradleはこんな感じです。
今回の使うものだけでなく色々役に立つもの詰めてるのでまた使います。
(Java11向けに改造したいですが。。。。)

build.gradle
plugins {
    id 'org.jetbrains.kotlin.jvm' version '1.3.50'
}

ext {
    kotlin_version = "1.3.50"
    spek_version = "2.0.8"
}

group 'kotlinDailyMail'
version '1.0-SNAPSHOT'

repositories {
    mavenCentral()
    jcenter()
}

dependencies {

    implementation group: 'org.jetbrains.kotlin', name: 'kotlin-stdlib-jdk8', version: kotlin_version
    compile 'com.sendgrid:sendgrid-java:4.4.1'
    compile group: 'com.amazonaws', name: 'aws-lambda-java-core', version: '1.2.0'

    //GSON
    compile 'com.google.code.gson:gson:2.8.6'

    //Fuel
    compile 'com.github.kittinunf.fuel:fuel:1.12.0'

    //JSoup
    compile 'org.jsoup:jsoup:1.12.1'


    //JUnit5,Spek2
    testImplementation group: 'org.jetbrains.kotlin', name: 'kotlin-reflect', version: kotlin_version
    testImplementation group: 'org.jetbrains.kotlin', name: 'kotlin-stdlib-jdk8', version: kotlin_version
    testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.3.1'
    testImplementation group: 'org.spekframework.spek2', name: 'spek-dsl-jvm', version: spek_version
    testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.3.1'
    testRuntimeOnly group: 'org.spekframework.spek2', name: 'spek-runner-junit5', version: spek_version
    testImplementation "org.jetbrains.kotlin:kotlin-test"
    testImplementation "org.jetbrains.kotlin:kotlin-test-junit"

    //MockK
    testImplementation "io.mockk:mockk:1.9.3"

}

test {
    useJUnitPlatform {
        includeEngines 'spek2'
    }
}

compileKotlin {
    kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
    kotlinOptions.jvmTarget = "1.8"
}

task buildZip(type: Zip) {
    from compileKotlin
    from processResources
    into("lib") {
        from configurations.runtime
    }
}
build.dependsOn buildZip

一通りコーディングが済んだらLambda関数を作成
環境変数はTZをとりあえず修正
image.png

CloudWatch Eventsでスケジュール式を設定
Lambdaは基本UTCなので時刻を逆算して起動時間を指定する(下記はAM 8:00 に1回起動)
image.png

試しにテスト起動
プログラムで指定したアドレスにメールが届きました。
SendGrid側で証明書の設定とかをしていないと迷惑メールに入ってるかもです。

キャプチャ.PNG

続き

軽い気持ちでQiitaのトレンドを試しに配信するか。
と思ったら結構大変で最適な方法を見つけるのに時間かかりました。(笑)

次は情報の取得先をより増やしたり、一度に取得する情報量を調整しようと思います。

他にも開発にSpek2とか導入していたのでそちらについても記事を書こうか考え中

ちなみにこの配信機能ですが、1円も開発には使ってないです。
日々の定時実行もLambdaの無料枠に余裕で収まります。
※実装中のおやつ代は別

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1