Skip to content

Commit

Permalink
✨ Add Jira & Gorgias
Browse files Browse the repository at this point in the history
  • Loading branch information
naelob committed Mar 23, 2024
1 parent aa9bcf0 commit 13ea074
Show file tree
Hide file tree
Showing 65 changed files with 3,764 additions and 128 deletions.
14 changes: 14 additions & 0 deletions packages/api/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,27 @@ FRESHSALES_CLIENT_ID=
FRESHSALES_CLIENT_SECRET=
ZENDESK_SELL_CLIENT_ID=
ZENDESK_SELL_CLIENT_SECRET=
ATTIO_CLIENT_ID=
ATTIO_CLIENT_SECRET=

# TICKETING
ZENDESK_TICKETING_SUBDOMAIN=
ZENDESK_TICKETING_CLIENT_ID=
ZENDESK_TICKETING_CLIENT_SECRET=
FRONT_CLIENT_ID=
FRONT_CLIENT_SECRET=
GORGIAS_CLIENT_ID=
GORGIAS_CLIENT_SECRET=
JIRA_CLIENT_ID=
JIRA_CLIENT_SECRET=
JIRA_SERVICE_MGMT_CLIENT_ID=
JIRA_SERVICE_MGMT_CLIENT_SECRET=
LINEAR_CLIENT_ID=
LINEAR_CLIENT_SECRET=
GITLAB_CLIENT_ID=
GITLAB_CLIENT_SECRET=
CLICKUP_CLIENT_ID=
CLICKUP_CLIENT_SECRET=

OAUTH_REDIRECT_BASE='https://api-staging.panora.dev/'

Expand Down
189 changes: 92 additions & 97 deletions packages/api/src/@core/connections/crm/services/attio/attio.service.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Injectable } from "@nestjs/common";
import { Injectable } from '@nestjs/common';
import {
AttioOAuthResponse,
CallbackParams,
ICrmConnectionService,
RefreshParams,
} from "../../types";
AttioOAuthResponse,
CallbackParams,
ICrmConnectionService,
RefreshParams,
} from '../../types';
import { PrismaService } from '@@core/prisma/prisma.service';
import axios from 'axios';
import { v4 as uuidv4 } from 'uuid';
Expand All @@ -14,104 +14,99 @@ import { EncryptionService } from '@@core/encryption/encryption.service';
import { ServiceConnectionRegistry } from '../registry.service';
import { LoggerService } from '@@core/logger/logger.service';


@Injectable()
export class AttioConnectionService implements ICrmConnectionService {
constructor(
private prisma: PrismaService,
private logger: LoggerService,
private env: EnvironmentService,
private cryptoService: EncryptionService,
private registry: ServiceConnectionRegistry
) {
this.logger.setContext(AttioConnectionService.name);
this.registry.registerService("attio", this);
}

async handleCallback(opts: CallbackParams) {
try {
console.log("Linked User iD : <MMMMKIIT")
const { linkedUserId, projectId, code } = opts;
this.logger.log(
'linkeduserid is ' + linkedUserId + ' inside callback attio',
);
const isNotUnique = await this.prisma.connections.findFirst({
where: {
id_linked_user: linkedUserId,
provider_slug: 'attio',
},
});
if (isNotUnique) return;
//reconstruct the redirect URI that was passed in the frontend it must be the same
const REDIRECT_URI = `${this.env.getOAuthRredirectBaseUrl()}/connections/oauth/callback`;
const formData = new URLSearchParams({
grant_type: 'authorization_code',
client_id: this.env.getAttioAuth().CLIENT_ID,
client_secret: this.env.getAttioAuth().CLIENT_SECRET,
redirect_uri: REDIRECT_URI,
code: code,
});
constructor(
private prisma: PrismaService,
private logger: LoggerService,
private env: EnvironmentService,
private cryptoService: EncryptionService,
private registry: ServiceConnectionRegistry,
) {
this.logger.setContext(AttioConnectionService.name);
this.registry.registerService('attio', this);
}

const res = await axios.post(
'https://app.attio.com/oauth/token',
formData.toString(),
{
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8',
},
},
);
async handleCallback(opts: CallbackParams) {
try {
const { linkedUserId, projectId, code } = opts;
this.logger.log(
'linkeduserid is ' + linkedUserId + ' inside callback attio',
);
const isNotUnique = await this.prisma.connections.findFirst({
where: {
id_linked_user: linkedUserId,
provider_slug: 'attio',
},
});
if (isNotUnique) return;
//reconstruct the redirect URI that was passed in the frontend it must be the same
const REDIRECT_URI = `${this.env.getOAuthRredirectBaseUrl()}/connections/oauth/callback`;
const formData = new URLSearchParams({
grant_type: 'authorization_code',
client_id: this.env.getAttioSecret().CLIENT_ID,
client_secret: this.env.getAttioSecret().CLIENT_SECRET,
redirect_uri: REDIRECT_URI,
code: code,
});

const data: AttioOAuthResponse = res.data;
const res = await axios.post(
'https://app.attio.com/oauth/token',
formData.toString(),
{
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8',
},
},
);

// Saving the token of customer inside db
let db_res;
const connection_token = uuidv4();
const data: AttioOAuthResponse = res.data;

if (isNotUnique) {
// Update existing connection
db_res = await this.prisma.connections.update({
where: {
id_connection: isNotUnique.id_connection,
},
data: {
access_token: this.cryptoService.encrypt(data.access_token),
status: 'valid',
created_at: new Date(),
},
});
} else {
// Create new connection
db_res = await this.prisma.connections.create({
data: {
id_connection: uuidv4(),
connection_token: connection_token,
provider_slug: 'attio',
token_type: 'oauth',
access_token: this.cryptoService.encrypt(data.access_token),
status: 'valid',
created_at: new Date(),
projects: {
connect: { id_project: projectId },
},
linked_users: {
connect: { id_linked_user: linkedUserId },
},
},
});
}
this.logger.log('Successfully added tokens inside DB ' + db_res);
return db_res;
// Saving the token of customer inside db
let db_res;
const connection_token = uuidv4();


} catch (error) {
handleServiceError(error, this.logger, 'attio', Action.oauthCallback);

}
if (isNotUnique) {
// Update existing connection
db_res = await this.prisma.connections.update({
where: {
id_connection: isNotUnique.id_connection,
},
data: {
access_token: this.cryptoService.encrypt(data.access_token),
status: 'valid',
created_at: new Date(),
},
});
} else {
// Create new connection
db_res = await this.prisma.connections.create({
data: {
id_connection: uuidv4(),
connection_token: connection_token,
provider_slug: 'attio',
token_type: 'oauth',
access_token: this.cryptoService.encrypt(data.access_token),
status: 'valid',
created_at: new Date(),
projects: {
connect: { id_project: projectId },
},
linked_users: {
connect: { id_linked_user: linkedUserId },
},
},
});
}
this.logger.log('Successfully added tokens inside DB ' + db_res);
return db_res;
} catch (error) {
handleServiceError(error, this.logger, 'attio', Action.oauthCallback);
}
}

// It is not required for Attio as it does not provide refresh_token
async handleTokenRefresh(opts: RefreshParams) {
return;
}
// It is not required for Attio as it does not provide refresh_token
async handleTokenRefresh(opts: RefreshParams) {

Check warning on line 109 in packages/api/src/@core/connections/crm/services/attio/attio.service.ts

View workflow job for this annotation

GitHub Actions / Build and Test (18.x)

'opts' is defined but never used
return;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import { Injectable } from '@nestjs/common';
import axios from 'axios';
import { PrismaService } from '@@core/prisma/prisma.service';
import { Action, handleServiceError } from '@@core/utils/errors';
import { LoggerService } from '@@core/logger/logger.service';
import { v4 as uuidv4 } from 'uuid';
import { EnvironmentService } from '@@core/environment/environment.service';
import { EncryptionService } from '@@core/encryption/encryption.service';
import {
CallbackParams,
RefreshParams,
ITicketingConnectionService,
ClickupOAuthResponse,
} from '../../types';
import { ServiceRegistry } from '../registry.service';

@Injectable()
export class ClickupConnectionService implements ITicketingConnectionService {
constructor(
private prisma: PrismaService,
private logger: LoggerService,
private env: EnvironmentService,
private cryptoService: EncryptionService,
private registry: ServiceRegistry,
) {
this.logger.setContext(ClickupConnectionService.name);
this.registry.registerService('clickup', this);
}

async handleCallback(opts: CallbackParams) {
try {
const { linkedUserId, projectId, code } = opts;
const isNotUnique = await this.prisma.connections.findFirst({
where: {
id_linked_user: linkedUserId,
provider_slug: 'clickup',
},
});

//reconstruct the redirect URI that was passed in the githubend it must be the same
//const REDIRECT_URI = `${this.env.getOAuthRredirectBaseUrl()}/connections/oauth/callback`;

const formData = new URLSearchParams({
client_id: this.env.getClickupSecret().CLIENT_ID,
client_secret: this.env.getClickupSecret().CLIENT_SECRET,
code: code,
});
const res = await axios.post(
`https://api.clickup.com/api/v2/oauth/token`,
formData.toString(),
{
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8',
},
},
);
const data: ClickupOAuthResponse = res.data;
this.logger.log(
'OAuth credentials : clickup ticketing ' + JSON.stringify(data),
);

let db_res;
const connection_token = uuidv4();

if (isNotUnique) {
db_res = await this.prisma.connections.update({
where: {
id_connection: isNotUnique.id_connection,
},
data: {
access_token: this.cryptoService.encrypt(data.access_token),
refresh_token: '',
expiration_timestamp: '',
status: 'valid',
created_at: new Date(),
},
});
} else {
db_res = await this.prisma.connections.create({
data: {
id_connection: uuidv4(),
connection_token: connection_token,
provider_slug: 'clickup',
token_type: 'oauth',
access_token: this.cryptoService.encrypt(data.access_token),
refresh_token: '',
expiration_timestamp: '',
status: 'valid',
created_at: new Date(),
projects: {
connect: { id_project: projectId },
},
linked_users: {
connect: { id_linked_user: linkedUserId },
},
},
});
}
return db_res;
} catch (error) {
handleServiceError(error, this.logger, 'clickup', Action.oauthCallback);
}
}

async handleTokenRefresh(opts: RefreshParams) {
return;
}
}
Loading

0 comments on commit 13ea074

Please sign in to comment.