-
Notifications
You must be signed in to change notification settings - Fork 195
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Attio CRM integration #320
Changes from 5 commits
0b4fa27
9f11d32
14b5f4f
66b6a3b
08e7a0a
9459865
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
node-linker=hoisted | ||
package-import-method=clone-or-copy |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,117 @@ | ||||||
import { Injectable } from "@nestjs/common"; | ||||||
import { | ||||||
AttioOAuthResponse, | ||||||
CallbackParams, | ||||||
ICrmConnectionService, | ||||||
RefreshParams, | ||||||
} from "../../types"; | ||||||
import { PrismaService } from '@@core/prisma/prisma.service'; | ||||||
import axios from 'axios'; | ||||||
import { v4 as uuidv4 } from 'uuid'; | ||||||
import { Action, handleServiceError } from '@@core/utils/errors'; | ||||||
import { EnvironmentService } from '@@core/environment/environment.service'; | ||||||
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, | ||||||
}); | ||||||
|
||||||
const res = await axios.post( | ||||||
'https://app.attio.com/oauth/token', | ||||||
formData.toString(), | ||||||
{ | ||||||
headers: { | ||||||
'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8', | ||||||
}, | ||||||
}, | ||||||
); | ||||||
|
||||||
const data: AttioOAuthResponse = res.data; | ||||||
|
||||||
// Saving the token of customer inside db | ||||||
let db_res; | ||||||
const connection_token = uuidv4(); | ||||||
|
||||||
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); | ||||||
|
||||||
} | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The - async handleTokenRefresh(opts: RefreshParams) {
+ async handleTokenRefresh() { Committable suggestion
Suggested change
|
||||||
} | ||||||
|
||||||
// It is not required for Attio as it does not provide refresh_token | ||||||
async handleTokenRefresh(opts: RefreshParams) { | ||||||
return; | ||||||
} | ||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
console.log
statement here appears to be a debugging statement. It's recommended to remove it or replace it withthis.logger.log
if you intend to keep it for logging purposes in production.- console.log("Linked User iD : <MMMMKIIT")
Committable suggestion