Skip to content

Commit

Permalink
(#102) LinkGenerator: extract to a separate module
Browse files Browse the repository at this point in the history
  • Loading branch information
ForNeVeR committed Oct 2, 2021
1 parent e671c7b commit 85a2459
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 25 deletions.
4 changes: 3 additions & 1 deletion Emulsion.Tests/Telegram/FunogramTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,9 @@ let private replyingUser = createUser (Some "replyingUser") "" None
let private forwardingUser = createUser (Some "forwardingUser") "" None

module ReadMessageTests =
let private readMessage = MessageConverter.read selfUserId
let private readMessage m =
let links = LinkGenerator.gatherLinks m
MessageConverter.read selfUserId (m, links)

[<Fact>]
let readMessageWithUnknownUser() =
Expand Down
1 change: 1 addition & 0 deletions Emulsion/Emulsion.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
<Compile Include="Lifetimes.fs" />
<Compile Include="ExceptionUtils.fs" />
<Compile Include="Telegram\Html.fs" />
<Compile Include="Telegram\LinkGenerator.fs" />
<Compile Include="Telegram\Funogram.fs" />
<Compile Include="Telegram\Client.fs" />
<Compile Include="Xmpp\Types.fs" />
Expand Down
45 changes: 21 additions & 24 deletions Emulsion/Telegram/Funogram.fs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ open Serilog

open Emulsion
open Emulsion.Settings
open Emulsion.Telegram.LinkGenerator

type private FunogramMessage = Types.Message
[<Struct>]
Expand Down Expand Up @@ -151,15 +152,7 @@ module MessageConverter =
|> addAuthorIfAvailable
|> markAsQuote quoteSettings.linePrefix

let private getLinkToMessage (message: FunogramMessage) =
match message with
| { MessageId = id
Chat = { Type = SuperGroup
Username = Some chatName } } ->
$"https://t.me/{chatName}/{id}"
| _ -> String.Empty

let private getAuthoredMessageBodyText (message: FunogramMessage) =
let private getAuthoredMessageBodyText (message: FunogramMessage) link =
let (|Text|_|) (message: FunogramMessage) = message.Text
let (|Poll|_|) (message: FunogramMessage) = message.Poll
let (|Content|_|) (message: FunogramMessage) =
Expand All @@ -181,10 +174,10 @@ module MessageConverter =
| { ForwardFromChat = Some chat } -> Some (getChatDisplayName chat)
| _ -> None

let appendLink link text =
if String.IsNullOrEmpty link
then text
else $"{text}: {link}"
let appendLinkTo text =
match link with
| Some link -> $"{text}: {link}"
| None -> text

let text =
match message with
Expand All @@ -197,12 +190,12 @@ module MessageConverter =
$"[{contentType} with caption \"{text}\"]"
| None ->
$"[{contentType}]"
contentInfo |> appendLink (getLinkToMessage message)
appendLinkTo contentInfo
| Poll poll ->
let text = getPollText poll
$"[Poll] {text}"
| _ ->
"[DATA UNRECOGNIZED]" |> appendLink (getLinkToMessage message)
appendLinkTo "[DATA UNRECOGNIZED]"

match message with
| ForwardFrom author ->
Expand Down Expand Up @@ -260,7 +253,7 @@ module MessageConverter =
then Some message
else None

let private extractMessageContent(message: FunogramMessage): Message =
let private extractMessageContent(message: FunogramMessage) link: Message =
match message with
| EventFunogramMessage msg ->
Event { text = getEventMessageBodyText msg }
Expand All @@ -269,18 +262,18 @@ module MessageConverter =
message.From
|> Option.map getUserDisplayName
|> Option.defaultValue "[UNKNOWN USER]"
let mainBody = getAuthoredMessageBodyText message
let mainBody = getAuthoredMessageBodyText message link
Authored { author = mainAuthor; text = mainBody }

/// For messages from the bot, the first bold section of the message will contain the nickname of the author.
/// Everything else is the message text.
let private extractSelfMessageContent(message: FunogramMessage): Message =
let private extractSelfMessageContent(message: FunogramMessage) link: Message =
match (message.Entities, message.Text) with
| None, _ | _, None -> extractMessageContent message
| None, _ | _, None -> extractMessageContent message link
| Some entities, Some text ->
let boldEntity = Seq.tryFind (fun (e: MessageEntity) -> e.Type = "bold") entities
match boldEntity with
| None -> extractMessageContent message
| None -> extractMessageContent message link
| Some section ->
let authorNameOffset = Math.Clamp(int32 section.Offset, 0, text.Length)
let authorNameLength = Math.Clamp(int32 section.Length, 0, text.Length - authorNameOffset)
Expand All @@ -289,15 +282,15 @@ module MessageConverter =
let messageText = text.Substring messageTextOffset
Authored { author = authorName; text = messageText }

let internal read (selfUserId: int64) (message: FunogramMessage): ThreadMessage =
let mainMessage = extractMessageContent message
let internal read (selfUserId: int64) (message: FunogramMessage, links: TelegramThreadLinks): ThreadMessage =
let mainMessage = extractMessageContent message links.ContentLink
match message.ReplyToMessage with
| None -> { main = mainMessage; replyTo = None }
| Some replyTo ->
let replyToMessage =
if isSelfMessage selfUserId replyTo
then extractSelfMessageContent replyTo
else extractMessageContent replyTo
then extractSelfMessageContent replyTo links.ReplyToContentLink
else extractMessageContent replyTo links.ReplyToContentLink
{ main = mainMessage; replyTo = Some replyToMessage }

let internal processSendResult(result: Result<'a, ApiResponseError>): unit =
Expand All @@ -306,11 +299,15 @@ let internal processSendResult(result: Result<'a, ApiResponseError>): unit =
| Error e ->
failwith $"Telegram API Call processing error {e.ErrorCode}: {e.Description}"

let private extractLinkData message =
message, gatherLinks message

let internal processMessage (context: {| SelfUserId: int64; GroupId: int64 |})
(message: FunogramMessage): Message option =
if context.GroupId = message.Chat.Id
then
message
|> extractLinkData
|> MessageConverter.read context.SelfUserId
|> MessageConverter.flatten MessageConverter.DefaultQuoteSettings
|> Some
Expand Down
34 changes: 34 additions & 0 deletions Emulsion/Telegram/LinkGenerator.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/// A module that generates links to various content from Telegram.
module Emulsion.Telegram.LinkGenerator

open Funogram.Telegram.Types

type FunogramMessage = Funogram.Telegram.Types.Message

type TelegramThreadLinks = {
ContentLink: string option
ReplyToContentLink: string option
}
with
static member None: TelegramThreadLinks = {
ContentLink = None
ReplyToContentLink = None
}

let private getMessageLink (message: FunogramMessage) =
match message with
| { MessageId = id
Chat = { Type = SuperGroup
Username = Some chatName } } ->
Some $"https://t.me/{chatName}/{id}"
| _ -> None

let private gatherMessageLink(message: FunogramMessage) =
match message with
| { Text = Some _} | { Poll = Some _ } -> None
| _ -> getMessageLink message

let gatherLinks(message: FunogramMessage): TelegramThreadLinks = {
ContentLink = gatherMessageLink message
ReplyToContentLink = message.ReplyToMessage |> Option.bind gatherMessageLink
}

0 comments on commit 85a2459

Please sign in to comment.