feat: Add user attribution to Linear integration with actor authorization (#11774)
- Add `actor=app` parameter to Linear OAuth authorization URL for consistent app-level authorization https://linear.app/developers/oauth-actor-authorization - Implement user attribution for Linear issue creation and linking using `createAsUser` and `displayIconUrl` parameters - Enhance Linear integration to properly attribute actions to specific Chatwoot agents **Note** - The displayIconUrl parameter is being sent correctly to Linear's GraphQL API (verified through testing), but there is an issues with icon is not attaching properly. - We might need to disconnect the integration connect again.
This commit is contained in:
@@ -22,8 +22,8 @@ class Integrations::Linear::ProcessorService
|
||||
}
|
||||
end
|
||||
|
||||
def create_issue(params)
|
||||
response = linear_client.create_issue(params)
|
||||
def create_issue(params, user = nil)
|
||||
response = linear_client.create_issue(params, user)
|
||||
return response if response[:error]
|
||||
|
||||
{
|
||||
@@ -33,8 +33,8 @@ class Integrations::Linear::ProcessorService
|
||||
}
|
||||
end
|
||||
|
||||
def link_issue(link, issue_id, title)
|
||||
response = linear_client.link_issue(link, issue_id, title)
|
||||
def link_issue(link, issue_id, title, user = nil)
|
||||
response = linear_client.link_issue(link, issue_id, title, user)
|
||||
return response if response[:error]
|
||||
|
||||
{
|
||||
|
||||
@@ -46,33 +46,24 @@ class Linear
|
||||
process_response(response)
|
||||
end
|
||||
|
||||
def create_issue(params)
|
||||
def create_issue(params, user = nil)
|
||||
validate_team_and_title(params)
|
||||
validate_priority(params[:priority])
|
||||
validate_label_ids(params[:label_ids])
|
||||
|
||||
variables = {
|
||||
title: params[:title],
|
||||
teamId: params[:team_id],
|
||||
description: params[:description],
|
||||
assigneeId: params[:assignee_id],
|
||||
priority: params[:priority],
|
||||
labelIds: params[:label_ids],
|
||||
projectId: params[:project_id],
|
||||
stateId: params[:state_id]
|
||||
}.compact
|
||||
variables = build_issue_variables(params, user)
|
||||
mutation = Linear::Mutations.issue_create(variables)
|
||||
response = post({ query: mutation })
|
||||
process_response(response)
|
||||
end
|
||||
|
||||
def link_issue(link, issue_id, title)
|
||||
def link_issue(link, issue_id, title, user = nil)
|
||||
raise ArgumentError, 'Missing link' if link.blank?
|
||||
raise ArgumentError, 'Missing issue id' if issue_id.blank?
|
||||
|
||||
payload = {
|
||||
query: Linear::Mutations.issue_link(issue_id, link, title)
|
||||
}
|
||||
link_params = build_link_params(issue_id, link, title, user)
|
||||
payload = { query: Linear::Mutations.issue_link(link_params) }
|
||||
|
||||
response = post(payload)
|
||||
process_response(response)
|
||||
end
|
||||
@@ -97,6 +88,42 @@ class Linear
|
||||
|
||||
private
|
||||
|
||||
def build_issue_variables(params, user)
|
||||
variables = {
|
||||
title: params[:title],
|
||||
teamId: params[:team_id],
|
||||
description: params[:description],
|
||||
assigneeId: params[:assignee_id],
|
||||
priority: params[:priority],
|
||||
labelIds: params[:label_ids],
|
||||
projectId: params[:project_id],
|
||||
stateId: params[:state_id]
|
||||
}.compact
|
||||
|
||||
# Add user attribution if available
|
||||
if user&.name.present?
|
||||
variables[:createAsUser] = user.name
|
||||
variables[:displayIconUrl] = user.avatar_url if user.avatar_url.present?
|
||||
end
|
||||
|
||||
variables
|
||||
end
|
||||
|
||||
def build_link_params(issue_id, link, title, user)
|
||||
params = {
|
||||
issue_id: issue_id,
|
||||
link: link,
|
||||
title: title
|
||||
}
|
||||
|
||||
if user.present?
|
||||
params[:user_name] = user.name if user.name.present?
|
||||
params[:user_avatar_url] = user.avatar_url if user.avatar_url.present?
|
||||
end
|
||||
|
||||
params
|
||||
end
|
||||
|
||||
def validate_team_and_title(params)
|
||||
raise ArgumentError, 'Missing team id' if params[:team_id].blank?
|
||||
raise ArgumentError, 'Missing title' if params[:title].blank?
|
||||
|
||||
@@ -32,10 +32,22 @@ module Linear::Mutations
|
||||
GRAPHQL
|
||||
end
|
||||
|
||||
def self.issue_link(issue_id, link, title)
|
||||
def self.issue_link(params)
|
||||
issue_id = params[:issue_id]
|
||||
link = params[:link]
|
||||
title = params[:title]
|
||||
user_name = params[:user_name]
|
||||
user_avatar_url = params[:user_avatar_url]
|
||||
|
||||
user_params = []
|
||||
user_params << "createAsUser: #{graphql_value(user_name)}" if user_name.present?
|
||||
user_params << "displayIconUrl: #{graphql_value(user_avatar_url)}" if user_avatar_url.present?
|
||||
|
||||
user_params_str = user_params.any? ? ", #{user_params.join(', ')}" : ''
|
||||
|
||||
<<~GRAPHQL
|
||||
mutation {
|
||||
attachmentLinkURL(url: "#{link}", issueId: "#{issue_id}", title: "#{title}") {
|
||||
attachmentLinkURL(url: "#{link}", issueId: "#{issue_id}", title: "#{title}"#{user_params_str}) {
|
||||
success
|
||||
attachment {
|
||||
id
|
||||
|
||||
Reference in New Issue
Block a user