Skip to content

Repository files navigation

Ticket URL Generator

A Rocket.Chat Apps-Engine app that automatically converts ticket references like #1234 or GH-42 in chat messages into clickable ticket URLs, across any number of independently configured ticket systems.

What it does

When a user sends a message containing a ticket reference matching one of the configured rules, the app rewrites it into a full ticket URL before the message is posted:

Can someone look at #1234? Also see GH-42.

becomes

Can someone look at https://www.myticketurl.com/1234? Also see https://github.com/org/repo/issues/42.

How it works

The app implements the IPreMessageSentModify event handler, which runs on every message before it is sent:

  1. Check phasecheckPreMessageSentModify quickly tests whether the message matches any configured rule's pattern. If not, the app does nothing.
  2. Modify phaseexecutePreMessageSentModify rewrites every match, from every rule, in a single pass.

Edge cases handled

  • Code is left untouched. Fenced code blocks (```) and inline code (`) are stashed as placeholders before rewriting and restored afterwards, so ticket-like patterns inside code are never modified.
  • Existing URLs are left untouched. A ticket reference that is part of a URL path or fragment (preceded by a word character or /) is not rewritten.

Configuration

Rules are configured from a single app setting, "Ticket Rules", editable from Admin → Apps → Ticket URL Generator → Settings with no code changes or repackaging required.

One rule per line:

<pattern> => <url template>
  • <pattern> — a regular expression matching a ticket reference. Must contain exactly one capturing group, which holds the ticket id.
  • <url template> — the URL to build, with {{id}} marking where the ticket id goes — anywhere in the URL (path, query string, even the host).

Default, if left unconfigured:

#(\d+) => https://www.myticketurl.com/{{id}}

Example with several independent ticket systems active at once:

#(\d+) => https://www.myticketurl.com/{{id}}
GH-(\d+) => https://github.com/org/repo/issues/{{id}}
SUP-(\d+) => https://helpdesk.example.com/ticket?id={{id}}

Blank lines are ignored. A line is rejected if:

  • the pattern doesn't compile as a regular expression,
  • the pattern doesn't have exactly one capturing group (that group must hold the ticket id),
  • the pattern is too complex and could hang the server on certain messages (catastrophic backtracking, e.g. nested repetition like (a+)+) — avoid nested or ambiguous repetition,
  • the pattern matches an internal sample of ordinary chat text (dates, times, plain numbers, a URL, an email address — no ticket references) — this catches a pattern that's too loose, e.g. a bare \d+ with no fixed prefix, which would turn every stray number in every message into a bogus link. Give the pattern a specific, fixed prefix (#, GH-, TICKET-, ...) so it can't match incidentally,
  • the template lacks {{id}} or isn't a valid http(s) URL once {{id}} is substituted.

As further defense in depth regardless of how safe a saved pattern looks, the app never runs any pattern against a message longer than 5000 characters (Rocket.Chat's own default message size limit) — this bounds the worst case even for a pattern that turns out to be slow in some edge case the checks above didn't catch.

Validated on save (onPreSettingUpdate): if any line is invalid, the whole update is rejected and the previous value is kept — every invalid line's reason is logged in one go (not just the first) under Admin → Apps → Ticket URL Generator → Logs, so all of them can be fixed in one edit. The settings UI itself doesn't surface the reason.

If two rules' patterns could both match the same text, whichever match starts earliest in the message wins; among rules that could start at the same position, the first-listed rule wins.

Upgrading from a single pattern/URL pair (pre-0.1.0)? Rewrite it as one line in the new format, e.g. an old pattern #(\d+) and base URL https://www.myticketurl.com/ becomes #(\d+) => https://www.myticketurl.com/{{id}}. An old value with no => on any line has zero valid rules and silently falls back to the default above — check the app logs after upgrading if your rules aren't behaving as expected.

Development

Requires the Rocket.Chat Apps CLI:

npm install -g @rocket.chat/apps-cli
npm install

Package the app

rc-apps package

The packaged .zip is written to dist/.

Deploy to a server

rc-apps deploy --url <your-server-url> --username <admin-user> --password <admin-password>

Or upload the zip from dist/ manually via Admin → Apps → Upload App (requires development mode enabled on the server).

Permissions

Permission Why
message.read Read outgoing messages to detect ticket references
message.write Rewrite the message text with the generated URL

License

See repository for license details.

About

turns hashtagged numbers into ticket urls

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages