mirror of
https://github.com/Eyre-S/Coeur-Morny-Cono.git
synced 2024-11-22 03:04:54 +08:00
add support for inline bilibili preview share. cha some social share query result names
- for Bilibili - from "[bilbili] Share video / avXXX/BVXXX" to "[Bilibili] Video avXXX/BVXXX", and also added description - from "[tweet] Share as VxTwitter/Fix-Tweet" to "[Twitter/X][VXTwitter/Fix-Tweet] $screenName/statusId" - from "[Xiaohongshu] Share Link [$id]" to "[Xiaohongshu] Note $id. - also added description. - if the note is from a share url, then the share url will be show in description
This commit is contained in:
parent
de522b2dd6
commit
0b560180f4
@ -1,15 +1,11 @@
|
|||||||
package cc.sukazyo.cono.morny.bot.command
|
package cc.sukazyo.cono.morny.bot.command
|
||||||
|
|
||||||
import cc.sukazyo.cono.morny.MornyCoeur
|
import cc.sukazyo.cono.morny.MornyCoeur
|
||||||
import cc.sukazyo.cono.morny.extra.BilibiliForms
|
|
||||||
import cc.sukazyo.cono.morny.extra.bilibili.XWebAPI
|
|
||||||
import cc.sukazyo.cono.morny.util.tgapi.InputCommand
|
import cc.sukazyo.cono.morny.util.tgapi.InputCommand
|
||||||
import cc.sukazyo.cono.morny.util.tgapi.TelegramExtensions.Bot.exec
|
import cc.sukazyo.cono.morny.util.tgapi.TelegramExtensions.Bot.exec
|
||||||
import com.pengrad.telegrambot.model.Update
|
import com.pengrad.telegrambot.model.Update
|
||||||
import com.pengrad.telegrambot.model.request.ParseMode
|
import com.pengrad.telegrambot.model.request.ParseMode
|
||||||
import com.pengrad.telegrambot.request.{SendMessage, SendPhoto}
|
import com.pengrad.telegrambot.request.SendMessage
|
||||||
|
|
||||||
import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramParseEscape.escapeHtml as h
|
|
||||||
|
|
||||||
import scala.language.postfixOps
|
import scala.language.postfixOps
|
||||||
|
|
||||||
@ -20,20 +16,6 @@ class Testing (using coeur: MornyCoeur) extends ISimpleCommand {
|
|||||||
|
|
||||||
override def execute (using command: InputCommand, event: Update): Unit = {
|
override def execute (using command: InputCommand, event: Update): Unit = {
|
||||||
|
|
||||||
val video = BilibiliForms.parse_videoUrl(command.args.mkString(" "))
|
|
||||||
val video_info = XWebAPI.get_view(video)
|
|
||||||
|
|
||||||
coeur.account exec new SendPhoto(
|
|
||||||
event.message.chat.id,
|
|
||||||
video_info.data.pic
|
|
||||||
).replyToMessageId(event.message.messageId)
|
|
||||||
.caption(
|
|
||||||
// language=html
|
|
||||||
s"""<a href="https://www.bilibili.com/video/av${video.av}"><b>${h(video_info.data.title)}</b></a>
|
|
||||||
| <a href="https://space.bilibili.com/${video_info.data.owner.mid}">@${h(video_info.data.owner.name)}</a>
|
|
||||||
|${h(video_info.data.desc)}""".stripMargin
|
|
||||||
).parseMode(ParseMode.HTML)
|
|
||||||
|
|
||||||
coeur.account exec new SendMessage(
|
coeur.account exec new SendMessage(
|
||||||
event.message.chat.id,
|
event.message.chat.id,
|
||||||
// language=html
|
// language=html
|
||||||
|
@ -4,14 +4,16 @@ import cc.sukazyo.cono.morny.MornyCoeur
|
|||||||
import cc.sukazyo.cono.morny.bot.api.{EventEnv, EventListener}
|
import cc.sukazyo.cono.morny.bot.api.{EventEnv, EventListener}
|
||||||
import cc.sukazyo.cono.morny.bot.event.OnGetSocial.tryFetchSocial
|
import cc.sukazyo.cono.morny.bot.event.OnGetSocial.tryFetchSocial
|
||||||
import cc.sukazyo.cono.morny.data.TelegramStickers
|
import cc.sukazyo.cono.morny.data.TelegramStickers
|
||||||
import cc.sukazyo.cono.morny.extra.{twitter, weibo}
|
import cc.sukazyo.cono.morny.extra.{twitter, weibo, BilibiliForms}
|
||||||
import cc.sukazyo.cono.morny.util.tgapi.TelegramExtensions.Bot.exec
|
import cc.sukazyo.cono.morny.util.tgapi.TelegramExtensions.Bot.exec
|
||||||
import cc.sukazyo.cono.morny.Log.{exceptionLog, logger}
|
import cc.sukazyo.cono.morny.Log.{exceptionLog, logger}
|
||||||
import cc.sukazyo.cono.morny.data.social.{SocialTwitterParser, SocialWeiboParser}
|
import cc.sukazyo.cono.morny.data.social.{SocialTwitterParser, SocialWeiboParser}
|
||||||
|
import cc.sukazyo.cono.morny.extra.BilibiliForms.{BiliB23, BiliVideoId}
|
||||||
|
import cc.sukazyo.cono.morny.extra.bilibili.XWebAPI
|
||||||
import cc.sukazyo.cono.morny.util.tgapi.TelegramExtensions.Message.entitiesSafe
|
import cc.sukazyo.cono.morny.util.tgapi.TelegramExtensions.Message.entitiesSafe
|
||||||
import com.pengrad.telegrambot.model.Chat
|
import com.pengrad.telegrambot.model.Chat
|
||||||
import com.pengrad.telegrambot.model.request.ParseMode
|
import com.pengrad.telegrambot.model.request.ParseMode
|
||||||
import com.pengrad.telegrambot.request.{SendMessage, SendSticker}
|
import com.pengrad.telegrambot.request.{SendMessage, SendPhoto, SendSticker}
|
||||||
|
|
||||||
class OnGetSocial (using coeur: MornyCoeur) extends EventListener {
|
class OnGetSocial (using coeur: MornyCoeur) extends EventListener {
|
||||||
|
|
||||||
@ -69,10 +71,43 @@ object OnGetSocial {
|
|||||||
succeed += 1
|
succeed += 1
|
||||||
tryFetchSocialOfWeibo(f)
|
tryFetchSocialOfWeibo(f)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
{
|
||||||
|
val bilibiliVideos: List[BiliVideoId] = text match
|
||||||
|
case Left(texts) =>
|
||||||
|
BiliVideoId.searchIn(texts) ::: BiliB23.searchIn(texts).map(_.toVideoId)
|
||||||
|
case Right(url) =>
|
||||||
|
try BilibiliForms.parse_videoUrl(url) :: Nil
|
||||||
|
catch case _: IllegalArgumentException =>
|
||||||
|
try BiliVideoId.matchUrl(BilibiliForms.destructB23Url(url)) :: Nil
|
||||||
|
catch case _: Exception => Nil
|
||||||
|
bilibiliVideos.foreach( video =>
|
||||||
|
succeed += 1
|
||||||
|
tryFetchSocialOfBilibili(video)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
succeed > 0
|
succeed > 0
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private def tryFetchSocialOfBilibili (video: BiliVideoId)(using replyChat: Long, replyToMessage: Int)(using coeur: MornyCoeur) = {
|
||||||
|
import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramParseEscape.escapeHtml as h
|
||||||
|
|
||||||
|
val video_info = XWebAPI.get_view(video)
|
||||||
|
coeur.account exec new SendPhoto(
|
||||||
|
replyChat,
|
||||||
|
video_info.data.pic
|
||||||
|
).replyToMessageId(replyToMessage)
|
||||||
|
.caption(
|
||||||
|
// language=html
|
||||||
|
s"""<a href="https://www.bilibili.com/video/av${video.av}"><b>${h(video_info.data.title)}</b></a>
|
||||||
|
| <a href="https://space.bilibili.com/${video_info.data.owner.mid}">@${h(video_info.data.owner.name)}</a>
|
||||||
|
|${h(video_info.data.desc)}""".stripMargin
|
||||||
|
).parseMode(ParseMode.HTML)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private def tryFetchSocialOfTweet (url: twitter.TweetUrlInformation)(using replyChat: Long, replyToMessage: Int)(using coeur: MornyCoeur) =
|
private def tryFetchSocialOfTweet (url: twitter.TweetUrlInformation)(using replyChat: Long, replyToMessage: Int)(using coeur: MornyCoeur) =
|
||||||
import io.circe.{DecodingFailure, ParsingFailure}
|
import io.circe.{DecodingFailure, ParsingFailure}
|
||||||
import sttp.client3.SttpClientException
|
import sttp.client3.SttpClientException
|
||||||
|
@ -8,8 +8,6 @@ import scala.language.postfixOps
|
|||||||
|
|
||||||
class ShareToolBilibili extends ITelegramQuery {
|
class ShareToolBilibili extends ITelegramQuery {
|
||||||
|
|
||||||
private val TITLE_BILI_AV = "[bilibili] Share video / av"
|
|
||||||
private val TITLE_BILI_BV = "[bilibili] Share video / BV"
|
|
||||||
private val ID_PREFIX_BILI_AV = "[morny/share/bili/av]"
|
private val ID_PREFIX_BILI_AV = "[morny/share/bili/av]"
|
||||||
private val ID_PREFIX_BILI_BV = "[morny/share/bili/bv]"
|
private val ID_PREFIX_BILI_BV = "[morny/share/bili/bv]"
|
||||||
private val SHARE_FORMAT_HTML = "<a href='%s'>%s</a>"
|
private val SHARE_FORMAT_HTML = "<a href='%s'>%s</a>"
|
||||||
@ -30,13 +28,17 @@ class ShareToolBilibili extends ITelegramQuery {
|
|||||||
List(
|
List(
|
||||||
InlineQueryUnit(InlineQueryResultArticle(
|
InlineQueryUnit(InlineQueryResultArticle(
|
||||||
inlineQueryId(ID_PREFIX_BILI_AV + it.av),
|
inlineQueryId(ID_PREFIX_BILI_AV + it.av),
|
||||||
TITLE_BILI_AV + it.av,
|
s"[Bilibili] Video av${it.av}",
|
||||||
InputTextMessageContent(formatShareHTML(it.avLink, it.toAvString)).parseMode(ParseMode HTML)
|
InputTextMessageContent(formatShareHTML(it.avLink, it.toAvString)).parseMode(ParseMode HTML)
|
||||||
|
).description(
|
||||||
|
s"Video URL only. Aka BV${it.bv}"
|
||||||
)),
|
)),
|
||||||
InlineQueryUnit(InlineQueryResultArticle(
|
InlineQueryUnit(InlineQueryResultArticle(
|
||||||
inlineQueryId(ID_PREFIX_BILI_BV + it.bv),
|
inlineQueryId(ID_PREFIX_BILI_BV + it.bv),
|
||||||
TITLE_BILI_BV + it.bv,
|
s"[Bilibili] Video BV${it.bv}",
|
||||||
InputTextMessageContent(formatShareHTML(it.bvLink, it.toBvString)).parseMode(ParseMode HTML)
|
InputTextMessageContent(formatShareHTML(it.bvLink, it.toBvString)).parseMode(ParseMode HTML)
|
||||||
|
).description(
|
||||||
|
s"Video URL only. Aka av${it.av}"
|
||||||
))
|
))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -4,7 +4,11 @@ import cc.sukazyo.cono.morny.data.social.{SocialTwitterParser, SocialWeiboParser
|
|||||||
import cc.sukazyo.cono.morny.extra.{twitter, weibo}
|
import cc.sukazyo.cono.morny.extra.{twitter, weibo}
|
||||||
import cc.sukazyo.cono.morny.extra.twitter.FXApi
|
import cc.sukazyo.cono.morny.extra.twitter.FXApi
|
||||||
import cc.sukazyo.cono.morny.extra.weibo.MApi
|
import cc.sukazyo.cono.morny.extra.weibo.MApi
|
||||||
|
import cc.sukazyo.cono.morny.extra.BilibiliForms.{BiliB23, BiliVideoId}
|
||||||
|
import cc.sukazyo.cono.morny.extra.bilibili.XWebAPI
|
||||||
|
import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramParseEscape.escapeHtml as h
|
||||||
import com.pengrad.telegrambot.model.Update
|
import com.pengrad.telegrambot.model.Update
|
||||||
|
import com.pengrad.telegrambot.model.request.{InlineQueryResultPhoto, ParseMode}
|
||||||
|
|
||||||
class ShareToolSocialContent extends ITelegramQuery {
|
class ShareToolSocialContent extends ITelegramQuery {
|
||||||
|
|
||||||
@ -13,7 +17,33 @@ class ShareToolSocialContent extends ITelegramQuery {
|
|||||||
val query = event.inlineQuery.query
|
val query = event.inlineQuery.query
|
||||||
if query == null then return null
|
if query == null then return null
|
||||||
|
|
||||||
twitterTweets(query) ::: weiboStatus(query)
|
twitterTweets(query) ::: weiboStatus(query) ::: bilibiliVideos(query)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private def bilibiliVideos (query: String): List[InlineQueryUnit[_]] = {
|
||||||
|
|
||||||
|
val results: List[(String, BiliVideoId)] =
|
||||||
|
BiliVideoId.searchIn(query).map(x => (x.toString, x)) ++
|
||||||
|
BiliB23.searchIn(query).map(x => (x.toString, x.toVideoId))
|
||||||
|
|
||||||
|
results.map { (_, video) =>
|
||||||
|
val video_info = XWebAPI.get_view(video)
|
||||||
|
InlineQueryUnit(InlineQueryResultPhoto(
|
||||||
|
"[morny/share/bilibili/video/preview]" + video.av + "/" + video.bv,
|
||||||
|
video_info.data.pic,
|
||||||
|
video_info.data.pic
|
||||||
|
).title(
|
||||||
|
s"[Bilibili] ${video_info.data.title}"
|
||||||
|
).description(
|
||||||
|
s"av${video.av} / BV${video.bv} - Preview"
|
||||||
|
).caption(
|
||||||
|
// language=html
|
||||||
|
s"""<a href="https://www.bilibili.com/video/av${video.av}"><b>${h(video_info.data.title)}</b></a>
|
||||||
|
| <a href="https://space.bilibili.com/${video_info.data.owner.mid}">@${h(video_info.data.owner.name)}</a>
|
||||||
|
|${h(video_info.data.desc)}""".stripMargin
|
||||||
|
).parseMode(ParseMode.HTML))
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,9 +9,9 @@ import scala.language.postfixOps
|
|||||||
|
|
||||||
class ShareToolTwitter extends ITelegramQuery {
|
class ShareToolTwitter extends ITelegramQuery {
|
||||||
|
|
||||||
private val TITLE_VX = "[tweet] Share as VxTwitter"
|
private val TITLE_VX = "[Twitter/X][VxTwitter]"
|
||||||
private val ID_PREFIX_VX = "[morny/share/twitter/vx_url]"
|
private val ID_PREFIX_VX = "[morny/share/twitter/vx_url]"
|
||||||
private val TITLE_FX = "[tweet] Share as Fix-Tweet"
|
private val TITLE_FX = "[Twitter/X][Fix-Tweet]"
|
||||||
private val ID_PREFIX_FX = "[morny/share/twitter/fx_url]"
|
private val ID_PREFIX_FX = "[morny/share/twitter/fx_url]"
|
||||||
|
|
||||||
override def query (event: Update): List[InlineQueryUnit[_]] | Null = {
|
override def query (event: Update): List[InlineQueryUnit[_]] | Null = {
|
||||||
@ -21,7 +21,7 @@ class ShareToolTwitter extends ITelegramQuery {
|
|||||||
def getQueryTweetId (prefix: String, tweet: TweetUrlInformation): String =
|
def getQueryTweetId (prefix: String, tweet: TweetUrlInformation): String =
|
||||||
prefix + tweet.hashCode
|
prefix + tweet.hashCode
|
||||||
def getTweetName (title_prefix: String, tweet: TweetUrlInformation): String =
|
def getTweetName (title_prefix: String, tweet: TweetUrlInformation): String =
|
||||||
s"$title_prefix ${tweet.screenName}.${tweet.statusId}"
|
s"$title_prefix ${tweet.screenName}/${tweet.statusId}"
|
||||||
|
|
||||||
twitter.guessTweetUrl(event.inlineQuery.query).flatMap(tweet =>
|
twitter.guessTweetUrl(event.inlineQuery.query).flatMap(tweet =>
|
||||||
List(
|
List(
|
||||||
|
@ -5,7 +5,7 @@ import com.pengrad.telegrambot.model.request.InlineQueryResultArticle
|
|||||||
|
|
||||||
class ShareToolXhs extends ITelegramQuery {
|
class ShareToolXhs extends ITelegramQuery {
|
||||||
|
|
||||||
private val TITLE = "[Xiaohongshu] Share Link"
|
private val TITLE = "[Xiaohongshu] Note"
|
||||||
private val ID = "[morny/share/xhs/link]"
|
private val ID = "[morny/share/xhs/link]"
|
||||||
|
|
||||||
override def query (event: Update): List[InlineQueryUnit[_]] | Null = {
|
override def query (event: Update): List[InlineQueryUnit[_]] | Null = {
|
||||||
@ -15,22 +15,24 @@ class ShareToolXhs extends ITelegramQuery {
|
|||||||
val content = inlineQuery.query
|
val content = inlineQuery.query
|
||||||
|
|
||||||
def getTitle (xhsLink: XHSLink): String = {
|
def getTitle (xhsLink: XHSLink): String = {
|
||||||
s"$TITLE [${xhsLink.exploreId}]"
|
s"$TITLE ${xhsLink.exploreId}"
|
||||||
}
|
}
|
||||||
|
|
||||||
val xhsLinks: List[(String, XHSLink)] = {
|
val xhsLinks: List[(String, XHSLink, Option[String])] = {
|
||||||
XHSLink.searchUrls(content).map {
|
XHSLink.searchUrls(content).map {
|
||||||
case xhsLink: XHSLink => (xhsLink.toString, xhsLink)
|
case xhsLink: XHSLink => (xhsLink.toString, xhsLink, None)
|
||||||
case shareLink: XHSLink.ShareLink =>
|
case shareLink: XHSLink.ShareLink =>
|
||||||
(shareLink.toString, shareLink.getXhsLink)
|
(shareLink.toString, shareLink.getXhsLink, Some(shareLink.link))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
xhsLinks.map((uniqueId, xhsLink) =>
|
xhsLinks.map((uniqueId, xhsLink, maybeFromShare) =>
|
||||||
InlineQueryUnit(InlineQueryResultArticle(
|
InlineQueryUnit(InlineQueryResultArticle(
|
||||||
ID+uniqueId,
|
ID+uniqueId,
|
||||||
getTitle(xhsLink),
|
getTitle(xhsLink),
|
||||||
xhsLink.link
|
xhsLink.link
|
||||||
|
).description(
|
||||||
|
"URL only." + (if maybeFromShare.nonEmpty then s" from $maybeFromShare" else "")
|
||||||
))
|
))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user