...
 
Commits (3)
......@@ -38,18 +38,18 @@ lazy val root = (project in file("."))
"ch.qos.logback" % "logback-classic" % "1.2.3",
// Http client
"com.softwaremill.sttp" %% "core" % "1.5.8",
"com.softwaremill.sttp" %% "core" % "1.5.11",
// xml and json
"org.scala-lang.modules" %% "scala-xml" % "1.1.1",
"org.json4s" %% "json4s-native" % "3.6.4",
"org.json4s" %% "json4s-native" % "3.6.5",
// AWS
"com.amazonaws" % "aws-java-sdk-dynamodb" % "1.11.492",
"com.amazonaws" % "aws-java-sdk-sns" % "1.11.492",
"com.amazonaws" % "aws-java-sdk-lambda" % "1.11.492",
"com.amazonaws" % "aws-java-sdk-elasticsearch" % "1.11.492",
"com.amazonaws" % "aws-java-sdk-api-gateway" % "1.11.492",
"com.amazonaws" % "aws-java-sdk-dynamodb" % "1.11.507",
"com.amazonaws" % "aws-java-sdk-sns" % "1.11.507",
"com.amazonaws" % "aws-java-sdk-lambda" % "1.11.507",
"com.amazonaws" % "aws-java-sdk-elasticsearch" % "1.11.507",
"com.amazonaws" % "aws-java-sdk-api-gateway" % "1.11.507",
"com.amazonaws" % "aws-lambda-java-events" % "2.2.5",
"com.amazonaws" % "aws-lambda-java-core" % "1.2.0",
......
libraryDependencies ++= Seq(
// AWS
"com.amazonaws" % "aws-java-sdk-dynamodb" % "1.11.492",
"com.amazonaws" % "aws-java-sdk-elasticsearch" % "1.11.492",
"com.amazonaws" % "aws-java-sdk-ecs" % "1.11.492",
"com.amazonaws" % "aws-java-sdk-ec2" % "1.11.492",
"com.amazonaws" % "aws-java-sdk-lambda" % "1.11.492",
"com.amazonaws" % "aws-java-sdk-dynamodb" % "1.11.507",
"com.amazonaws" % "aws-java-sdk-elasticsearch" % "1.11.507",
"com.amazonaws" % "aws-java-sdk-ecs" % "1.11.507",
"com.amazonaws" % "aws-java-sdk-ec2" % "1.11.507",
"com.amazonaws" % "aws-java-sdk-lambda" % "1.11.507",
// ElasticSearch
"com.sksamuel.elastic4s" % "elastic4s-core_2.12" % "6.3.8",
......
......@@ -48,10 +48,10 @@ functions:
reservedConcurrency: 1 # Only one instance may run at a time
iamRoleStatementsInherit: true
events:
# Monday to Friday - once at 3am
- schedule:
enabled: ${self:custom.scheduleEnabled.${opt:stage}, self:custom.scheduleEnabled.other}
rate: cron(0 3 ? * MON-FRI *)
# Monday to Friday - once at 3am
- schedule:
enabled: ${self:custom.scheduleEnabled.${self:provider.stage}, self:custom.scheduleEnabled.other}
rate: cron(0 3 ? * MON-FRI *)
ScheduledPlannedTimetableFetchWorker:
handler: de.codecentric.amuttsch.bahndelayinfo.aws.lambda.ScheduledPlannedTimetableFetchWorker::handleRequest
reservedConcurrency: 1 # Only one instance may run at a time
......@@ -63,8 +63,8 @@ functions:
#- schedule: cron(0/2 5-10 ? * MON-FRI *)
#- schedule: cron(0/2 14-19 ? * MON-FRI *)
- schedule:
enabled: ${self:custom.scheduleEnabled.${opt:stage}, self:custom.scheduleEnabled.other}
rate: cron(0/1 5-19 ? * MON-FRI *)
enabled: ${self:custom.scheduleEnabled.${self:provider.stage}, self:custom.scheduleEnabled.other}
rate: cron(0/1 5-19 ? * MON-FRI *)
SlackChangeReporter:
handler: de.codecentric.amuttsch.bahndelayinfo.aws.lambda.SNSChangeSlackReporter::handleRequest
reservedConcurrency: 1 # Only one instance may run at a time
......@@ -75,35 +75,35 @@ functions:
iamRoleStatementsInherit: true
timeout: 30
events:
- schedule:
enabled: ${self:custom.scheduleEnabled.${opt:stage}, self:custom.scheduleEnabled.other}
rate: cron(0/2 6-18 ? * MON-FRI *)
- http:
path: slack/event
method: post
- schedule:
enabled: ${self:custom.scheduleEnabled.${self:provider.stage}, self:custom.scheduleEnabled.other}
rate: cron(0/2 6-18 ? * MON-FRI *)
- http:
path: slack/event
method: post
APISlackBotEventHandlerWorker:
handler: de.codecentric.amuttsch.bahndelayinfo.aws.lambda.APISlackBotEventHandlerWorker::handleRequest
reservedConcurrency: 1 # Only one instance may run at a time
events:
- schedule:
enabled: ${self:custom.scheduleEnabled.${opt:stage}, self:custom.scheduleEnabled.other}
rate: cron(0/2 6-18 ? * MON-FRI *)
- schedule:
enabled: ${self:custom.scheduleEnabled.${self:provider.stage}, self:custom.scheduleEnabled.other}
rate: cron(0/2 6-18 ? * MON-FRI *)
APIStationQuery:
handler: de.codecentric.amuttsch.bahndelayinfo.aws.lambda.APIStationQuery::handleRequest
iamRoleStatementsInherit: true
timeout: 30
events:
- http:
path: stations
method: get
- http:
path: stations
method: get
APIGraphQLHandler:
handler: de.codecentric.amuttsch.bahndelayinfo.aws.lambda.APIGraphQLHandler::handleRequest
iamRoleStatementsInherit: true
timeout: 30
events:
- http:
path: graphql
method: post
- http:
path: graphql
method: post
resources:
Resources:
......@@ -112,31 +112,31 @@ resources:
Properties:
TableName: ${self:service}-${self:provider.stage}-Stations
AttributeDefinitions:
- AttributeName: eva
AttributeType: N
- AttributeName: name
AttributeType: S
- AttributeName: eva
AttributeType: N
- AttributeName: name
AttributeType: S
KeySchema:
- AttributeName: eva
KeyType: HASH
- AttributeName: eva
KeyType: HASH
BillingMode: PAY_PER_REQUEST
GlobalSecondaryIndexes:
- IndexName: NameIndex
KeySchema:
- AttributeName: name
KeyType: HASH
Projection:
ProjectionType: ALL
- IndexName: NameIndex
KeySchema:
- AttributeName: name
KeyType: HASH
Projection:
ProjectionType: ALL
TimeTableStopTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: ${self:service}-${self:provider.stage}-TimetableStops
AttributeDefinitions:
- AttributeName: id
AttributeType: S
- AttributeName: id
AttributeType: S
KeySchema:
- AttributeName: id
KeyType: HASH
- AttributeName: id
KeyType: HASH
TimeToLiveSpecification:
AttributeName: ttl
Enabled: true
......@@ -146,11 +146,11 @@ resources:
Properties:
TableName: ${self:service}-${self:provider.stage}-PlannedTimetables
AttributeDefinitions:
- AttributeName: eva
AttributeType: S
- AttributeName: eva
AttributeType: S
KeySchema:
- AttributeName: eva
KeyType: HASH
- AttributeName: eva
KeyType: HASH
TimeToLiveSpecification:
AttributeName: ttl
Enabled: true
......@@ -160,11 +160,11 @@ resources:
Properties:
TableName: ${self:service}-${self:provider.stage}-SlackUsers
AttributeDefinitions:
- AttributeName: id
AttributeType: S
- AttributeName: id
AttributeType: S
KeySchema:
- AttributeName: id
KeyType: HASH
- AttributeName: id
KeyType: HASH
TimeToLiveSpecification:
AttributeName: ttl
Enabled: true
......@@ -187,10 +187,10 @@ resources:
AccessPolicies:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Principal:
AWS: "*"
Action: "es:*"
Resource: "*"
- Effect: "Allow"
Principal:
AWS: "*"
Action: "es:*"
Resource: "*"
AdvancedOptions:
rest.action.multi.allow_explicit_index: "true"
\ No newline at end of file
......@@ -8,9 +8,14 @@ import com.amazonaws.services.lambda.runtime.Context
import com.amazonaws.services.lambda.runtime.events.{APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent}
import com.typesafe.scalalogging.Logger
import de.codecentric.amuttsch.bahndelayinfo.aws
import de.codecentric.amuttsch.bahndelayinfo.slackbot.UrlVerification
import org.json4s._
import org.json4s.native.JsonMethods.parse
import org.json4s.native.Serialization.write
import scala.collection.JavaConverters._
import scala.util.{Failure, Success, Try}
class APISlackBotEventHandler {
implicit val logger: Logger = Logger(classOf[APISlackBotEventHandlerWorker])
implicit val jsonFormats: DefaultFormats.type = DefaultFormats
......@@ -21,6 +26,18 @@ class APISlackBotEventHandler {
logger.info(s"Got event ${event.getBody}")
if (event.getBody != null) {
// Handle url verification here
Try(parse(event.getBody)) match {
case Success(json) =>
json \ "type" match {
case JString("url_verification") =>
val urlVerificationMsg = json.extract[UrlVerification]
return urlVerification(urlVerificationMsg)
case _ =>
}
case Failure(_) =>
}
val payloadStr = "payload="
val body = if (event.getBody.startsWith(payloadStr)) {
URLDecoder.decode(event.getBody.substring(payloadStr.length), "UTF-8")
......@@ -37,4 +54,15 @@ class APISlackBotEventHandler {
new APIGatewayProxyResponseEvent()
.withStatusCode(200)
}
def urlVerification(urlVerification: UrlVerification): APIGatewayProxyResponseEvent = {
new APIGatewayProxyResponseEvent()
.withStatusCode(200)
.withBody(urlVerification.challenge)
.withHeaders(
Map(
"Content-type" -> "text/plain"
).asJava
)
}
}
\ No newline at end of file
......@@ -14,7 +14,6 @@ import org.json4s._
import org.json4s.native.JsonMethods._
import org.json4s.native.Serialization.write
import scala.collection.JavaConverters._
import scala.collection.mutable
import scala.util.{Failure, Success, Try}
......@@ -54,9 +53,6 @@ class APISlackBotEventHandlerWorker {
logger.info(compact(render(json)))
json \ "type" match {
case JString("url_verification") =>
val urlVerificationMsg = json.extract[UrlVerification]
urlVerification(urlVerificationMsg)
case JString("event_callback") =>
val eventId = (json \ "event_id").extract[String]
if (seenEvents.contains(eventId)) {
......@@ -90,17 +86,6 @@ class APISlackBotEventHandlerWorker {
}
}
def urlVerification(urlVerification: UrlVerification): APIGatewayProxyResponseEvent = {
new APIGatewayProxyResponseEvent()
.withStatusCode(200)
.withBody(urlVerification.challenge)
.withHeaders(
Map(
"Content-type" -> "text/plain"
).asJava
)
}
def parseInteractiveMessageAction(msg: InteractiveMessage): Unit = {
implicit var slackUser: SlackUser = getOrCreateUser(msg.user.id, msg.channel.id)
......
......@@ -66,7 +66,7 @@ class SNSChangeSlackReporter {
.filter(_.eva == newDelayInformation.eva)
.filter(!_.isHistory)
.filter(_.delayInMinutes > 2)
.cross(slackUserCache.get())
.cross(slackUserCache.get(Unit))
.filter { case (tti, sr) =>
!sr.seenTimetableInformation.contains(tti.id) ||
// Only send messages when time difference is greater than 2 minutes
......