Skip to content
This repository has been archived by the owner on Sep 16, 2024. It is now read-only.

Commit

Permalink
feat: slack integration (#322)
Browse files Browse the repository at this point in the history
* removed install state for rebasing

* slack integration with refactored code

* removed cert.pem

* client side updated with respect to slack integration

* localhost https configs removed

* Refactored code worked successfully with hubspot

* Added PubSub for chat feature

* removed install-state to fix rebase

* make improvements & fixes post testing

* update header text

---------

Co-authored-by: Ashutosh Dhande <[email protected]>
  • Loading branch information
jatinsandilya and ashutoshdhande authored Oct 20, 2023
1 parent a8a5faf commit 1176f76
Show file tree
Hide file tree
Showing 37 changed files with 909 additions and 89 deletions.
Binary file removed .yarn/install-state.gz
Binary file not shown.
45 changes: 45 additions & 0 deletions fern/api/definition/chat/channels.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
imports:
errors: ../common/errors.yml
types: ../common/types.yml
unified: ../common/unified.yml
associations: ../common/associations.yml

types:
GetChannelsResponse:
properties:
status: types.ResponseStatus
next: optional<string>
previous: optional<string>
results: list<unified.Channel>

service:
base-path: /chat/channels
auth: false
headers:
x-revert-api-token:
type: string
docs: Your official API key for accessing revert apis.
x-revert-t-id:
type: string
docs: The unique customer id used when the customer linked their account.
x-api-version:
type: optional<string>
docs: Optional Revert API version you're using. If missing we default to the latest version of the API.
audiences:
- external
endpoints:
getChannels:
docs: Get all the channels
method: GET
path: ''
request:
name: GetChannelsRequest
query-parameters:
fields: optional<string>
pageSize: optional<string>
cursor: optional<string>
response: GetChannelsResponse
errors:
- errors.UnAuthorizedError
- errors.InternalServerError
- errors.NotFoundError
43 changes: 43 additions & 0 deletions fern/api/definition/chat/messages.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
imports:
errors: ../common/errors.yml
types: ../common/types.yml
unified: ../common/unified.yml
associations: ../common/associations.yml

types:
CreateorUpdateMessageRequest:
extends: unified.Message
CreateorUpdateMessageResponse:
properties:
status: types.ResponseStatus
result: unified.Message

service:
base-path: /chat/message
auth: false
headers:
x-revert-api-token:
type: string
docs: Your official API key for accessing revert apis.
x-revert-t-id:
type: string
docs: The unique customer id used when the customer linked their account.
x-api-version:
type: optional<string>
docs: Optional Revert API version you're using. If missing we default to the latest version of the API.
audiences:
- external
endpoints:
createMessage:
docs: Create a new message
method: POST
path: ''
request:
name: CreateMessageRequest
body: CreateorUpdateMessageRequest
response: CreateorUpdateMessageResponse
errors:
- errors.UnAuthorizedError
- errors.InternalServerError
- errors.NotFoundError
- errors.BadRequestError
45 changes: 45 additions & 0 deletions fern/api/definition/chat/users.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
imports:
errors: ../common/errors.yml
types: ../common/types.yml
unified: ../common/unified.yml
associations: ../common/associations.yml

types:
GetUsersResponse:
properties:
status: types.ResponseStatus
next: optional<string>
previous: optional<string>
results: list<unified.UserChat>

service:
base-path: /chat/users
auth: false
headers:
x-revert-api-token:
type: string
docs: Your official API key for accessing revert apis.
x-revert-t-id:
type: string
docs: The unique customer id used when the customer linked their account.
x-api-version:
type: optional<string>
docs: Optional Revert API version you're using. If missing we default to the latest version of the API.
audiences:
- external
endpoints:
getUsers:
docs: Get all the users
method: GET
path: ''
request:
name: GetUsersRequest
query-parameters:
fields: optional<string>
pageSize: optional<string>
cursor: optional<string>
response: GetUsersResponse
errors:
- errors.UnAuthorizedError
- errors.InternalServerError
- errors.NotFoundError
1 change: 1 addition & 0 deletions fern/api/definition/common/types.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ types:
- zohocrm
- sfdc
- pipedrive
- slack
StandardObject:
enum:
- company
Expand Down
30 changes: 30 additions & 0 deletions fern/api/definition/common/unified.yml
Original file line number Diff line number Diff line change
Expand Up @@ -195,3 +195,33 @@ types:
extends:
- CommonUnifiedFields
- UserWrite
UserChat:
properties:
id:
type: string
docs: Id of user according to connected communication app
name:
type: string
docs: The name of user in communication app
createdTimestamp:
type: unknown
docs: Date at which user account has been created
Channel:
properties:
id:
type: string
docs: Id of channel belonging to workspace
name:
type: string
docs: The name of channel in communication app
createdTimestamp:
type: unknown
docs: Date at which channel has been created
Message:
properties:
text:
type: string
docs: Message sent by user
channelId:
type: string
docs: Id of channel to which message was sent
3 changes: 3 additions & 0 deletions packages/backend/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ const config = {
WHITE_LISTED_DOMAINS: process.env.WHITE_LISTED_DOMAINS?.split(','),
AES_ENCRYPTION_SECRET: process.env.AES_ENCRYPTION_SECRET!,
MOESIF_APPLICATION_ID: process.env.MOESIF_APPLICATION_ID,
SLACK_CLIENT_ID: process.env.SLACK_CLIENT_ID!,
SLACK_CLIENT_SECRET: process.env.SLACK_CLIENT_SECRET!,
SLACK_BOT_TOKEN: process.env.SLACK_BOT_TOKEN!,
};

export default config;
17 changes: 11 additions & 6 deletions packages/backend/constants/common.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { TP_ID } from '@prisma/client';

export type CRM_TP_ID = 'zohocrm' | 'sfdc' | 'pipedrive' | 'hubspot';
// export type CHAT_TP_ID = 'slack';

export const DEFAULT_SCOPE = {
[TP_ID.hubspot]: [
'crm.objects.contacts.read',
Expand Down Expand Up @@ -34,14 +37,16 @@ export const DEFAULT_SCOPE = {
[TP_ID.zohocrm]: ['ZohoCRM.modules.ALL', 'ZohoCRM.settings.ALL', 'ZohoCRM.users.ALL', 'AaaServer.profile.READ'],
[TP_ID.sfdc]: [], // https://help.salesforce.com/s/articleView?id=sf.remoteaccess_oauth_tokens_scopes.htm&type=5
[TP_ID.pipedrive]: [],
[TP_ID.slack]: ['users:read', 'users.profile:read'],
};

export const mapIntegrationIdToIntegrationName = {
[TP_ID.hubspot]: "Hubspot",
[TP_ID.pipedrive]: "Pipedrive",
[TP_ID.sfdc]: "Salesforce",
[TP_ID.zohocrm]: "Zoho",
}
[TP_ID.hubspot]: 'Hubspot',
[TP_ID.pipedrive]: 'Pipedrive',
[TP_ID.sfdc]: 'Salesforce',
[TP_ID.zohocrm]: 'Zoho',
[TP_ID.slack]: 'Slack',
};

export const rootSchemaMappingId = 'revertRootSchemaMapping';

Expand All @@ -56,7 +61,7 @@ export enum StandardObjects {
user = 'user',
}

export const objectNameMapping: Record<string, Record<TP_ID, string | undefined>> = {
export const objectNameMapping: Record<string, Record<CRM_TP_ID, string | undefined>> = {
[StandardObjects.company]: {
[TP_ID.hubspot]: 'companies',
[TP_ID.pipedrive]: 'organization',
Expand Down
4 changes: 2 additions & 2 deletions packages/backend/helpers/crm/transform/disunify.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { TP_ID, accountFieldMappingConfig } from '@prisma/client';
import { StandardObjects } from '../../../constants/common';
import { CRM_TP_ID, StandardObjects } from '../../../constants/common';
import { transformModelToFieldMapping } from '.';
import { handleHubspotDisunify, handlePipedriveDisunify, handleSfdcDisunify, handleZohoDisunify } from '..';
import { postprocessDisUnifyObject } from './preprocess';
Expand All @@ -13,7 +13,7 @@ export async function disunifyObject<T extends Record<string, any>>({
accountFieldMappingConfig,
}: {
obj: T;
tpId: TP_ID;
tpId: CRM_TP_ID;
objType: StandardObjects;
tenantSchemaMappingId?: string;
accountFieldMappingConfig?: accountFieldMappingConfig;
Expand Down
12 changes: 6 additions & 6 deletions packages/backend/helpers/crm/transform/preprocess.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { TP_ID } from '@prisma/client';
import { StandardObjects } from '../../../constants/common';
import { CRM_TP_ID, StandardObjects } from '../../../constants/common';
import { PipedriveDealStatus } from '../../../constants/pipedrive';

export const preprocessUnifyObject = <T extends Record<string, any>>({
Expand All @@ -8,7 +8,7 @@ export const preprocessUnifyObject = <T extends Record<string, any>>({
objType,
}: {
obj: T;
tpId: TP_ID;
tpId: CRM_TP_ID;
objType: StandardObjects;
}) => {
const preprocessMap: any = {
Expand Down Expand Up @@ -39,10 +39,10 @@ export const postprocessDisUnifyObject = <T extends Record<string, any>>({
objType,
}: {
obj: T;
tpId: TP_ID;
tpId: CRM_TP_ID;
objType: StandardObjects;
}) => {
const preprocessMap: Record<TP_ID, Record<any, Function>> = {
const preprocessMap: Record<CRM_TP_ID, Record<any, Function>> = {
[TP_ID.pipedrive]: {
[StandardObjects.event]: (obj: T) => {
return {
Expand All @@ -66,13 +66,13 @@ export const postprocessDisUnifyObject = <T extends Record<string, any>>({
[StandardObjects.contact]: (obj: T) => {
return {
...obj,
name: `${obj.first_name} ${obj.last_name}`
name: `${obj.first_name} ${obj.last_name}`,
};
},
[StandardObjects.lead]: (obj: T) => {
return {
...obj,
person: undefined
person: undefined,
};
},
},
Expand Down
6 changes: 3 additions & 3 deletions packages/backend/helpers/crm/transform/unify.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { TP_ID, accountFieldMappingConfig } from '@prisma/client';
import { StandardObjects } from '../../../constants/common';
import { accountFieldMappingConfig } from '@prisma/client';
import { CRM_TP_ID, StandardObjects } from '../../../constants/common';
import { transformFieldMappingToModel } from '.';
import { preprocessUnifyObject } from './preprocess';

Expand All @@ -11,7 +11,7 @@ export async function unifyObject<T extends Record<string, any>, K>({
accountFieldMappingConfig,
}: {
obj: T;
tpId: TP_ID;
tpId: CRM_TP_ID;
objType: StandardObjects;
tenantSchemaMappingId?: string;
accountFieldMappingConfig?: accountFieldMappingConfig;
Expand Down
1 change: 1 addition & 0 deletions packages/backend/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,5 +145,6 @@ app.listen(config.PORT, () => {
// TODO: do this optimistically.
cron.schedule(`*/2 * * * *`, async () => {
await AuthService.refreshOAuthTokensForThirdParty();
await AuthService.refreshOAuthTokensForThirdPartyChatServices();
});
}).setTimeout(600000);
24 changes: 24 additions & 0 deletions packages/backend/models/unified/channel.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
export interface UnifiedChannel {
id: string;
name: string;
createdTimeStamp: string;
additional: any;
}

export function unifyChannel(channel: any) {
const unifiedChannel: UnifiedChannel = {
id: channel.id,
name: channel.name_normalized,
createdTimeStamp: new Date(channel.created * 1000).toISOString(),
additional: {},
};

// Map additional fields
Object.keys(channel).forEach((key) => {
if (!(key in unifiedChannel)) {
unifiedChannel['additional'][key] = channel[key];
}
});

return unifiedChannel;
}
24 changes: 24 additions & 0 deletions packages/backend/models/unified/chatUsers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
export interface UnifiedChatUser {
id: string;
name: string;
createdTimeStamp: string;
additional: any;
}

export function unifyChatUser(user: any): UnifiedChatUser {
const unifiedUser: UnifiedChatUser = {
id: user.id,
name: user.real_name,
createdTimeStamp: new Date(user.updated * 1000).toISOString(),
additional: {},
};

// Map additional fields
Object.keys(user).forEach((key) => {
if (!(key in unifiedUser)) {
unifiedUser['additional'][key] = user[key];
}
});

return unifiedUser;
}
Loading

1 comment on commit 1176f76

@vercel
Copy link

@vercel vercel bot commented on 1176f76 Oct 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

revert-client – ./

revert-client-revertdev.vercel.app
revert-client-git-main-revertdev.vercel.app
app.revert.dev

Please sign in to comment.