- SendEmail: real nodemailer transport with SMTP config, dynamic recipient resolution
(static + ticket creator/owner lookup), Handlebars template support
- Webhook: HTTP POST/any method with configurable headers and JSON body
- FetchMetadata: external HTTP fetch, Handlebars URL/body templating,
auto-adds result as comment/correspondence on ticket
- RunScript: arbitrary async JS execution with helpers (addComment,
createTransaction, updateTicket, touchTicket), ticket context, and
Drizzle ORM access
- SetCustomField: lookup by id/key/name, clear+insert value, record
CustomFieldChange transaction
- CreateTransaction: insert arbitrary transaction record
- Add OnCustomFieldChange condition
- Pass condition_config to evaluator in engine
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- config.ts: add SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASS, SMTP_FROM
- engine.ts: prepare() queries real scrips from DB, matches by queue_id + condition_type, loads lifecycle for OnResolve context, renders Handlebars templates, builds PreparedScrip. commit() dispatches to real action executors.
- actions.ts: SendEmail via nodemailer SMTP, Webhook via fetch POST, SetCustomField writes to custom_field_values table
- conditions.ts: OnResolve uses LifecycleValidator.isResolvedStatus()
- tickets.ts: updated to pass lifecycleDef context to scrip engine
- nodemailer installed
- Port changed to 9876 (8080 occupied by Apache)
Verification: bun run src/index.ts starts server, GET /health returns {"status":"ok","version":"0.1.0"}