feat: add liner integration

This commit is contained in:
Muhsin Keloth
2024-05-02 13:39:57 +05:30
parent af39308851
commit ead7cc0c36
10 changed files with 135 additions and 3 deletions
+3
View File
@@ -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
+9
View File
@@ -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) {
+24
View File
@@ -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: []
+3
View File
@@ -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...
+5
View File
@@ -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
+39
View File
@@ -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