Every 15 minutes
Import contacts from a CSV in Google Drive into Notion
Drop a contacts CSV into your Drive folder and each contact is added to your Notion database, with duplicates skipped.
- Runs
- Every 15 minutes
- Apps
- Google Drive, Notion
- AI
- Not needed
- Access
- drive.readonly; Notion read+insert
Send this to your assistant
Create a ClickRuntime automation: when a CSV lands in my Drive 'Imports' folder, add each contact to my Notion Contacts database, skipping anyone whose email is already there.
First time? Adding ClickRuntime to your assistant takes about two minutes.
Why use it
Why teams use this automation
A small team keeps its contacts in a Notion database, but new contacts arrive as spreadsheets: an event attendee list, an export from a webinar tool, a list from a partner. Notion's own import creates a new database rather than adding to the existing one, so people end up copying rows by hand and creating duplicates.
Dropping the file into a Drive folder and having each contact added to the right database, checked against existing emails, turns a fiddly afternoon task into a file upload.
What you get out of it
No duplicate contacts
Each email is checked against your database before a contact is added. People already in Notion are skipped, so your list stays clean.
Adds to the database you already use
Contacts land in your existing Contacts database with its views, relations and filters. You do not end up with a pile of separate imported tables.
Anyone can import
Uploading a file to a Drive folder needs no Notion know-how. A colleague can bring in an event list without help.
Every import is processed once
Each file is remembered after it is imported. Leaving it in the folder does not create the contacts again.
How it works
What happens, step by step
Every 15 minutes, ClickRuntime checks your Imports folder in Google Drive for CSV files it has not processed.
If there are none, it stops there until the next check.
It reads each new file and looks up which email addresses are already in your Notion Contacts database.
Each new contact is added as a page in the database, duplicates are skipped, and the file is remembered so it is not imported again.
Before it runs live
- Connect Google Drive
- Connect Notion and share the database you want it to use
What you get
Build your own
Need it to work differently?
Your own rules
Conditions, thresholds, filters and exceptions, written the way you'd explain them to a colleague.
Any number of apps
One automation can read from one app and update several others. Over 248 apps are ready, and anything with an API works too.
AI where it helps
Summaries, classification, extraction and drafts use ClickRuntime's built-in AI, with no extra key.
On a schedule or on each event
Runs as often as every 5 minutes, or the moment an app sends an event, and keeps track of what it already handled.
Changes you can ask for
- Act only on the items that match your own rules, and skip the rest
- Add an AI step, for example to summarize, sort or draft a reply
- Add another app, for example also send it to Slack
- Combine it with other Google Drive and Notion steps into one automation
Under the hood
The code that runs this automation
import csv, io, time
from google.oauth2.credentials import Credentials
from googleapiclient.discovery import build
from clickruntime import on_trigger, credentials, http, state, report_fetched
FOLDER_ID, DB = "your-folder-id", "your-database-id"
@on_trigger
def run(event):
drive = build("drive", "v3", credentials=Credentials(credentials.connection("google", "work")), cache_discovery=False)
done = set(state.get("done") or [])
files = [f for f in drive.files().list(q=f"'{FOLDER_ID}' in parents and mimeType='text/csv' and trashed=false").execute().get("files", []) if f["id"] not in done]
report_fetched(len(files))
if not files:
return {"summary": "Nothing new"}
nh = {"Authorization": f"Bearer {credentials.connection('notion', 'work')}", "Notion-Version": "2022-06-28"}
added = 0
for f in files:
for row in csv.DictReader(io.StringIO(drive.files().get_media(fileId=f["id"]).execute().decode("utf-8-sig"))):
email = (row.get("email") or row.get("Email") or "").strip().lower()
if not email:
continue
q = {"filter": {"property": "Email", "email": {"equals": email}}}
if http.post(f"https://api.notion.com/v1/databases/{DB}/query", headers=nh, json=q).json()["results"]:
continue
http.post("https://api.notion.com/v1/pages", headers=nh, json={"parent": {"database_id": DB}, "properties": {
"Name": {"title": [{"text": {"content": row.get("name") or email}}]}, "Email": {"email": email}}})
added += 1
time.sleep(0.35)
done.add(f["id"])
state.set("done", list(done))
return {"files": len(files), "added": added}FAQ
Common questions
Which columns does the CSV need?
What happens to a contact who is already in Notion?
How large can the file be?
What permissions does it need?
Does it need AI?
How many runs does it use?
Can I change how it works?
Related
You might also like
Turn recordings in Google Drive into summarised notes in Notion
Drop an audio recording in your Drive folder and get a Notion page with its summary and action items.
See how it worksScreen new résumés from Google Drive into Notion
Each new CV dropped into your Drive folder is read, scored against the job, and added as a card on your Notion hiring board.
See how it worksReview new contracts in Drive and log the findings in Notion
When a contract or finance document lands in your Drive folder, AI reviews it for risky terms and the findings are saved as a Notion page.
See how it worksKeep exploring
Set up “Import contacts from a CSV in Google Drive into Notion” from your assistant
Copy the prompt above, or connect your assistant first. Free plan, no credit card.