Skip to content

Commit

Permalink
Added pipedrive integration.
Browse files Browse the repository at this point in the history
  • Loading branch information
zadoev-ra committed Nov 22, 2023
1 parent 8375cd3 commit 997bcc4
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 1 deletion.
78 changes: 78 additions & 0 deletions lambda-package/lambda_function.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,79 @@
from json import JSONDecodeError

import gspread
from pipedrive.client import Client
from slack_sdk import WebClient


PIPEDRIVE_CUSTOM_FIELD_FALLBACK = "6244292b70f654e8adb467e7c4b6e417c59099a8"


def pipedrive_get_or_create_person(client, form_person):
resp = client.persons.search_persons({
"term": form_person["email"],
"exact_match": 1,
"fields": "email",
"limit": 1,
})

if len(resp['data']['items']):
result = resp['data']['items'][0]['item']
print(f"Person found: {result['id']}")
return result

resp = client.persons.create_person(form_person)
print(f"Person created {resp['data']['id']}")
return resp['data']


def pipedrive_create_deals(client, title, person, data):
# pd works with custom fields using internal IDs, not names
# making mapping "field_name" : "internal_id" for future usage
cf_mapping = {}
response = client.deals.get_deal_fields()

for item in response['data']:
if not item.get('edit_flag', False):
continue # built in field in pd
cf_mapping[item['name']] = item['key']

# unknown fields and values will be written into special field
# by default it has name "Other"
cf_fallback = cf_mapping.pop('Other', PIPEDRIVE_CUSTOM_FIELD_FALLBACK)

cf_data = {
cf_fallback: '',
}

for k, v in data.items():
if k in cf_mapping:
cf_data[cf_mapping[k]] = v
else:
# in case form field was not found, keep it in special pd field
cf_data[cf_fallback] += f'{k}: {v}\n'

payload = {
'title': title,
'person_id': person['id'],
**cf_data,
}
resp = client.deals.create_deal(payload)

print(f"Deals {resp['data']['id']} was created")


def send_data_to_pipedrive(title, form_data):
client = Client(domain='https://api.pipedrive.com')
client.set_api_token(os.environ.get('PIPEDRIVE_TOKEN'))
form_person = {
'email': form_data.pop('email', ''),
'name': form_data.pop('fullName', '')
}

api_person = pipedrive_get_or_create_person(client, form_person)
pipedrive_create_deals(client, title, api_person, form_data)


def lambda_handler(event, context):
info = json.loads(os.environ['GOOGLE_API_SERVICE_ACCOUNT_INFO'])
spreadsheet_id = os.environ['GOOGLE_SPREADSHEET_ID']
Expand Down Expand Up @@ -66,4 +136,12 @@ def error_response(message):
),
)

# average time for longest path is about 1.5-2 s
# in good circumstances (fast internet, pd works without delays)
try:
event_body.pop('ts', None) # deals has its own ts
send_data_to_pipedrive(f'New "{job}" job application', event_body)
except Exception as e: # temporary catch all exceptions
print(str(e))

return {'status': 'ok'}
1 change: 1 addition & 0 deletions lambda-package/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
gspread==4.0.1
slack-sdk==3.9.1
pipedrive-python-lib==1.2.3
3 changes: 2 additions & 1 deletion run.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,14 @@ def get_function_config():
info = info.replace('"', '\\"') # encode quotes inside json string
spreadsheet_id = os.environ['GOOGLE_SPREADSHEET_ID']
slack_bot_token = os.environ['SLACK_BOT_TOKEN']

pipedrive_token = os.environ['PIPEDRIVE_TOKEN']
aws(
f'lambda update-function-configuration '
f'--function-name {function_name} '
f'--environment "Variables={{'
f'GOOGLE_API_SERVICE_ACCOUNT_INFO=\'{info}\','
f'GOOGLE_SPREADSHEET_ID={spreadsheet_id},'
f'PIPEDRIVE_TOKEN={pipedrive_token},'
f'SLACK_BOT_TOKEN={slack_bot_token}'
f'}}"',
)
Expand Down

0 comments on commit 997bcc4

Please sign in to comment.