From b5917d92af4fec6c700ab340d273e0e52789ea4c Mon Sep 17 00:00:00 2001 From: Pavel Kachalouski Date: Sun, 27 Oct 2019 20:39:50 +0100 Subject: [PATCH] Added comment to the parcel --- build.sbt | 6 +- project/Dependencies.scala | 34 +- project/plugins.sbt | 4 +- .../eu/xeppaka/bot/CheckDeliveryDialog.scala | 24 +- .../xeppaka/bot/CzechPostDeliveryCheck.scala | 29 +- .../scala/eu/xeppaka/bot/DialogManager.scala | 2 +- .../scala/eu/xeppaka/bot/TelegramBot.scala | 9 +- .../eu/xeppaka/bot/TelegramEntities.scala | 313 ------------------ .../bot/TelegramEntitiesDerivations.scala | 24 -- 9 files changed, 57 insertions(+), 388 deletions(-) delete mode 100644 src/main/scala/eu/xeppaka/bot/TelegramEntities.scala delete mode 100644 src/main/scala/eu/xeppaka/bot/TelegramEntitiesDerivations.scala diff --git a/build.sbt b/build.sbt index f7a94e1..7546973 100644 --- a/build.sbt +++ b/build.sbt @@ -2,8 +2,7 @@ import Dependencies._ lazy val commonSettings = Seq( organization := "com.example", - scalaVersion := "2.12.8", - version := "1.0.0", + scalaVersion := "2.13.1", mainClass := Some("eu.xeppaka.bot.Main") ) @@ -23,7 +22,8 @@ lazy val `telegram-bot-delivery` = (project in file(".")) circleCore, circleGeneric, circleParser, - circeAkkaHttp + circeAkkaHttp, + slibTelegram ), dockerBaseImage := "openjdk:13-jdk-oracle", dockerExposedPorts := Seq(8443), diff --git a/project/Dependencies.scala b/project/Dependencies.scala index c0cc943..8994f2f 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -4,23 +4,25 @@ import Dependencies.Versions._ object Dependencies { object Versions { - val akkaVersion = "2.5.22" - val akkaHttpVersion = "10.1.8" + val akkaVersion = "2.5.26" + val akkaHttpVersion = "10.1.10" val levelDbJniVersion = "1.8" - val circeVersion = "0.11.1" - val akkaHttpCirceVersion = "1.23.0" - val scalaTestVersion = "3.0.5" + val circeVersion = "0.12.3" + val akkaHttpCirceVersion = "1.29.1" + val scalaTestVersion = "3.2.0-M1" + val slibTelegramVersion = "0.1.0" } - lazy val akka = "com.typesafe.akka" %% "akka-actor" % akkaVersion - lazy val akkaTyped = "com.typesafe.akka" %% "akka-actor-typed" % akkaVersion - lazy val akkaStream = "com.typesafe.akka" %% "akka-stream" % akkaVersion - lazy val akkaHttp = "com.typesafe.akka" %% "akka-http" % akkaHttpVersion - lazy val akkaPersistence = "com.typesafe.akka" %% "akka-persistence-typed" % akkaVersion - lazy val levelDbJni = "org.fusesource.leveldbjni" % "leveldbjni-all" % levelDbJniVersion - lazy val circleCore = "io.circe" %% "circe-core" % circeVersion - lazy val circleGeneric = "io.circe" %% "circe-generic" % circeVersion - lazy val circleParser = "io.circe" %% "circe-parser" % circeVersion - lazy val circeAkkaHttp = "de.heikoseeberger" %% "akka-http-circe" % akkaHttpCirceVersion - lazy val scalaTest = "org.scalatest" %% "scalatest" % scalaTestVersion + val akka = "com.typesafe.akka" %% "akka-actor" % akkaVersion + val akkaTyped = "com.typesafe.akka" %% "akka-actor-typed" % akkaVersion + val akkaStream = "com.typesafe.akka" %% "akka-stream" % akkaVersion + val akkaHttp = "com.typesafe.akka" %% "akka-http" % akkaHttpVersion + val akkaPersistence = "com.typesafe.akka" %% "akka-persistence-typed" % akkaVersion + val levelDbJni = "org.fusesource.leveldbjni" % "leveldbjni-all" % levelDbJniVersion + val circleCore = "io.circe" %% "circe-core" % circeVersion + val circleGeneric = "io.circe" %% "circe-generic" % circeVersion + val circleParser = "io.circe" %% "circe-parser" % circeVersion + val circeAkkaHttp = "de.heikoseeberger" %% "akka-http-circe" % akkaHttpCirceVersion + val slibTelegram = "eu.xeppaka" %% "slib-telegram" % slibTelegramVersion + val scalaTest = "org.scalatest" %% "scalatest" % scalaTestVersion } diff --git a/project/plugins.sbt b/project/plugins.sbt index cc632f7..f9199c9 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,2 +1,2 @@ -addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.6") -addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.3.21") \ No newline at end of file +addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.4.1") +addSbtPlugin("com.github.gseitz" % "sbt-release" % "1.0.12") diff --git a/src/main/scala/eu/xeppaka/bot/CheckDeliveryDialog.scala b/src/main/scala/eu/xeppaka/bot/CheckDeliveryDialog.scala index ce56984..ceb630a 100644 --- a/src/main/scala/eu/xeppaka/bot/CheckDeliveryDialog.scala +++ b/src/main/scala/eu/xeppaka/bot/CheckDeliveryDialog.scala @@ -8,8 +8,7 @@ import akka.http.scaladsl.model._ import akka.stream.ActorMaterializer import akka.stream.scaladsl.{Sink, Source} import akka.util.{ByteString, Timeout} -import eu.xeppaka.bot.TelegramEntities._ -import eu.xeppaka.bot.TelegramEntitiesDerivations._ +import eu.xeppaka.telegram.bot.TelegramEntities._ import io.circe.Printer import scala.concurrent.ExecutionContext @@ -60,9 +59,9 @@ object CheckDeliveryDialog { private val removeKeyboard = Some(ReplyKeyboardRemove()) def behavior(chatId: Long, botUri: BotUri): Behavior[Command] = Behaviors.setup[Command] { ctx => - implicit val materializer: ActorMaterializer = ActorMaterializer()(ctx.system.toUntyped) + implicit val materializer: ActorMaterializer = ActorMaterializer()(ctx.system.toClassic) implicit val executionContext: ExecutionContext = ctx.system.dispatchers.lookup(DispatcherSelector.default()) - val http = Http()(ctx.system.toUntyped) + val http = Http()(ctx.system.toClassic) val stashBuffer = StashBuffer[Command](100) val deliveryStateAdapter: ActorRef[CzechPostDeliveryCheck.DeliveryStateChanged] = ctx.messageAdapter(stateChanged => DeliveryStateChanged(stateChanged.state)) val czechPostDeliveryCheck = ctx.spawnAnonymous(Behaviors.supervise(CzechPostDeliveryCheck.behavior(chatId.toString, deliveryStateAdapter)).onFailure(SupervisorStrategy.restart)) @@ -80,8 +79,9 @@ object CheckDeliveryDialog { sendMessage(message, waitCommand, waitCommand) } case AddParcel => - val message = SendMessage(chatId, "Please enter a parcel ID.", reply_markup = removeKeyboard) - sendMessage(message, waitParcelId(parcelId => addParcel(parcelId)), waitCommand) + val parcelIdMessage = SendMessage(chatId, "Please enter a parcel ID.", reply_markup = removeKeyboard) + val commentMessage = SendMessage(chatId, "Please enter a comment.", reply_markup = removeKeyboard) + sendMessage(parcelIdMessage, waitTextMessage(parcelId => sendMessage(commentMessage, waitTextMessage(comment => addParcel(parcelId, comment)), waitCommand)), waitCommand) case RemoveParcel => removeParcel(waitCommand, waitCommand) case ListParcels => @@ -96,12 +96,12 @@ object CheckDeliveryDialog { Behaviors.unhandled } - def addParcel(parcelId: String): Behavior[Command] = Behaviors.setup { ctx => + def addParcel(parcelId: String, comment: String): Behavior[Command] = Behaviors.setup { ctx => case object AddParcelSuccess extends Command case class AddParcelFailure(exception: Throwable) extends Command implicit val timeout: Timeout = 5.seconds - ctx.ask[CzechPostDeliveryCheck.Command, CzechPostDeliveryCheck.CommandResult](czechPostDeliveryCheck)(ref => CzechPostDeliveryCheck.AddParcel(parcelId, ref)) { + ctx.ask[CzechPostDeliveryCheck.Command, CzechPostDeliveryCheck.CommandResult](czechPostDeliveryCheck)(ref => CzechPostDeliveryCheck.AddParcel(parcelId, comment, ref)) { case Success(CzechPostDeliveryCheck.CommandResultSuccess) => AddParcelSuccess case Success(CzechPostDeliveryCheck.CommandResultFailure(exception)) => AddParcelFailure(exception) case Failure(exception) => AddParcelFailure(exception) @@ -169,7 +169,7 @@ object CheckDeliveryDialog { val keyboardButtons = parcelsList.toSeq.sorted.grouped(3).map(_.map(id => KeyboardButton(id))).toSeq val markup = ReplyKeyboardMarkup(keyboard = keyboardButtons, resize_keyboard = Some(true), one_time_keyboard = Some(true)) val message = SendMessage(chatId, "Please enter a parcel id to remove.", reply_markup = Some(markup)) - sendMessage(message, waitParcelId(parcelId => removeParcelId(parcelId)), onFailure) + sendMessage(message, waitTextMessage(parcelId => removeParcelId(parcelId)), onFailure) } else { val message = SendMessage(chatId, "You don't have watched parcels. There is nothing to remove.", reply_markup = commandsKeyboard) sendMessage(message, onSuccess, onFailure) @@ -225,7 +225,7 @@ object CheckDeliveryDialog { // sendMessage(message, waitParcelId(parcelId => addParcel(parcelId)), waitCommand) // } - def waitParcelId(onFinish: String => Behavior[Command]): Behavior[Command] = Behaviors.receiveMessage { + def waitTextMessage(onFinish: String => Behavior[Command]): Behavior[Command] = Behaviors.receiveMessage { case ProcessMessage(msg, replyTo) => if (msg.text.isDefined) { val parcelId = msg.text.get @@ -233,7 +233,7 @@ object CheckDeliveryDialog { onFinish(parcelId) } else { replyTo ! ProcessMessageSuccess - waitParcelId(onFinish) + waitTextMessage(onFinish) } case otherMsg => stashBuffer.stash(otherMsg) @@ -247,7 +247,7 @@ object CheckDeliveryDialog { case object SendMessageSuccess extends Command case class SendMessageFailure(exception: Throwable) extends Command - val json = printer.pretty(message.asJson) + val json = printer.print(message.asJson) val request = HttpRequest(HttpMethods.POST, uri = botUri.sendMessage, entity = HttpEntity.Strict(ContentTypes.`application/json`, ByteString(json))) ctx.log.debug("action=send_message status=started chat_id={} message={}", chatId, json) diff --git a/src/main/scala/eu/xeppaka/bot/CzechPostDeliveryCheck.scala b/src/main/scala/eu/xeppaka/bot/CzechPostDeliveryCheck.scala index 74b156c..2250d52 100644 --- a/src/main/scala/eu/xeppaka/bot/CzechPostDeliveryCheck.scala +++ b/src/main/scala/eu/xeppaka/bot/CzechPostDeliveryCheck.scala @@ -60,7 +60,7 @@ object CzechPostDeliveryCheck { sealed trait Command sealed trait CommandResult sealed trait Event - case class ParcelState(attributes: Option[Entities.Attributes] = None, states: Set[Entities.State] = Set.empty) { + case class ParcelState(comment: String, attributes: Option[Entities.Attributes] = None, states: Set[Entities.State] = Set.empty) { def prettyPrint(parcelId: String): String = { val statesString = states .toSeq @@ -68,14 +68,14 @@ object CzechPostDeliveryCheck { .map(state => s"${printDateFormat.format(czechPostDateFormat.parse(state.date))} - ${state.text}\n===========================\n") .mkString - s"""|*New state(s) of the parcel $parcelId:* + s"""|*New state(s) of the parcel $parcelId ($comment):* |=========================== |$statesString""".stripMargin } } case class State(parcelStates: Map[String, ParcelState] = Map.empty) - case class AddParcel(parcelId: String, replyTo: ActorRef[CommandResult]) extends Command + case class AddParcel(parcelId: String, comment: String, replyTo: ActorRef[CommandResult]) extends Command case class RemoveParcel(parcelId: String, replyTo: ActorRef[CommandResult]) extends Command case class ListParcels(replyTo: ActorRef[ListParcelsResult]) extends Command case class ListParcelsResult(parcelsList: Set[String]) @@ -91,7 +91,7 @@ object CzechPostDeliveryCheck { private case class ParcelHistoryRetrieved(parcelHistory: Entities.ParcelHistory) extends Command case class DeliveryStateChanged(state: String) - case class ParcelAdded(parcelId: String) extends Event + case class ParcelAdded(parcelId: String, comment: String) extends Event case class ParcelRemoved(parcelId: String) extends Event case class ParcelHistoryStateAdded(parcelId: String, state: Entities.State) extends Event case class ParcelAttributesChanged(parcelId: String, attributes: Entities.Attributes) extends Event @@ -137,7 +137,7 @@ object CzechPostDeliveryCheck { val commandHandler: CommandHandler[Command, Event, State] = (state, cmd) => { cmd match { - case AddParcel(parcelId, replyTo) => + case AddParcel(parcelId, comment, replyTo) => val parcelIdUpper = parcelId.toUpperCase if (state.parcelStates.keySet.contains(parcelIdUpper)) { Effect @@ -145,7 +145,7 @@ object CzechPostDeliveryCheck { .thenRun(_ => replyTo ! CommandResultFailure(DuplicateParcelId(parcelIdUpper))) } else { Effect - .persist(ParcelAdded(parcelIdUpper)) + .persist(ParcelAdded(parcelIdUpper, comment)) .thenRun(_ => { replyTo ! CommandResultSuccess ctx.self ! CheckParcels @@ -205,21 +205,25 @@ object CzechPostDeliveryCheck { case ParcelHistoryRetrieved(parcelHistory) => val parcelId = parcelHistory.id val parcelState = state.parcelStates(parcelId) - val attributesChangedEvent = (if (parcelState.attributes.isEmpty) + val attributesChangedEvents: Seq[Event] = (if (parcelState.attributes.isEmpty) Some(parcelHistory.attributes) else parcelState.attributes .flatMap(oldAttributes => if (oldAttributes != parcelHistory.attributes) Some(parcelHistory.attributes) else None)) - .map(attributes => ParcelAttributesChanged(parcelId, attributes)).to[collection.immutable.Seq] + .map(attributes => ParcelAttributesChanged(parcelId, attributes)) + .toSeq val newStates = parcelHistory.states.state.toSet -- parcelState.states - val stateEvents: Seq[Event] = newStates.map(state => ParcelHistoryStateAdded(parcelId, state)).to[collection.immutable.Seq] + val stateEvents: Seq[Event] = newStates + .map(state => ParcelHistoryStateAdded(parcelId, state)) + .toSeq + val comment = state.parcelStates(parcelId).comment Effect - .persist(attributesChangedEvent ++ stateEvents) + .persist(attributesChangedEvents ++ stateEvents) .thenRun(_ => { if (newStates.nonEmpty) { - stateReporter ! DeliveryStateChanged(ParcelState(None, newStates).prettyPrint(parcelId)) + stateReporter ! DeliveryStateChanged(ParcelState(comment, None, newStates).prettyPrint(parcelId)) } }) } @@ -227,7 +231,8 @@ object CzechPostDeliveryCheck { val eventHandler: EventHandler[State, Event] = (state, evt) => { evt match { - case ParcelAdded(parcelId) => state.copy(parcelStates = state.parcelStates + (parcelId -> ParcelState())) + case ParcelAdded(parcelId, comment) => + state.copy(parcelStates = state.parcelStates + (parcelId -> ParcelState(comment))) case ParcelRemoved(parcelId) => state.copy(parcelStates = state.parcelStates - parcelId) case ParcelHistoryStateAdded(parcelId, newState) => val parcelState = state.parcelStates(parcelId) diff --git a/src/main/scala/eu/xeppaka/bot/DialogManager.scala b/src/main/scala/eu/xeppaka/bot/DialogManager.scala index 65e7f32..7295dc1 100644 --- a/src/main/scala/eu/xeppaka/bot/DialogManager.scala +++ b/src/main/scala/eu/xeppaka/bot/DialogManager.scala @@ -7,7 +7,7 @@ import akka.persistence.typed.scaladsl.EventSourcedBehavior.{CommandHandler, Eve import akka.persistence.typed.scaladsl.{Effect, EffectBuilder, EventSourcedBehavior} import akka.util.Timeout import eu.xeppaka.bot.CheckDeliveryDialog.{ProcessMessageFailure, ProcessMessageSuccess} -import eu.xeppaka.bot.TelegramEntities.Update +import eu.xeppaka.telegram.bot.TelegramEntities._ import scala.concurrent.duration._ import scala.util.{Failure, Success} diff --git a/src/main/scala/eu/xeppaka/bot/TelegramBot.scala b/src/main/scala/eu/xeppaka/bot/TelegramBot.scala index 751af3c..6a1010a 100644 --- a/src/main/scala/eu/xeppaka/bot/TelegramBot.scala +++ b/src/main/scala/eu/xeppaka/bot/TelegramBot.scala @@ -1,15 +1,14 @@ package eu.xeppaka.bot import java.io.InputStream -import java.nio.file.Path import java.security.{KeyStore, SecureRandom} import java.util.UUID import akka.Done -import akka.actor.{ActorSystem, Scheduler} import akka.actor.typed.scaladsl.adapter._ import akka.actor.typed.scaladsl.{Behaviors, StashBuffer} import akka.actor.typed.{ActorRef, Behavior, DispatcherSelector, SupervisorStrategy} +import akka.actor.{ActorSystem, Scheduler} import akka.http.scaladsl.marshalling.Marshal import akka.http.scaladsl.model._ import akka.http.scaladsl.server.Directives.{as, complete, entity, extractLog, onComplete, path, post} @@ -17,11 +16,11 @@ import akka.http.scaladsl.server.Route import akka.http.scaladsl.{ConnectionContext, Http, HttpExt, HttpsConnectionContext} import akka.stream.ActorMaterializer import akka.util.{ByteString, Timeout} -import eu.xeppaka.bot.TelegramEntities._ +import eu.xeppaka.telegram.bot.TelegramEntities._ import javax.net.ssl.{KeyManagerFactory, SSLContext, TrustManagerFactory} import scala.collection.immutable -import scala.concurrent.{ExecutionContextExecutor, Future} +import scala.concurrent.ExecutionContextExecutor import scala.concurrent.duration._ import scala.io.Source import scala.util.{Failure, Success} @@ -38,7 +37,7 @@ object TelegramBot { def behavior(botId: String, interface: String, localPort: Int, hookDomain: String, hookPort: Int, useHttpsServer: Boolean = true): Behavior[Command] = Behaviors.setup[Command] { ctx => ctx.log.info("action=start_bot") - implicit val untypedSystem: ActorSystem = ctx.system.toUntyped + implicit val untypedSystem: ActorSystem = ctx.system.toClassic implicit val actorMaterializer: ActorMaterializer = ActorMaterializer() implicit val executionContextExecutor: ExecutionContextExecutor = ctx.system.dispatchers.lookup(DispatcherSelector.default()) diff --git a/src/main/scala/eu/xeppaka/bot/TelegramEntities.scala b/src/main/scala/eu/xeppaka/bot/TelegramEntities.scala deleted file mode 100644 index b2075e0..0000000 --- a/src/main/scala/eu/xeppaka/bot/TelegramEntities.scala +++ /dev/null @@ -1,313 +0,0 @@ -package eu.xeppaka.bot - -object TelegramEntities { - - case class Response[T](ok: Boolean, - description: Option[String] = None, - error_code: Option[Int] = None, - result: T - ) - - case class GetMe(id: Int, is_bot: Boolean, first_name: String, username: String) - - case class KeyboardButton(text: String, - request_contact: Option[Boolean] = None, - request_location: Option[Boolean] = None - ) - - case class InlineKeyboardButton(text: String, - url: Option[String] = None, - callback_data: Option[String] = None, - switch_inline_query: Option[String] = None, - switch_inline_query_current_chat: Option[String] = None, - callback_game: Option[String] = None, - pay: Option[Boolean] = None - ) - - sealed trait ReplyMarkup - - case class ReplyKeyboardRemove(remove_keyboard: Boolean = true, selective: Option[Boolean] = None) extends ReplyMarkup - - case class ReplyKeyboardMarkup(keyboard: Seq[Seq[KeyboardButton]], - resize_keyboard: Option[Boolean] = None, - one_time_keyboard: Option[Boolean] = None, - selective: Option[Boolean] = None - ) extends ReplyMarkup - - case class InlineKeyboardMarkup(inline_keyboard: Seq[Seq[InlineKeyboardButton]]) - extends ReplyMarkup - - case class ForceReply(force_reply: Boolean = true, selective: Option[Boolean] = None) extends ReplyMarkup - - case class InlineQuery(id: String, - from: User, - location: Location, - query: String, - offset: String - ) - - case class Location(longitude: Float, - latitude: Float - ) - - case class Update(update_id: Int, - message: Option[Message] = None, - edited_message: Option[Message] = None, - channel_post: Option[Message] = None, - edited_channel_post: Option[Message] = None, - inline_query: Option[InlineQuery] = None, - chosen_inline_result: Option[ChosenInlineResult] = None, - callback_query: Option[CallbackQuery] = None, - shipping_query: Option[ShippingQuery] = None, - pre_checkout_query: Option[PreCheckoutQuery] = None - ) - - case class ChosenInlineResult(result_id: String, - from: User, - location: Option[Location] = None, - inline_message_id: Option[String] = None, - query: String - ) - - case class CallbackQuery(id: String, - from: User, - message: Option[Message] = None, - inline_message_id: Option[String] = None, - chat_instance: String, - data: Option[String] = None, - game_short_name: Option[String] = None - ) - - case class ShippingQuery(id: String, - from: User, - invoice_payload: String, - shipping_address: ShippingAddress - ) - - case class ShippingAddress(country_code: String, - state: String, - city: String, - street_line1: String, - street_line2: String, - post_code: String - ) - - case class PreCheckoutQuery(id: String, - from: User, - currency: String, - total_amount: Int, - invoice_payload: String, - shipping_option_id: Option[String] = None, - order_info: Option[OrderInfo] = None - ) - - case class OrderInfo(name: Option[String] = None, - phone_number: Option[String] = None, - email: Option[String] = None, - shipping_address: Option[ShippingAddress] = None - ) - - case class User(id: Int, - is_bot: Boolean, - first_name: String, - last_name: Option[String] = None, - username: Option[String] = None, - language_code: Option[String] = None - ) - - case class EditMessageReplyMarkup(chat_id: Option[Long], - message_id: Option[Int], - inline_message_id: Option[String], - reply_markup: Option[InlineKeyboardMarkup] - ) - - case class SendMessage(chat_id: Long, - text: String, - parse_mode: Option[String] = None, - disable_web_page_preview: Option[Boolean] = None, - disable_notification: Option[Boolean] = None, - reply_to_message_id: Option[Int] = None, - reply_markup: Option[ReplyMarkup] = None - ) - - case class Message(message_id: Int, - from: Option[User] = None, - date: Int, - chat: Chat, - forward_from: Option[User] = None, - forward_from_chat: Option[User] = None, - forward_from_message_id: Option[Int] = None, - forward_signature: Option[String] = None, - forward_date: Option[Int] = None, - reply_to_message: Option[Message] = None, - edit_date: Option[Int] = None, - media_group_id: Option[String] = None, - author_signature: Option[String] = None, - text: Option[String] = None, - entities: Option[Seq[MessageEntity]] = None, - caption_entities: Option[Seq[MessageEntity]] = None, - audio: Option[Audio] = None, - document: Option[Document] = None, - game: Option[Game] = None, - photo: Option[Seq[PhotoSize]] = None, - sticker: Option[Sticker] = None, - video: Option[Video] = None, - voice: Option[Voice] = None, - video_note: Option[VideoNote] = None, - caption: Option[String] = None, - contact: Option[Contact] = None, - location: Option[Location] = None, - venue: Option[Venue] = None, - new_chat_members: Option[Seq[User]] = None, - left_chat_member: Option[Seq[User]] = None, - new_chat_title: Option[String] = None, - new_chat_photo: Option[Seq[PhotoSize]] = None, - delete_chat_photo: Option[Boolean] = None, - group_chat_created: Option[Boolean] = None, - supergroup_chat_created: Option[Boolean] = None, - channel_chat_created: Option[Boolean] = None, - migrate_to_chat_id: Option[Int] = None, - migrate_from_chat_id: Option[Int] = None, - pinned_message: Option[Message] = None, - invoice: Option[Invoice] = None, - successful_payment: Option[SuccessfulPayment] = None, - connected_website: Option[String] = None - ) - - case class MessageEntity(`type`: String, - offset: Int, - length: Int, - url: Option[String] = None, - user: Option[User] = None - ) - - case class Contact(phone_number: String, - first_name: String, - last_name: Option[String] = None, - user_id: Option[Int] = None - ) - - case class Sticker(file_id: String, - width: Int, - height: Int, - thumb: Option[PhotoSize] = None, - emoji: Option[String] = None, - set_name: Option[String] = None, - mask_position: Option[String] = None, - file_size: Option[Int] = None - ) - - case class Video(file_id: String, - width: Int, - height: Int, - duration: Int, - thumb: Option[PhotoSize] = None, - mime_type: Option[String] = None, - file_size: Option[Int] = None - ) - - case class Audio(file_id: String, - duration: Int, - performer: Option[String] = None, - title: Option[String] = None, - mime_type: Option[String] = None, - file_size: Option[Int] = None - ) - - case class Document(file_id: String, - thumb: Option[PhotoSize] = None, - file_name: Option[String] = None, - mime_type: Option[String] = None, - file_size: Option[Int] = None - ) - - case class PhotoSize(file_id: String, - width: Int, - height: Int, - file_size: Option[Int] = None - ) - - case class Voice(file_id: String, - duration: Int, - mime_type: Option[String] = None, - file_size: Option[Int] = None - ) - - case class VideoNote(file_id: String, - length: Int, - duration: Int, - thumb: Option[PhotoSize] = None, - file_size: Option[Int] = None - ) - - case class ChatPhoto(small_file_id: String, big_file_id: String) - - case class Chat(id: Long, - `type`: String, - title: Option[String] = None, - username: Option[String] = None, - first_name: Option[String] = None, - last_name: Option[String] = None, - all_members_are_administrators: Option[Boolean] = None, - photo: Option[ChatPhoto] = None, - description: Option[String] = None, - invite_link: Option[String] = None, - pinned_message: Option[Message] = None, - sticker_set_name: Option[String] = None, - can_set_sticker_set: Option[Boolean] = None - ) - - case class Game(title: String, - description: String, - photo: Seq[PhotoSize], - text: Option[String] = None, - text_entities: Option[Seq[MessageEntity]] = None, - animation: Option[Animation] = None - ) - - case class Animation(file_id: String, - thumb: Option[PhotoSize] = None, - file_name: Option[String] = None, - mime_type: Option[String] = None, - file_size: Option[Int] = None - ) - - case class InputFile() - - case class Venue(location: Location, - title: String, - address: String, - foursquare_id: Option[String] = None - ) - - case class Invoice(title: String, - description: String, - start_parameter: String, - currency: String, - total_amount: Int - ) - - case class SuccessfulPayment(currency: String, - total_amount: Int, - invoice_payload: String, - shipping_option_id: Option[String] = None, - order_info: Option[OrderInfo] = None, - telegram_payment_charge_id: String, - provider_payment_charge_id: String - ) - - case class Webhook(url: String, - certificate: Option[InputFile] = None, - max_connections: Option[Int] = None, - allowed_updates: Option[Seq[String]] = None - ) - - case class WebhookInfo(url: String, - has_custom_certificate: Boolean, - pending_update_count: Int, - last_error_date: Option[Int] = None, - last_error_message: Option[String] = None, - max_connections: Option[Int] = None, - allowed_updates: Option[Seq[String]] = None - ) -} diff --git a/src/main/scala/eu/xeppaka/bot/TelegramEntitiesDerivations.scala b/src/main/scala/eu/xeppaka/bot/TelegramEntitiesDerivations.scala deleted file mode 100644 index acacc1b..0000000 --- a/src/main/scala/eu/xeppaka/bot/TelegramEntitiesDerivations.scala +++ /dev/null @@ -1,24 +0,0 @@ -package eu.xeppaka.bot - -import cats.syntax.functor._ -import eu.xeppaka.bot.TelegramEntities._ -import io.circe.{Decoder, Encoder} -import io.circe.generic.auto._ -import io.circe.syntax._ - -object TelegramEntitiesDerivations { - implicit val encodeReplyMarkup: Encoder[ReplyMarkup] = Encoder.instance { - case replyKeyboardMarkup: ReplyKeyboardMarkup => replyKeyboardMarkup.asJson - case replyKeyboardRemove: ReplyKeyboardRemove => replyKeyboardRemove.asJson - case inlineKeyboardMarkup: InlineKeyboardMarkup => inlineKeyboardMarkup.asJson - case forceReply: ForceReply => forceReply.asJson - } - - implicit val decodeReplyMarkup: Decoder[ReplyMarkup] = - List[Decoder[ReplyMarkup]]( - Decoder[ReplyKeyboardMarkup].widen, - Decoder[ReplyKeyboardRemove].widen, - Decoder[InlineKeyboardMarkup].widen, - Decoder[ForceReply].widen - ).reduceLeft(_ or _) -}