linear

package
v1.0.0-rc1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 16, 2026 License: Apache-2.0 Imports: 35 Imported by: 0

Documentation

Index

Constants

View Source
const (
	ReactionTargetIssue   = "issue"
	ReactionTargetComment = "comment"
)
View Source
const (
	// AuthorizeURL is where the user approves the OAuth application.
	AuthorizeURL = "https://linear.app/oauth/authorize"

	// TokenURL exchanges authorization codes and refresh tokens for access tokens.
	TokenURL = "https://api.linear.app/oauth/token"

	// AppsNewURL is Linear's OAuth application creation form. There is no API to
	// create OAuth apps, but the form accepts manifest query parameters that
	// pre-fill every field, so the user only has to click Create.
	AppsNewURL = "https://linear.app/settings/api/applications/new"
)
View Source
const (
	// IssuePayloadType is the payload type emitted for every Linear issue,
	// both by the createIssue action and the onIssue trigger.
	IssuePayloadType = "linear.issue"

	// CommentPayloadType is the payload type emitted by the addIssueComment action.
	CommentPayloadType = "linear.comment"

	// AttachmentPayloadType is the payload type emitted for every Linear attachment,
	// both by the createAttachment action and the onIssueAttachment trigger.
	AttachmentPayloadType = "linear.attachment"

	// ReactionPayloadType is the payload type emitted by the addReaction action.
	ReactionPayloadType = "linear.reaction"

	// SignatureHeader carries a hex-encoded HMAC-SHA256 of the raw request body.
	SignatureHeader = "Linear-Signature"

	// EventHeader carries the resource type that triggered the delivery, e.g. "Issue".
	EventHeader = "Linear-Event"

	// IssueResourceType is the Linear webhook resource type for issue events.
	IssueResourceType = "Issue"

	// CommentResourceType is the Linear webhook resource type for comment events.
	CommentResourceType = "Comment"

	// AttachmentResourceType is the Linear webhook resource type for attachment events.
	AttachmentResourceType = "Attachment"
)
View Source
const (
	OAuthAccessToken  = "accessToken"
	OAuthRefreshToken = "refreshToken"

	// WebhookSecretConfig is the signing secret of a customer Linear OAuth application.
	WebhookSecretConfig = "webhookSecret"
)
View Source
const (
	ResourceTypeTeam          = "team"
	ResourceTypeWorkflowState = "workflowState"
	ResourceTypeMember        = "member"
	ResourceTypeLabel         = "label"
	ResourceTypeProject       = "project"
	ResourceTypeAttachment    = "attachment"
	ResourceTypeComment       = "comment"
)
View Source
const APIURL = "https://api.linear.app/graphql"

APIURL is Linear's single GraphQL endpoint. Linear has no REST API.

View Source
const ReceiptField = "superplaneReceiptId"

ReceiptField is the canvas payload key for the stored receipt ID. Linear does not send this field.

Variables

This section is empty.

Functions

func AppWebhookSigningSecret

func AppWebhookSigningSecret(integration core.IntegrationContext) string

AppWebhookSigningSecret is the secret Linear uses to sign the application webhook. A customer application stores the secret on the connection. SuperPlane's application stores it in the process environment.

func AppWebhookURL

func AppWebhookURL(baseURL string) string

AppWebhookURL is the address to enter on a Linear OAuth application.

func DeliveryKey

func DeliveryKey(body []byte) string

DeliveryKey identifies one Linear payload. Linear retries send the same body, so a subscription that already accepted this key is not run again.

func DescriptionWithLinks(description string, links []IssueLink) string

DescriptionWithLinks appends link attachments to description. A description that already contains the section is left unchanged.

func EventNeedsTeamLookup

func EventNeedsTeamLookup(event AppEvent, configs []WebhookConfiguration, teams []Team) bool

EventNeedsTeamLookup reports whether a team-scoped subscription can match this event only after SuperPlane loads the parent issue. Events that no subscription can use do not need that request.

func HostedOAuthCallbackURL

func HostedOAuthCallbackURL(baseURL string) string

HostedOAuthCallbackURL is the stable Linear callback for the hosted app.

func HostedWebhookSecret

func HostedWebhookSecret() string

HostedWebhookSecret is the signing secret of SuperPlane's Linear OAuth application. An empty value means triggers still create webhooks through the Linear API.

func IsAppLevelWebhook

func IsAppLevelWebhook(metadata any) bool

IsAppLevelWebhook reports whether this subscription receives the application webhook.

func IsLinearUploadURL

func IsLinearUploadURL(raw string) bool

IsLinearUploadURL reports whether raw points at Linear's private file storage. Only HTTPS is accepted. The download sends the OAuth bearer token, so an http://uploads.linear.app link must not be fetched.

func IssueEventPayload

func IssueEventPayload(issue Issue) map[string]any

IssueEventPayload builds the Linear webhook body for one issue, so an imported issue uses the same shape as a live linear.issue event.

func IssueHasWorkOrder

func IssueHasWorkOrder(tx *gorm.DB, factory *models.Factory, ref IssueRef) (bool, error)

IssueHasWorkOrder reports whether this factory already has a work order for the Linear issue. Matching covers every work-order state.

func IssueIDFromEventData

func IssueIDFromEventData(eventData any) (string, bool)

IssueIDFromEventData reads the Linear issue id used by the API.

func IssueURLFragment

func IssueURLFragment(ref IssueRef) string

IssueURLFragment is the origin-URL substring that identifies a Linear issue. Callers use it for a coarse lookup, then confirm with IssueRefFromURL so ENG-142 cannot match ENG-1420.

func LinkSectionMarkdown

func LinkSectionMarkdown(links []IssueLink) string

LinkSectionMarkdown renders link attachments as a markdown list. An empty list returns an empty string.

func ListAttachments

func ListAttachments(ctx core.ListResourcesContext) ([]core.IntegrationResource, error)

ListAttachments returns the attachments on the issue selected in the sibling field. It stays empty until an issue is chosen, and an issue set from an expression cannot be resolved here, so the picker offers nothing in that case.

func ListComments

ListComments returns the comments on the issue selected in the sibling field. It stays empty until an issue is chosen, and an issue set from an expression cannot be resolved here, so the picker offers nothing in that case.

func ListTeams

ListTeams reads the teams captured during sync, so the picker stays responsive and does not spend Linear's per-user request budget on every render.

func LockIssueWorkOrder

func LockIssueWorkOrder(tx *gorm.DB, factory *models.Factory, ref IssueRef) error

LockIssueWorkOrder serializes work-order creation for one Linear issue in this factory. The lock is held until the caller commits tx.

func OAuthScopes

func OAuthScopes(integration core.IntegrationContext) string

OAuthScopes is the scope list for the authorize URL. The admin scope is omitted when this connection can verify the application webhook.

func ReceiptIDFromEventData

func ReceiptIDFromEventData(eventData any) (uuid.UUID, bool)

ReceiptIDFromEventData reads the SuperPlane webhook receipt ID stored on a Linear canvas event. Linear does not send this field.

func SignatureMatches

func SignatureMatches(signature string, body, secret []byte) bool

SignatureMatches reports whether signature is the hex HMAC-SHA256 of body.

func SubscriptionMatches

func SubscriptionMatches(config WebhookConfiguration, event AppEvent, teams []Team) bool

SubscriptionMatches reports whether a local subscription wants this Linear event. A subscription with no team listens to every team. A missing team on the event does not match a team-scoped subscription.

func UseHostedInstall

func UseHostedInstall(integrationName string) bool

UseHostedInstall is true when Connect should authorize SuperPlane's Linear OAuth app. The manual Client ID and Client Secret fields stay available.

func UseHostedOAuth

func UseHostedOAuth() bool

UseHostedOAuth reports whether the process holds SuperPlane's Linear OAuth app.

Types

type AddIssueComment

type AddIssueComment struct{}

func (*AddIssueComment) Cancel

func (c *AddIssueComment) Cancel(ctx core.ExecutionContext) error

func (*AddIssueComment) Cleanup

func (c *AddIssueComment) Cleanup(ctx core.SetupContext) error

func (*AddIssueComment) Color

func (c *AddIssueComment) Color() string

func (*AddIssueComment) Configuration

func (c *AddIssueComment) Configuration() []configuration.Field

func (*AddIssueComment) Description

func (c *AddIssueComment) Description() string

func (*AddIssueComment) Documentation

func (c *AddIssueComment) Documentation() string

func (*AddIssueComment) ExampleOutput

func (c *AddIssueComment) ExampleOutput() map[string]any

func (*AddIssueComment) Execute

func (c *AddIssueComment) Execute(ctx core.ExecutionContext) error

func (*AddIssueComment) HandleHook

func (c *AddIssueComment) HandleHook(ctx core.ActionHookContext) error

func (*AddIssueComment) HandleWebhook

func (*AddIssueComment) Hooks

func (c *AddIssueComment) Hooks() []core.Hook

func (*AddIssueComment) Icon

func (c *AddIssueComment) Icon() string

func (*AddIssueComment) Label

func (c *AddIssueComment) Label() string

func (*AddIssueComment) Name

func (c *AddIssueComment) Name() string

func (*AddIssueComment) OutputChannels

func (c *AddIssueComment) OutputChannels(configuration any) []core.OutputChannel

func (*AddIssueComment) Setup

func (c *AddIssueComment) Setup(ctx core.SetupContext) error

type AddIssueCommentSpec

type AddIssueCommentSpec struct {
	Issue string `json:"issue" mapstructure:"issue"`
	Body  string `json:"body" mapstructure:"body"`
}

type AddIssueLabel

type AddIssueLabel struct{}

func (*AddIssueLabel) Cancel

func (c *AddIssueLabel) Cancel(ctx core.ExecutionContext) error

func (*AddIssueLabel) Cleanup

func (c *AddIssueLabel) Cleanup(ctx core.SetupContext) error

func (*AddIssueLabel) Color

func (c *AddIssueLabel) Color() string

func (*AddIssueLabel) Configuration

func (c *AddIssueLabel) Configuration() []configuration.Field

func (*AddIssueLabel) Description

func (c *AddIssueLabel) Description() string

func (*AddIssueLabel) Documentation

func (c *AddIssueLabel) Documentation() string

func (*AddIssueLabel) ExampleOutput

func (c *AddIssueLabel) ExampleOutput() map[string]any

func (*AddIssueLabel) Execute

func (c *AddIssueLabel) Execute(ctx core.ExecutionContext) error

func (*AddIssueLabel) HandleHook

func (c *AddIssueLabel) HandleHook(ctx core.ActionHookContext) error

func (*AddIssueLabel) HandleWebhook

func (*AddIssueLabel) Hooks

func (c *AddIssueLabel) Hooks() []core.Hook

func (*AddIssueLabel) Icon

func (c *AddIssueLabel) Icon() string

func (*AddIssueLabel) Label

func (c *AddIssueLabel) Label() string

func (*AddIssueLabel) Name

func (c *AddIssueLabel) Name() string

func (*AddIssueLabel) OutputChannels

func (c *AddIssueLabel) OutputChannels(configuration any) []core.OutputChannel

func (*AddIssueLabel) Setup

func (c *AddIssueLabel) Setup(ctx core.SetupContext) error

type AddIssueLabelSpec

type AddIssueLabelSpec struct {
	Team      string   `json:"team" mapstructure:"team"`
	Issue     string   `json:"issue" mapstructure:"issue"`
	Labels    []string `json:"labels" mapstructure:"labels"`
	NewLabels []string `json:"newLabels" mapstructure:"newLabels"`
}

type AddReaction

type AddReaction struct{}

func (*AddReaction) Cancel

func (c *AddReaction) Cancel(ctx core.ExecutionContext) error

func (*AddReaction) Cleanup

func (c *AddReaction) Cleanup(ctx core.SetupContext) error

func (*AddReaction) Color

func (c *AddReaction) Color() string

func (*AddReaction) Configuration

func (c *AddReaction) Configuration() []configuration.Field

func (*AddReaction) Description

func (c *AddReaction) Description() string

func (*AddReaction) Documentation

func (c *AddReaction) Documentation() string

func (*AddReaction) ExampleOutput

func (c *AddReaction) ExampleOutput() map[string]any

func (*AddReaction) Execute

func (c *AddReaction) Execute(ctx core.ExecutionContext) error

func (*AddReaction) HandleHook

func (c *AddReaction) HandleHook(ctx core.ActionHookContext) error

func (*AddReaction) HandleWebhook

func (*AddReaction) Hooks

func (c *AddReaction) Hooks() []core.Hook

func (*AddReaction) Icon

func (c *AddReaction) Icon() string

func (*AddReaction) Label

func (c *AddReaction) Label() string

func (*AddReaction) Name

func (c *AddReaction) Name() string

func (*AddReaction) OutputChannels

func (c *AddReaction) OutputChannels(configuration any) []core.OutputChannel

func (*AddReaction) Setup

func (c *AddReaction) Setup(ctx core.SetupContext) error

type AddReactionSpec

type AddReactionSpec struct {
	Target  string `json:"target" mapstructure:"target"`
	Issue   string `json:"issue" mapstructure:"issue"`
	Comment string `json:"comment" mapstructure:"comment"`
	Emoji   string `json:"emoji" mapstructure:"emoji"`
}

type AppEvent

type AppEvent struct {
	OrganizationID string
	WorkspaceKey   string
	ResourceType   string
	TeamID         string
	TeamKey        string
	// IssueID is the parent issue when the payload is not itself an issue.
	IssueID string
}

AppEvent is the part of a Linear webhook SuperPlane uses to choose a subscription.

func ParseAppEvent

func ParseAppEvent(headers http.Header, body []byte) (AppEvent, error)

ParseAppEvent reads the routing fields from a Linear webhook.

func ResolveEventTeam

func ResolveEventTeam(httpCtx core.HTTPContext, integration core.IntegrationContext, event AppEvent, teams []Team) (AppEvent, error)

ResolveEventTeam fills the team on events that do not carry one. Attachment payloads identify the parent issue and omit the team. The team list resolves a team key. Otherwise SuperPlane reads the issue from Linear.

type Attachment

type Attachment struct {
	ID        string        `json:"id"`
	Title     string        `json:"title"`
	Subtitle  string        `json:"subtitle,omitempty"`
	URL       string        `json:"url"`
	CreatedAt string        `json:"createdAt,omitempty"`
	UpdatedAt string        `json:"updatedAt,omitempty"`
	Creator   *User         `json:"creator,omitempty"`
	Issue     *CommentIssue `json:"issue,omitempty"`
}

Attachment is a link card on an issue. Linear deduplicates attachments by url within an issue, so creating one with an existing url updates it in place. iconUrl is deliberately absent: Linear accepts it on AttachmentCreateInput but does not expose it on the Attachment type, so it can never be read back.

type Auth

type Auth struct {
	// contains filtered or unexported fields
}

func NewAuth

func NewAuth(client core.HTTPContext) *Auth

func (*Auth) ExchangeCode

func (a *Auth) ExchangeCode(clientID, clientSecret, code, redirectURI string) (*TokenResponse, error)

func (*Auth) HandleCallback

func (a *Auth) HandleCallback(req *http.Request, clientID, clientSecret, expectedState, redirectURI string) (*TokenResponse, error)

func (*Auth) RefreshToken

func (a *Auth) RefreshToken(clientID, clientSecret, refreshToken string) (*TokenResponse, error)

type Client

type Client struct {
	AccessToken string
	// contains filtered or unexported fields
}

Client talks to Linear's GraphQL API using an OAuth access token, which Linear expects with a "Bearer " prefix — unlike personal API keys.

func NewClient

func NewClient(httpCtx core.HTTPContext, ctx core.IntegrationContext) (*Client, error)

func (*Client) AddIssueLabel

func (c *Client) AddIssueLabel(id, labelID string) (*Issue, error)

AddIssueLabel adds a single label to an issue without touching its existing labels, returning the updated issue. Like UpdateIssue, the id may be the issue UUID or its identifier (e.g. ENG-142).

func (*Client) CreateAttachment

func (c *Client) CreateAttachment(input map[string]any) (*Attachment, error)

CreateAttachment adds a link attachment to an issue. Linear deduplicates by url within an issue, so an existing url updates that attachment instead of creating a second one. The input's issueId may be the issue UUID or its identifier (e.g. ENG-142).

func (*Client) CreateComment

func (c *Client) CreateComment(input map[string]any) (*Comment, error)

CreateComment adds a comment to an issue. The input's issueId may be the issue UUID or its identifier (e.g. ENG-142).

func (*Client) CreateIssue

func (c *Client) CreateIssue(input map[string]any) (*Issue, error)

func (*Client) CreateLabel

func (c *Client) CreateLabel(name, teamID string) (*Label, error)

CreateLabel creates a label and returns it. A non-empty teamID scopes the label to that team; an empty teamID creates a workspace-level label. Linear assigns a color when none is given.

func (*Client) CreateReaction

func (c *Client) CreateReaction(input map[string]any) (*Reaction, error)

CreateReaction adds an emoji reaction to an issue or a comment. Re-sending the same emoji returns the existing reaction rather than failing, but sending an alias of an emoji already present is rejected - see isReactionConflict.

func (*Client) CreateWebhook

func (c *Client) CreateWebhook(url, secret, label, teamID string, resourceTypes []string) (*Webhook, error)

CreateWebhook registers a webhook on Linear. Managing webhooks requires a workspace admin or an OAuth token carrying the admin scope.

func (*Client) DeleteAttachment

func (c *Client) DeleteAttachment(id string) error

DeleteAttachment removes an attachment by its ID. Linear has no delete-by-url, so the ID must come from createAttachment's output or an attachment event.

func (*Client) DeleteWebhook

func (c *Client) DeleteWebhook(id string) error

func (*Client) GetIssue

func (c *Client) GetIssue(id string) (*Issue, error)

GetIssue fetches a single issue. Linear accepts either the issue UUID or the human-readable identifier (e.g. ENG-142) as the id argument.

func (*Client) GetViewer

func (c *Client) GetViewer() (*Viewer, error)

func (*Client) IssueFiles

func (c *Client) IssueFiles(ctx context.Context, issueID, description string) ([]IssueFile, []IssueLink, error)

IssueFiles downloads files on uploads.linear.app that are embedded in the description or listed as issue attachments. Link attachments are returned separately. OAuth credentials stay on the request.

func (*Client) ListIssueAttachments

func (c *Client) ListIssueAttachments(issueID string) ([]Attachment, error)

ListIssueAttachments returns the attachments on a single issue, for the attachment picker. Issues carry few enough attachments that one page is plenty.

func (*Client) ListIssueComments

func (c *Client) ListIssueComments(issueID string) ([]Comment, error)

ListIssueComments returns the comments on a single issue, for the comment picker. Issues carry few enough comments that one page is plenty.

func (*Client) ListLabels

func (c *Client) ListLabels(teamID string) ([]Label, error)

func (*Client) ListOpenProjectIssues

func (c *Client) ListOpenProjectIssues(projectIDs []string, limit int) ([]Issue, error)

ListOpenProjectIssues returns the newest open issues in the given projects. Completed and canceled issues are left out. limit is capped at one page.

func (*Client) ListTeamMembers

func (c *Client) ListTeamMembers(teamID string) ([]User, error)

func (*Client) ListTeamProjects

func (c *Client) ListTeamProjects(teamID string) ([]Project, error)

func (*Client) ListTeams

func (c *Client) ListTeams() ([]Team, error)

func (*Client) ListWorkflowStates

func (c *Client) ListWorkflowStates(teamID string) ([]WorkflowState, error)

func (*Client) ListWorkspaceProjects

func (c *Client) ListWorkspaceProjects() ([]WorkspaceProject, error)

ListWorkspaceProjects returns every project the token can read, including projects on private teams the authorizing user belongs to.

func (*Client) ProjectTeamIDs

func (c *Client) ProjectTeamIDs(projectIDs []string) ([]string, error)

ProjectTeamIDs returns the teams that own the given projects. The result is sorted and has no duplicates. Every requested project must be readable. A project the token cannot read is an error, so setup does not register webhooks for only part of the intake.

func (*Client) RemoveIssueLabel

func (c *Client) RemoveIssueLabel(id, labelID string) (*Issue, error)

RemoveIssueLabel removes a single label from an issue without touching its other labels, returning the updated issue. Like AddIssueLabel, the id may be the issue UUID or its identifier (e.g. ENG-142). Linear errors when the label is not on the issue - see isLabelNotOnIssue.

func (*Client) SearchOpenProjectIssues

func (c *Client) SearchOpenProjectIssues(projectIDs []string, query string, limit int) ([]Issue, error)

SearchOpenProjectIssues returns open issues in the given projects whose title or description contains query. An empty query lists the newest open issues. An identifier such as ENG-142 is included when that issue belongs to one of the projects.

func (*Client) UpdateComment

func (c *Client) UpdateComment(id string, input map[string]any) (*Comment, error)

UpdateComment edits an existing comment. Unlike issues, comments are addressed only by their UUID - there is no human-readable identifier for one.

func (*Client) UpdateIssue

func (c *Client) UpdateIssue(id string, input map[string]any) (*Issue, error)

UpdateIssue applies the given IssueUpdateInput fields to an issue. Like GetIssue, the id may be the issue UUID or its identifier (e.g. ENG-142).

type Comment

type Comment struct {
	ID        string        `json:"id"`
	Body      string        `json:"body"`
	URL       string        `json:"url"`
	CreatedAt string        `json:"createdAt,omitempty"`
	UpdatedAt string        `json:"updatedAt,omitempty"`
	EditedAt  string        `json:"editedAt,omitempty"`
	User      *User         `json:"user,omitempty"`
	Issue     *CommentIssue `json:"issue,omitempty"`
}

Comment is a comment on an issue. user is the author and is null when Linear attributes the comment to a bot or integration rather than a person. editedAt stays null until the body is changed, so it doubles as an edited marker.

type CommentIssue

type CommentIssue struct {
	ID         string `json:"id"`
	Identifier string `json:"identifier"`
	Title      string `json:"title"`
	URL        string `json:"url"`
}

CommentIssue is the issue a comment belongs to, trimmed to the fields worth surfacing alongside the comment.

type CreateAttachment

type CreateAttachment struct{}

func (*CreateAttachment) Cancel

func (*CreateAttachment) Cleanup

func (c *CreateAttachment) Cleanup(ctx core.SetupContext) error

func (*CreateAttachment) Color

func (c *CreateAttachment) Color() string

func (*CreateAttachment) Configuration

func (c *CreateAttachment) Configuration() []configuration.Field

func (*CreateAttachment) Description

func (c *CreateAttachment) Description() string

func (*CreateAttachment) Documentation

func (c *CreateAttachment) Documentation() string

func (*CreateAttachment) ExampleOutput

func (c *CreateAttachment) ExampleOutput() map[string]any

func (*CreateAttachment) Execute

func (c *CreateAttachment) Execute(ctx core.ExecutionContext) error

func (*CreateAttachment) HandleHook

func (c *CreateAttachment) HandleHook(ctx core.ActionHookContext) error

func (*CreateAttachment) HandleWebhook

func (*CreateAttachment) Hooks

func (c *CreateAttachment) Hooks() []core.Hook

func (*CreateAttachment) Icon

func (c *CreateAttachment) Icon() string

func (*CreateAttachment) Label

func (c *CreateAttachment) Label() string

func (*CreateAttachment) Name

func (c *CreateAttachment) Name() string

func (*CreateAttachment) OutputChannels

func (c *CreateAttachment) OutputChannels(configuration any) []core.OutputChannel

func (*CreateAttachment) Setup

func (c *CreateAttachment) Setup(ctx core.SetupContext) error

type CreateAttachmentSpec

type CreateAttachmentSpec struct {
	Issue    string `json:"issue" mapstructure:"issue"`
	Title    string `json:"title" mapstructure:"title"`
	URL      string `json:"url" mapstructure:"url"`
	Subtitle string `json:"subtitle" mapstructure:"subtitle"`
	IconURL  string `json:"iconUrl" mapstructure:"iconUrl"`
}

type CreateIssue

type CreateIssue struct{}

func (*CreateIssue) Cancel

func (c *CreateIssue) Cancel(ctx core.ExecutionContext) error

func (*CreateIssue) Cleanup

func (c *CreateIssue) Cleanup(ctx core.SetupContext) error

func (*CreateIssue) Color

func (c *CreateIssue) Color() string

func (*CreateIssue) Configuration

func (c *CreateIssue) Configuration() []configuration.Field

func (*CreateIssue) Description

func (c *CreateIssue) Description() string

func (*CreateIssue) Documentation

func (c *CreateIssue) Documentation() string

func (*CreateIssue) ExampleOutput

func (c *CreateIssue) ExampleOutput() map[string]any

func (*CreateIssue) Execute

func (c *CreateIssue) Execute(ctx core.ExecutionContext) error

func (*CreateIssue) HandleHook

func (c *CreateIssue) HandleHook(ctx core.ActionHookContext) error

func (*CreateIssue) HandleWebhook

func (*CreateIssue) Hooks

func (c *CreateIssue) Hooks() []core.Hook

func (*CreateIssue) Icon

func (c *CreateIssue) Icon() string

func (*CreateIssue) Label

func (c *CreateIssue) Label() string

func (*CreateIssue) Name

func (c *CreateIssue) Name() string

func (*CreateIssue) OutputChannels

func (c *CreateIssue) OutputChannels(configuration any) []core.OutputChannel

func (*CreateIssue) Setup

func (c *CreateIssue) Setup(ctx core.SetupContext) error

type CreateIssueSpec

type CreateIssueSpec struct {
	Team        string   `json:"team" mapstructure:"team"`
	Title       string   `json:"title" mapstructure:"title"`
	Description string   `json:"description" mapstructure:"description"`
	Project     string   `json:"project" mapstructure:"project"`
	State       string   `json:"state" mapstructure:"state"`
	Assignee    string   `json:"assignee" mapstructure:"assignee"`
	Priority    string   `json:"priority" mapstructure:"priority"`
	Labels      []string `json:"labels" mapstructure:"labels"`
}

type DeleteAttachment

type DeleteAttachment struct{}

func (*DeleteAttachment) Cancel

func (*DeleteAttachment) Cleanup

func (c *DeleteAttachment) Cleanup(ctx core.SetupContext) error

func (*DeleteAttachment) Color

func (c *DeleteAttachment) Color() string

func (*DeleteAttachment) Configuration

func (c *DeleteAttachment) Configuration() []configuration.Field

func (*DeleteAttachment) Description

func (c *DeleteAttachment) Description() string

func (*DeleteAttachment) Documentation

func (c *DeleteAttachment) Documentation() string

func (*DeleteAttachment) ExampleOutput

func (c *DeleteAttachment) ExampleOutput() map[string]any

func (*DeleteAttachment) Execute

func (c *DeleteAttachment) Execute(ctx core.ExecutionContext) error

func (*DeleteAttachment) HandleHook

func (c *DeleteAttachment) HandleHook(ctx core.ActionHookContext) error

func (*DeleteAttachment) HandleWebhook

func (*DeleteAttachment) Hooks

func (c *DeleteAttachment) Hooks() []core.Hook

func (*DeleteAttachment) Icon

func (c *DeleteAttachment) Icon() string

func (*DeleteAttachment) Label

func (c *DeleteAttachment) Label() string

func (*DeleteAttachment) Name

func (c *DeleteAttachment) Name() string

func (*DeleteAttachment) OutputChannels

func (c *DeleteAttachment) OutputChannels(configuration any) []core.OutputChannel

func (*DeleteAttachment) Setup

func (c *DeleteAttachment) Setup(ctx core.SetupContext) error

type DeleteAttachmentResult

type DeleteAttachmentResult struct {
	ID      string `json:"id"`
	Deleted bool   `json:"deleted"`
}

DeleteAttachmentResult is the emitted payload. Linear's attachmentDelete returns only a success flag, so the deleted ID is echoed back for downstream steps.

type DeleteAttachmentSpec

type DeleteAttachmentSpec struct {
	Issue      string `json:"issue" mapstructure:"issue"`
	Attachment string `json:"attachment" mapstructure:"attachment"`
}

type GetIssue

type GetIssue struct{}

func (*GetIssue) Cancel

func (c *GetIssue) Cancel(ctx core.ExecutionContext) error

func (*GetIssue) Cleanup

func (c *GetIssue) Cleanup(ctx core.SetupContext) error

func (*GetIssue) Color

func (c *GetIssue) Color() string

func (*GetIssue) Configuration

func (c *GetIssue) Configuration() []configuration.Field

func (*GetIssue) Description

func (c *GetIssue) Description() string

func (*GetIssue) Documentation

func (c *GetIssue) Documentation() string

func (*GetIssue) ExampleOutput

func (c *GetIssue) ExampleOutput() map[string]any

func (*GetIssue) Execute

func (c *GetIssue) Execute(ctx core.ExecutionContext) error

func (*GetIssue) HandleHook

func (c *GetIssue) HandleHook(ctx core.ActionHookContext) error

func (*GetIssue) HandleWebhook

func (*GetIssue) Hooks

func (c *GetIssue) Hooks() []core.Hook

func (*GetIssue) Icon

func (c *GetIssue) Icon() string

func (*GetIssue) Label

func (c *GetIssue) Label() string

func (*GetIssue) Name

func (c *GetIssue) Name() string

func (*GetIssue) OutputChannels

func (c *GetIssue) OutputChannels(configuration any) []core.OutputChannel

func (*GetIssue) Setup

func (c *GetIssue) Setup(ctx core.SetupContext) error

type GetIssueSpec

type GetIssueSpec struct {
	Issue string `json:"issue" mapstructure:"issue"`
}

type Issue

type Issue struct {
	ID            string         `json:"id"`
	Identifier    string         `json:"identifier"`
	Number        int            `json:"number"`
	Title         string         `json:"title"`
	Description   string         `json:"description,omitempty"`
	URL           string         `json:"url"`
	Priority      int            `json:"priority"`
	PriorityLabel string         `json:"priorityLabel,omitempty"`
	BranchName    string         `json:"branchName,omitempty"`
	CreatedAt     string         `json:"createdAt,omitempty"`
	UpdatedAt     string         `json:"updatedAt,omitempty"`
	State         *WorkflowState `json:"state,omitempty"`
	Team          *Team          `json:"team,omitempty"`
	Assignee      *User          `json:"assignee,omitempty"`
	Creator       *User          `json:"creator,omitempty"`
	Project       *Project       `json:"project,omitempty"`
	Labels        LabelList      `json:"labels,omitempty"`
}

type IssueFile

type IssueFile struct {
	Name        string
	ContentType string
	Body        []byte
	ReplaceURLs []string
}

IssueFile is a downloaded Linear file ready to store on a work order. ReplaceURLs are the description strings that should become the stored file reference. An empty list means the file is appended.

type IssueLink struct {
	Title string
	URL   string
}

IssueLink is a Linear attachment that points at another service. It is not a file, so the task lists it as a link.

type IssueRef

type IssueRef struct {
	ID         string
	Identifier string
	Host       string
}

IssueRef identifies one Linear issue by its browse URL.

func IssueRefFromEventData

func IssueRefFromEventData(eventData any) (IssueRef, bool)

IssueRefFromEventData reads the Linear issue from a canvas root event envelope. The envelope looks like:

{ "type": "linear.issue", "data": { "url": "https://linear.app/acme/issue/ENG-142/slug", "data": { "id": "...", "identifier": "ENG-142" } } }

func IssueRefFromURL

func IssueRefFromURL(rawURL string) (IssueRef, bool)

IssueRefFromURL reads the issue identifier from a Linear issue page URL. The path is /{workspace}/issue/{identifier} with an optional slug.

type Label

type Label struct {
	ID   string `json:"id"`
	Name string `json:"name"`
}

type LabelList

type LabelList []Label

LabelList flattens Linear's `labels { nodes { ... } }` connection into a plain array, so emitted payloads expose `labels[0].name` rather than `labels.nodes[0].name`. Null connections and null node lists decode as empty rather than failing: erroring here would fail the execution after the issue was already created on Linear, inviting duplicate-creating retries.

func (*LabelList) UnmarshalJSON

func (l *LabelList) UnmarshalJSON(data []byte) error

type Linear

type Linear struct{}

func (*Linear) Actions

func (l *Linear) Actions() []core.Action

func (*Linear) Cleanup

func (l *Linear) Cleanup(ctx core.IntegrationCleanupContext) error

func (*Linear) Configuration

func (l *Linear) Configuration() []configuration.Field

func (*Linear) Description

func (l *Linear) Description() string

func (*Linear) HandleHook

func (l *Linear) HandleHook(ctx core.IntegrationHookContext) error

func (*Linear) HandleRequest

func (l *Linear) HandleRequest(ctx core.HTTPRequestContext)

func (*Linear) Hooks

func (l *Linear) Hooks() []core.Hook

func (*Linear) Icon

func (l *Linear) Icon() string

func (*Linear) Instructions

func (l *Linear) Instructions() string

func (*Linear) Label

func (l *Linear) Label() string

func (*Linear) ListResources

func (l *Linear) ListResources(resourceType string, ctx core.ListResourcesContext) ([]core.IntegrationResource, error)

func (*Linear) Name

func (l *Linear) Name() string

func (*Linear) Sync

func (l *Linear) Sync(ctx core.SyncContext) error

func (*Linear) Triggers

func (l *Linear) Triggers() []core.Trigger

type LinearWebhookHandler

type LinearWebhookHandler struct{}

func (*LinearWebhookHandler) Cleanup

func (*LinearWebhookHandler) CompareConfig

func (h *LinearWebhookHandler) CompareConfig(a, b any) (bool, error)

func (*LinearWebhookHandler) Merge

func (h *LinearWebhookHandler) Merge(current, requested any) (any, bool, error)

func (*LinearWebhookHandler) Setup

type Metadata

type Metadata struct {
	State                *string `json:"state,omitempty" mapstructure:"state,omitempty"`
	User                 *User   `json:"user,omitempty" mapstructure:"user,omitempty"`
	Teams                []Team  `json:"teams" mapstructure:"teams"`
	Organization         string  `json:"organization,omitempty" mapstructure:"organization,omitempty"`
	OrganizationID       string  `json:"organizationId,omitempty" mapstructure:"organizationId,omitempty"`
	URLKey               string  `json:"urlKey,omitempty" mapstructure:"urlKey,omitempty"`
	AccessTokenExpiresAt string  `json:"accessTokenExpiresAt,omitempty" mapstructure:"accessTokenExpiresAt,omitempty"`
	// HostedOAuth is true when this connection uses SuperPlane's Linear OAuth app.
	HostedOAuth bool `json:"hostedOAuth,omitempty" mapstructure:"hostedOAuth,omitempty"`
	// SetupReturnPath is a same-origin path to open after OAuth, such as the intake wizard.
	SetupReturnPath string `json:"setupReturnPath,omitempty" mapstructure:"setupReturnPath,omitempty"`
	// OAuthScopes is the scope list from the last authorize URL.
	// A delivery-mode change uses it to decide when consent must be requested again.
	OAuthScopes string `json:"oauthScopes,omitempty" mapstructure:"oauthScopes,omitempty"`
}

type NodeMetadata

type NodeMetadata struct {
	Team *Team `json:"team,omitempty" mapstructure:"team,omitempty"`
}

NodeMetadata is stored on Linear nodes at setup time, so canvas cards can show the team without re-querying Linear.

type OnIssue

type OnIssue struct{}

func (*OnIssue) Cleanup

func (i *OnIssue) Cleanup(ctx core.TriggerContext) error

func (*OnIssue) Color

func (i *OnIssue) Color() string

func (*OnIssue) Configuration

func (i *OnIssue) Configuration() []configuration.Field

func (*OnIssue) Description

func (i *OnIssue) Description() string

func (*OnIssue) Documentation

func (i *OnIssue) Documentation() string

func (*OnIssue) ExampleData

func (i *OnIssue) ExampleData() map[string]any

func (*OnIssue) HandleHook

func (i *OnIssue) HandleHook(ctx core.TriggerHookContext) (map[string]any, error)

func (*OnIssue) HandleWebhook

func (i *OnIssue) HandleWebhook(ctx core.WebhookRequestContext) (int, *core.WebhookResponseBody, error)

func (*OnIssue) Hooks

func (i *OnIssue) Hooks() []core.Hook

func (*OnIssue) Icon

func (i *OnIssue) Icon() string

func (*OnIssue) Label

func (i *OnIssue) Label() string

func (*OnIssue) Name

func (i *OnIssue) Name() string

func (*OnIssue) Setup

func (i *OnIssue) Setup(ctx core.TriggerContext) error

type OnIssueAttachment

type OnIssueAttachment struct{}

func (*OnIssueAttachment) Cleanup

func (i *OnIssueAttachment) Cleanup(ctx core.TriggerContext) error

func (*OnIssueAttachment) Color

func (i *OnIssueAttachment) Color() string

func (*OnIssueAttachment) Configuration

func (i *OnIssueAttachment) Configuration() []configuration.Field

func (*OnIssueAttachment) Description

func (i *OnIssueAttachment) Description() string

func (*OnIssueAttachment) Documentation

func (i *OnIssueAttachment) Documentation() string

func (*OnIssueAttachment) ExampleData

func (i *OnIssueAttachment) ExampleData() map[string]any

func (*OnIssueAttachment) HandleHook

func (i *OnIssueAttachment) HandleHook(ctx core.TriggerHookContext) (map[string]any, error)

func (*OnIssueAttachment) HandleWebhook

func (*OnIssueAttachment) Hooks

func (i *OnIssueAttachment) Hooks() []core.Hook

func (*OnIssueAttachment) Icon

func (i *OnIssueAttachment) Icon() string

func (*OnIssueAttachment) Label

func (i *OnIssueAttachment) Label() string

func (*OnIssueAttachment) Name

func (i *OnIssueAttachment) Name() string

func (*OnIssueAttachment) Setup

type OnIssueAttachmentConfiguration

type OnIssueAttachmentConfiguration struct {
	Team    string   `json:"team" mapstructure:"team"`
	Actions []string `json:"actions" mapstructure:"actions"`
}

type OnIssueComment

type OnIssueComment struct{}

func (*OnIssueComment) Cleanup

func (i *OnIssueComment) Cleanup(ctx core.TriggerContext) error

func (*OnIssueComment) Color

func (i *OnIssueComment) Color() string

func (*OnIssueComment) Configuration

func (i *OnIssueComment) Configuration() []configuration.Field

func (*OnIssueComment) Description

func (i *OnIssueComment) Description() string

func (*OnIssueComment) Documentation

func (i *OnIssueComment) Documentation() string

func (*OnIssueComment) ExampleData

func (i *OnIssueComment) ExampleData() map[string]any

func (*OnIssueComment) HandleHook

func (i *OnIssueComment) HandleHook(ctx core.TriggerHookContext) (map[string]any, error)

func (*OnIssueComment) HandleWebhook

func (*OnIssueComment) Hooks

func (i *OnIssueComment) Hooks() []core.Hook

func (*OnIssueComment) Icon

func (i *OnIssueComment) Icon() string

func (*OnIssueComment) Label

func (i *OnIssueComment) Label() string

func (*OnIssueComment) Name

func (i *OnIssueComment) Name() string

func (*OnIssueComment) Setup

func (i *OnIssueComment) Setup(ctx core.TriggerContext) error

type OnIssueCommentConfiguration

type OnIssueCommentConfiguration struct {
	Team          string   `json:"team" mapstructure:"team"`
	Actions       []string `json:"actions" mapstructure:"actions"`
	ContentFilter string   `json:"contentFilter" mapstructure:"contentFilter"`
}

type OnIssueConfiguration

type OnIssueConfiguration struct {
	Team     string                    `json:"team" mapstructure:"team"`
	Projects []string                  `json:"projects" mapstructure:"projects"`
	Actions  []string                  `json:"actions" mapstructure:"actions"`
	Labels   []configuration.Predicate `json:"labels" mapstructure:"labels"`
}

type OnIssueLabel

type OnIssueLabel struct{}

func (*OnIssueLabel) Cleanup

func (i *OnIssueLabel) Cleanup(ctx core.TriggerContext) error

func (*OnIssueLabel) Color

func (i *OnIssueLabel) Color() string

func (*OnIssueLabel) Configuration

func (i *OnIssueLabel) Configuration() []configuration.Field

func (*OnIssueLabel) Description

func (i *OnIssueLabel) Description() string

func (*OnIssueLabel) Documentation

func (i *OnIssueLabel) Documentation() string

func (*OnIssueLabel) ExampleData

func (i *OnIssueLabel) ExampleData() map[string]any

func (*OnIssueLabel) HandleHook

func (i *OnIssueLabel) HandleHook(ctx core.TriggerHookContext) (map[string]any, error)

func (*OnIssueLabel) HandleWebhook

func (*OnIssueLabel) Hooks

func (i *OnIssueLabel) Hooks() []core.Hook

func (*OnIssueLabel) Icon

func (i *OnIssueLabel) Icon() string

func (*OnIssueLabel) Label

func (i *OnIssueLabel) Label() string

func (*OnIssueLabel) Name

func (i *OnIssueLabel) Name() string

func (*OnIssueLabel) Setup

func (i *OnIssueLabel) Setup(ctx core.TriggerContext) error

type OnIssueLabelConfiguration

type OnIssueLabelConfiguration struct {
	Team   string   `json:"team" mapstructure:"team"`
	Labels []string `json:"labels" mapstructure:"labels"`
}

type Organization

type Organization struct {
	ID     string `json:"id"`
	Name   string `json:"name"`
	URLKey string `json:"urlKey"`
}

type Project

type Project struct {
	ID   string `json:"id"`
	Name string `json:"name"`
}

type Reaction

type Reaction struct {
	ID        string   `json:"id"`
	Emoji     string   `json:"emoji"`
	CreatedAt string   `json:"createdAt,omitempty"`
	User      *User    `json:"user,omitempty"`
	Issue     *Issue   `json:"issue,omitempty"`
	Comment   *Comment `json:"comment,omitempty"`
}

Reaction is an emoji reaction on an issue or a comment. Linear normalizes emoji aliases on write, so the stored emoji can differ from the one sent (thumbsup becomes +1).

type RemoveIssueLabel

type RemoveIssueLabel struct{}

func (*RemoveIssueLabel) Cancel

func (*RemoveIssueLabel) Cleanup

func (c *RemoveIssueLabel) Cleanup(ctx core.SetupContext) error

func (*RemoveIssueLabel) Color

func (c *RemoveIssueLabel) Color() string

func (*RemoveIssueLabel) Configuration

func (c *RemoveIssueLabel) Configuration() []configuration.Field

func (*RemoveIssueLabel) Description

func (c *RemoveIssueLabel) Description() string

func (*RemoveIssueLabel) Documentation

func (c *RemoveIssueLabel) Documentation() string

func (*RemoveIssueLabel) ExampleOutput

func (c *RemoveIssueLabel) ExampleOutput() map[string]any

func (*RemoveIssueLabel) Execute

func (c *RemoveIssueLabel) Execute(ctx core.ExecutionContext) error

func (*RemoveIssueLabel) HandleHook

func (c *RemoveIssueLabel) HandleHook(ctx core.ActionHookContext) error

func (*RemoveIssueLabel) HandleWebhook

func (*RemoveIssueLabel) Hooks

func (c *RemoveIssueLabel) Hooks() []core.Hook

func (*RemoveIssueLabel) Icon

func (c *RemoveIssueLabel) Icon() string

func (*RemoveIssueLabel) Label

func (c *RemoveIssueLabel) Label() string

func (*RemoveIssueLabel) Name

func (c *RemoveIssueLabel) Name() string

func (*RemoveIssueLabel) OutputChannels

func (c *RemoveIssueLabel) OutputChannels(configuration any) []core.OutputChannel

func (*RemoveIssueLabel) Setup

func (c *RemoveIssueLabel) Setup(ctx core.SetupContext) error

type RemoveIssueLabelSpec

type RemoveIssueLabelSpec struct {
	Team           string   `json:"team" mapstructure:"team"`
	Issue          string   `json:"issue" mapstructure:"issue"`
	Labels         []string `json:"labels" mapstructure:"labels"`
	FailIfNotFound bool     `json:"failIfNotFound" mapstructure:"failIfNotFound"`
}

type Team

type Team struct {
	ID   string `json:"id"`
	Key  string `json:"key"`
	Name string `json:"name"`
}

type TokenResponse

type TokenResponse struct {
	AccessToken  string `json:"access_token"`
	RefreshToken string `json:"refresh_token"`
	TokenType    string `json:"token_type"`
	ExpiresIn    int    `json:"expires_in"`
}

TokenResponse is Linear's token endpoint response. Since April 2026 Linear issues 24-hour access tokens with rotating refresh tokens, so both fields must be stored and refresh handled on resync.

func (*TokenResponse) ExpiresAt

func (t *TokenResponse) ExpiresAt() time.Time

ExpiresAt returns when the access token stops working, or the zero time when Linear did not report a lifetime.

func (*TokenResponse) GetExpiration

func (t *TokenResponse) GetExpiration() time.Duration

GetExpiration returns how long to wait before resyncing to refresh the token: half its lifetime, so one failed resync still leaves time to retry.

type UpdateIssue

type UpdateIssue struct{}

func (*UpdateIssue) Cancel

func (c *UpdateIssue) Cancel(ctx core.ExecutionContext) error

func (*UpdateIssue) Cleanup

func (c *UpdateIssue) Cleanup(ctx core.SetupContext) error

func (*UpdateIssue) Color

func (c *UpdateIssue) Color() string

func (*UpdateIssue) Configuration

func (c *UpdateIssue) Configuration() []configuration.Field

func (*UpdateIssue) Description

func (c *UpdateIssue) Description() string

func (*UpdateIssue) Documentation

func (c *UpdateIssue) Documentation() string

func (*UpdateIssue) ExampleOutput

func (c *UpdateIssue) ExampleOutput() map[string]any

func (*UpdateIssue) Execute

func (c *UpdateIssue) Execute(ctx core.ExecutionContext) error

func (*UpdateIssue) HandleHook

func (c *UpdateIssue) HandleHook(ctx core.ActionHookContext) error

func (*UpdateIssue) HandleWebhook

func (*UpdateIssue) Hooks

func (c *UpdateIssue) Hooks() []core.Hook

func (*UpdateIssue) Icon

func (c *UpdateIssue) Icon() string

func (*UpdateIssue) Label

func (c *UpdateIssue) Label() string

func (*UpdateIssue) Name

func (c *UpdateIssue) Name() string

func (*UpdateIssue) OutputChannels

func (c *UpdateIssue) OutputChannels(configuration any) []core.OutputChannel

func (*UpdateIssue) Setup

func (c *UpdateIssue) Setup(ctx core.SetupContext) error

type UpdateIssueComment

type UpdateIssueComment struct{}

func (*UpdateIssueComment) Cancel

func (*UpdateIssueComment) Cleanup

func (c *UpdateIssueComment) Cleanup(ctx core.SetupContext) error

func (*UpdateIssueComment) Color

func (c *UpdateIssueComment) Color() string

func (*UpdateIssueComment) Configuration

func (c *UpdateIssueComment) Configuration() []configuration.Field

func (*UpdateIssueComment) Description

func (c *UpdateIssueComment) Description() string

func (*UpdateIssueComment) Documentation

func (c *UpdateIssueComment) Documentation() string

func (*UpdateIssueComment) ExampleOutput

func (c *UpdateIssueComment) ExampleOutput() map[string]any

func (*UpdateIssueComment) Execute

func (*UpdateIssueComment) HandleHook

func (c *UpdateIssueComment) HandleHook(ctx core.ActionHookContext) error

func (*UpdateIssueComment) HandleWebhook

func (*UpdateIssueComment) Hooks

func (c *UpdateIssueComment) Hooks() []core.Hook

func (*UpdateIssueComment) Icon

func (c *UpdateIssueComment) Icon() string

func (*UpdateIssueComment) Label

func (c *UpdateIssueComment) Label() string

func (*UpdateIssueComment) Name

func (c *UpdateIssueComment) Name() string

func (*UpdateIssueComment) OutputChannels

func (c *UpdateIssueComment) OutputChannels(configuration any) []core.OutputChannel

func (*UpdateIssueComment) Setup

func (c *UpdateIssueComment) Setup(ctx core.SetupContext) error

type UpdateIssueCommentSpec

type UpdateIssueCommentSpec struct {
	Issue   string `json:"issue" mapstructure:"issue"`
	Comment string `json:"comment" mapstructure:"comment"`
	Body    string `json:"body" mapstructure:"body"`
}

type UpdateIssueSpec

type UpdateIssueSpec struct {
	Team        string   `json:"team" mapstructure:"team"`
	Issue       string   `json:"issue" mapstructure:"issue"`
	Title       string   `json:"title" mapstructure:"title"`
	Description string   `json:"description" mapstructure:"description"`
	State       string   `json:"state" mapstructure:"state"`
	Assignee    string   `json:"assignee" mapstructure:"assignee"`
	Priority    string   `json:"priority" mapstructure:"priority"`
	Labels      []string `json:"labels" mapstructure:"labels"`
	Project     string   `json:"project" mapstructure:"project"`
}

type User

type User struct {
	ID          string `json:"id"`
	Name        string `json:"name"`
	DisplayName string `json:"displayName,omitempty"`
	Email       string `json:"email,omitempty"`
}

type Viewer

type Viewer struct {
	User         *User        `json:"viewer"`
	Organization Organization `json:"organization"`
}

Viewer identifies the account behind the access token and the workspace it belongs to.

type Webhook

type Webhook struct {
	ID     string `json:"id"`
	URL    string `json:"url"`
	Secret string `json:"secret,omitempty"`
}

type WebhookConfiguration

type WebhookConfiguration struct {
	// TeamID is the single team used by triggers that listen to one team.
	TeamID string `json:"teamId" mapstructure:"teamId"`
	// TeamIDs is the set of teams a project-scoped trigger listens on.
	// Linear cannot subscribe a webhook to a project, so each team gets
	// its own webhook and SuperPlane filters by project.
	TeamIDs      []string `json:"teamIds" mapstructure:"teamIds"`
	ResourceType string   `json:"resourceType" mapstructure:"resourceType"`
	// AppLevel is true when Linear delivers this subscription through the
	// OAuth application webhook. Saving a trigger again must not reuse a
	// subscription whose delivery mode no longer matches.
	AppLevel bool `json:"appLevel,omitempty" mapstructure:"appLevel,omitempty"`
}

type WebhookMetadata

type WebhookMetadata struct {
	// ID is the first Linear webhook. Older rows store only this field.
	ID string `json:"id" mapstructure:"id"`
	// IDs holds every Linear webhook this subscription created.
	IDs []string `json:"ids" mapstructure:"ids"`
	// AppLevel is true when Linear delivers events to the OAuth application
	// webhook instead of a webhook created for this subscription.
	AppLevel bool `json:"appLevel,omitempty" mapstructure:"appLevel,omitempty"`
}

type WebhookSummary

type WebhookSummary struct {
	EventType       string
	Action          string
	IssueIdentifier string
	IssueID         string
	TeamKey         string
	WorkspaceKey    string
}

WebhookSummary is the metadata stored for one Linear call. It does not include the body, the signature, or actor details.

func SummarizeWebhook

func SummarizeWebhook(headers http.Header, body []byte) WebhookSummary

SummarizeWebhook reads event metadata from a Linear webhook body.

type WorkflowState

type WorkflowState struct {
	ID   string `json:"id"`
	Name string `json:"name"`
	Type string `json:"type,omitempty"`
}

type WorkspaceProject

type WorkspaceProject struct {
	ID      string
	Name    string
	TeamIDs []string
}

WorkspaceProject is a Linear project the token can see, with the teams that own it. A project can belong to more than one team, including a private team the authorizing user is a member of.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL