@@ -503,10 +503,7 @@ func (p *webhookPlugin) buildEventData(topic string, payload map[string]any) (ma
503503 Title string `json:"title"`
504504 }
505505 _ = json .Unmarshal ([]byte (rawContent ), & c )
506- if c .Title == "" {
507- return map [string ]any {}, fmt .Sprintf ("%s created a task" , actor )
508- }
509- return map [string ]any {"title" : c .Title }, fmt .Sprintf ("%s created a task: %q" , actor , c .Title )
506+ return map [string ]any {"title" : c .Title }, fmt .Sprintf ("%s created %s" , actor , p .taskRef (payload ))
510507
511508 case "task.updated" :
512509 ref := p .taskRef (payload )
@@ -635,21 +632,48 @@ func (p *webhookPlugin) lookupName(sqlStr, param string) string {
635632 return newRowScanner (result .Columns , result .Rows [0 ]).str ("name" )
636633}
637634
638- // taskRef returns a quoted reference to the task ("task \"Fix login bug\"")
639- // for use in a summary line, falling back to "a task" when the title can't
640- // be resolved (e.g. task_id missing from the payload).
635+ // taskRef returns a quoted reference to the task, prefixed with its
636+ // human-readable alias when the project has a task ID prefix configured
637+ // (e.g. `task ABC-123 "Fix login bug"`), falling back to "a task" when the
638+ // title can't be resolved (e.g. task_id missing from the payload).
641639func (p * webhookPlugin ) taskRef (payload map [string ]any ) string {
642640 taskID , _ := payload ["task_id" ].(string )
643641 if taskID == "" {
644642 return "a task"
645643 }
646- title := p .lookupName (`SELECT title AS name FROM tasks WHERE id = $1` , taskID )
644+ result , err := p .db .Query (`SELECT title, task_number, project_id FROM tasks WHERE id = $1` , taskID )
645+ if err != nil || len (result .Rows ) == 0 {
646+ return "a task"
647+ }
648+ sc := newRowScanner (result .Columns , result .Rows [0 ])
649+ title := sc .str ("title" )
647650 if title == "" {
648651 return "a task"
649652 }
653+ if alias := p .taskAlias (sc .str ("project_id" ), sc .intVal ("task_number" )); alias != "" {
654+ return fmt .Sprintf ("task %s %q" , alias , title )
655+ }
650656 return fmt .Sprintf ("task %q" , title )
651657}
652658
659+ // taskAlias formats a task's human-readable alias (e.g. "ABC-123") from its
660+ // project's task_id_prefix and the task's sequential task_number, or ""
661+ // when the project has no prefix configured or the task number is unset.
662+ func (p * webhookPlugin ) taskAlias (projectID string , taskNumber int ) string {
663+ if projectID == "" || taskNumber <= 0 {
664+ return ""
665+ }
666+ result , err := p .db .Query (`SELECT task_id_prefix FROM projects WHERE id = $1` , projectID )
667+ if err != nil || len (result .Rows ) == 0 {
668+ return ""
669+ }
670+ prefix := newRowScanner (result .Columns , result .Rows [0 ]).str ("task_id_prefix" )
671+ if prefix == "" {
672+ return ""
673+ }
674+ return fmt .Sprintf ("%s-%d" , prefix , taskNumber )
675+ }
676+
653677// blockContentToText converts a field-change value (decoded from JSON into
654678// an `any` by fieldChange) back into BlockNote JSON text and extracts plain
655679// text from it. Used for fields like "description" that store BlockNote
@@ -701,6 +725,16 @@ func extractBlockText(raw string) string {
701725 return ""
702726}
703727
728+ // projectName resolves the display name of the event's project, or "" when
729+ // project_id is missing from the payload or doesn't match a project.
730+ func (p * webhookPlugin ) projectName (payload map [string ]any ) string {
731+ projectID , _ := payload ["project_id" ].(string )
732+ if projectID == "" {
733+ return ""
734+ }
735+ return p .lookupName (`SELECT name FROM projects WHERE id = $1` , projectID )
736+ }
737+
704738// taskURL builds a link to the task on the Paca web app, using the host's
705739// PUBLIC_URL config value. Returns "" when PUBLIC_URL isn't configured or
706740// the event has no task_id/project_id (e.g. webhook.test).
@@ -725,6 +759,10 @@ func (p *webhookPlugin) deliver(sc *scanner, eventType string, payload map[strin
725759 targetURL := sc .str ("url" )
726760
727761 data , text := p .buildEventData (eventType , payload )
762+ if pname := p .projectName (payload ); pname != "" {
763+ data ["project_name" ] = pname
764+ text = fmt .Sprintf ("[%s] %s" , pname , text )
765+ }
728766 if url := p .taskURL (payload ); url != "" {
729767 data ["url" ] = url
730768 text = text + " - " + url
0 commit comments