Автоматизируйте свою личную CRM с помощью Notion и Hazel Base
Введение
Hazelbase и Notion — это два мощных инструмента, которые можно использовать вместе для создания собственной CRM-системы. С помощью Hazelbase вы можете организовать данные из Интернета в сеть идентификации с миллиардами записей, которые каждый может использовать и вносить свой вклад. С Notion вы можете создать собственное приложение, которое можно использовать в качестве инструмента CRM. В этом сообщении блога мы рассмотрим, как создать приложение Node JS, а также решения для развертывания и будущие идеи для этого проекта.
Демонстрация приложения
Демо
Как это развивать
Предпосылки
- Базовый JavaScript
- Узел JS
- Учетная запись понятия
- Аккаунт Hazelbase
Создание базовой учетной записи Hazel
Для начала посетите и создайте свою учетную запись Hazelbase. После того, как вы зарегистрировали свою учетную запись, перейдите на Организации tab и создайте собственную организацию. Как только ваша организация будет создана, вы сможете получить доступ к панели инструментов. Чтобы помочь вам начать работу, мы предоставили пошаговое руководство на изображении ниже. Просто следуйте этим простым инструкциям, и вы будете готовы к работе в кратчайшие сроки.
Получение базового API-ключа Hazel
После того, как вы перешли на панель инструментов, вы можете выполнить следующие простые шаги, чтобы создать свой собственный личный ключ API:
- Нажмите кнопку «Показать портал разработчика», расположенную на левой боковой панели страницы.
- Дайте ключу API описательное имя, чтобы вы могли запомнить его назначение.
- Нажмите кнопку «Создать», чтобы сгенерировать код.
- Ваш API-ключ готов к использованию!
- Чтобы лучше понять, как использовать ваш новый ключ, вы можете изучить GraphQL Explorer, который действует как своего рода игровая площадка, позволяя вам экспериментировать с различными запросами и мутациями.
Создание интеграции Notion
Команда Notion проделала поистине замечательную работу над документацией по разработке интеграций Notion. Этот пошаговый процесс можно найти здесь, и это невероятно полезное руководство для разработчиков, желающих создать интеграцию. В нем представлен обзор всего процесса и изложены требования для создания интеграции, а также даны полезные советы и рекомендации. Кроме того, есть подробные инструкции о том, как подключиться к Notion API и настроить необходимую аутентификацию. Благодаря обширной документации команды Notion у разработчиков не должно возникнуть проблем с созданием интеграции.
Для следующего раздела нам понадобится токен внутренней интеграции.
Добавление интеграции в созданную базу данных Notion
Теперь, когда у нас есть наша база данных, нам нужно предоставить доступ к интеграции Notion, которую мы создали на первом шаге.
Шаги можно увидеть в GIF ниже:
Вы можете добавить в таблицу много разных полей, в зависимости от ваших потребностей. Для этого примера мы добавим:
- Имя
- Твиттер
- Электронная почта
- Разное
Строки таблицы будут выглядеть примерно так:
Создание приложения Node JS
Выполните следующие команды, чтобы создать проект и установить необходимые зависимости и зависимости для разработчиков:
mkdir notion-crm-hazelbase # Create new directory
cd notion-crm-hazelbase # Move to the created directory
npm init -y # Initialize the basic npm app
npm install @notionhq/client dotenv # Install the required dependencies
npm install --save-dev nodemon # Install the required dev dependencies
Редактирование package.json
Файл
Изменить package.json
файл, добавив следующую строку:
"type": "module",
Это гарантирует, что мы сможем использовать импорт ES6.
в scripts
раздел, добавьте следующий скрипт:
"dev": "nodemon index.js"
Это будет прослушивать изменения и постоянно запускать приложение.
После его завершения, package.json
файл выглядит примерно так.
{
"name": "notion-crm-hazelbase",
"version": "1.0.0",
"description": "",
"type": "module",
"main": "index.js",
"scripts": {
"dev": "nodemon index.js"
},
"keywords": [],
"author": "Rohith Gilla",
"license": "ISC",
"dependencies": {
"@notionhq/client": "^0.3.2",
"dotenv": "^10.0.0"
},
"devDependencies": {
"nodemon": "^2.0.12"
}
}
Файл среды
Нам понадобится NOTION_DATABASE_ID
, NOTION_SECRET_KEY
и HAZEL_BASE_KEY
чтобы завершить настройку интеграции Notion. Мы видели, как получить идентификатор базы данных и секретный ключ на первом этапе процесса интеграции. HAZEL_BASE_KEY
было получено на начальных этапах.
Рекомендуется сохранить эти учетные данные в файле среды для удобства и облегчения доступа. я предоставил .env.example
файл в репозитории GitHub, ссылка на который находится под сообщением в блоге. Этот файл должен дать представление о том, как должен выглядеть ваш файл среды, однако вам нужно будет заполнить детали вместо строк с правильной информацией.
NOTION_DATABASE_ID=""
NOTION_SECRET_KEY=""
HAZEL_BASE_KEY=""
Основной
Поскольку мы используем его как модуль для использования require
ключевое слово, которое нам нужно определить, require следующим образом.
import { createRequire } from "module";
const require = createRequire(import.meta.url);
База Hazel раскрывает graphql
конечная точка, которую можно использовать с помощью любого из популярных клиентов, таких как Apollo, Relay или даже библиотеки GraphQL.js. Для простоты воспользуемся POST
метод для получения результатов вызова API. Этот метод удобен для отправки данных в конечную точку и получения обратно результатов, которые можно использовать для построения запроса и получения нужных данных. Кроме того, его легко понять, и его можно использовать с минимальной настройкой и настройкой.
const GRAPHQL_ENDPOINT = "
const searchQuery = () => `
query SearchV2($email: String) {
searchV2(email: $email) {
name {
first
last
full
}
addresses {
city
}
phoneAccounts {
uri
name
carrier
type
}
emailAddresses
profiles {
network
url
}
}
}
`
Этот запрос был взят из API Explorer
Теперь мы отправим запрос GraphQL на конечную точку, используя адрес электронной почты пользователя, которого мы пытаемся найти. Этот запрос потенциально может предоставить нам соответствующую информацию, связанную с пользователем, такую как его имя и фамилия, контактные данные и другую личную информацию. Кроме того, запрос также может предоставить нам любую дополнительную информацию, которая могла быть связана с пользователем, например его возраст, пол или любые другие предпочтения, которые они могли сохранить. Используя этот запрос, мы можем быстро и легко получить доступ к информации, необходимой для точной идентификации рассматриваемого пользователя.
const getSearchResults = async (email) => {
try {
const response = await fetch(GRAPHQL_ENDPOINT, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `ApiKey ${process.env.HAZEL_BASE_KEY}`
},
body: JSON.stringify({
query: searchQuery(),
variables: {email},
}),
});
const {data} = await response.json();
return data.searchV2;
} catch (e) {
return [];
}
}
Концепция инициализации API
import { Client } from "@notionhq/client";
const NOTION_SECRET_KEY = process.env.NOTION_SECRET_KEY;
const NOTION_DATABASE_ID = process.env.NOTION_DATABASE_ID;
const notion = new Client({ auth: NOTION_SECRET_KEY });
Запрос
Теперь нам нужно запросить таблицу Notion, которую мы создали на шаге 1.
const response = await notion.databases.query({
database_id: NOTION_DATABASE_ID,
});
Мы можем напрямую запросить базу данных с помощью database_id
параметр. Мы также можем передать несколько параметров в filter
, sort
и установите размеры страниц. В этом примере мы не будем усложнять и будем передавать только database_id
.
Нам нужно получить объекты столбца и, что более важно, текст в поле электронной почты.
Получить обязательные поля
Теперь нам нужны все объекты столбцов, а также, что более важно, текст в поле электронной почты.
const email = result.properties["Email"];
const name = result.properties["Name"];
const emailText = email[email.type][0]["plain_text"];
const isAdded = result.properties["Added"];
const isAddedBool = isAdded[isAdded.type];
const linkedIn = result.properties["LinkedIn"];
const misc = result.properties["Misc"];
const twitter = result.properties["Twitter"];
Переменные email
, name
, isAdded
, linkedIn
, twitter
и misc
содержать значения соответствующих полей. Это немного сумасшедшие вложенные объекты!
Чтобы получить текст письма, мы можем использовать следующую операцию: const emailText = email[email.type][0]["plain_text"];
.
Кроме того, в базе данных есть поле, называемое Added
, который является флажком. Это поможет нам понять, была ли строка уже обработана. Чтобы получить значение этого поля, мы можем использовать ту же операцию, что и для получения значений других полей.
const isAdded = result.properties["Added"];
Инициализировать переменные данными
var fullName = "Not Found";
var linkedInUrl = "Not Found";
var twitterUrl = "Not Found";
var miscData = "Not Found";
Мы хотим узнать следующие данные о человеке в нашем случае использования. Мы предварительно заполним их значением «Не найдено» и заменим фактическим значением, как только найдем его.
Поиск и сохранение
if (!isAddedBool) {
}
Во-первых, мы проверяем, является ли значение флажка true
что указывает на то, что строка уже обработана.
Самая простая часть всего кода — попасть в конечную точку и получить результаты.
const searchResponse = await getSearchResults(emailText)
Получаем необходимые поля из ответа и сохраняем их в созданных нами ранее переменных.
if (searchResponse.length !== 0) {
fullName = searchResponse[0].name.full;
const linkedInObj = searchResponse[0].profiles.find(
(profile) => profile.network === "linkedin"
);
const twitterObj = searchResponse[0].profiles.find(
(profile) => profile.network === "twitter"
);
if (linkedInObj) {
linkedInUrl = linkedInObj.url;
}
if (twitterObj) {
twitterUrl = twitterObj.url;
}
}
Обновление API-интерфейса Notion
То, как работает обновление Notion API, не документировано должным образом для всех случаев использования, в документах API говорится только об обновлении логического или числового значения. Они не говорят об обновлении текста или других полей.
Немного покопавшись, я нашел, как обновить его, обратите внимание, что это может измениться в будущих версиях, но в основном это будет похоже.
Нам нужно построить объект для обновления полей, что можно сделать следующим образом.
var changedResult = {
...result.properties,
Twitter: {
...twitter,
rich_text: [
{
type: "text",
text: {
content: twitterUrl,
link: twitterUrl !== "Not Found" ? { url: twitterUrl } : null,
},
plain_text: twitterUrl,
href: null,
},
],
},
LinkedIn: {
...linkedIn,
rich_text: [
{
type: "text",
text: {
content: linkedInUrl,
link:
linkedInUrl !== "Not Found" ? { url: linkedInUrl } : null,
},
plain_text: linkedInUrl,
href: null,
},
],
},
Misc: {
...misc,
rich_text: [
{
type: "text",
text: { content: miscData, link: null },
plain_text: miscData,
href: null,
},
],
},
Added: {
...isAdded,
checkbox: true,
},
Name: {
...name,
title: [
{
type: "text",
text: { content: fullName, link: null },
plain_text: fullName,
href: null,
},
],
},
};
Пройдемся по объекту и проверим, что происходит
LinkedIn: {
...linkedIn,
rich_text: [
{
type: "text",
text: {
content: linkedInUrl,
link:
linkedInUrl !== "Not Found" ? { url: linkedInUrl } : null,
},
plain_text: linkedInUrl,
href: null,
},
],
},
...linkedIn
мы распространяем начальные значения, так как они содержат несколько полей, таких какid
и другие.- Нам нужно переопределить
rich_text
поле, для этого мы делаем следующее, добавляя следующий объект к этомуrich_text
множество.
{
type: "text",
text: {
content: linkedInUrl,
link:
linkedInUrl !== "Not Found" ? { url: linkedInUrl } : null,
},
plain_text: linkedInUrl,
href: null,
},
Аналогично поступаем с остальными полями.
Последний шаг обновите объект с помощью Notion API
Это довольно просто: мы берем обновленный объект и обновляем базу данных, используя понятие API.
await notion.pages.update({
page_id: result.id,
properties: changedResult,
});
Обработка ошибок
Мы будем держать его простым; вся функция будет завернута в try/catch
блок, чтобы гарантировать, что любые ошибки, возникающие во время выполнения функции, могут быть обнаружены и обработаны соответствующим образом. Это поможет нам сохранить целостность нашей программы, так как любые возникающие ошибки не могут привести к ее сбою.
Запускать периодически
Функция, которую мы имеем, должна запускаться периодически, скажем, каждые 5 секунд, подобно заданию cron, но не заданию cron. Этого можно добиться, настроив таймер, который запускает функцию каждые 5 секунд, таким образом гарантируя, что функция всегда будет выполняться каждые 5 секунд.
Мы можем использовать JavaScript setTimeout
функцию для достижения этого. setTimeout
функция, которая принимает два аргумента; первый аргумент — это функция, которую нужно выполнить, а второй аргумент — это время в миллисекундах, по истечении которого функция должна быть выполнена. Поэтому мы можем использовать setTimeout
настроить таймер, который будет запускать нашу функцию каждые 5 секунд (5000 миллисекунд).
setTimeout(main, 5000);
Объединение всего вместе
После того, как мы сделали все вышеперечисленные шаги, конечные результаты будут похожи на этот index.js
файл
Репозиторий GitHub
Вы можете найти репозиторий здесь.
Пожалуйста, отметьте репозиторий, если он вам понравился.
Решения для развертывания
Здесь мы не будем рассматривать развертывание в этом сообщении блога, но мы предложим несколько бесплатных альтернатив. Вы можете развернуть приложения Node.js на Deta с помощью Deta Micros; узнать больше здесь. Deta Micros — отличное решение для тех, кто ищет простой в использовании и простой способ развертывания своих приложений Node.js. Vercel также предлагает Node.js Время выполнения как вариант для развертывания, предлагая интуитивно понятную и удобную платформу. Кроме того, вы можете ознакомиться StackBlitz и Повторить, оба из которых предоставляют удобные и простые решения для развертывания Node.js. Неважно, каковы ваши потребности, всегда найдется подходящее решение; это лишь некоторые из многих доступных вариантов.
Продолжайте доставлять и творите чудеса!!