feat(monkeyd): add /monkeyd_tags to report a novel's tags as hashtags

Replies with a hashtag line led by #MonkeyD, then a blank line and the novel
URL, sent as a code block so it can be copied in one tap. Each genre label
becomes one hashtag with spaces and punctuation stripped and every word
capitalised, since Telegram ends a hashtag at the first character that is not a
letter, digit, or underscore. Diacritics survive; a label with no letters is
dropped rather than emitted as a bare hash.

The command costs one request and runs inline under a short timeout rather than
in the background: handlers are dispatched one at a time, so a stalled fetch
would block every other command. It shares the export page cache.

Advance the submodule to the tag parser, which matches itemprop="genre"
microdata so the site-wide genre navigation stays out of the result.
This commit is contained in:
tiennm99 committed 2026-07-30 00:52:10 +07:00
1 parent 67341b8772
commit 181bfb5a8d
9 files changed
+508 -22

No files matched your search

+6 -4
View File
@@ -36,12 +36,13 @@ var usage = fmt.Sprintf(
// New is the module Factory. The module keeps no persistent state — an export
// is a one-shot job — so deps.Store is unused.
func New(_ modules.Deps) modules.Module {
return newModule(newRunner())
return newModule(newRunner(), fetchTags)
}
// newModule builds the module around a given runner, which is how tests supply
// one with a stubbed exporter and a synchronous launch.
func newModule(r *runner) modules.Module {
// newModule builds the module around a given runner and tag fetcher, which is
// how tests supply a stubbed exporter, a synchronous launch, and tags without
// network access.
func newModule(r *runner, fetch tagsFetcher) modules.Module {
return modules.Module{
Commands: []modules.Command{
{
@@ -55,6 +56,7 @@ func newModule(r *runner) modules.Module {
Parameters: parameters,
Handler: r.handle,
},
tagsCommand(fetch),
},
}
}