
لا تزال تبحث عن مفتاح HubSpot API لتشغيل تكامل HubSpot API الخاص بك؟ توقف عن البحث. ألغت HubSpot مفاتيح API الثابتة في 30 نوفمبر 2022، وحزمة SDK الحالية لـ Node (@hubspot/api-client، الآن عند الإصدار v14) لن تقبل مفتاحاً كهذا أصلاً. بيانات الاعتماد الصحيحة لأداة داخلية بحساب واحد هي توكن وصول تطبيق خاص، وهذا الدليل يبني تزامناً حقيقياً بين HubSpot وأداتك الداخلية بلغتي Node وPython، بدءاً من أول استدعاء create contact وصولاً إلى webhook موثّق التوقيع.
الإجابة المختصرة: تكامل HubSpot API يسمح لأداة داخلية مخصصة بقراءة وكتابة بيانات CRM عبر REST API الإصدار v3 من HubSpot. لأداة داخلية بحساب واحد، وثّق الهوية بتوكن وصول تطبيق خاص (أوقفت HubSpot مفاتيح API عام 2022)، ثم زامن التغييرات لحظياً عبر webhooks بدلاً من الاستقصاء الدوري.
إليك ما ستبنيه:
- مصادقة بتوكن التطبيق الخاص، وأول استدعاء
create contactبلغتي Node وPython - مستقبل webhook يتحقق من
X-HubSpot-Signature-v3قبل الوثوق بأي حمولة بيانات - تزامن آمن ضد أخطاء 429، بدفعات من 100 سجل، إلى تذكرة داخلية أو سجل ERP
كيف يعمل تكامل HubSpot API مع الأدوات الداخلية المخصصة؟
تكامل HubSpot API يربط أداة داخلية مخصصة (تطبيق تذاكر، نظام ERP، لوحة فوترة، بوابة عملاء) بنظام CRM الخاص بـ HubSpot عبر REST API الإصدار v3. أداتك تقرأ وتكتب كائنات CRM (جهات اتصال، صفقات، شركات، أو كائنات مخصصة) عبر HTTPS باستخدام توكن وصول تطبيق خاص، وتعود التغييرات اللحظية عبر webhooks.
تخيّل CRM الخاص بـ HubSpot كقاعدة بيانات تتحدث معها عبر HTTP. كل سجل هو كائن له نوع ومعرّف. تكامل hubspot crm api الذي تبنيه يؤدي مهمتين: يدفع بيانات إلى HubSpot (إنشاء جهة اتصال عند فتح تذكرة) ويسحب بيانات منه (قراءة صفقة عند عرض لوحة التحكم الداخلية لديك).
يسير التزامن في أحد اتجاهين. التزامن أحادي الاتجاه ينسخ التغييرات من HubSpot إلى أداتك، أو من أداتك إلى HubSpot. التزامن ثنائي الاتجاه يفعل الاثنين معاً ويحتاج حماية من الحلقات المتكررة، وهذا ما نتناوله لاحقاً. وبدلاً من سؤال HubSpot "هل هناك جديد؟" كل دقيقة (الاستقصاء الدوري)، تسجّل webhook ليخبرك HubSpot لحظة تغيّر أي سجل.
إن كنت تفضّل امتلاك بياناتك بالكامل بدلاً من التكامل مع CRM مُستضاف أصلاً، فاستضافة نظام CRM مفتوح المصدر بنفسك مسار مختلف يستحق التفكير فيه قبل الالتزام. لكن إن كان HubSpot مصدرك الأساسي للحقيقة أصلاً، فـ API هو الطريقة التي يتحدث بها كل شيء آخر معه.
لأداة داخلية بحساب واحد، لا تحتاج OAuth ولا إدراجاً في سوق التطبيقات. توكن تطبيق خاص وwebhook واحد يمثلان التكامل بأكمله.
المصادقة في 2026: لماذا لم يعد هناك مفتاح API لـ HubSpot؟
من أجل مصادقة HubSpot API على أداة داخلية بحساب واحد، استخدم توكن وصول تطبيق خاص. إنه توكن bearer ثابت تولّده مرة واحدة في حساب HubSpot الخاص بك، ومحدود النطاق بدقة على الكائنات التي تلمسها أداتك فقط. لا يوجد تجديد ولا انتهاء صلاحية. أما OAuth فموجود للتطبيقات العامة متعددة الحسابات، لا للوحة التحكم التي يديرها فريق العمليات لديك داخلياً.
توكن التطبيق الخاص مقابل مفتاح API الملغى
إليك الفخ الذي يوقع نصف المطورين الذين يصلون إلى هذه الصفحة. أوقفت HubSpot مفاتيح API في 30 نوفمبر 2022، وهي غير مدعومة إطلاقاً الآن. لا يزال الإكمال التلقائي يقترح "hubspot api key" لأن العادة لم تُواكب التغيير، لكن لا يوجد مفتاح لجلبه. اتجه بدلاً من ذلك إلى تطبيق HubSpot خاص (private app): أنشئه من الإعدادات، امنحه الصلاحيات التي يحتاجها، وانسخ توكن الوصول من تبويب Auth. نظرة HubSpot العامة على التطبيقات الخاصة تغطي خطوات الإعداد.
| الطريقة | حالة الاستخدام | هل تنتهي أو تحتاج تجديداً؟ | الأنسب لـ |
|---|---|---|---|
| مفتاح API | مُزال | أُوقف نوفمبر 2022 | لا شيء، فهو ملغى |
| توكن وصول تطبيق خاص | أداة داخلية بحساب واحد | لا، ثابت، بلا تجديد | أداتك الداخلية، الخيار الافتراضي هنا |
| OAuth 2.0 | تطبيق عام أو متعدد الحسابات | نعم، تنتهي التوكنات خلال حوالي 6 ساعات وتحتاج تجديداً | التطبيقات التي تدرجها لبوابات شركات أخرى |
| Service Key (تجربة عامة، فبراير 2026) | بيانات اعتماد على مستوى الحساب، للبيانات فقط | محدودة بالحساب، وفق التوثيق | مهام خادم للبيانات فقط، لا تزال تجريبية |
قاعدتان بخصوص التوكن نفسه. امنح أقل صلاحية ممكنة: إذا كانت أداتك تقرأ الصفقات فقط وتكتب جهات الاتصال، اطلب crm.objects.contacts.write وcrm.objects.deals.read، ولا شيء أكثر. واحتفظ بالتوكن في متغيّر بيئة أو مدير أسرار، وأرسله عبر ترويسة Authorization: Bearer، ولا تكتبه مباشرة في الكود ولا تشحنه أبداً إلى المتصفح.
الخلاصة بسيطة. لأداة داخلية، استخدم توكن وصول تطبيق خاص. لا تلجأ إلى OAuth إلا إذا أصبح هذا لاحقاً تطبيقاً عاماً متعدد الحسابات تُثبّته شركات أخرى في بواباتها الخاصة.
أول استدعاء لـ HubSpot API: إنشاء جهة اتصال بلغتي Node وPython
الاستدعاء الأول التقليدي هو create contact، وحزم SDK الرسمية تختزله في بضعة أسطر. ثبّت العميل، هيّئه بتوكن التطبيق الخاص من متغيرات البيئة، ثم أنشئ جهة اتصال واقرأ صفقة بالمقابل. هذا هو النمط ذاته الذي ستعيد استخدامه للشركات والتذاكر واستدعاءات hubspot custom objects api، ويتغيّر فقط نوع الكائن.
إليك نسخة Node باستخدام @hubspot/api-client (v14):
// npm i @hubspot/api-client (v14.x)
import { Client } from "@hubspot/api-client";
// Private app token from a secret manager or env var, never hard-coded
const hubspot = new Client({ accessToken: process.env.HUBSPOT_PRIVATE_APP_TOKEN });
// Create a contact
const { id } = await hubspot.crm.contacts.basicApi.create({
properties: {
email: "[email protected]",
firstname: "Ada",
lastname: "Lovelace",
lifecyclestage: "lead",
},
associations: [],
});
console.log("Created contact", id);
// Read a deal by ID
const deal = await hubspot.crm.deals.basicApi.getById(
"1234567890",
["dealname", "amount", "dealstage"],
);
console.log(deal.properties.dealname, deal.properties.amount);والشيء نفسه بلغة Python باستخدام hubspot-api-client (v12):
# pip install hubspot-api-client (v12.x)
import os
from hubspot import HubSpot
from hubspot.crm.contacts import SimplePublicObjectInputForCreate
# Private app token from the environment, not source control
client = HubSpot(access_token=os.environ["HUBSPOT_PRIVATE_APP_TOKEN"])
# Create a contact
contact = client.crm.contacts.basic_api.create(
simple_public_object_input_for_create=SimplePublicObjectInputForCreate(
properties={
"email": "[email protected]",
"firstname": "Ada",
"lastname": "Lovelace",
"lifecyclestage": "lead",
}
)
)
print("Created contact", contact.id)
# Read a deal by ID
deal = client.crm.deals.basic_api.get_by_id(
deal_id="1234567890",
properties=["dealname", "amount", "dealstage"],
)
print(deal.properties["dealname"], deal.properties["amount"])نصيحة احترافية: اختبر أولاً في بيئة تطوير تجريبية (developer sandbox) من HubSpot، لا في الإنتاج مباشرة. استدعاء إنشاء مُشوَّه في الإنتاج يترك سجلات فعلية عشوائية يضطر فريق المبيعات لتنظيفها. التوكن والصلاحيات ونموذج الكائنات تتصرف بنفس الطريقة تماماً في بيئة الـ sandbox.
كيف تُزامن HubSpot مع أداة داخلية لحظياً؟
استخدم webhooks، لا الاستقصاء الدوري. سجّل اشتراك webhook في تطبيقك الخاص للكائن والحدث الذي يهمّك (لنقل deal.propertyChange)، ووجّهه إلى نقطة HTTPS تستضيفها أنت، وسترسل HubSpot طلب POST بمصفوفة JSON صغيرة لحظة حدوث تغيير مطابق. الجأ إلى الاستقصاء فقط عندما لا يوجد اشتراك متاح لما تريد مراقبته.
الفائدة هي الكفاءة. الاستقصاء يسأل "هل هناك جديد؟" كل دقيقة ويستهلك حد معدل الطلبات لديك أثناء ذلك؛ بينما webhook يخبرك فقط لحظة تغيّر صفقة ما. هذا الفرق مهم عند التوسّع، وwebhooks أصبحت اليوم شائعة، لا استثنائية: تقرير حالة API لعام 2025 من Postman، وهو استطلاع شمل أكثر من 5,700 مطوّر، وجد أن نحو نصف الفرق تعتمد عليها.
سجّل الاشتراك من تبويب Webhooks في تطبيقك الخاص، وحدّد رابط الوجهة، واختر الأحداث. ترسل HubSpot مصفوفة من كائنات الأحداث، يحمل كل منها subscriptionType وobjectId وما الذي تغيّر. إليك مسودة مستقبِل بلغة Node مع Express:
import express from "express";
const app = express();
// Capture the raw body: you need the exact bytes to validate the signature next
app.use(express.json({
verify: (req, _res, buf) => { req.rawBody = buf.toString("utf8"); },
}));
// HubSpot POSTs an array of events to this URL
app.post("/webhooks/hubspot", (req, res) => {
const events = req.body; // [{ subscriptionType: "deal.propertyChange", objectId: 1234, ... }]
for (const event of events) {
console.log("HubSpot event:", event.subscriptionType, event.objectId);
// Do NOT trust this payload yet. The next section validates it before we act.
}
res.sendStatus(200);
});
app.listen(3000, () => console.log("Listening on :3000"));هنا يصبح البناء التطبيقي حقيقياً. لنقل إنك تُزامن صفقة مع سجل ERP لمصنّع صغير: يُطلق webhook، ويُنشئ معالجك تذكرة ERP المطابقة أو يُحدّثها، ويرى فريق العمليات التغيير دون لمس HubSpot. هذا هو النهج اللحظي ذاته الذي نستخدمه في ربط وكيل صوت بـ CRM، إلا أن المُحفّز هنا تغيّر خاصية بدلاً من مكالمة هاتفية. تحذير واحد: المسودة أعلاه تثق بأي شيء يُرسل إليها عبر POST. أصلح ذلك قبل الانتقال إلى الإنتاج.
التحقق من توقيعات webhook (v3) حتى لا تثق أبداً بحمولة مزوَّرة
تحقق من كل webhook وارد باستخدام توقيع v3. توقّع HubSpot كل طلب بسر تطبيقك، وترسل ترويستين، X-HubSpot-Signature-v3 وX-HubSpot-Request-Timestamp. ارفض أي طلب أقدم من 5 دقائق، أعد بناء نص المصدر كـ method + full URL + raw body + timestamp، طبّق عليه HMAC-SHA256 بسر التطبيق، رمّزه بـ base64، وقارِنه بزمن ثابت.
إذا تجاوزت هذه الخطوة، فبإمكان أي شخص يخمّن رابط الـ webhook الخاص بك تزوير تحديث صفقة. التحقق ليس اختيارياً. توثّق HubSpot الوصفة بالضبط في مستند التحقق من الطلبات وسجل تغييرات توقيعات v3. إليها كوسيط جاهز للتركيب في Express:
import crypto from "crypto";
const CLIENT_SECRET = process.env.HUBSPOT_APP_SECRET; // from your private app settings
const MAX_AGE_MS = 5 * 60 * 1000; // reject anything older than 5 minutes
export function validateHubSpotSignature(req, res, next) {
const signature = req.header("X-HubSpot-Signature-v3");
const timestamp = req.header("X-HubSpot-Request-Timestamp");
// 1. Reject stale requests (replay protection)
if (!signature || !timestamp || Date.now() - Number(timestamp) > MAX_AGE_MS) {
return res.sendStatus(401);
}
// 2. Rebuild the exact source string: method + full URL + raw body + timestamp
const uri = `https://${req.get("host")}${req.originalUrl}`;
const source = `${req.method}${uri}${req.rawBody}${timestamp}`;
// 3. HMAC-SHA256 with the app secret, base64-encoded
const hash = crypto
.createHmac("sha256", CLIENT_SECRET)
.update(source, "utf8")
.digest("base64");
// 4. Constant-time compare against the header
const expected = Buffer.from(hash);
const received = Buffer.from(signature);
if (expected.length !== received.length ||
!crypto.timingSafeEqual(expected, received)) {
return res.sendStatus(401);
}
next();
}الفحص نفسه كدالة Python، بحيث تكون كلتا المجموعتين التقنيتين مغطاتين:
import base64
import hashlib
import hmac
import os
import time
CLIENT_SECRET = os.environ["HUBSPOT_APP_SECRET"].encode("utf-8")
MAX_AGE_MS = 5 * 60 * 1000 # 5 minutes
def is_valid_signature(method, uri, body, signature, timestamp):
# 1. Reject stale requests
if not signature or not timestamp:
return False
if int(time.time() * 1000) - int(timestamp) > MAX_AGE_MS:
return False
# 2. method + full URL + raw body + timestamp
source = f"{method}{uri}{body}{timestamp}".encode("utf-8")
# 3. HMAC-SHA256, base64
digest = hmac.new(CLIENT_SECRET, source, hashlib.sha256).digest()
expected = base64.b64encode(digest).decode("utf-8")
# 4. Constant-time compare
return hmac.compare_digest(expected, signature)الفخ الذي يُكلّف الناس عصراً كاملاً من وقتهم: توقّع HubSpot الرابط الكامل للوجهة، بما في ذلك المخطط والمضيف والمسار معاً. خلف بروكسي، أو موازن أحمال، أو نفق ngrok، قد يُبلّغ req.get("host") عن المضيف الداخلي بدلاً من المضيف العام الذي وقّعته HubSpot. إذا استمر فشل التحقق مع حمولة أنت متأكد من صحتها، سجّل الـ URI الذي أعدت بناءه وقارِنه برابط الـ webhook العام لديك، حرفاً بحرف.
حدود معدل الطلبات، أخطاء 429، وAPI الدفعات: ما شغّلناه في الإنتاج
تحصل التطبيقات الخاصة على نحو 10 طلبات في الثانية (100 لكل 10 ثوانٍ في خطة Free/Starter، و190 لكل 10 ثوانٍ في خطة Pro/Enterprise) بحد يومي يتراوح بين 250,000 و1,000,000. الفخ: CRM Search له حد منفصل عند 4 طلبات في الثانية، ونقاط نهاية الدُفعات تقبل حداً أقصى قدره 100 سجل لكل طلب. تسرد إرشادات الاستخدام من HubSpot الفئات المختلفة.
| الفئة | لكل 10 ثوانٍ | لكل ثانية | الحد اليومي | ملاحظات |
|---|---|---|---|---|
| Free / Starter (تطبيق خاص) | 100 | ~10 | 250,000 | CRM Search محدود بشكل منفصل عند 4 طلبات/ثانية |
| Pro / Enterprise (تطبيق خاص) | 190 | ~19 | حتى 1,000,000 | نقاط نهاية الدُفعات بحد أقصى 100 سجل لكل طلب |
هنا اصطدمت النظرية بلوحة تحكم staging حمراء. خلال عملية تعبئة بيانات تاريخية (backfill) هذا الربيع، دفعنا نحو 8,000 سجل موجود مسبقاً إلى HubSpot من أداة تذاكر داخلية، وأثرينا كل سجل ببحث CRM Search. كنا نشغّل @hubspot/api-client v14 على جانب Node وhubspot-api-client v12 لعامل إثراء بلغة Python. الكتابات الجماعية سارت بلا مشاكل. لكن استدعاءات Search انهارت خلال دقيقة واحدة، لأن العامل لدينا كان يُطلق طلبات Search بمعدل نحو 15 طلباً في الثانية مقابل سقف صارم قدره 4 طلبات في الثانية لم نُخصّص له ميزانية منفصلة.
أصلح تغييران المشكلة. أولاً، غلاف إعادة محاولة يقرأ ترويسات الاستجابة X-HubSpot-RateLimit-* ويتراجع عند خطأ 429:
// Wrap any HubSpot call; retries on 429 with exponential backoff
async function withRetry(fn, maxRetries = 5) {
let attempt = 0;
while (true) {
try {
return await fn();
} catch (err) {
const status = err.code ?? err.response?.status;
if (status !== 429 || attempt >= maxRetries) throw err;
// Honor HubSpot's reset window if the header is present
const headers = err.response?.headers ?? {};
const resetMs = Number(headers["x-hubspot-ratelimit-interval-milliseconds"]) || 0;
const backoff = Math.max(resetMs, 2 ** attempt * 500); // 0.5s, 1s, 2s, 4s...
console.warn(`429 hit, retry ${attempt + 1} in ${backoff}ms`);
await new Promise((r) => setTimeout(r, backoff));
attempt++;
}
}
}ثانياً، توقفنا عن كتابة السجلات واحداً تلو الآخر. نقطة نهاية الدُفعات تقبل حتى 100 سجل لكل POST /crm/v3/objects/{objectType}/batch/create، لذا قسّمنا عملية التعبئة إلى 80 استدعاء دفعة بدلاً من 8,000 طلب POST منفرد:
// HubSpot batch endpoints accept at most 100 records per request
function chunk(arr, size = 100) {
const out = [];
for (let i = 0; i < arr.length; i += size) out.push(arr.slice(i, i + size));
return out;
}
// POST /crm/v3/objects/contacts/batch/create, chunked to 100 at a time
async function batchCreateContacts(records) {
for (const group of chunk(records, 100)) {
const inputs = group.map((r) => ({
properties: { email: r.email, firstname: r.firstName, lastname: r.lastName },
associations: [],
}));
await withRetry(() => hubspot.crm.contacts.batchApi.create({ inputs }));
console.log(`Wrote ${group.length} contacts`);
}
}تقييد عامل Search عند 4 طلبات في الثانية وتجميع الكتابات في دفعات حوّل تشغيلاً كان يغرق في إعادة المحاولات إلى تشغيل انتهى بهدوء. إن كنت ستتذكر رقماً واحداً من هذا القسم، فليكن 4: حد CRM Search هو القيد الذي يلدغك في الإنتاج، وهو الرقم الذي تنساه كل مقالات الملخصات. بالمناسبة، سقف الدُفعات القديم "10 لجهات الاتصال" اختفى؛ الحالي هو 100 عبر جميع أنواع الكائنات.
التزامن ثنائي الاتجاه: كتابة التغييرات إلى HubSpot دون حلقات لا نهائية
التزامن ثنائي الاتجاه يكتب التغييرات إلى HubSpot من أداتك الداخلية بقدر ما يقرأها منه. الخطر هو حلقة تغذية راجعة: كتابتك المرتدة تُطلق webhook نفسه الذي شغّل معالجك، والذي يكتب مجدداً، إلى ما لا نهاية. امنع ذلك بـ مفتاح idempotency (تجاوز التغييرات التي طبّقتها مسبقاً) وعلامة مصدر (تجاهل الأحداث الواردة التي تسببت بها أداتك ذاتها).
const processed = new Set(); // use Redis or a unique DB constraint in production
async function writeBackToHubSpot(record) {
// Dedup key: object id + a hash of the change we're about to apply
const key = `${record.id}:${record.updatedHash}`;
if (processed.has(key)) return; // already synced this exact change
processed.add(key);
await withRetry(() =>
hubspot.crm.contacts.basicApi.update(record.id, {
// Tag the source so the resulting webhook is ignored by our own receiver
// (check for source: "internal-tool" before acting on an inbound event)
properties: { internal_status: record.status, last_sync_source: "internal-tool" },
})
);
}النمط صغير، لكن تجاوزه هو بالضبط كيف يُضاعف التزامن حجم كتاباتك بصمت بين ليلة وضحاها. بمجرد أن تصبح البيانات نظيفة في الاتجاهين، غالباً ما تُغذّي الفرق بها لاحقاً خط أنابيب AI SDR أو طبقة تقارير. دليل Nango لتكامل HubSpot مرجع جيد يقتصر على Node إذا أردت رأياً ثانياً حول التزامن ثنائي الاتجاه، رغم أنك ستحتاج لنقل فكرة منع الحلقات بنفسك.
هل تبني هذا داخلياً أم تستعين بشريك تكامل؟
ابنِ داخلياً عندما يكون التزامن صغيراً ومستقراً ومملوكاً: مسار أحادي الاتجاه، وحفنة من الكائنات، ومهندس قادر على استيعاب تغييرات HubSpot الجذرية التي تحدث مرتين تقريباً في السنة. استعن بشريك عندما تحتاج تزامناً ثنائي الاتجاه، أو نمذجة كائنات مخصصة، أو عندما لا يستطيع أحد في الفريق تحمّل الصيانة المستمرة. العامل الحاسم نادراً ما يكون البناء الأولي؛ بل من سيراقبه بعد سنة من الآن.
إليك قائمة تحقق صادقة. ابنِه بنفسك إذا: كان الاتجاه أحادياً، وتُزامن كائنات قياسية، ولديك مطوّر قادر على استضافة نقطة نهاية webhook، وسيلاحظ أحدهم عندما تبدأ حمولة بالفشل. كل ما سبق أعلاه هو مخططك الجاهز.
استعن بشريك إذا: احتجت تزامناً ثنائي الاتجاه مع منع حلقات عبر عدة كائنات، أو كنت تنمذج كائنات مخصصة بارتباطات مصنّفة، أو تربط أنظمة متعددة (HubSpot زائد ERP زائد فوترة)، أو كان الشخص الذي سيصونه مُثقلاً بالفعل. تستخدم HubSpot إصداراً قائماً على التاريخ مع تغييرات جذرية مرتين تقريباً في السنة فقط، وهو ما يبدو لطيفاً حتى يقع أحدها في أكثر أسبوع ازدحاماً لديك ولا يوجد من يملك المسؤولية. ذيل الصيانة هذا، لا النشر الأول، هو ما يُغرق التكاملات الداخلية بصمت. إن كنت تفضّل عدم تحمّل ذلك بنفسك، فهنا يأتي دور خدمات تكامل CRM المخصصة لدينا.
أهم النقاط
- لم يعد هناك مفتاح API لـ HubSpot بعد الآن. استخدم توكن وصول تطبيق خاص لأداة داخلية بحساب واحد؛ OAuth مخصص فقط للتطبيقات العامة متعددة الحسابات.
- تحقق دائماً من
X-HubSpot-Signature-v3قبل الوثوق بحمولة أي webhook. أعد بناء نص المصدر بالرابط الكامل للوجهة. - احترم حد 4 طلبات/ثانية لـ CRM Search، ونفّذ الكتابات الكبيرة في دفعات من 100 مع تراجع عند خطأ 429.
- فضّل webhooks على الاستقصاء الدوري للتزامن اللحظي، وتكامل HubSpot ما هو إلا قطعة واحدة من مجموعة أدوات أوسع من أدوات الذكاء الاصطناعي للأعمال.
عالق في جانب الصيانة، أو تريد رأياً إضافياً قبل الإطلاق؟ احجز استشارة تكامل مجانية. لا ضغط في أي من الاتجاهين؛ الكود أعلاه ملكك لتشغيله بصرف النظر.
عن الكاتب
مرت باتور غوربوز هو المؤسس المشارك لـ Techsy.io، حيث يشحن الفريق وكلاء الذكاء الاصطناعي وأنظمة الأتمتة وخطوط الصوت/SDR لعملاء B2B. يدرس في جامعة برمنغهام ويكتب عن مجموعة أدوات LLM التي يستخدمها فريق Techsy فعلاً في الإنتاج. تواصل عبر LinkedIn.
الأسئلة الشائعة
هل ما زلت بحاجة إلى مفتاح API لـ HubSpot في 2026؟
لا. أوقفت HubSpot مفاتيح API الثابتة في 30 نوفمبر 2022، وهي غير مدعومة إطلاقاً الآن. لا يزال الإكمال التلقائي يقترح "hubspot api key" بحكم العادة، لكن لا يوجد شيء لجلبه. لأداة داخلية بحساب واحد، أنشئ تطبيقاً خاصاً من الإعدادات واستخدم توكن الوصول الخاص به بدلاً من ذلك.
ما الفرق بين توكن التطبيق الخاص وOAuth في HubSpot؟
توكن وصول التطبيق الخاص هو بيانات اعتماد ثابتة لحساب HubSpot واحد، بلا انتهاء صلاحية وبلا تجديد، وهو مثالي لأداة داخلية. أما OAuth 2.0 فهو للتطبيقات العامة متعددة الحسابات التي تُثبّتها شركات أخرى في بواباتها الخاصة؛ وتنتهي توكناته خلال نحو ست ساعات وتتطلب دورة تجديد.
ما هي حدود معدل طلبات API لـ HubSpot في 2026؟
تحصل التطبيقات الخاصة على نحو 10 طلبات في الثانية (100 لكل 10 ثوانٍ في Free/Starter، و190 في Pro/Enterprise) بحد يومي من 250,000 إلى 1,000,000. أما CRM Search API فله حد منفصل عند 4 طلبات في الثانية، ونقاط نهاية الدُفعات تقبل حداً أقصى قدره 100 سجل لكل طلب.
كيف أتحقق من توقيع webhook في HubSpot؟
استخدم وصفة v3: ارفض الطلبات التي تكون فيها X-HubSpot-Request-Timestamp أقدم من خمس دقائق، ثم ابنِ نص مصدر من method زائد الرابط الكامل للوجهة زائد الجسم الخام زائد الطابع الزمني. طبّق عليه HMAC-SHA256 بسر تطبيقك، رمّز النتيجة بـ base64، وقارنها بـ X-HubSpot-Signature-v3 بزمن ثابت.
أي حزمة SDK لـ HubSpot يجب أن أستخدم، Node أم Python؟
كلتاهما رسمية ومدعومة بالصيانة. تستخدم Node حزمة @hubspot/api-client (v14) وتستخدم Python حزمة hubspot-api-client (v12). تعرضان نموذج كائنات CRM ذاته من الإصدار v3، فاختر ما يناسب مجموعتك التقنية. هذا الدليل يقدّم كوداً متطابقاً للمصادقة والتحقق من التوقيع بكلتا اللغتين.
كيف أزامن HubSpot مع أداة داخلية مخصصة لحظياً؟
سجّل اشتراك webhook في تطبيقك الخاص للكائن والحدث الذي يهمّك، ثم استضف نقطة نهاية HTTPS تُرسل HubSpot إليها طلب POST عند حدوث تغيير مطابق. تحقق من التوقيع، ثم اكتب التغيير في أداتك الداخلية. الجأ إلى الاستقصاء فقط عندما لا يغطي أي اشتراك webhook ما تحتاجه.
ما هو Service Key في HubSpot وهل يجب أن أستخدمه؟
Service Key هو بيانات اعتماد على مستوى الحساب، مخصصة للبيانات فقط، وضعتها HubSpot في تجربة عامة في فبراير 2026. وهو موجّه لمهام على جانب الخادم تلمس البيانات فقط. بالنسبة لأداة داخلية قياسية اليوم، لا يزال توكن وصول التطبيق الخاص هو الخيار الافتراضي الأكثر أماناً وتوثيقاً؛ تعامل مع Service Key كخاصية تجريبية إلى أن تتخرج منها.
هل يمكنني اختبار تكامل HubSpot دون لمس بيئة الإنتاج؟
نعم. أنشئ بيئة تطوير تجريبية من HubSpot ووجّه توكن تطبيقك الخاص إليها. الصلاحيات ونموذج الكائنات وwebhooks وحدود معدل الطلبات تتصرف بنفس طريقة الإنتاج، فتستطيع إنشاء جهات اتصال تجريبية وإطلاق webhooks دون ترك سجلات عشوائية يضطر فريق المبيعات لتنظيفها لاحقاً.
كم عدد السجلات التي يقبلها HubSpot batch API في المرة الواحدة؟
تقبل نقاط نهاية الدُفعات (POST /crm/v3/objects/{objectType}/batch/create وما يشابهها من عمليات update وupsert) حداً أقصى قدره 100 سجل لكل طلب. قسّم الحمولات الأكبر إلى مجموعات من 100. سقف "10 سجلات لجهات الاتصال" القديم الذي لا تزال بعض الدروس تستشهد به قد أُزيل؛ الحالي هو 100 عبر جميع أنواع الكائنات.
هل ينبغي أن أبني هذا داخلياً أم أستعين بوكالة؟
ابنِ داخلياً عندما يكون التزامن أحادي الاتجاه، ويستخدم كائنات قياسية، ولديه مالك قادر على استيعاب تغييرات HubSpot الجذرية التي تحدث مرتين في السنة. استعن بشريك من أجل التزامن ثنائي الاتجاه، أو نمذجة الكائنات المخصصة، أو عندما لا يستطيع أحد تحمّل الصيانة. النشر الأول سهل؛ سنة الصيانة التي تليه هي التكلفة الحقيقية.