{ "kind": "open-flow-workflow", "version": 1, "name": "Linear Support Sentiment to Slack", "content": { "modelVersion": 14, "document": { "bindings": {}, "graph": { "nodes": { "n_be21c465e33fbb33": { "name": "Test sentiment analysis", "kind": "start", "inputDefs": [] }, "n_9132d1ab472858ec": { "name": "Analyze every30minutes UTC", "kind": "cron", "cronTimes": [ { "type": "cron", "expression": "*/30 * * * *", "timezone": "UTC" } ] }, "n_bfccdb99ea52e0fa": { "inputs": {}, "name": "Set issue update window", "kind": "task", "task": { "inputs": [], "outputs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "updatedAfter" } ], "name": "Set issue update window", "moduleId": "n_306f66398bc767e7", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_6238c23f922e6ad4": { "inputs": { "first": { "kind": "value", "value": 50 }, "updated_after": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_bfccdb99ea52e0fa", "output": "updatedAfter" } ] } }, "name": "Read first fifty updated issues", "kind": "task", "task": { "inputs": [ { "description": "Next page cursor.", "jsonSchema": { "type": "string", "description": "Next page cursor." }, "nullable": true, "handle": "after", "value": null }, { "description": "Return quantity per page.", "jsonSchema": { "type": "number", "description": "Return quantity per page." }, "nullable": true, "handle": "first", "value": null }, { "description": "Only issues updated at or after this ISO 8601 timestamp.", "jsonSchema": { "type": "string", "format": "date-time", "description": "Only issues updated at or after this ISO 8601 timestamp." }, "nullable": true, "handle": "updated_after", "value": null }, { "description": "Include archived issues.", "jsonSchema": { "type": "boolean", "description": "Include archived issues." }, "nullable": true, "handle": "include_archived", "value": null }, { "description": "The field used to order results.", "jsonSchema": { "type": "string", "enum": [ "createdAt", "updatedAt" ], "description": "The field used to order results." }, "nullable": true, "handle": "order_by", "value": null }, { "description": "The unique identifier of the project used for filtering.", "jsonSchema": { "type": "string", "description": "The unique identifier of the project used for filtering." }, "nullable": true, "handle": "project_id", "value": null }, { "description": "The unique identifier of the person responsible for filtering.", "jsonSchema": { "type": "string", "description": "The unique identifier of the person responsible for filtering." }, "nullable": true, "handle": "assignee_id", "value": null } ], "outputs": [ { "description": "issue list.", "jsonSchema": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "description": "issue unique identifier." }, "identifier": { "type": "string", "description": "Issue abbreviation identifier." }, "title": { "type": "string", "description": "issue title." }, "description": { "type": [ "string", "null" ], "description": "issue description." }, "url": { "type": "string", "description": "issue link." }, "createdAt": { "type": "string", "description": "issue creation time." }, "updatedAt": { "type": "string", "description": "issue update time." }, "archivedAt": { "type": [ "string", "null" ], "description": "Issue filing time." }, "dueDate": { "type": [ "string", "null" ], "description": "issue deadline." }, "priority": { "type": [ "number", "null" ], "description": "issue priority." }, "estimate": { "type": [ "number", "null" ], "description": "issue estimate." }, "team": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "The team's unique identifier." }, "name": { "type": "string", "description": "Team name." }, "key": { "type": "string", "description": "The team shorthand key." } }, "required": [ "id", "name" ], "additionalProperties": false, "description": "Team information." }, "state": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "The unique identifier of the status." }, "name": { "type": "string", "description": "Status name." }, "type": { "type": "string", "description": "Status type." }, "color": { "type": "string", "description": "Status color." }, "description": { "type": "string", "description": "Status description." } }, "required": [ "id", "name" ], "additionalProperties": false, "description": "Current workflow status." }, "project": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "The unique identifier of the project." }, "name": { "type": "string", "description": "Project name." }, "slugId": { "type": "string", "description": "Project slug identifier." }, "url": { "type": "string", "description": "Project link." }, "state": { "type": "string", "description": "Project status." }, "health": { "type": [ "string", "null" ], "description": "Project health status." }, "progress": { "type": "number", "description": "Project progress." }, "priority": { "type": "number", "description": "Project priority." }, "priorityLabel": { "type": "string", "description": "Project priority label." }, "scope": { "type": "number", "description": "Project scope value." }, "color": { "type": [ "string", "null" ], "description": "Item color." }, "description": { "type": [ "string", "null" ], "description": "Project description." }, "icon": { "type": [ "string", "null" ], "description": "Project icon." }, "startDate": { "type": [ "string", "null" ], "description": "Project start date." }, "targetDate": { "type": [ "string", "null" ], "description": "Project target date." }, "createdAt": { "type": "string", "description": "Project creation time." }, "updatedAt": { "type": "string", "description": "Project update time." }, "lead": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "User unique identifier." }, "name": { "type": "string", "description": "User name." }, "displayName": { "type": "string", "description": "User display name." }, "email": { "type": "string", "description": "User email." }, "avatarUrl": { "type": "string", "description": "User avatar address." }, "active": { "type": "boolean", "description": "Whether the user is active." }, "admin": { "type": "boolean", "description": "Whether the user is an administrator." }, "createdAt": { "type": "string", "description": "User creation time." } }, "required": [ "id" ], "additionalProperties": false, "description": "Project leader." }, "creator": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "User unique identifier." }, "name": { "type": "string", "description": "User name." }, "displayName": { "type": "string", "description": "User display name." }, "email": { "type": "string", "description": "User email." }, "avatarUrl": { "type": "string", "description": "User avatar address." }, "active": { "type": "boolean", "description": "Whether the user is active." }, "admin": { "type": "boolean", "description": "Whether the user is an administrator." }, "createdAt": { "type": "string", "description": "User creation time." } }, "required": [ "id" ], "additionalProperties": false, "description": "Project creator." }, "status": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "Unique identifier of project status." }, "name": { "type": "string", "description": "Project status name." }, "type": { "type": "string", "description": "Project status type." }, "color": { "type": "string", "description": "Project status color." }, "description": { "type": "string", "description": "Project status description." } }, "required": [ "id", "name" ], "additionalProperties": false, "description": "Project status object." } }, "required": [ "id", "name" ], "additionalProperties": false, "description": "Project information." }, "assignee": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "User unique identifier." }, "name": { "type": "string", "description": "User name." }, "displayName": { "type": "string", "description": "User display name." }, "email": { "type": "string", "description": "User email." }, "avatarUrl": { "type": "string", "description": "User avatar address." }, "active": { "type": "boolean", "description": "Whether the user is active." }, "admin": { "type": "boolean", "description": "Whether the user is an administrator." }, "createdAt": { "type": "string", "description": "User creation time." } }, "required": [ "id" ], "additionalProperties": false, "description": "Current person in charge information." }, "labels": { "type": "object", "properties": { "nodes": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "description": "Tag unique identifier." }, "name": { "type": "string", "description": "Tag name." }, "color": { "type": "string", "description": "Label color." }, "description": { "type": "string", "description": "Tag description." }, "is_group": { "type": "boolean", "description": "Whether to group labels." }, "isGroup": { "type": "boolean", "description": "Whether to group labels." }, "parent": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "The unique identifier of the parent label group." }, "name": { "type": "string", "description": "The name of the parent label group." } }, "required": [ "id", "name" ], "additionalProperties": false, "description": "Parent label group information." } }, "required": [ "id", "name" ], "additionalProperties": false, "description": "Linear label object." }, "description": "tag list." } }, "required": [ "nodes" ], "additionalProperties": false, "description": "issue tag connection." } }, "required": [ "id", "identifier", "title", "createdAt", "updatedAt" ], "additionalProperties": false, "description": "Linear issue summary object." }, "description": "issue list." }, "nullable": false, "handle": "issues" }, { "description": "Pagination information.", "jsonSchema": { "type": "object", "properties": { "startCursor": { "type": [ "string", "null" ], "description": "The starting point of the cursor on the previous page." }, "endCursor": { "type": [ "string", "null" ], "description": "The end cursor for the next page." }, "hasPreviousPage": { "type": "boolean", "description": "Whether there is a previous page." }, "hasNextPage": { "type": "boolean", "description": "Whether the next page exists." } }, "required": [ "endCursor", "hasNextPage" ], "additionalProperties": false, "description": "Pagination information." }, "nullable": false, "handle": "page_info" } ], "name": "Read first fifty updated issues", "executor": { "kind": "connector", "action": "linear.list_linear_issues" } } }, "n_bdd0d487d320ce00": { "inputs": { "issues": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_6238c23f922e6ad4", "output": "issues" } ] }, "previousState": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_bdd0d487d320ce00", "output": "state" } ] }, "issue": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_2e4927957a0ae23d", "output": "issue" } ] } }, "name": "Collect issue conversations", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "description": "issue unique identifier." }, "identifier": { "type": "string", "description": "Issue abbreviation identifier." }, "title": { "type": "string", "description": "issue title." }, "description": { "type": [ "string", "null" ], "description": "issue description." }, "url": { "type": "string", "description": "issue link." }, "createdAt": { "type": "string", "description": "issue creation time." }, "updatedAt": { "type": "string", "description": "issue update time." }, "archivedAt": { "type": [ "string", "null" ], "description": "Issue filing time." }, "dueDate": { "type": [ "string", "null" ], "description": "issue deadline." }, "priority": { "type": [ "number", "null" ], "description": "issue priority." }, "estimate": { "type": [ "number", "null" ], "description": "issue estimate." }, "team": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "The team's unique identifier." }, "name": { "type": "string", "description": "Team name." }, "key": { "type": "string", "description": "The team shorthand key." } }, "required": [ "id", "name" ], "additionalProperties": false, "description": "Team information." }, "state": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "The unique identifier of the status." }, "name": { "type": "string", "description": "Status name." }, "type": { "type": "string", "description": "Status type." }, "color": { "type": "string", "description": "Status color." }, "description": { "type": "string", "description": "Status description." } }, "required": [ "id", "name" ], "additionalProperties": false, "description": "Current workflow status." }, "project": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "The unique identifier of the project." }, "name": { "type": "string", "description": "Project name." }, "slugId": { "type": "string", "description": "Project slug identifier." }, "url": { "type": "string", "description": "Project link." }, "state": { "type": "string", "description": "Project status." }, "health": { "type": [ "string", "null" ], "description": "Project health status." }, "progress": { "type": "number", "description": "Project progress." }, "priority": { "type": "number", "description": "Project priority." }, "priorityLabel": { "type": "string", "description": "Project priority label." }, "scope": { "type": "number", "description": "Project scope value." }, "color": { "type": [ "string", "null" ], "description": "Item color." }, "description": { "type": [ "string", "null" ], "description": "Project description." }, "icon": { "type": [ "string", "null" ], "description": "Project icon." }, "startDate": { "type": [ "string", "null" ], "description": "Project start date." }, "targetDate": { "type": [ "string", "null" ], "description": "Project target date." }, "createdAt": { "type": "string", "description": "Project creation time." }, "updatedAt": { "type": "string", "description": "Project update time." }, "lead": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "User unique identifier." }, "name": { "type": "string", "description": "User name." }, "displayName": { "type": "string", "description": "User display name." }, "email": { "type": "string", "description": "User email." }, "avatarUrl": { "type": "string", "description": "User avatar address." }, "active": { "type": "boolean", "description": "Whether the user is active." }, "admin": { "type": "boolean", "description": "Whether the user is an administrator." }, "createdAt": { "type": "string", "description": "User creation time." } }, "required": [ "id" ], "additionalProperties": false, "description": "Project leader." }, "creator": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "User unique identifier." }, "name": { "type": "string", "description": "User name." }, "displayName": { "type": "string", "description": "User display name." }, "email": { "type": "string", "description": "User email." }, "avatarUrl": { "type": "string", "description": "User avatar address." }, "active": { "type": "boolean", "description": "Whether the user is active." }, "admin": { "type": "boolean", "description": "Whether the user is an administrator." }, "createdAt": { "type": "string", "description": "User creation time." } }, "required": [ "id" ], "additionalProperties": false, "description": "Project creator." }, "status": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "Unique identifier of project status." }, "name": { "type": "string", "description": "Project status name." }, "type": { "type": "string", "description": "Project status type." }, "color": { "type": "string", "description": "Project status color." }, "description": { "type": "string", "description": "Project status description." } }, "required": [ "id", "name" ], "additionalProperties": false, "description": "Project status object." } }, "required": [ "id", "name" ], "additionalProperties": false, "description": "Project information." }, "assignee": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "User unique identifier." }, "name": { "type": "string", "description": "User name." }, "displayName": { "type": "string", "description": "User display name." }, "email": { "type": "string", "description": "User email." }, "avatarUrl": { "type": "string", "description": "User avatar address." }, "active": { "type": "boolean", "description": "Whether the user is active." }, "admin": { "type": "boolean", "description": "Whether the user is an administrator." }, "createdAt": { "type": "string", "description": "User creation time." } }, "required": [ "id" ], "additionalProperties": false, "description": "Current person in charge information." }, "labels": { "type": "object", "properties": { "nodes": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "description": "Tag unique identifier." }, "name": { "type": "string", "description": "Tag name." }, "color": { "type": "string", "description": "Label color." }, "description": { "type": "string", "description": "Tag description." }, "is_group": { "type": "boolean", "description": "Whether to group labels." }, "isGroup": { "type": "boolean", "description": "Whether to group labels." }, "parent": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "The unique identifier of the parent label group." }, "name": { "type": "string", "description": "The name of the parent label group." } }, "required": [ "id", "name" ], "additionalProperties": false, "description": "Parent label group information." } }, "required": [ "id", "name" ], "additionalProperties": false, "description": "Linear label object." }, "description": "tag list." } }, "required": [ "nodes" ], "additionalProperties": false, "description": "issue tag connection." } }, "required": [ "id", "identifier", "title", "createdAt", "updatedAt" ], "additionalProperties": false, "description": "Linear issue summary object." }, "description": "issue list." }, "nullable": true, "handle": "issues" }, { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": true, "handle": "previousState" }, { "jsonSchema": { "type": "object", "additionalProperties": false, "description": "issue details object.", "properties": { "id": { "type": "string", "description": "issue unique identifier." }, "identifier": { "type": "string", "description": "Issue abbreviation identifier." }, "title": { "type": "string", "description": "issue title." }, "description": { "type": [ "string", "null" ], "description": "issue description." }, "url": { "type": "string", "description": "issue link." }, "createdAt": { "type": "string", "description": "issue creation time." }, "updatedAt": { "type": "string", "description": "issue update time." }, "archivedAt": { "type": [ "string", "null" ], "description": "Issue filing time." }, "dueDate": { "type": [ "string", "null" ], "description": "issue deadline." }, "priority": { "type": [ "number", "null" ], "description": "issue priority." }, "estimate": { "type": [ "number", "null" ], "description": "issue estimate." }, "team": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "The team's unique identifier." }, "name": { "type": "string", "description": "Team name." }, "key": { "type": "string", "description": "The team shorthand key." } }, "required": [ "id", "name" ], "additionalProperties": false, "description": "Team information." }, "state": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "The unique identifier of the status." }, "name": { "type": "string", "description": "Status name." }, "type": { "type": "string", "description": "Status type." }, "color": { "type": "string", "description": "Status color." }, "description": { "type": "string", "description": "Status description." } }, "required": [ "id", "name" ], "additionalProperties": false, "description": "Current workflow status." }, "project": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "The unique identifier of the project." }, "name": { "type": "string", "description": "Project name." }, "slugId": { "type": "string", "description": "Project slug identifier." }, "url": { "type": "string", "description": "Project link." }, "state": { "type": "string", "description": "Project status." }, "health": { "type": [ "string", "null" ], "description": "Project health status." }, "progress": { "type": "number", "description": "Project progress." }, "priority": { "type": "number", "description": "Project priority." }, "priorityLabel": { "type": "string", "description": "Project priority label." }, "scope": { "type": "number", "description": "Project scope value." }, "color": { "type": [ "string", "null" ], "description": "Item color." }, "description": { "type": [ "string", "null" ], "description": "Project description." }, "icon": { "type": [ "string", "null" ], "description": "Project icon." }, "startDate": { "type": [ "string", "null" ], "description": "Project start date." }, "targetDate": { "type": [ "string", "null" ], "description": "Project target date." }, "createdAt": { "type": "string", "description": "Project creation time." }, "updatedAt": { "type": "string", "description": "Project update time." }, "lead": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "User unique identifier." }, "name": { "type": "string", "description": "User name." }, "displayName": { "type": "string", "description": "User display name." }, "email": { "type": "string", "description": "User email." }, "avatarUrl": { "type": "string", "description": "User avatar address." }, "active": { "type": "boolean", "description": "Whether the user is active." }, "admin": { "type": "boolean", "description": "Whether the user is an administrator." }, "createdAt": { "type": "string", "description": "User creation time." } }, "required": [ "id" ], "additionalProperties": false, "description": "Project leader." }, "creator": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "User unique identifier." }, "name": { "type": "string", "description": "User name." }, "displayName": { "type": "string", "description": "User display name." }, "email": { "type": "string", "description": "User email." }, "avatarUrl": { "type": "string", "description": "User avatar address." }, "active": { "type": "boolean", "description": "Whether the user is active." }, "admin": { "type": "boolean", "description": "Whether the user is an administrator." }, "createdAt": { "type": "string", "description": "User creation time." } }, "required": [ "id" ], "additionalProperties": false, "description": "Project creator." }, "status": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "Unique identifier of project status." }, "name": { "type": "string", "description": "Project status name." }, "type": { "type": "string", "description": "Project status type." }, "color": { "type": "string", "description": "Project status color." }, "description": { "type": "string", "description": "Project status description." } }, "required": [ "id", "name" ], "additionalProperties": false, "description": "Project status object." } }, "required": [ "id", "name" ], "additionalProperties": false, "description": "Project information." }, "assignee": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "User unique identifier." }, "name": { "type": "string", "description": "User name." }, "displayName": { "type": "string", "description": "User display name." }, "email": { "type": "string", "description": "User email." }, "avatarUrl": { "type": "string", "description": "User avatar address." }, "active": { "type": "boolean", "description": "Whether the user is active." }, "admin": { "type": "boolean", "description": "Whether the user is an administrator." }, "createdAt": { "type": "string", "description": "User creation time." } }, "required": [ "id" ], "additionalProperties": false, "description": "Current person in charge information." }, "labels": { "type": "object", "properties": { "nodes": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "description": "Tag unique identifier." }, "name": { "type": "string", "description": "Tag name." }, "color": { "type": "string", "description": "Label color." }, "description": { "type": "string", "description": "Tag description." }, "is_group": { "type": "boolean", "description": "Whether to group labels." }, "isGroup": { "type": "boolean", "description": "Whether to group labels." }, "parent": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "The unique identifier of the parent label group." }, "name": { "type": "string", "description": "The name of the parent label group." } }, "required": [ "id", "name" ], "additionalProperties": false, "description": "Parent label group information." } }, "required": [ "id", "name" ], "additionalProperties": false, "description": "Linear label object." }, "description": "tag list." } }, "required": [ "nodes" ], "additionalProperties": false, "description": "issue tag connection." }, "creator": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "User unique identifier." }, "name": { "type": "string", "description": "User name." }, "displayName": { "type": "string", "description": "User display name." }, "email": { "type": "string", "description": "User email." }, "avatarUrl": { "type": "string", "description": "User avatar address." }, "active": { "type": "boolean", "description": "Whether the user is active." }, "admin": { "type": "boolean", "description": "Whether the user is an administrator." }, "createdAt": { "type": "string", "description": "User creation time." } }, "required": [ "id" ], "additionalProperties": false, "description": "Issue creator information." }, "cycle": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "The unique identifier of the cycle." }, "name": { "type": "string", "description": "Cycle name." }, "number": { "type": "number", "description": "Cycle number." }, "description": { "type": "string", "description": "Cycle description." }, "startsAt": { "type": "string", "description": "Cycle start time." }, "endsAt": { "type": "string", "description": "Cycle end time." }, "completedAt": { "type": "string", "description": "Cycle completion time." }, "isActive": { "type": "boolean", "description": "Whether it is the current activation period." }, "isFuture": { "type": "boolean", "description": "Whether it is a future period." }, "isPast": { "type": "boolean", "description": "Whether it is a past period." }, "team": { "type": "object", "properties": { "id": { "type": "string", "description": "The team's unique identifier." }, "name": { "type": "string", "description": "Team name." }, "key": { "type": "string", "description": "The team shorthand key." } }, "required": [ "id", "name" ], "additionalProperties": false, "description": "Team information." } }, "required": [ "id", "name" ], "additionalProperties": false, "description": "The cycle to which the issue belongs." }, "parent": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "The unique identifier of the parent issue." }, "identifier": { "type": "string", "description": "The abbreviated identifier of the parent issue." }, "title": { "type": "string", "description": "Parent issue title." } }, "required": [ "id", "identifier", "title" ], "additionalProperties": false, "description": "Parent issue information." }, "attachments": { "type": "object", "properties": { "nodes": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "description": "The unique identifier of the attachment." }, "title": { "type": "string", "description": "Attachment title." }, "subtitle": { "type": [ "string", "null" ], "description": "Attachment subtitle." }, "url": { "type": "string", "description": "Attachment link." }, "sourceType": { "type": [ "string", "null" ], "description": "Attachment source type." }, "metadata": { "type": "object", "additionalProperties": { "description": "A record value." }, "description": "Attachment metadata." }, "source": { "type": [ "object", "null" ], "additionalProperties": { "description": "A record value." }, "description": "Attachment source information." }, "issue": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "Unique identifier associated with the issue." }, "identifier": { "type": "string", "description": "Associated issue abbreviation identifier." }, "title": { "type": "string", "description": "Associated issue title." } }, "required": [ "id" ], "additionalProperties": false, "description": "The issue to which the attachment belongs." }, "createdAt": { "type": "string", "description": "The time the attachment was created." }, "updatedAt": { "type": "string", "description": "Attachment update time." } }, "required": [ "id", "title", "url" ], "additionalProperties": false, "description": "Linear attachment object." }, "description": "Attachment list." }, "pageInfo": { "type": "object", "properties": { "startCursor": { "type": [ "string", "null" ], "description": "The starting point of the cursor on the previous page." }, "endCursor": { "type": [ "string", "null" ], "description": "The end cursor for the next page." }, "hasPreviousPage": { "type": "boolean", "description": "Whether there is a previous page." }, "hasNextPage": { "type": "boolean", "description": "Whether the next page exists." } }, "required": [ "endCursor", "hasNextPage" ], "additionalProperties": false, "description": "Attachment paging information." } }, "required": [ "nodes" ], "additionalProperties": false, "description": "issue attachment connection." }, "comments": { "type": "object", "properties": { "nodes": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "description": "The unique identifier of the comment." }, "body": { "type": "string", "description": "Comment text." }, "url": { "type": "string", "description": "Comment link." }, "quotedText": { "type": [ "string", "null" ], "description": "Quote text." }, "createdAt": { "type": "string", "description": "Comment creation time." }, "updatedAt": { "type": "string", "description": "Comment updated time." }, "editedAt": { "type": [ "string", "null" ], "description": "Comment editing time." }, "resolvedAt": { "type": [ "string", "null" ], "description": "Comment resolution time." }, "issueId": { "type": [ "string", "null" ], "description": "Unique identifier associated with the issue." }, "parentId": { "type": [ "string", "null" ], "description": "The unique identifier of the parent comment." }, "projectUpdateId": { "type": [ "string", "null" ], "description": "Associated project updates unique identifier." }, "user": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "User unique identifier." }, "name": { "type": "string", "description": "User name." }, "displayName": { "type": "string", "description": "User display name." }, "email": { "type": "string", "description": "User email." }, "avatarUrl": { "type": "string", "description": "User avatar address." }, "active": { "type": "boolean", "description": "Whether the user is active." }, "admin": { "type": "boolean", "description": "Whether the user is an administrator." }, "createdAt": { "type": "string", "description": "User creation time." } }, "required": [ "id" ], "additionalProperties": false, "description": "Comment author information." }, "reactions": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "description": "Reaction unique identifier." }, "emoji": { "type": "string", "description": "The emoji used by the reaction." }, "createdAt": { "type": "string", "description": "Reaction creation time." }, "updatedAt": { "type": "string", "description": "Response update time." }, "user": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "User unique identifier." }, "name": { "type": "string", "description": "User name." }, "displayName": { "type": "string", "description": "User display name." }, "email": { "type": "string", "description": "User email." }, "avatarUrl": { "type": "string", "description": "User avatar address." }, "active": { "type": "boolean", "description": "Whether the user is active." }, "admin": { "type": "boolean", "description": "Whether the user is an administrator." }, "createdAt": { "type": "string", "description": "User creation time." } }, "required": [ "id" ], "additionalProperties": false, "description": "The user who triggered the reaction." }, "comment": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "The unique identifier of the comment." } }, "required": [ "id" ], "additionalProperties": false, "description": "The comment value." }, "issue": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "issue unique identifier." }, "identifier": { "type": "string", "description": "Issue abbreviation identifier." } }, "required": [ "id" ], "additionalProperties": false, "description": "The issue value." }, "projectUpdate": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "Project update unique identifier." } }, "required": [ "id" ], "additionalProperties": false, "description": "The projectUpdate value." } }, "required": [ "id", "emoji" ], "additionalProperties": false, "description": "Linear reaction object." }, "description": "List of reactions on comments." } }, "required": [ "id" ], "additionalProperties": false, "description": "Linear comment object." }, "description": "Comments list." }, "pageInfo": { "type": "object", "properties": { "startCursor": { "type": [ "string", "null" ], "description": "The starting point of the cursor on the previous page." }, "endCursor": { "type": [ "string", "null" ], "description": "The end cursor for the next page." }, "hasPreviousPage": { "type": "boolean", "description": "Whether there is a previous page." }, "hasNextPage": { "type": "boolean", "description": "Whether the next page exists." } }, "required": [ "endCursor", "hasNextPage" ], "additionalProperties": false, "description": "Comment pagination information." } }, "required": [ "nodes" ], "additionalProperties": false, "description": "issue comment link." }, "subscribers": { "type": "object", "properties": { "nodes": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "description": "User unique identifier." }, "name": { "type": "string", "description": "User name." }, "displayName": { "type": "string", "description": "User display name." }, "email": { "type": "string", "description": "User email." }, "avatarUrl": { "type": "string", "description": "User avatar address." }, "active": { "type": "boolean", "description": "Whether the user is active." }, "admin": { "type": "boolean", "description": "Whether the user is an administrator." }, "createdAt": { "type": "string", "description": "User creation time." } }, "required": [ "id" ], "additionalProperties": false, "description": "Linear user object." }, "description": "Subscriber list." }, "pageInfo": { "type": "object", "properties": { "startCursor": { "type": [ "string", "null" ], "description": "The starting point of the cursor on the previous page." }, "endCursor": { "type": [ "string", "null" ], "description": "The end cursor for the next page." }, "hasPreviousPage": { "type": "boolean", "description": "Whether there is a previous page." }, "hasNextPage": { "type": "boolean", "description": "Whether the next page exists." } }, "required": [ "endCursor", "hasNextPage" ], "additionalProperties": false, "description": "Subscriber pagination information." } }, "required": [ "nodes" ], "additionalProperties": false, "description": "issue subscriber connection." }, "reactions": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "description": "Reaction unique identifier." }, "emoji": { "type": "string", "description": "The emoji used by the reaction." }, "createdAt": { "type": "string", "description": "Reaction creation time." }, "updatedAt": { "type": "string", "description": "Response update time." }, "user": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "User unique identifier." }, "name": { "type": "string", "description": "User name." }, "displayName": { "type": "string", "description": "User display name." }, "email": { "type": "string", "description": "User email." }, "avatarUrl": { "type": "string", "description": "User avatar address." }, "active": { "type": "boolean", "description": "Whether the user is active." }, "admin": { "type": "boolean", "description": "Whether the user is an administrator." }, "createdAt": { "type": "string", "description": "User creation time." } }, "required": [ "id" ], "additionalProperties": false, "description": "The user who triggered the reaction." }, "comment": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "The unique identifier of the comment." } }, "required": [ "id" ], "additionalProperties": false, "description": "The comment value." }, "issue": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "issue unique identifier." }, "identifier": { "type": "string", "description": "Issue abbreviation identifier." } }, "required": [ "id" ], "additionalProperties": false, "description": "The issue value." }, "projectUpdate": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "Project update unique identifier." } }, "required": [ "id" ], "additionalProperties": false, "description": "The projectUpdate value." } }, "required": [ "id", "emoji" ], "additionalProperties": false, "description": "Linear reaction object." }, "description": "List of reactions on the issue." } }, "required": [ "id", "identifier", "title", "createdAt", "updatedAt" ] }, "nullable": true, "handle": "issue" } ], "outputs": [ { "jsonSchema": { "type": "object", "properties": { "issues": { "type": "array", "items": { "type": "object", "additionalProperties": true } } }, "required": [ "issues" ], "additionalProperties": true }, "nullable": false, "handle": "state" }, { "jsonSchema": { "type": "boolean" }, "nullable": false, "handle": "more" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "issueId" } ], "name": "Collect issue conversations", "moduleId": "n_42c730280961a0a0", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_b1879de13de77e99": { "inputs": {}, "name": "More issue conversations", "kind": "condition", "matchMode": "first", "cases": [ { "output": "more", "groups": [ { "expressions": [ { "left": { "kind": "source", "source": { "kind": "node", "nodeId": "n_bdd0d487d320ce00", "output": "more" } }, "operator": "==", "right": { "kind": "value", "value": true } } ] } ] } ] }, "n_2e4927957a0ae23d": { "inputs": { "issue_id": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_bdd0d487d320ce00", "output": "issueId" } ] } }, "name": "Read first fifty comments", "kind": "task", "task": { "inputs": [ { "description": "The issue ID to be queried.", "jsonSchema": { "type": "string", "description": "The issue ID to be queried." }, "nullable": false, "handle": "issue_id" } ], "outputs": [ { "description": "issue details object.", "jsonSchema": { "type": "object", "additionalProperties": false, "description": "issue details object.", "properties": { "id": { "type": "string", "description": "issue unique identifier." }, "identifier": { "type": "string", "description": "Issue abbreviation identifier." }, "title": { "type": "string", "description": "issue title." }, "description": { "type": [ "string", "null" ], "description": "issue description." }, "url": { "type": "string", "description": "issue link." }, "createdAt": { "type": "string", "description": "issue creation time." }, "updatedAt": { "type": "string", "description": "issue update time." }, "archivedAt": { "type": [ "string", "null" ], "description": "Issue filing time." }, "dueDate": { "type": [ "string", "null" ], "description": "issue deadline." }, "priority": { "type": [ "number", "null" ], "description": "issue priority." }, "estimate": { "type": [ "number", "null" ], "description": "issue estimate." }, "team": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "The team's unique identifier." }, "name": { "type": "string", "description": "Team name." }, "key": { "type": "string", "description": "The team shorthand key." } }, "required": [ "id", "name" ], "additionalProperties": false, "description": "Team information." }, "state": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "The unique identifier of the status." }, "name": { "type": "string", "description": "Status name." }, "type": { "type": "string", "description": "Status type." }, "color": { "type": "string", "description": "Status color." }, "description": { "type": "string", "description": "Status description." } }, "required": [ "id", "name" ], "additionalProperties": false, "description": "Current workflow status." }, "project": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "The unique identifier of the project." }, "name": { "type": "string", "description": "Project name." }, "slugId": { "type": "string", "description": "Project slug identifier." }, "url": { "type": "string", "description": "Project link." }, "state": { "type": "string", "description": "Project status." }, "health": { "type": [ "string", "null" ], "description": "Project health status." }, "progress": { "type": "number", "description": "Project progress." }, "priority": { "type": "number", "description": "Project priority." }, "priorityLabel": { "type": "string", "description": "Project priority label." }, "scope": { "type": "number", "description": "Project scope value." }, "color": { "type": [ "string", "null" ], "description": "Item color." }, "description": { "type": [ "string", "null" ], "description": "Project description." }, "icon": { "type": [ "string", "null" ], "description": "Project icon." }, "startDate": { "type": [ "string", "null" ], "description": "Project start date." }, "targetDate": { "type": [ "string", "null" ], "description": "Project target date." }, "createdAt": { "type": "string", "description": "Project creation time." }, "updatedAt": { "type": "string", "description": "Project update time." }, "lead": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "User unique identifier." }, "name": { "type": "string", "description": "User name." }, "displayName": { "type": "string", "description": "User display name." }, "email": { "type": "string", "description": "User email." }, "avatarUrl": { "type": "string", "description": "User avatar address." }, "active": { "type": "boolean", "description": "Whether the user is active." }, "admin": { "type": "boolean", "description": "Whether the user is an administrator." }, "createdAt": { "type": "string", "description": "User creation time." } }, "required": [ "id" ], "additionalProperties": false, "description": "Project leader." }, "creator": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "User unique identifier." }, "name": { "type": "string", "description": "User name." }, "displayName": { "type": "string", "description": "User display name." }, "email": { "type": "string", "description": "User email." }, "avatarUrl": { "type": "string", "description": "User avatar address." }, "active": { "type": "boolean", "description": "Whether the user is active." }, "admin": { "type": "boolean", "description": "Whether the user is an administrator." }, "createdAt": { "type": "string", "description": "User creation time." } }, "required": [ "id" ], "additionalProperties": false, "description": "Project creator." }, "status": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "Unique identifier of project status." }, "name": { "type": "string", "description": "Project status name." }, "type": { "type": "string", "description": "Project status type." }, "color": { "type": "string", "description": "Project status color." }, "description": { "type": "string", "description": "Project status description." } }, "required": [ "id", "name" ], "additionalProperties": false, "description": "Project status object." } }, "required": [ "id", "name" ], "additionalProperties": false, "description": "Project information." }, "assignee": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "User unique identifier." }, "name": { "type": "string", "description": "User name." }, "displayName": { "type": "string", "description": "User display name." }, "email": { "type": "string", "description": "User email." }, "avatarUrl": { "type": "string", "description": "User avatar address." }, "active": { "type": "boolean", "description": "Whether the user is active." }, "admin": { "type": "boolean", "description": "Whether the user is an administrator." }, "createdAt": { "type": "string", "description": "User creation time." } }, "required": [ "id" ], "additionalProperties": false, "description": "Current person in charge information." }, "labels": { "type": "object", "properties": { "nodes": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "description": "Tag unique identifier." }, "name": { "type": "string", "description": "Tag name." }, "color": { "type": "string", "description": "Label color." }, "description": { "type": "string", "description": "Tag description." }, "is_group": { "type": "boolean", "description": "Whether to group labels." }, "isGroup": { "type": "boolean", "description": "Whether to group labels." }, "parent": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "The unique identifier of the parent label group." }, "name": { "type": "string", "description": "The name of the parent label group." } }, "required": [ "id", "name" ], "additionalProperties": false, "description": "Parent label group information." } }, "required": [ "id", "name" ], "additionalProperties": false, "description": "Linear label object." }, "description": "tag list." } }, "required": [ "nodes" ], "additionalProperties": false, "description": "issue tag connection." }, "creator": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "User unique identifier." }, "name": { "type": "string", "description": "User name." }, "displayName": { "type": "string", "description": "User display name." }, "email": { "type": "string", "description": "User email." }, "avatarUrl": { "type": "string", "description": "User avatar address." }, "active": { "type": "boolean", "description": "Whether the user is active." }, "admin": { "type": "boolean", "description": "Whether the user is an administrator." }, "createdAt": { "type": "string", "description": "User creation time." } }, "required": [ "id" ], "additionalProperties": false, "description": "Issue creator information." }, "cycle": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "The unique identifier of the cycle." }, "name": { "type": "string", "description": "Cycle name." }, "number": { "type": "number", "description": "Cycle number." }, "description": { "type": "string", "description": "Cycle description." }, "startsAt": { "type": "string", "description": "Cycle start time." }, "endsAt": { "type": "string", "description": "Cycle end time." }, "completedAt": { "type": "string", "description": "Cycle completion time." }, "isActive": { "type": "boolean", "description": "Whether it is the current activation period." }, "isFuture": { "type": "boolean", "description": "Whether it is a future period." }, "isPast": { "type": "boolean", "description": "Whether it is a past period." }, "team": { "type": "object", "properties": { "id": { "type": "string", "description": "The team's unique identifier." }, "name": { "type": "string", "description": "Team name." }, "key": { "type": "string", "description": "The team shorthand key." } }, "required": [ "id", "name" ], "additionalProperties": false, "description": "Team information." } }, "required": [ "id", "name" ], "additionalProperties": false, "description": "The cycle to which the issue belongs." }, "parent": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "The unique identifier of the parent issue." }, "identifier": { "type": "string", "description": "The abbreviated identifier of the parent issue." }, "title": { "type": "string", "description": "Parent issue title." } }, "required": [ "id", "identifier", "title" ], "additionalProperties": false, "description": "Parent issue information." }, "attachments": { "type": "object", "properties": { "nodes": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "description": "The unique identifier of the attachment." }, "title": { "type": "string", "description": "Attachment title." }, "subtitle": { "type": [ "string", "null" ], "description": "Attachment subtitle." }, "url": { "type": "string", "description": "Attachment link." }, "sourceType": { "type": [ "string", "null" ], "description": "Attachment source type." }, "metadata": { "type": "object", "additionalProperties": { "description": "A record value." }, "description": "Attachment metadata." }, "source": { "type": [ "object", "null" ], "additionalProperties": { "description": "A record value." }, "description": "Attachment source information." }, "issue": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "Unique identifier associated with the issue." }, "identifier": { "type": "string", "description": "Associated issue abbreviation identifier." }, "title": { "type": "string", "description": "Associated issue title." } }, "required": [ "id" ], "additionalProperties": false, "description": "The issue to which the attachment belongs." }, "createdAt": { "type": "string", "description": "The time the attachment was created." }, "updatedAt": { "type": "string", "description": "Attachment update time." } }, "required": [ "id", "title", "url" ], "additionalProperties": false, "description": "Linear attachment object." }, "description": "Attachment list." }, "pageInfo": { "type": "object", "properties": { "startCursor": { "type": [ "string", "null" ], "description": "The starting point of the cursor on the previous page." }, "endCursor": { "type": [ "string", "null" ], "description": "The end cursor for the next page." }, "hasPreviousPage": { "type": "boolean", "description": "Whether there is a previous page." }, "hasNextPage": { "type": "boolean", "description": "Whether the next page exists." } }, "required": [ "endCursor", "hasNextPage" ], "additionalProperties": false, "description": "Attachment paging information." } }, "required": [ "nodes" ], "additionalProperties": false, "description": "issue attachment connection." }, "comments": { "type": "object", "properties": { "nodes": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "description": "The unique identifier of the comment." }, "body": { "type": "string", "description": "Comment text." }, "url": { "type": "string", "description": "Comment link." }, "quotedText": { "type": [ "string", "null" ], "description": "Quote text." }, "createdAt": { "type": "string", "description": "Comment creation time." }, "updatedAt": { "type": "string", "description": "Comment updated time." }, "editedAt": { "type": [ "string", "null" ], "description": "Comment editing time." }, "resolvedAt": { "type": [ "string", "null" ], "description": "Comment resolution time." }, "issueId": { "type": [ "string", "null" ], "description": "Unique identifier associated with the issue." }, "parentId": { "type": [ "string", "null" ], "description": "The unique identifier of the parent comment." }, "projectUpdateId": { "type": [ "string", "null" ], "description": "Associated project updates unique identifier." }, "user": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "User unique identifier." }, "name": { "type": "string", "description": "User name." }, "displayName": { "type": "string", "description": "User display name." }, "email": { "type": "string", "description": "User email." }, "avatarUrl": { "type": "string", "description": "User avatar address." }, "active": { "type": "boolean", "description": "Whether the user is active." }, "admin": { "type": "boolean", "description": "Whether the user is an administrator." }, "createdAt": { "type": "string", "description": "User creation time." } }, "required": [ "id" ], "additionalProperties": false, "description": "Comment author information." }, "reactions": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "description": "Reaction unique identifier." }, "emoji": { "type": "string", "description": "The emoji used by the reaction." }, "createdAt": { "type": "string", "description": "Reaction creation time." }, "updatedAt": { "type": "string", "description": "Response update time." }, "user": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "User unique identifier." }, "name": { "type": "string", "description": "User name." }, "displayName": { "type": "string", "description": "User display name." }, "email": { "type": "string", "description": "User email." }, "avatarUrl": { "type": "string", "description": "User avatar address." }, "active": { "type": "boolean", "description": "Whether the user is active." }, "admin": { "type": "boolean", "description": "Whether the user is an administrator." }, "createdAt": { "type": "string", "description": "User creation time." } }, "required": [ "id" ], "additionalProperties": false, "description": "The user who triggered the reaction." }, "comment": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "The unique identifier of the comment." } }, "required": [ "id" ], "additionalProperties": false, "description": "The comment value." }, "issue": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "issue unique identifier." }, "identifier": { "type": "string", "description": "Issue abbreviation identifier." } }, "required": [ "id" ], "additionalProperties": false, "description": "The issue value." }, "projectUpdate": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "Project update unique identifier." } }, "required": [ "id" ], "additionalProperties": false, "description": "The projectUpdate value." } }, "required": [ "id", "emoji" ], "additionalProperties": false, "description": "Linear reaction object." }, "description": "List of reactions on comments." } }, "required": [ "id" ], "additionalProperties": false, "description": "Linear comment object." }, "description": "Comments list." }, "pageInfo": { "type": "object", "properties": { "startCursor": { "type": [ "string", "null" ], "description": "The starting point of the cursor on the previous page." }, "endCursor": { "type": [ "string", "null" ], "description": "The end cursor for the next page." }, "hasPreviousPage": { "type": "boolean", "description": "Whether there is a previous page." }, "hasNextPage": { "type": "boolean", "description": "Whether the next page exists." } }, "required": [ "endCursor", "hasNextPage" ], "additionalProperties": false, "description": "Comment pagination information." } }, "required": [ "nodes" ], "additionalProperties": false, "description": "issue comment link." }, "subscribers": { "type": "object", "properties": { "nodes": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "description": "User unique identifier." }, "name": { "type": "string", "description": "User name." }, "displayName": { "type": "string", "description": "User display name." }, "email": { "type": "string", "description": "User email." }, "avatarUrl": { "type": "string", "description": "User avatar address." }, "active": { "type": "boolean", "description": "Whether the user is active." }, "admin": { "type": "boolean", "description": "Whether the user is an administrator." }, "createdAt": { "type": "string", "description": "User creation time." } }, "required": [ "id" ], "additionalProperties": false, "description": "Linear user object." }, "description": "Subscriber list." }, "pageInfo": { "type": "object", "properties": { "startCursor": { "type": [ "string", "null" ], "description": "The starting point of the cursor on the previous page." }, "endCursor": { "type": [ "string", "null" ], "description": "The end cursor for the next page." }, "hasPreviousPage": { "type": "boolean", "description": "Whether there is a previous page." }, "hasNextPage": { "type": "boolean", "description": "Whether the next page exists." } }, "required": [ "endCursor", "hasNextPage" ], "additionalProperties": false, "description": "Subscriber pagination information." } }, "required": [ "nodes" ], "additionalProperties": false, "description": "issue subscriber connection." }, "reactions": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "description": "Reaction unique identifier." }, "emoji": { "type": "string", "description": "The emoji used by the reaction." }, "createdAt": { "type": "string", "description": "Reaction creation time." }, "updatedAt": { "type": "string", "description": "Response update time." }, "user": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "User unique identifier." }, "name": { "type": "string", "description": "User name." }, "displayName": { "type": "string", "description": "User display name." }, "email": { "type": "string", "description": "User email." }, "avatarUrl": { "type": "string", "description": "User avatar address." }, "active": { "type": "boolean", "description": "Whether the user is active." }, "admin": { "type": "boolean", "description": "Whether the user is an administrator." }, "createdAt": { "type": "string", "description": "User creation time." } }, "required": [ "id" ], "additionalProperties": false, "description": "The user who triggered the reaction." }, "comment": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "The unique identifier of the comment." } }, "required": [ "id" ], "additionalProperties": false, "description": "The comment value." }, "issue": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "issue unique identifier." }, "identifier": { "type": "string", "description": "Issue abbreviation identifier." } }, "required": [ "id" ], "additionalProperties": false, "description": "The issue value." }, "projectUpdate": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "Project update unique identifier." } }, "required": [ "id" ], "additionalProperties": false, "description": "The projectUpdate value." } }, "required": [ "id", "emoji" ], "additionalProperties": false, "description": "Linear reaction object." }, "description": "List of reactions on the issue." } }, "required": [ "id", "identifier", "title", "createdAt", "updatedAt" ] }, "nullable": false, "handle": "issue" } ], "name": "Read first fifty comments", "executor": { "kind": "connector", "action": "linear.get_linear_issue" } } }, "n_373e36f69cec7ece": { "inputs": { "issues": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_bdd0d487d320ce00", "output": "state", "field": "issues" } ] }, "previousState": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_373e36f69cec7ece", "output": "state" } ] }, "formatInstructions": { "kind": "value", "value": "You must format your output as a JSON value that adheres to a given \"JSON Schema\" instance.\n\n\"JSON Schema\" is a declarative language that allows you to annotate and validate JSON documents.\n\nFor example, the example \"JSON Schema\" instance {{\"properties\": {{\"foo\": {{\"description\": \"a list of test words\", \"type\": \"array\", \"items\": {{\"type\": \"string\"}}}}}}, \"required\": [\"foo\"]}}}}\nwould match an object with one required property, \"foo\". The \"type\" property specifies \"foo\" must be an \"array\", and the \"description\" property semantically describes it as \"a list of test words\". The items within \"foo\" must be strings.\nThus, the object {{\"foo\": [\"bar\", \"baz\"]}} is a well-formatted instance of this example \"JSON Schema\". The object {{\"properties\": {{\"foo\": [\"bar\", \"baz\"]}}}} is not well-formatted.\n\nYour output will be parsed and type-checked according to the provided schema instance, so make sure all fields in your output match the schema exactly and there are no trailing commas!\n\nHere is the JSON Schema instance your output must adhere to. Include the enclosing markdown codeblock:\n```json\n{\"type\":\"object\",\"properties\":{\"sentiment\":{\"type\":\"string\",\"enum\":[\"positive\",\"negative\",\"neutral\"],\"description\":\"One of positive, negative or neutral\"},\"sentimentSummary\":{\"type\":\"string\",\"description\":\"Describe the sentiment of the conversation\"}},\"required\":[\"sentiment\"],\"additionalProperties\":false,\"$schema\":\"http://json-schema.org/draft-07/schema#\"}\n```\n" }, "systemPrompt": { "kind": "value", "value": "You are an expert extraction algorithm.\nOnly extract relevant information from the text.\nIf you do not know the value of an attribute asked to extract, you may omit the attribute's value." }, "repairTemplate": { "kind": "value", "value": "Instructions:\n--------------\n{instructions}\n--------------\nCompletion:\n--------------\n{completion}\n--------------\n\nAbove, the Completion did not satisfy the constraints given in the Instructions.\nError:\n--------------\n{error}\n--------------\n\nPlease try again. Please only respond with an answer that satisfies the constraints laid out in the Instructions:" }, "response": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_8a8241031867d40e", "output": "output" } ] } }, "name": "Collect issue sentiments", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "array", "items": { "type": "object", "additionalProperties": true } }, "nullable": false, "handle": "issues" }, { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": true, "handle": "previousState" }, { "jsonSchema": { "type": "string" }, "nullable": true, "handle": "response" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "formatInstructions" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "systemPrompt" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "repairTemplate" } ], "outputs": [ { "jsonSchema": { "type": "object", "properties": { "drafts": { "type": "array", "items": { "type": "object", "additionalProperties": true } } }, "required": [ "drafts" ], "additionalProperties": true }, "nullable": false, "handle": "state" }, { "jsonSchema": { "type": "boolean" }, "nullable": false, "handle": "more" }, { "jsonSchema": { "type": "boolean" }, "nullable": false, "handle": "repair" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "prompt" } ], "name": "Collect issue sentiments", "moduleId": "n_e3fe1ffd9e026d2c", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_76fca7cb94487499": { "inputs": {}, "name": "More analysis or repair", "kind": "condition", "matchMode": "first", "cases": [ { "output": "more", "groups": [ { "expressions": [ { "left": { "kind": "source", "source": { "kind": "node", "nodeId": "n_373e36f69cec7ece", "output": "more" } }, "operator": "==", "right": { "kind": "value", "value": true } } ] } ] } ] }, "n_8a8241031867d40e": { "inputs": { "prompt": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_373e36f69cec7ece", "output": "prompt" } ] } }, "name": "Analyze or repair sentiment", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "prompt" } ], "outputs": [ { "description": "The final result produced by the Agent.", "jsonSchema": { "type": "string" }, "nullable": false, "handle": "output" } ], "name": "Analyze or repair sentiment", "executor": { "kind": "agent", "code": false, "model": "gpt-5-mini", "prompt": "{{prompt}}", "maxRounds": 1, "tools": [] } } }, "n_ab7c079d7b6c3f04": { "inputs": { "drafts": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_373e36f69cec7ece", "output": "state", "field": "drafts" } ] }, "previousState": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_ab7c079d7b6c3f04", "output": "state" } ] }, "records": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_3114b99d37aafd66", "output": "records" } ] }, "offset": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_3114b99d37aafd66", "output": "offset" } ] }, "body": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_b2dbe55a782d9dd1", "output": "body" } ] }, "statusCode": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_b2dbe55a782d9dd1", "output": "statusCode" } ] }, "bodyEncoding": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_b2dbe55a782d9dd1", "output": "bodyEncoding" } ] } }, "name": "Collect sentiment receipts", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "array", "items": { "type": "object", "additionalProperties": true } }, "nullable": false, "handle": "drafts" }, { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": true, "handle": "previousState" }, { "jsonSchema": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "description": "Record ID." }, "createdTime": { "type": "string", "description": "Record creation timestamp returned by Airtable." }, "fields": { "type": "object", "additionalProperties": { "description": "A record value." }, "description": "Record fields keyed by field name or field ID." }, "commentCount": { "type": "integer", "description": "Comment count returned by Airtable when enabled on the endpoint." } }, "required": [ "id", "fields" ], "additionalProperties": true, "description": "Airtable record." }, "description": "Records returned by Airtable." }, "nullable": true, "handle": "records" }, { "jsonSchema": { "type": [ "string", "null" ], "description": "Pagination cursor for the next page of records, or null when unavailable." }, "nullable": true, "handle": "offset" }, { "jsonSchema": {}, "nullable": true, "handle": "body" }, { "jsonSchema": { "type": "integer" }, "nullable": true, "handle": "statusCode" }, { "jsonSchema": { "const": "base64" }, "nullable": true, "handle": "bodyEncoding" } ], "outputs": [ { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": false, "handle": "state" }, { "jsonSchema": { "type": "boolean" }, "nullable": false, "handle": "lookup" }, { "jsonSchema": { "type": "boolean" }, "nullable": false, "handle": "upsert" }, { "jsonSchema": { "type": "string", "minLength": 1 }, "nullable": false, "handle": "filterByFormula" }, { "jsonSchema": { "type": "string", "minLength": 1, "description": "Opaque pagination cursor returned by a previous Airtable response." }, "nullable": true, "handle": "offset" }, { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": false, "handle": "body" }, { "jsonSchema": { "type": "integer" }, "nullable": false, "handle": "count" }, { "jsonSchema": { "type": "array", "items": { "type": "object", "additionalProperties": true } }, "nullable": false, "handle": "saved" }, { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": false, "handle": "report" } ], "name": "Collect sentiment receipts", "moduleId": "n_ff97375a0a7d5ba1", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_737244bd65bcf46d": { "inputs": {}, "name": "Next sentiment storage step", "kind": "condition", "matchMode": "first", "cases": [ { "output": "lookup", "groups": [ { "expressions": [ { "left": { "kind": "source", "source": { "kind": "node", "nodeId": "n_ab7c079d7b6c3f04", "output": "lookup" } }, "operator": "==", "right": { "kind": "value", "value": true } } ] } ] }, { "output": "upsert", "groups": [ { "expressions": [ { "left": { "kind": "source", "source": { "kind": "node", "nodeId": "n_ab7c079d7b6c3f04", "output": "upsert" } }, "operator": "==", "right": { "kind": "value", "value": true } } ] } ] } ] }, "n_3114b99d37aafd66": { "inputs": { "baseId": { "kind": "value", "value": "app00000000000000" }, "tableIdOrName": { "kind": "value", "value": "YOUR_SENTIMENT_TABLE" }, "filterByFormula": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_ab7c079d7b6c3f04", "output": "filterByFormula" } ] }, "fields": { "kind": "value", "value": [ "Issue ID", "Current Sentiment" ] }, "pageSize": { "kind": "value", "value": 100 }, "offset": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_ab7c079d7b6c3f04", "output": "offset" } ] } }, "name": "Find previous sentiment", "kind": "task", "task": { "inputs": [ { "description": "Base ID in the format appXXXXXXXXXXXXXX.", "jsonSchema": { "type": "string", "minLength": 1, "description": "Base ID in the format appXXXXXXXXXXXXXX." }, "nullable": false, "handle": "baseId" }, { "description": "Table ID or table name accepted by the Airtable path parameter.", "jsonSchema": { "type": "string", "minLength": 1, "description": "Table ID or table name accepted by the Airtable path parameter." }, "nullable": false, "handle": "tableIdOrName" }, { "description": "View name or view ID used by Airtable to filter and sort results.", "jsonSchema": { "type": "string", "minLength": 1, "description": "View name or view ID used by Airtable to filter and sort results." }, "nullable": true, "handle": "view", "value": null }, { "description": "Field names or field IDs to include in the Airtable response.", "jsonSchema": { "type": "array", "items": { "type": "string", "minLength": 1, "description": "An array item." }, "minItems": 1, "description": "Field names or field IDs to include in the Airtable response." }, "nullable": true, "handle": "fields", "value": null }, { "description": "Sort rules applied by Airtable in order.", "jsonSchema": { "type": "array", "items": { "type": "object", "properties": { "field": { "type": "string", "minLength": 1, "description": "Field name or field ID used by Airtable for sorting." }, "direction": { "type": "string", "enum": [ "asc", "desc" ], "description": "Sort direction accepted by Airtable." } }, "required": [ "field" ], "additionalProperties": false, "description": "Sort rule accepted by the Airtable list records endpoint." }, "minItems": 1, "description": "Sort rules applied by Airtable in order." }, "nullable": true, "handle": "sort", "value": null }, { "description": "Formula string evaluated by Airtable to filter matching records.", "jsonSchema": { "type": "string", "minLength": 1, "description": "Formula string evaluated by Airtable to filter matching records." }, "nullable": true, "handle": "filterByFormula", "value": null }, { "description": "Maximum total number of records to return before Airtable stops pagination.", "jsonSchema": { "type": "integer", "minimum": 1, "description": "Maximum total number of records to return before Airtable stops pagination." }, "nullable": true, "handle": "maxRecords", "value": null }, { "description": "Number of records to return per page.", "jsonSchema": { "type": "integer", "minimum": 1, "maximum": 100, "description": "Number of records to return per page." }, "nullable": true, "handle": "pageSize", "value": null }, { "description": "Opaque pagination cursor returned by a previous Airtable response.", "jsonSchema": { "type": "string", "minLength": 1, "description": "Opaque pagination cursor returned by a previous Airtable response." }, "nullable": true, "handle": "offset", "value": null }, { "description": "Cell format accepted by Airtable for read operations.", "jsonSchema": { "type": "string", "enum": [ "json", "string" ], "description": "Cell format accepted by Airtable for read operations." }, "nullable": true, "handle": "cellFormat", "value": null }, { "description": "Timezone string sent to Airtable when cellFormat is string.", "jsonSchema": { "type": "string", "minLength": 1, "description": "Timezone string sent to Airtable when cellFormat is string." }, "nullable": true, "handle": "timeZone", "value": null }, { "description": "User locale sent to Airtable when cellFormat is string.", "jsonSchema": { "type": "string", "minLength": 1, "description": "User locale sent to Airtable when cellFormat is string." }, "nullable": true, "handle": "userLocale", "value": null }, { "description": "Whether Airtable should return field IDs instead of field names in record objects.", "jsonSchema": { "type": "boolean", "description": "Whether Airtable should return field IDs instead of field names in record objects." }, "nullable": true, "handle": "returnFieldsByFieldId", "value": null }, { "description": "Whether Airtable should return date dependency metadata for linked record fields.", "jsonSchema": { "type": "boolean", "description": "Whether Airtable should return date dependency metadata for linked record fields." }, "nullable": true, "handle": "includeDateDependencyMetadata", "value": null }, { "description": "Record metadata fields to include in Airtable list records responses.", "jsonSchema": { "type": "array", "items": { "const": "commentCount", "description": "An array item." }, "minItems": 1, "description": "Record metadata fields to include in Airtable list records responses." }, "nullable": true, "handle": "recordMetadata", "value": null } ], "outputs": [ { "description": "Records returned by Airtable.", "jsonSchema": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "description": "Record ID." }, "createdTime": { "type": "string", "description": "Record creation timestamp returned by Airtable." }, "fields": { "type": "object", "additionalProperties": { "description": "A record value." }, "description": "Record fields keyed by field name or field ID." }, "commentCount": { "type": "integer", "description": "Comment count returned by Airtable when enabled on the endpoint." } }, "required": [ "id", "fields" ], "additionalProperties": true, "description": "Airtable record." }, "description": "Records returned by Airtable." }, "nullable": false, "handle": "records" }, { "description": "Pagination cursor for the next page of records, or null when unavailable.", "jsonSchema": { "type": [ "string", "null" ], "description": "Pagination cursor for the next page of records, or null when unavailable." }, "nullable": true, "handle": "offset" } ], "name": "Find previous sentiment", "executor": { "kind": "connector", "action": "airtable.list_records" } } }, "n_b2dbe55a782d9dd1": { "inputs": { "endpoint": { "kind": "value", "value": "/v0/app00000000000000/YOUR_SENTIMENT_TABLE" }, "body": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_ab7c079d7b6c3f04", "output": "body" } ] } }, "name": "Upsert sentiment atomically", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "endpoint" }, { "jsonSchema": {}, "nullable": true, "handle": "body" } ], "outputs": [ { "jsonSchema": {}, "nullable": true, "handle": "body" }, { "jsonSchema": { "type": "integer" }, "nullable": false, "handle": "statusCode" }, { "jsonSchema": { "type": "object", "additionalProperties": { "type": "string" } }, "nullable": false, "handle": "headers" }, { "jsonSchema": { "const": "base64" }, "nullable": true, "handle": "bodyEncoding" } ], "name": "Upsert sentiment atomically", "executor": { "providerId": "airtable", "method": "PATCH", "query": { "mode": "fields", "names": [] }, "headers": { "mode": "fields", "names": [] }, "bodyFormat": "json", "kind": "connector-proxy" } } }, "n_3126a5720004cea1": { "name": "Poll changes hourly UTC", "kind": "poll", "config": { "baseId": { "kind": "value", "value": "app00000000000000" }, "tableIdOrName": { "kind": "value", "value": "YOUR_SENTIMENT_TABLE" }, "triggerField": { "kind": "value", "value": "Last Modified" }, "fields": { "kind": "value", "value": [ "Issue ID", "Previous Sentiment", "Current Sentiment", "Issue Title", "Summary", "Last Modified" ] }, "formula": { "kind": "value", "value": "" }, "view": { "kind": "value", "value": "" }, "maxRecordsPerPoll": { "kind": "value", "value": 200 } }, "definition": { "configInputs": [ { "jsonSchema": { "type": "string", "pattern": "^app[A-Za-z0-9]{14}$" }, "nullable": false, "handle": "baseId" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "formula", "value": "" }, { "jsonSchema": { "type": "string", "minLength": 1, "maxLength": 255 }, "nullable": false, "handle": "tableIdOrName" }, { "jsonSchema": { "type": "string", "minLength": 1, "maxLength": 255, "pattern": "^[^}]*$" }, "nullable": false, "handle": "triggerField" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "view", "value": "" }, { "collapsed": true, "group": "Advanced settings" }, { "jsonSchema": { "type": "array", "items": { "type": "string", "minLength": 1 } }, "nullable": false, "handle": "fields", "value": [] }, { "jsonSchema": { "type": "integer", "minimum": 1, "maximum": 1000 }, "nullable": false, "handle": "maxRecordsPerPoll", "value": 200 } ], "definitionVersion": 2, "description": "Polls an Airtable table and triggers when a record is created or updated, ordered by a time field.", "displayName": "Record Created or Updated", "key": "airtable.on_record_changed", "name": "on_record_changed", "outputs": [ { "jsonSchema": { "type": "array", "items": { "type": "object", "properties": { "baseId": { "type": "string" }, "createdTime": { "type": "string" }, "fields": { "type": "object" }, "recordId": { "type": "string" }, "tableIdOrName": { "type": "string" }, "triggerField": { "type": "string" }, "triggerFieldValue": { "type": "string" } }, "additionalProperties": false, "required": [ "baseId", "tableIdOrName", "recordId", "createdTime", "triggerField", "triggerFieldValue", "fields" ] } }, "nullable": false, "handle": "events" } ], "provider": "airtable", "type": "poll" }, "pollTimes": [ { "type": "cron", "expression": "0 * * * *", "timezone": "UTC" } ] }, "n_df544e824481fbd2": { "inputs": { "events": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_3126a5720004cea1", "output": "events" } ] }, "issueUrlBase": { "kind": "value", "value": "https://linear.app/YOUR_ORGANIZATION/issue/" } }, "name": "Group negative transitions", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "array", "items": { "type": "object", "additionalProperties": true } }, "nullable": false, "handle": "events" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "issueUrlBase" } ], "outputs": [ { "jsonSchema": { "type": "array", "items": { "type": "object", "additionalProperties": true } }, "nullable": false, "handle": "messages" }, { "jsonSchema": { "type": "integer" }, "nullable": false, "handle": "count" } ], "name": "Group negative transitions", "moduleId": "n_0201bc3f8d030145", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_94980ea96d5308e9": { "inputs": { "messages": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_df544e824481fbd2", "output": "messages" } ] }, "transitionCount": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_df544e824481fbd2", "output": "count" } ] }, "previousState": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_94980ea96d5308e9", "output": "state" } ] }, "ts": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_3d570465ebe0ee34", "output": "ts" } ] }, "channel": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_3d570465ebe0ee34", "output": "channelId" } ] } }, "name": "Collect Slack receipts", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "array", "items": { "type": "object", "additionalProperties": true } }, "nullable": false, "handle": "messages" }, { "jsonSchema": { "type": "integer" }, "nullable": false, "handle": "transitionCount" }, { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": true, "handle": "previousState" }, { "jsonSchema": { "type": "string", "description": "The timestamp identifier of the posted message." }, "nullable": true, "handle": "ts" }, { "jsonSchema": { "type": "string", "description": "The channel ID where the message was posted." }, "nullable": true, "handle": "channel" } ], "outputs": [ { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": false, "handle": "state" }, { "jsonSchema": { "type": "boolean" }, "nullable": false, "handle": "more" }, { "jsonSchema": { "type": "array", "items": { "type": "object", "properties": {}, "additionalProperties": true, "description": "A Slack Block Kit block object. Pass the block exactly as Slack documents it." }, "minItems": 1, "description": "Slack Block Kit blocks to render in the message." }, "nullable": true, "handle": "blocks" }, { "jsonSchema": { "type": "string", "minLength": 1 }, "nullable": false, "handle": "text" }, { "jsonSchema": { "type": "array", "items": { "type": "object", "additionalProperties": true } }, "nullable": false, "handle": "notifications" }, { "jsonSchema": { "type": "integer" }, "nullable": false, "handle": "transitionCount" }, { "jsonSchema": { "type": "integer" }, "nullable": false, "handle": "messageCount" }, { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": false, "handle": "report" } ], "name": "Collect Slack receipts", "moduleId": "n_db9a143e41fa5613", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_59c4562d21905d70": { "inputs": {}, "name": "More grouped alerts", "kind": "condition", "matchMode": "first", "cases": [ { "output": "more", "groups": [ { "expressions": [ { "left": { "kind": "source", "source": { "kind": "node", "nodeId": "n_94980ea96d5308e9", "output": "more" } }, "operator": "==", "right": { "kind": "value", "value": true } } ] } ] } ] }, "n_3d570465ebe0ee34": { "inputs": { "channelId": { "kind": "value", "value": "YOUR_SLACK_CHANNEL_ID" }, "blocks": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_94980ea96d5308e9", "output": "blocks" } ] }, "text": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_94980ea96d5308e9", "output": "text" } ] }, "unfurlLinks": { "kind": "value", "value": false }, "unfurlMedia": { "kind": "value", "value": false } }, "name": "Send grouped Slack alert", "kind": "task", "task": { "inputs": [ { "description": "The Slack conversation or channel ID.", "jsonSchema": { "type": "string", "minLength": 1, "description": "The Slack conversation or channel ID." }, "nullable": false, "handle": "channelId" }, { "description": "Plain text message content. When blocks are provided, Slack uses this as notification and accessibility fallback text.", "jsonSchema": { "type": "string", "description": "Plain text message content. When blocks are provided, Slack uses this as notification and accessibility fallback text." }, "nullable": true, "handle": "text", "value": null }, { "description": "Slack Block Kit blocks to render in the message.", "jsonSchema": { "type": "array", "items": { "type": "object", "properties": {}, "additionalProperties": true, "description": "A Slack Block Kit block object. Pass the block exactly as Slack documents it." }, "minItems": 1, "description": "Slack Block Kit blocks to render in the message." }, "nullable": true, "handle": "blocks", "value": null }, { "description": "Slack legacy attachments to include in the message.", "jsonSchema": { "type": "array", "items": { "type": "object", "properties": {}, "additionalProperties": true, "description": "A Slack legacy attachment object. Prefer blocks for new messages when possible." }, "minItems": 1, "description": "Slack legacy attachments to include in the message." }, "nullable": true, "handle": "attachments", "value": null }, { "description": "Whether Slack should unfurl links in the message.", "jsonSchema": { "type": "boolean", "description": "Whether Slack should unfurl links in the message." }, "nullable": true, "handle": "unfurlLinks", "value": null }, { "description": "Whether Slack should unfurl media in the message.", "jsonSchema": { "type": "boolean", "description": "Whether Slack should unfurl media in the message." }, "nullable": true, "handle": "unfurlMedia", "value": null }, { "description": "Slack message metadata to attach to the message.", "jsonSchema": { "type": "object", "properties": {}, "additionalProperties": true, "description": "Slack message metadata to attach to the message." }, "nullable": true, "handle": "metadata", "value": null } ], "outputs": [ { "description": "The timestamp identifier of the posted message.", "jsonSchema": { "type": "string", "description": "The timestamp identifier of the posted message." }, "nullable": false, "handle": "ts" }, { "description": "The channel ID where the message was posted.", "jsonSchema": { "type": "string", "description": "The channel ID where the message was posted." }, "nullable": false, "handle": "channelId" } ], "name": "Send grouped Slack alert", "executor": { "kind": "connector", "action": "slack.post_message" } } }, "n_b7fb6ed8806409bc": { "name": "Sentiment workflow result", "kind": "outputs", "outputDefs": [ { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": false, "handle": "report" } ], "outputMappings": { "report": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_ab7c079d7b6c3f04", "output": "report" }, { "kind": "node", "nodeId": "n_94980ea96d5308e9", "output": "report" } ] } } } }, "edges": [ { "source": "n_be21c465e33fbb33", "target": "n_bfccdb99ea52e0fa" }, { "source": "n_9132d1ab472858ec", "target": "n_bfccdb99ea52e0fa" }, { "source": "n_bfccdb99ea52e0fa", "target": "n_6238c23f922e6ad4" }, { "source": "n_6238c23f922e6ad4", "target": "n_bdd0d487d320ce00" }, { "source": "n_bdd0d487d320ce00", "target": "n_b1879de13de77e99" }, { "source": "n_b1879de13de77e99", "target": "n_2e4927957a0ae23d", "sourceHandle": "more" }, { "source": "n_2e4927957a0ae23d", "target": "n_bdd0d487d320ce00" }, { "source": "n_b1879de13de77e99", "target": "n_373e36f69cec7ece", "sourceHandle": "otherwise" }, { "source": "n_373e36f69cec7ece", "target": "n_76fca7cb94487499" }, { "source": "n_76fca7cb94487499", "target": "n_8a8241031867d40e", "sourceHandle": "more" }, { "source": "n_8a8241031867d40e", "target": "n_373e36f69cec7ece" }, { "source": "n_76fca7cb94487499", "target": "n_ab7c079d7b6c3f04", "sourceHandle": "otherwise" }, { "source": "n_ab7c079d7b6c3f04", "target": "n_737244bd65bcf46d" }, { "source": "n_737244bd65bcf46d", "target": "n_3114b99d37aafd66", "sourceHandle": "lookup" }, { "source": "n_3114b99d37aafd66", "target": "n_ab7c079d7b6c3f04" }, { "source": "n_737244bd65bcf46d", "target": "n_b2dbe55a782d9dd1", "sourceHandle": "upsert" }, { "source": "n_b2dbe55a782d9dd1", "target": "n_ab7c079d7b6c3f04" }, { "source": "n_737244bd65bcf46d", "target": "n_b7fb6ed8806409bc", "sourceHandle": "otherwise" }, { "source": "n_3126a5720004cea1", "target": "n_df544e824481fbd2" }, { "source": "n_df544e824481fbd2", "target": "n_94980ea96d5308e9" }, { "source": "n_94980ea96d5308e9", "target": "n_59c4562d21905d70" }, { "source": "n_59c4562d21905d70", "target": "n_3d570465ebe0ee34", "sourceHandle": "more" }, { "source": "n_3d570465ebe0ee34", "target": "n_94980ea96d5308e9" }, { "source": "n_59c4562d21905d70", "target": "n_b7fb6ed8806409bc", "sourceHandle": "otherwise" } ] } }, "modules": { "n_306f66398bc767e7": { "name": "Set issue update window", "imports": [], "source": "export default function prepareSentimentScan(){return {updatedAfter:new Date(Date.now()-30*60*1000).toISOString()};}\n" }, "n_42c730280961a0a0": { "name": "Collect issue conversations", "imports": [], "source": "export default function collectSentimentDetails({issues,previousState,issue}){\n const state=previousState===null?{index:0,issues:[]}:JSON.parse(JSON.stringify(previousState));\n if(!Array.isArray(issues)||issues.length>50||new Set(issues.map(i=>i.id)).size!==issues.length)throw new Error('Expected the source first50 unique Linear issues.');\n if(previousState!==null){const expected=issues[state.index];if(!expected||!issue||issue.id!==expected.id||!Array.isArray(issue.comments?.nodes)||issue.comments.nodes.length>50)throw new Error('Linear issue detail does not match the selected issue.');\n for(const k of['id','identifier','title','createdAt','updatedAt'])if(typeof issue[k]!=='string'||!issue[k])throw new Error('Linear issue metadata is incomplete.');\n const text=issue.comments.nodes.map(c=>{if(typeof c.body!=='string'||typeof c.createdAt!=='string')throw new Error('Linear comment content is incomplete.');return (c.user?.displayName??c.user?.name??'Unknown author')+' commented on '+c.createdAt+':\\n'+c.body;}).join('---\\n');\n if(!text.trim())throw new Error('The source Information Extractor needs nonempty comment text.');\n state.issues.push({id:issue.id,identifier:issue.identifier,title:issue.title,url:issue.url,createdAt:issue.createdAt,updatedAt:issue.updatedAt,assignee:issue.assignee??null,commentText:text});state.index++;\n }\n return {state,more:state.index!['sentiment','sentimentSummary'].includes(k)))throw new Error('Expected sentiment positive/negative/neutral and optional text sentimentSummary.');return {sentiment:result.sentiment,sentimentSummary:result.sentimentSummary??''};}\nexport default function collectIssueSentiments({issues,previousState,response,formatInstructions,systemPrompt,repairTemplate}){\n const state=previousState===null?{index:0,drafts:[],repair:false,repairPrompt:''}:JSON.parse(JSON.stringify(previousState));\n if(previousState!==null){if(state.index>=issues.length)throw new Error('Unexpected sentiment completion.');try{const result=parseSentimentText(response);const {commentText,...metadata}=issues[state.index];state.drafts.push({...metadata,...result});state.index++;state.repair=false;state.repairPrompt='';}catch(error){if(state.repair)throw new Error('Sentiment format repair failed: '+error.message);state.repair=true;const replacements={instructions:formatInstructions,completion:String(response),error:error.message};state.repairPrompt=repairTemplate.replace(/\\{(instructions|completion|error)\\}/g,(_,key)=>replacements[key]);}}\n const next=issues[state.index];return {state,more:state.index1)throw new Error('Issue ID must uniquely identify an Airtable row.');\n if(offset!==null){if(typeof offset!=='string'||!offset||state.seenOffsets.includes(offset))throw new Error('Airtable lookup cursor did not advance.');state.offset=offset;state.seenOffsets.push(offset);}\n else{const prior=state.records[0]?.fields?.['Current Sentiment'];if(prior!==undefined&&typeof prior!=='string')throw new Error('Previous sentiment is not a text/select value.');state.writeBody={performUpsert:{fieldsToMergeOn:['Issue ID']},records:[{fields:{'Issue ID':draft.identifier,'Previous Sentiment':prior??'N/A','Current Sentiment':draft.sentiment[0].toUpperCase()+draft.sentiment.slice(1),Summary:draft.sentimentSummary,'Issue Title':draft.title,'Issue Created':draft.createdAt,'Issue Updated':draft.updatedAt,Assigned:draft.assignee?.name??''}}],typecast:false};state.phase='upsert';state.offset=null;}\n }else{\n if(statusCode<200||statusCode>=300||bodyEncoding!==null||!body||!Array.isArray(body.records)||body.records.length!==1||typeof body.records[0].id!=='string'||!body.records[0].id.trim()||body.records[0].fields?.['Issue ID']!==draft.identifier||body.records[0].fields?.['Current Sentiment']!==state.writeBody.records[0].fields['Current Sentiment'])throw new Error('Airtable did not confirm the expected sentiment upsert.');\n state.saved.push({issueId:draft.id,identifier:draft.identifier,recordId:body.records[0].id,currentSentiment:body.records[0].fields['Current Sentiment']});state.index++;state.phase='lookup';state.records=[];state.offset=null;state.seenOffsets=[];state.writeBody=null;\n }\n }\n const next=drafts[state.index];return {state,lookup:!!next&&state.phase==='lookup',upsert:!!next&&state.phase==='upsert',filterByFormula:next?\"{Issue ID} = '\"+next.identifier.replace(/\\\\/g,'\\\\\\\\').replace(/'/g,\"\\\\'\")+\"'\":'FALSE()',offset:state.offset,body:state.writeBody??{},count:state.saved.length,saved:state.saved,report:{kind:\"sentiment-analysis\",count:state.saved.length,saved:state.saved}};\n}\n" }, "n_0201bc3f8d030145": { "name": "Group negative transitions", "imports": [], "source": "export function escapeSentimentSlack(text){return text.replace(/&/g,'&').replace(//g,'>');}\nexport default function prepareSentimentNotices({events,issueUrlBase}){\n if(!Array.isArray(events)||typeof issueUrlBase!=='string'||!/^https:\\/\\/linear\\.app\\/[a-zA-Z0-9_-]+\\/issue\\/$/.test(issueUrlBase))throw new Error('Configure the Linear organization issue URL.');\n const seen=new Set(),transitions=[];for(const event of events){const f=event.fields;if(!f||typeof f!=='object')throw new Error('Airtable event fields are missing.');if(f['Previous Sentiment']==='Negative'||f['Current Sentiment']!=='Negative')continue;for(const key of['Issue ID','Issue Title','Last Modified'])if(typeof f[key]!=='string'||!f[key])throw new Error('Negative transition metadata is incomplete.');if(!/^\\d{4}-\\d\\d-\\d\\dT/.test(f['Last Modified'])||!Number.isFinite(Date.parse(f['Last Modified'])))throw new Error('Last Modified must be an Airtable time field.');if(f.Summary!==undefined&&typeof f.Summary!=='string')throw new Error('Airtable summary is not text.');const key=f['Issue ID']+':'+f['Last Modified'];if(seen.has(key))continue;seen.add(key);transitions.push({...f});}\n const chunks=[],header={type:'section',text:{type:'mrkdwn',text:':rotating_light: The following issues transitioned to Negative Sentiment'}},divider={type:'divider'};let blocks=[header,divider];\n for(const f of transitions){const url=issueUrlBase+encodeURIComponent(f['Issue ID']),link='*<'+url+'|'+escapeSentimentSlack(f['Issue ID'])+'>* ';if(link.length>3000)throw new Error('Linear issue link exceeds one Slack section.');let segment=link;const parts=[];for(const character of f['Issue Title']+'\\n'+(f.Summary??'')){const token=escapeSentimentSlack(character);if(segment.length+token.length>3000){parts.push(segment);segment='';}segment+=token;}if(segment)parts.push(segment);for(const text of parts){if(blocks.length===50){chunks.push({blocks});blocks=[header,divider];}blocks.push({type:'section',text:{type:'mrkdwn',text}});}}\n if(blocks.length>2)chunks.push({blocks});return {messages:chunks.map((chunk,i)=>({...chunk,text:transitions.length+' issues transitioned to Negative Sentiment'+(chunks.length>1?' ('+(i+1)+'/'+chunks.length+')':'')})),count:transitions.length};\n}\n" }, "n_db9a143e41fa5613": { "name": "Collect Slack receipts", "imports": [], "source": "export default function collectSentimentNotifications({messages,transitionCount,previousState,ts,channel}){const state=previousState===null?{index:0,receipts:[]}:JSON.parse(JSON.stringify(previousState));if(previousState!==null){if(state.index>=messages.length||typeof ts!=='string'||!ts||typeof channel!=='string'||!channel)throw new Error('Slack did not confirm the sentiment notification.');state.receipts.push({ts,channel});state.index++;}const next=messages[state.index];return {state,more:state.index