-
Notifications
You must be signed in to change notification settings - Fork 0
/
generic-text.ts
99 lines (82 loc) · 2.69 KB
/
generic-text.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import { MAX_CHARS } from './constants.js'
import type { Link, Section } from './interfaces.js'
import { anchor } from './utils.js'
export interface Config {
title: string
subtitle?: string
description: string
sections?: Section[]
links?: Link[]
}
export interface Options {
is_title_bold?: boolean
is_subtitle_italic?: boolean
is_section_title_bold?: boolean
}
export const DEFAULT_OPTIONS: Required<Options> = {
is_title_bold: true,
is_subtitle_italic: true,
is_section_title_bold: true
}
/**
* Generic text message.
*/
export const genericText = (
config: Config,
options: Options = DEFAULT_OPTIONS
) => {
const { description, links, sections, subtitle, title } = config
const is_subtitle_italic =
options.is_subtitle_italic !== undefined
? options.is_subtitle_italic
: DEFAULT_OPTIONS.is_subtitle_italic
const is_title_bold =
options.is_title_bold !== undefined
? options.is_title_bold
: DEFAULT_OPTIONS.is_title_bold
let s = is_title_bold ? `<b>${title}</b>` : title
if (subtitle) {
s = is_subtitle_italic ? `${s}\n<i>${subtitle}</i>` : `${s}\n${subtitle}`
}
s = `${s}\n\n${description}`
if (sections && sections.length > 0) {
const is_section_title_bold =
options.is_section_title_bold !== undefined
? options.is_section_title_bold
: DEFAULT_OPTIONS.is_section_title_bold
const s_sections = sections
.map((d) => {
let s_section = is_section_title_bold
? `<b>${d.title}</b>\n${d.body}`
: `${d.title}\n${d.body}`
if (d.links && d.links.length > 0) {
const s_links = d.links.map(anchor).join('\n')
s_section = `${s_section}\n\n${s_links}`
}
return s_section
})
.join('\n\n')
s = `${s}\n\n${s_sections}`
}
if (links && links.length > 0) {
const s_links = links.map(anchor).join('\n')
s = `${s}\n\n${s_links}`
}
// When the string is longer than MAX_CHARS we have 2 options:
// 1. return s.slice(0, MAX_CHARS)
// 2. throw an error
//
// Returning s.slice(0, MAX_CHARS) would be too risky, because the call to the
// Telegram sendMessage API endpoint might fail because we might cut away a
// closing tag from the text message. This occurred to me several times, and
// the error message from Telegram is not immediately clear.
// It's much better to fail now, with a clear error message, that trying our
// luck with a call to the sendMessage API that might fail because of some
// missing tag.
if (s.length > MAX_CHARS) {
throw new Error(
`Text message is too long (${s.length} chars). Telegram sendMessage API endpoint accepts a max of ${MAX_CHARS} chars.`
)
}
return s
}