mirror of
https://github.com/Eyre-S/Coeur-Morny-Cono.git
synced 2024-11-22 11:14:55 +08:00
add HTTP server and basic tstickers-api
- add HTTP server backend - with configurable listening port - default is 30179 - cannot disable it yet - with UI service with a 523 image - with simple RESTful API service - add basic tstickers-api - now can only get and output binary content without file-type tagging or converting -
This commit is contained in:
parent
ee47446900
commit
5aa63de2a9
@ -25,7 +25,7 @@
|
||||
[![Maven metadata of snapshots][badge_snapshot_img]][badge_snapshot_target]
|
||||
|
||||
[//]: # (**[说明书][book] | [FindInTelegram][tg-account]**)
|
||||
[badge_handbook_img]: https://img.shields.io/website?url=https%3A%2F%2Fbook.sukazyo.cc%2Fmorny&up_message=0.8.0.11*PUTIAN&up_color=7b68ee&down_message=%E4%B8%8D%E5%8F%AF%E7%94%A8&down_color=dc143c&label=%E8%AF%B4%E6%98%8E%E4%B9%A6
|
||||
[badge_handbook_img]: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fbook.sukazyo.cc%2Fmorny%2Fmain.json&query=%24.target_version&label=%E8%AF%B4%E6%98%8E%E4%B9%A6&color=7b68ee
|
||||
[badge_handbook_target]: https://book.sukazyo.cc/morny
|
||||
[badge_telegram_img]: https://img.shields.io/website?url=https%3A%2F%2Ft.me%2Fmorny_cono_annie_bot&up_message=%40morny_cono_annie_bot&up_color=28a8ea&down_message=unavailable&down_color=red&logo=telegram&label=Telegram
|
||||
[badge_telegram_target]: https://t.me/morny_cono_annie_bot
|
||||
|
@ -66,7 +66,11 @@ lazy val root = (project in file("."))
|
||||
},
|
||||
assembly / artifact := (assembly / artifact).value
|
||||
.withClassifier(Some("fat")),
|
||||
addArtifact(assembly / artifact, assembly),
|
||||
if (MornyProject.publishWithFatJar) {
|
||||
addArtifact(assembly / artifact, assembly)
|
||||
} else {
|
||||
Nil
|
||||
},
|
||||
if (System.getenv("DOCKER_BUILD") != null) {
|
||||
assembly / assemblyJarName := {
|
||||
sLog.value info "environment DOCKER_BUILD checked"
|
||||
|
@ -8,13 +8,13 @@ object MornyConfiguration {
|
||||
val MORNY_CODE_STORE = "https://github.com/Eyre-S/Coeur-Morny-Cono"
|
||||
val MORNY_COMMIT_PATH = "https://github.com/Eyre-S/Coeur-Morny-Cono/commit/%s"
|
||||
|
||||
val VERSION = "2.0.0-alpha10"
|
||||
val VERSION = "2.0.0-alpha11"
|
||||
val VERSION_DELTA: Option[String] = None
|
||||
val CODENAME = "guanggu"
|
||||
|
||||
val SNAPSHOT = true
|
||||
|
||||
val dependencies = Seq(
|
||||
val dependencies: Seq[ModuleID] = Seq(
|
||||
|
||||
"com.github.spotbugs" % "spotbugs-annotations" % "4.7.3" % Compile,
|
||||
|
||||
@ -22,11 +22,15 @@ object MornyConfiguration {
|
||||
"cc.sukazyo" % "resource-tools" % "0.2.2",
|
||||
|
||||
"com.github.pengrad" % "java-telegram-bot-api" % "6.2.0",
|
||||
"org.http4s" %% "http4s-dsl" % "0.23.24",
|
||||
"org.http4s" %% "http4s-circe" % "0.23.24",
|
||||
"org.http4s" %% "http4s-netty-server" % "0.5.11",
|
||||
|
||||
"com.softwaremill.sttp.client3" %% "core" % "3.9.0",
|
||||
"com.softwaremill.sttp.client3" %% "okhttp-backend" % "3.9.0",
|
||||
"com.squareup.okhttp3" % "okhttp" % "4.11.0" % Runtime,
|
||||
|
||||
"org.typelevel" %% "case-insensitive" % "1.4.0",
|
||||
"com.google.code.gson" % "gson" % "2.10.1",
|
||||
"io.circe" %% "circe-core" % "0.14.6",
|
||||
"io.circe" %% "circe-generic" % "0.14.6",
|
||||
|
@ -1,15 +1,14 @@
|
||||
import org.eclipse.jgit.api.Git
|
||||
import org.eclipse.jgit.revwalk.RevWalk
|
||||
import org.eclipse.jgit.storage.file.FileRepositoryBuilder
|
||||
|
||||
import java.io.File
|
||||
import sbt.*
|
||||
|
||||
//noinspection TypeAnnotation
|
||||
object MornyProject {
|
||||
|
||||
val _git_repo = new FileRepositoryBuilder()
|
||||
.setGitDir(new File(".git"))
|
||||
.setWorkTree(new File(""))
|
||||
.setGitDir(file(".git"))
|
||||
.setWorkTree(file("."))
|
||||
.readEnvironment()
|
||||
.build()
|
||||
val _git = new Git(_git_repo)
|
||||
@ -45,6 +44,7 @@ object MornyProject {
|
||||
|
||||
val dependencies = MornyConfiguration.dependencies
|
||||
|
||||
val publishWithFatJar = !version_is_snapshot
|
||||
def publishTo = MornyConfiguration.publishTo
|
||||
val publishCredentials = MornyConfiguration.publishCredentials
|
||||
|
||||
|
BIN
src/main/resources/assets_morny/images/http-sekai-404.png
Normal file
BIN
src/main/resources/assets_morny/images/http-sekai-404.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 82 KiB |
BIN
src/main/resources/assets_morny/images/http-sekai-500.png
Normal file
BIN
src/main/resources/assets_morny/images/http-sekai-500.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 73 KiB |
BIN
src/main/resources/assets_morny/images/http-sekai-501.png
Normal file
BIN
src/main/resources/assets_morny/images/http-sekai-501.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 90 KiB |
BIN
src/main/resources/assets_morny/images/http-sekai-523.png
Normal file
BIN
src/main/resources/assets_morny/images/http-sekai-523.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 80 KiB |
@ -4,6 +4,8 @@ import cc.sukazyo.cono.morny.core.Log.{exceptionLog, logger}
|
||||
import cc.sukazyo.cono.morny.core.MornyCoeur.*
|
||||
import cc.sukazyo.cono.morny.core.bot.api.{EventListenerManager, MornyCommandManager, MornyQueryManager}
|
||||
import cc.sukazyo.cono.morny.core.bot.event.{MornyOnInlineQuery, MornyOnTelegramCommand, MornyOnUpdateTimestampOffsetLock}
|
||||
import cc.sukazyo.cono.morny.core.http.api.{HttpServer, MornyHttpServerContext}
|
||||
import cc.sukazyo.cono.morny.core.http.internal.MornyHttpServerContextImpl
|
||||
import cc.sukazyo.cono.morny.reporter.MornyReport
|
||||
import cc.sukazyo.cono.morny.util.schedule.Scheduler
|
||||
import cc.sukazyo.cono.morny.util.EpochDateTime.EpochMillis
|
||||
@ -38,6 +40,7 @@ object MornyCoeur {
|
||||
eventManager: EventListenerManager,
|
||||
commandManager: MornyCommandManager,
|
||||
queryManager: MornyQueryManager,
|
||||
httpServer: MornyHttpServerContext,
|
||||
givenCxt: GivenContext
|
||||
)
|
||||
|
||||
@ -52,6 +55,7 @@ object MornyCoeur {
|
||||
eventManager: EventListenerManager,
|
||||
commandManager: MornyCommandManager,
|
||||
queryManager: MornyQueryManager,
|
||||
httpServer: MornyHttpServerContext,
|
||||
givenCxt: GivenContext
|
||||
)
|
||||
|
||||
@ -66,6 +70,7 @@ object MornyCoeur {
|
||||
eventManager: EventListenerManager,
|
||||
commandManager: MornyCommandManager,
|
||||
queryManager: MornyQueryManager,
|
||||
httpServer: MornyHttpServerContext,
|
||||
givenCxt: GivenContext
|
||||
)
|
||||
|
||||
@ -166,11 +171,14 @@ class MornyCoeur (modules: List[MornyModule])(using val config: MornyConfig)(tes
|
||||
val commands: MornyCommandManager = MornyCommandManager()
|
||||
val queries: MornyQueryManager = MornyQueryManager()
|
||||
|
||||
private var _httpServerContext: MornyHttpServerContext = MornyHttpServerContextImpl()
|
||||
|
||||
// Coeur Initializing Pre Event
|
||||
modules.foreach(it => it.onInitializingPre(OnInitializingPreContext(
|
||||
externalContext,
|
||||
coeurStartTimestamp, account, username, userid, tasks, trusted,
|
||||
eventManager, commands, queries,
|
||||
_httpServerContext,
|
||||
initializeContext)))
|
||||
|
||||
// register core/api events
|
||||
@ -199,12 +207,16 @@ class MornyCoeur (modules: List[MornyModule])(using val config: MornyConfig)(tes
|
||||
|
||||
)
|
||||
}
|
||||
// register core http api service
|
||||
import cc.sukazyo.cono.morny.core.http.services as http_srv
|
||||
_httpServerContext register4API http_srv.Ping()
|
||||
|
||||
// Coeur Initializing Event
|
||||
modules.foreach(it => it.onInitializing(OnInitializingContext(
|
||||
externalContext,
|
||||
coeurStartTimestamp, account, username, userid, tasks, trusted,
|
||||
eventManager, commands, queries,
|
||||
_httpServerContext,
|
||||
initializeContext)))
|
||||
|
||||
val watchDog: WatchDog = WatchDog("watch-dog", 1000, 1500, { (consumed, _) =>
|
||||
@ -221,6 +233,7 @@ class MornyCoeur (modules: List[MornyModule])(using val config: MornyConfig)(tes
|
||||
externalContext,
|
||||
coeurStartTimestamp, account, username, userid, tasks, trusted,
|
||||
eventManager, commands, queries,
|
||||
_httpServerContext,
|
||||
initializeContext)))
|
||||
|
||||
///>>> BLOCK START instance configure & startup stage 2
|
||||
@ -237,6 +250,9 @@ class MornyCoeur (modules: List[MornyModule])(using val config: MornyConfig)(tes
|
||||
modules.foreach(it => it.onStarting(OnStartingContext(
|
||||
initializeContext)))
|
||||
|
||||
logger info "start http server"
|
||||
val http: HttpServer = _httpServerContext.start
|
||||
_httpServerContext = null
|
||||
logger info "start telegram event listening"
|
||||
import com.pengrad.telegrambot.TelegramException
|
||||
account.setUpdatesListener(eventManager, (e: TelegramException) => {
|
||||
|
@ -103,7 +103,13 @@ public class MornyConfig {
|
||||
public final boolean commandLogoutClear;
|
||||
|
||||
/* ======================================= *
|
||||
* system: morny report *
|
||||
* system: http server *
|
||||
* ======================================= */
|
||||
|
||||
public final int httpPort;
|
||||
|
||||
/* ======================================= *
|
||||
* function: reporter *
|
||||
* ======================================= */
|
||||
|
||||
/**
|
||||
@ -164,11 +170,14 @@ public class MornyConfig {
|
||||
this.medicationTimerUseTimezone = prototype.medicationTimerUseTimezone;
|
||||
prototype.medicationNotifyAt.forEach(i -> { if (i < 0 || i > 23) throw new CheckFailure.UnavailableTimeInMedicationNotifyAt(); });
|
||||
this.medicationNotifyAt = prototype.medicationNotifyAt;
|
||||
if (prototype.httpPort < 0 || prototype.httpPort > 65535) throw new CheckFailure.UnavailableHttpPort();
|
||||
this.httpPort = prototype.httpPort;
|
||||
}
|
||||
|
||||
public static class CheckFailure extends RuntimeException {
|
||||
public static class NullTelegramBotKey extends CheckFailure {}
|
||||
public static class UnavailableTimeInMedicationNotifyAt extends CheckFailure {}
|
||||
public static class UnavailableHttpPort extends CheckFailure {}
|
||||
}
|
||||
|
||||
public static class Prototype {
|
||||
@ -193,6 +202,7 @@ public class MornyConfig {
|
||||
public long medicationNotifyToChat = -1L;
|
||||
@Nonnull public ZoneOffset medicationTimerUseTimezone = ZoneOffset.UTC;
|
||||
@Nonnull public final Set<Integer> medicationNotifyAt = new HashSet<>();
|
||||
public int httpPort = 30179;
|
||||
|
||||
}
|
||||
|
||||
|
@ -57,6 +57,10 @@ object ServerMain {
|
||||
case "--trusted-reader-dinner" | "-trsd" => i += 1; config.dinnerTrustedReaders add(args(i) toLong)
|
||||
case "--dinner-chat" | "-chd" => i += 1; config.dinnerChatId = args(i) toLong
|
||||
|
||||
case "--http-listen-port" | "-hp" =>
|
||||
i += 1
|
||||
config.httpPort = args(i) toInt
|
||||
|
||||
case "--medication-notify-chat" | "-medc" => i += 1; config.medicationNotifyToChat = args(i) toLong
|
||||
case "--medication-notify-timezone" | "-medtz" =>
|
||||
i += 1
|
||||
|
@ -19,7 +19,8 @@ object ServerModulesLoader {
|
||||
morny.medication_timer.ModuleMedicationTimer(),
|
||||
morny.morny_misc.ModuleMornyMisc(),
|
||||
morny.uni_meow.ModuleUniMeow(),
|
||||
morny.reporter.Module()
|
||||
morny.reporter.Module(),
|
||||
morny.stickers_get.Module(),
|
||||
|
||||
)
|
||||
|
||||
|
@ -0,0 +1,19 @@
|
||||
package cc.sukazyo.cono.morny.core.http
|
||||
|
||||
import cats.effect.IO
|
||||
import cc.sukazyo.cono.morny.core.http.api.HttpService4Api
|
||||
import cc.sukazyo.cono.morny.data.TelegramImages
|
||||
import org.http4s.{HttpRoutes, MediaType}
|
||||
import org.http4s.dsl.impl./
|
||||
import org.http4s.dsl.io.*
|
||||
import org.http4s.headers.`Content-Type`
|
||||
|
||||
class ServiceUI extends HttpService4Api {
|
||||
|
||||
override lazy val service: HttpRoutes[IO] = HttpRoutes.of[IO] {
|
||||
case GET -> Root =>
|
||||
NotImplemented(TelegramImages.IMG_501.get)
|
||||
.map(_.withContentType(`Content-Type`(MediaType.image.jpeg)))
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package cc.sukazyo.cono.morny.core.http.api
|
||||
|
||||
import cats.effect.unsafe.IORuntime
|
||||
|
||||
trait HttpServer (using IORuntime) {
|
||||
|
||||
def stop(): Unit
|
||||
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package cc.sukazyo.cono.morny.core.http.api
|
||||
|
||||
import cats.effect.IO
|
||||
import cc.sukazyo.cono.morny.core.Log.exceptionLog
|
||||
import org.http4s.{HttpRoutes, Response}
|
||||
|
||||
trait HttpService4Api {
|
||||
|
||||
lazy val service: HttpRoutes[IO]
|
||||
|
||||
extension (response: Response[IO]) {
|
||||
def setMornyInternalErrorHeader (e: Throwable): Response[IO] =
|
||||
response.setMornyInternalErrorHeader(
|
||||
e.getClass.getSimpleName,
|
||||
e.getMessage,
|
||||
exceptionLog(e)
|
||||
)
|
||||
def setMornyInternalErrorHeader (
|
||||
`Morny-Internal-Error-Type`: String,
|
||||
`Morny-Internal-Error-Message`: String,
|
||||
`Morny-Internal-Error-Detail`: String
|
||||
): Response[IO] =
|
||||
response.withHeaders(
|
||||
"Morny-Internal-Error-Type" -> `Morny-Internal-Error-Type`,
|
||||
"Morny-Internal-Error-Message" -> `Morny-Internal-Error-Message`,
|
||||
"Morny-Internal-Error-Detail" -> `Morny-Internal-Error-Detail`,
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
object HttpService4Api {
|
||||
def apply (_service: HttpRoutes[IO]): HttpService4Api = new HttpService4Api:
|
||||
override lazy val service: HttpRoutes[IO] = _service
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package cc.sukazyo.cono.morny.core.http.api
|
||||
|
||||
trait MornyHttpServerContext {
|
||||
|
||||
def register4API (service: HttpService4Api*): Unit
|
||||
|
||||
def start: HttpServer
|
||||
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
package cc.sukazyo.cono.morny.core.http.internal
|
||||
|
||||
import cc.sukazyo.cono.morny.core.MornyCoeur
|
||||
import cc.sukazyo.cono.morny.core.http.api.{HttpServer, HttpService4Api, MornyHttpServerContext}
|
||||
import cc.sukazyo.cono.morny.core.http.ServiceUI
|
||||
import cc.sukazyo.cono.morny.core.Log.{exceptionLog, logger}
|
||||
|
||||
import scala.collection.mutable
|
||||
|
||||
class MornyHttpServerContextImpl (using coeur: MornyCoeur) extends MornyHttpServerContext {
|
||||
|
||||
private val services_api = mutable.Queue.empty[HttpService4Api]
|
||||
|
||||
private lazy val service_ui = ServiceUI()
|
||||
|
||||
override def register4API (services: HttpService4Api*): Unit =
|
||||
services_api ++= services
|
||||
|
||||
override def start: HttpServer = {
|
||||
import cats.data.OptionT
|
||||
import cats.effect.unsafe.implicits.global
|
||||
import cats.effect.IO
|
||||
import cats.implicits.toSemigroupKOps
|
||||
import org.http4s.server.{Router, Server}
|
||||
import org.http4s.server.middleware.{ErrorAction, ErrorHandling}
|
||||
|
||||
val router = Router(
|
||||
"/" -> service_ui.service,
|
||||
"/api" -> services_api.map(_.service).reduce(_ <+> _)
|
||||
)
|
||||
|
||||
def errorHandler (t: Throwable, message: =>String): OptionT[IO, Unit] =
|
||||
OptionT.liftF(IO {
|
||||
logger error
|
||||
s"""Unexpected exception occurred on Morny Http Server :
|
||||
|${exceptionLog(t)}""".stripMargin
|
||||
})
|
||||
val withErrorHandler = ErrorHandling.Recover.total(
|
||||
ErrorAction.log(
|
||||
router,
|
||||
messageFailureLogAction = errorHandler,
|
||||
serviceErrorLogAction = errorHandler
|
||||
)
|
||||
)
|
||||
|
||||
val server = org.http4s.netty.server.NettyServerBuilder[IO]
|
||||
.bindHttp(coeur.config.httpPort, "0.0.0.0")
|
||||
.withHttpApp(withErrorHandler.orNotFound)
|
||||
.resource
|
||||
val (_server, _shutdown_io) = server.allocated.unsafeRunSync() match
|
||||
case (_1, _2) => (_1, _2)
|
||||
logger notice s"Morny HTTP Server started at ${_server.baseUri}"
|
||||
|
||||
new HttpServer(using global):
|
||||
val server: Server = _server
|
||||
private val shutdown_io = _shutdown_io
|
||||
override def stop (): Unit = shutdown_io.unsafeRunSync()
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package cc.sukazyo.cono.morny.core.http.services
|
||||
|
||||
import cats.effect.IO
|
||||
import cc.sukazyo.cono.morny.core.http.api.HttpService4Api
|
||||
import org.http4s.{HttpRoutes, Response}
|
||||
import org.http4s.circe.jsonEncoder
|
||||
import org.http4s.dsl.io.*
|
||||
|
||||
class Ping extends HttpService4Api {
|
||||
|
||||
case class PingResult (
|
||||
pong: Boolean = true
|
||||
)
|
||||
|
||||
override lazy val service: HttpRoutes[IO] = HttpRoutes.of[IO] {
|
||||
case GET -> Root / "ping" =>
|
||||
import io.circe.generic.auto.*
|
||||
import io.circe.syntax.*
|
||||
Ok(PingResult().asJson)
|
||||
}
|
||||
|
||||
}
|
@ -31,5 +31,9 @@ object TelegramImages {
|
||||
}
|
||||
|
||||
val IMG_ABOUT: AssetsFileImage = AssetsFileImage("images/featured-image@0.5x.jpg")
|
||||
val IMG_404: AssetsFileImage = AssetsFileImage("images/http-sekai-404.png")
|
||||
val IMG_500: AssetsFileImage = AssetsFileImage("images/http-sekai-500.png")
|
||||
val IMG_501: AssetsFileImage = AssetsFileImage("images/http-sekai-501.png")
|
||||
val IMG_523: AssetsFileImage = AssetsFileImage("images/http-sekai-523.png")
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,28 @@
|
||||
package cc.sukazyo.cono.morny.stickers_get
|
||||
|
||||
import cc.sukazyo.cono.morny.core.internal.MornyInternalModule
|
||||
import cc.sukazyo.cono.morny.core.MornyCoeur
|
||||
import cc.sukazyo.cono.morny.stickers_get.http.StickerService
|
||||
|
||||
class Module extends MornyInternalModule {
|
||||
|
||||
override val id: String = "morny.stickers-get"
|
||||
override val name: String = "Morny Can Get and Provide Stickers"
|
||||
override val description: String | Null =
|
||||
// language=markdown
|
||||
"""Make Morny as a Telegram Stickers API.
|
||||
|
|
||||
|This module handles `/api/sticker` route that you can get a sticker
|
||||
|by a sticker ID via HTTP request.
|
||||
|
|
||||
|original idea is: https://github.com/tjhorner/tstickers-api
|
||||
|""".stripMargin
|
||||
|
||||
override def onInitializing (using MornyCoeur)(cxt: MornyCoeur.OnInitializingContext): Unit = {
|
||||
import cxt.*
|
||||
|
||||
httpServer register4API StickerService()
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
package cc.sukazyo.cono.morny.stickers_get.http
|
||||
|
||||
import cats.effect.IO
|
||||
import cc.sukazyo.cono.morny.core.http.api.HttpService4Api
|
||||
import cc.sukazyo.cono.morny.core.MornyCoeur
|
||||
import cc.sukazyo.cono.morny.data.TelegramImages
|
||||
import com.pengrad.telegrambot.request.GetFile
|
||||
import org.http4s.{HttpRoutes, MediaType}
|
||||
import org.http4s.dsl.io.*
|
||||
import org.http4s.headers.`Content-Type`
|
||||
|
||||
import java.io.IOException
|
||||
|
||||
class StickerService (using coeur: MornyCoeur) extends HttpService4Api {
|
||||
|
||||
override lazy val service: HttpRoutes[IO] = HttpRoutes.of {
|
||||
|
||||
case GET -> Root / "sticker" / "id" / id =>
|
||||
try {
|
||||
val response = coeur.account execute GetFile(id)
|
||||
if response.isOk then
|
||||
try {
|
||||
val file = coeur.account getFileContent response.file
|
||||
Ok(file)
|
||||
} catch {
|
||||
case e: IOException =>
|
||||
ServiceUnavailable(
|
||||
TelegramImages.IMG_523.get,
|
||||
`Content-Type`(MediaType.image.png),
|
||||
).map(_.setMornyInternalErrorHeader(e))
|
||||
}
|
||||
else
|
||||
NotFound(
|
||||
TelegramImages.IMG_404.get,
|
||||
`Content-Type`(MediaType.image.png),
|
||||
).map(_.setMornyInternalErrorHeader(
|
||||
"_telegram_api",
|
||||
response.errorCode.toString,
|
||||
response.description,
|
||||
))
|
||||
} catch
|
||||
case io: IOException =>
|
||||
ServiceUnavailable(
|
||||
TelegramImages.IMG_523.get,
|
||||
`Content-Type`(MediaType.image.png),
|
||||
).map(_.setMornyInternalErrorHeader(io))
|
||||
case e: Throwable =>
|
||||
InternalServerError(
|
||||
TelegramImages.IMG_500.get,
|
||||
`Content-Type`(MediaType.image.png),
|
||||
).map(_.setMornyInternalErrorHeader(e))
|
||||
|
||||
case GET -> Root / "sticker" =>
|
||||
NotFound("not found")
|
||||
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package cc.sukazyo.cono.morny
|
||||
|
||||
import cc.sukazyo.cono.morny.core.ServerMain
|
||||
import cc.sukazyo.cono.morny.util.UniversalCommand
|
||||
|
||||
import scala.io.StdIn
|
||||
|
Loading…
Reference in New Issue
Block a user