mirror of
https://github.com/Eyre-S/Coeur-Morny-Cono.git
synced 2024-11-25 12:37:39 +08:00
add inline share xhs url
This commit is contained in:
parent
46519138e1
commit
3c42738816
@ -5,7 +5,7 @@ MORNY_ARCHIVE_NAME = morny-coeur
|
|||||||
MORNY_CODE_STORE = https://github.com/Eyre-S/Coeur-Morny-Cono
|
MORNY_CODE_STORE = https://github.com/Eyre-S/Coeur-Morny-Cono
|
||||||
MORNY_COMMIT_PATH = https://github.com/Eyre-S/Coeur-Morny-Cono/commit/%s
|
MORNY_COMMIT_PATH = https://github.com/Eyre-S/Coeur-Morny-Cono/commit/%s
|
||||||
|
|
||||||
VERSION = 1.3.5-dev
|
VERSION = 1.4.0-SNAPSHOT
|
||||||
|
|
||||||
USE_DELTA = false
|
USE_DELTA = false
|
||||||
VERSION_DELTA =
|
VERSION_DELTA =
|
||||||
|
@ -13,6 +13,7 @@ class MornyQueries (using MornyCoeur) {
|
|||||||
MyInformation(),
|
MyInformation(),
|
||||||
ShareToolTwitter(),
|
ShareToolTwitter(),
|
||||||
ShareToolBilibili(),
|
ShareToolBilibili(),
|
||||||
|
ShareToolXhs(),
|
||||||
ShareToolSocialContent()
|
ShareToolSocialContent()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -0,0 +1,39 @@
|
|||||||
|
package cc.sukazyo.cono.morny.bot.query
|
||||||
|
import cc.sukazyo.cono.morny.extra.xhs.XHSLink
|
||||||
|
import com.pengrad.telegrambot.model.Update
|
||||||
|
import com.pengrad.telegrambot.model.request.InlineQueryResultArticle
|
||||||
|
|
||||||
|
class ShareToolXhs extends ITelegramQuery {
|
||||||
|
|
||||||
|
private val TITLE = "[Xiaohongshu] Share Link"
|
||||||
|
private val ID = "[morny/share/xhs/link]"
|
||||||
|
|
||||||
|
override def query (event: Update): List[InlineQueryUnit[_]] | Null = {
|
||||||
|
import event.inlineQuery
|
||||||
|
|
||||||
|
if inlineQuery.query == null then return null
|
||||||
|
val content = inlineQuery.query
|
||||||
|
|
||||||
|
val xhsLink: XHSLink = {
|
||||||
|
XHSLink.matchUrl(content) match
|
||||||
|
case Some(matched) => matched match
|
||||||
|
case xhsLink: XHSLink => xhsLink
|
||||||
|
case shareLink: XHSLink.ShareLink =>
|
||||||
|
shareLink.getXhsLink
|
||||||
|
case None =>
|
||||||
|
XHSLink.searchShareText(content).map(_.getXhsLink) match
|
||||||
|
case Some(found) => found
|
||||||
|
case None => return null
|
||||||
|
}
|
||||||
|
|
||||||
|
List(
|
||||||
|
InlineQueryUnit(InlineQueryResultArticle(
|
||||||
|
ID+content.hashCode,
|
||||||
|
TITLE,
|
||||||
|
xhsLink.link
|
||||||
|
))
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
87
src/main/scala/cc/sukazyo/cono/morny/extra/xhs/XHSLink.scala
Normal file
87
src/main/scala/cc/sukazyo/cono/morny/extra/xhs/XHSLink.scala
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
package cc.sukazyo.cono.morny.extra.xhs
|
||||||
|
|
||||||
|
import cc.sukazyo.cono.morny.util.SttpPublic.{mornyBasicRequest, Schemes}
|
||||||
|
import sttp.client3.okhttp.OkHttpSyncBackend
|
||||||
|
import sttp.client3.{HttpError, RequestT, SttpClientException}
|
||||||
|
import sttp.model.Uri
|
||||||
|
|
||||||
|
case class XHSLink (exploreId: String) {
|
||||||
|
|
||||||
|
def link =
|
||||||
|
s"https://www.xiaohongshu.com/explore/$exploreId"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
object XHSLink {
|
||||||
|
|
||||||
|
private lazy val http_client = OkHttpSyncBackend()
|
||||||
|
|
||||||
|
private lazy val REGEX_EXPLORER_URL = "(?:(?:https?:)?//)?(?:www\\.)?xiaohongshu\\.com/(?:explore/|discovery/item/)([a-fA-F0-9]+)/?(?:\\?.+)?"r
|
||||||
|
private lazy val REGEX_SHARE_URL = "(?:(?:https?:)?//)?(?:www\\.)?xhslink\\.com/([a-zA-Z0-9]+)/?(?:\\?.+)?"r
|
||||||
|
private lazy val REGEX_SHARE_TEXTS = "\uD83D\uDE06 ([0-9a-zA-Z]+) \uD83D\uDE06 (?:(?:https?:)?//)?(?:www\\.)?xhslink\\.com/([a-zA-Z0-9]+)/?"r
|
||||||
|
|
||||||
|
def matchExplorerUrl (url: String): Option[XHSLink] = {
|
||||||
|
url match
|
||||||
|
case REGEX_EXPLORER_URL(explorerId) => Some(XHSLink(explorerId))
|
||||||
|
case _ => None
|
||||||
|
}
|
||||||
|
|
||||||
|
def matchShareUrl (url: String): Option[ShareLink] = {
|
||||||
|
url match
|
||||||
|
case REGEX_SHARE_URL(shareId) => Some(ShareLink(shareId))
|
||||||
|
case _ => None
|
||||||
|
}
|
||||||
|
|
||||||
|
def matchUrl (url: String): Option[XHSLink|ShareLink] = {
|
||||||
|
matchExplorerUrl(url) orElse matchShareUrl(url)
|
||||||
|
}
|
||||||
|
|
||||||
|
def searchShareText (texts: String): Option[ShareLink] = {
|
||||||
|
REGEX_SHARE_TEXTS.findFirstMatchIn(texts).map(x => ShareLink(x.group(2)))
|
||||||
|
}
|
||||||
|
|
||||||
|
case class ShareLink (shareId: String) {
|
||||||
|
|
||||||
|
def link =
|
||||||
|
s"https://xhslink.com/$shareId"
|
||||||
|
|
||||||
|
/** Get the [[XHSLink xiaohongshu explorer link]] that this share link is linked to via sttp request.
|
||||||
|
*
|
||||||
|
* @param http_client the sttp http client backend that will be used. defaults is [[XHSLink]] owned backend.
|
||||||
|
* @param basic_request the sttp basic request that will be used. defaults is [[mornyBasicRequest]].
|
||||||
|
* @throws IllegalArgumentException When the XHS server does not returns a valid explorer link. Mostly maybe the
|
||||||
|
* share url is invalid or expired.
|
||||||
|
* @throws IllegalStateException When cannot connect to the XHS server.
|
||||||
|
* @return the [[XHSLink xiaohongshu explorer link]] that this share link is linked to.
|
||||||
|
*/
|
||||||
|
@throws[IllegalArgumentException]
|
||||||
|
@throws[IllegalStateException]
|
||||||
|
def getXhsLink (using
|
||||||
|
http_client: sttp.client3.SttpBackend[sttp.client3.Identity, _] = http_client,
|
||||||
|
basic_request: RequestT[sttp.client3.Empty, Either[String, String], Any] = mornyBasicRequest
|
||||||
|
): XHSLink = {
|
||||||
|
|
||||||
|
val uri = try Uri.unsafeParse(this.link).scheme(Schemes.HTTPS) catch
|
||||||
|
case e: IllegalArgumentException => throw IllegalStateException("Cannot format this Share link to a valid request url.").initCause(e)
|
||||||
|
|
||||||
|
try {
|
||||||
|
import sttp.client3.*
|
||||||
|
val request = basic_request
|
||||||
|
.get(uri)
|
||||||
|
.followRedirects(false)
|
||||||
|
.response(ignore)
|
||||||
|
val response = request.send(http_client)
|
||||||
|
val redir = response.header("Location").get
|
||||||
|
matchExplorerUrl(redir) match
|
||||||
|
case None => throw IllegalArgumentException(s"XHS server returns a non-XHSLink url: $redir")
|
||||||
|
case Some(link) => link
|
||||||
|
} catch
|
||||||
|
case e: SttpClientException => throw IllegalStateException("failed get response from xhs server.").initCause(e)
|
||||||
|
case e: HttpError[_] => throw IllegalStateException("failed parse response from xhs server.").initCause(e)
|
||||||
|
case e: NoSuchElementException => throw IllegalArgumentException("XHS server does not returns any url.").initCause(e)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
package cc.sukazyo.cono.morny.util
|
package cc.sukazyo.cono.morny.util
|
||||||
|
|
||||||
import cc.sukazyo.cono.morny.MornySystem
|
import cc.sukazyo.cono.morny.MornySystem
|
||||||
import sttp.client3.basicRequest
|
import sttp.client3.{basicRequest, RequestT}
|
||||||
import sttp.model.Header
|
import sttp.model.Header
|
||||||
|
|
||||||
object SttpPublic {
|
object SttpPublic {
|
||||||
@ -23,7 +23,7 @@ object SttpPublic {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val mornyBasicRequest =
|
val mornyBasicRequest: RequestT[sttp.client3.Empty, Either[String, String], Any] =
|
||||||
basicRequest
|
basicRequest
|
||||||
.header(Headers.UserAgent.MORNY_CURRENT, true)
|
.header(Headers.UserAgent.MORNY_CURRENT, true)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user