feat: add liner integration
This commit is contained in:
@@ -155,6 +155,9 @@ gem 'stripe'
|
||||
## to populate db with sample data
|
||||
gem 'faker'
|
||||
|
||||
# to consume GraphQL-based APIs
|
||||
gem 'graphlient'
|
||||
|
||||
# Include logrange conditionally in intializer using env variable
|
||||
gem 'lograge', '~> 0.14.0', require: false
|
||||
|
||||
|
||||
@@ -333,6 +333,14 @@ GEM
|
||||
multi_json (~> 1.11)
|
||||
os (>= 0.9, < 2.0)
|
||||
signet (>= 0.16, < 2.a)
|
||||
graphlient (0.8.0)
|
||||
faraday (~> 2.0)
|
||||
graphql-client
|
||||
graphql (2.3.2)
|
||||
base64
|
||||
graphql-client (0.22.0)
|
||||
activesupport (>= 3.0)
|
||||
graphql (>= 1.13.0)
|
||||
groupdate (6.2.1)
|
||||
activesupport (>= 5.2)
|
||||
grpc (1.62.0)
|
||||
@@ -876,6 +884,7 @@ DEPENDENCIES
|
||||
google-cloud-dialogflow-v2
|
||||
google-cloud-storage
|
||||
google-cloud-translate-v3
|
||||
graphlient
|
||||
groupdate
|
||||
grpc
|
||||
haikunator
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
class Api::V1::Accounts::Integrations::LinearController < Api::V1::Accounts::BaseController
|
||||
before_action :fetch_conversation, only: [:list]
|
||||
|
||||
def list
|
||||
issues = linear_processor_service.list_issues
|
||||
render json: issues, status: :ok
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def linear_processor_service
|
||||
Integrations::Linear::ProcessorService.new(account: Current.account, conversation: @conversation)
|
||||
end
|
||||
|
||||
def permitted_params
|
||||
params.permit(:conversation_id)
|
||||
end
|
||||
|
||||
def fetch_conversation
|
||||
@conversation = Current.account.conversations.find_by!(display_id: permitted_params[:conversation_id])
|
||||
end
|
||||
end
|
||||
@@ -21,9 +21,13 @@ const state = {
|
||||
};
|
||||
|
||||
const isAValidAppIntegration = integration => {
|
||||
return ['dialogflow', 'dyte', 'google_translate', 'openai'].includes(
|
||||
integration.id
|
||||
);
|
||||
return [
|
||||
'dialogflow',
|
||||
'dyte',
|
||||
'google_translate',
|
||||
'openai',
|
||||
'linear',
|
||||
].includes(integration.id);
|
||||
};
|
||||
export const getters = {
|
||||
getIntegrations($state) {
|
||||
|
||||
@@ -159,3 +159,27 @@ openai:
|
||||
},
|
||||
]
|
||||
visible_properties: ['api_key', 'label_suggestion']
|
||||
dyte:
|
||||
id: linear
|
||||
logo: linear.png
|
||||
i18n_key: linear
|
||||
action: /linear
|
||||
hook_type: account
|
||||
allow_multiple_hooks: false
|
||||
settings_json_schema: {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"api_key": { "type": "string" },
|
||||
},
|
||||
"required": ["api_key"],
|
||||
"additionalProperties": false,
|
||||
}
|
||||
settings_form_schema: [
|
||||
{
|
||||
"label": "API Key",
|
||||
"type": "text",
|
||||
"name": "api_key",
|
||||
"validation": "required",
|
||||
},
|
||||
]
|
||||
visible_properties: []
|
||||
|
||||
@@ -220,6 +220,9 @@ en:
|
||||
openai:
|
||||
name: "OpenAI"
|
||||
description: "Integrate powerful AI features into Chatwoot by leveraging the GPT models from OpenAI."
|
||||
linear:
|
||||
name: "Linear"
|
||||
description: "Connect your account with Linear to get realtime updates on the status of your conversations."
|
||||
public_portal:
|
||||
search:
|
||||
search_placeholder: Search for article by title or body...
|
||||
|
||||
@@ -226,6 +226,11 @@ Rails.application.routes.draw do
|
||||
post :add_participant_to_meeting
|
||||
end
|
||||
end
|
||||
resource :linear, controller: 'linear', only: [] do
|
||||
collection do
|
||||
post :list
|
||||
end
|
||||
end
|
||||
end
|
||||
resources :working_hours, only: [:update]
|
||||
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
class Integrations::Linear::ProcessorService
|
||||
pattr_initialize [:account!, :conversation!]
|
||||
|
||||
def create_issue; end
|
||||
|
||||
def link_issue; end
|
||||
|
||||
def list_issues
|
||||
issues = linear_client.list_issues
|
||||
issues.map(&:as_json)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def linear_hook
|
||||
@linear_hook ||= account.hooks.find_by!(app_id: 'linear')
|
||||
end
|
||||
|
||||
def linear_client
|
||||
credentials = linear_hook.settings
|
||||
@linear_client ||= Linear.new(credentials['api_key'])
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,39 @@
|
||||
require 'graphlient'
|
||||
|
||||
class Linear
|
||||
BASE_URL = 'https://api.linear.app/graphql'.freeze
|
||||
|
||||
def initialize(api_key)
|
||||
@api_key = api_key
|
||||
raise ArgumentError, 'Missing Credentials' if @api_key.blank?
|
||||
|
||||
@client = Graphlient::Client.new(
|
||||
BASE_URL,
|
||||
headers: {
|
||||
'Authorization' => @api_key,
|
||||
'Content-Type' => 'application/json'
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
def list_issues
|
||||
query = <<~GRAPHQL
|
||||
query {
|
||||
issues(first: 5) {
|
||||
nodes {
|
||||
id
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
GRAPHQL
|
||||
|
||||
begin
|
||||
response = @client.query(query)
|
||||
response.data.issues.nodes
|
||||
rescue StandardError => e
|
||||
# return error message
|
||||
e.message
|
||||
end
|
||||
end
|
||||
end
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
Reference in New Issue
Block a user