ایک اسکرپٹ (Python، Node.js، cURL) کے ساتھ CSV یا Excel گاہکوں کو Brevo میں کیسے امپورٹ کریں

import-contacts API کا استعمال کرتے ہوئے CSV یا Excel فائل سے گاہکوں کو Brevo میں بلک امپورٹ کریں۔ تیار چلانے والے Python اور Node.js اسکرپٹ، cURL ون لائنر، ایرر ہینڈلنگ اور 10 MB سے بڑی فائلوں کے لیے ٹپس شامل ہیں۔

Featured image for article: ایک اسکرپٹ (Python، Node.js، cURL) کے ساتھ CSV یا Excel گاہکوں کو Brevo میں کیسے امپورٹ کریں

اگر آپ کو کبھی اسپریڈشیٹ سے چند ہزار گاہک Brevo میں پش کرنے کی ضرورت پڑی ہو، تو دستی UI راستہ جلد ہی تکلیف دہ ہو جاتا ہے: فائل منتخب کریں، کالم میپ کریں، فہرست منتخب کریں، انتظار کریں، دہرائیں۔ ایک اسکرپٹ وہی کام چند سیکنڈ میں کرتا ہے، اور اس سے بھی اہم بات یہ کہ آپ اسے شیڈول پر، ڈیٹا بیس ایکسپورٹ کے بعد، یا جب بھی آپ کا CRM ایک تازہ CSV نکالے، دوبارہ چلا سکتے ہیں۔

یہ گائیڈ Brevo کی طرف سے بالکل اسی کے لیے فراہم کردہ API اینڈ پوائنٹ کا احاطہ کرتی ہے، Python، Node.js میں مکمل ورکنگ اسکرپٹس اور ایک cURL ون لائنر کے ساتھ۔ اس گائیڈ میں ہر چیز POST /v3/contacts/import کو ہٹ کرتی ہے۔

اینڈ پوائنٹ ایک نظر میں

POST https://api.brevo.com/v3/contacts/import
Content-Type: application/json
api-key: YOUR_API_KEY
{
"fileBody": "EMAIL;FIRSTNAME;LASTNAME\n[email protected];Jane;Doe",
"listIds": [42],
"updateExistingContacts": true,
"emailBlacklist": false,
"smsBlacklist": false
}

جواب جلدی واپس آتا ہے:

{ "processId": 78 }

یہ ایک 202 Accepted ہے، Brevo نے امپورٹ قبول کر لیا ہے اور بیک گراؤنڈ میں اس پر کام کر رہا ہے۔ اگر آپ مکمل ہونے کے لیے poll کرنا چاہیں یا notifyUrl ویب ہک سیٹ اپ کرنا چاہیں تو processId آپ کا ٹریکنگ ہینڈل ہے۔

کوڈ لکھنے سے پہلے قابل غور چند چیزیں:

  • باڈی CSV (fileBody)، JSON (jsonBody)، یا ایک ریموٹ URL (fileUrl) ہو سکتی ہے۔ ایک منتخب کریں۔ CSV فارم کالم الگ کرنے کے لیے سیمی کولن (;) استعمال کرتا ہے، کاما نہیں، یہ ایک عام پھندہ ہے۔
  • fileBody اور jsonBody پر 10 MB کی حد ہے۔ Brevo محفوظ رہنے کے لیے 8 MB کے قریب رہنے کی سفارش کرتا ہے۔ اس سے بڑی کسی بھی چیز کے لیے، فائل کو S3، GCS، یا کسی بھی HTTPS ہوسٹ پر اپ لوڈ کریں اور اس کے بجائے fileUrl پاس کریں۔
  • آپ کے اکاؤنٹ میں موجود نہ ہونے والے کسٹم اٹریبیوٹس خاموشی سے نظر انداز ہو جاتے ہیں۔ انہیں استعمال کرنے والی قطاروں کو امپورٹ کرنے سے پہلے، Brevo کے UI میں (یا Attributes API کے ذریعے) ان کو بنائیں، ورنہ ڈیٹا بس غائب ہو جاتا ہے۔
  • updateExistingContacts ڈیفالٹ true ہے۔ اگر آپ اسے false پر سیٹ کریں، تو Brevo ایسے گاہکوں کو چھوڑ دیتا ہے جن کا ای میل پہلے سے موجود ہے۔ “صرف نئے شامل کریں” جابز کے لیے مفید ہے۔
  • emptyContactsAttributes کنٹرول کرتا ہے کہ آیا آپ کے CSV میں خالی سیلز موجودہ ویلیوز کو مٹاتے ہیں۔ ڈیفالٹ false (خالی سیلز نظر انداز ہوتے ہیں)۔ اگر آپ کا CSV سچ کا ذریعہ ہے اور آپ چاہتے ہیں کہ خالی سیلز پرانے ڈیٹا کو صاف کریں تو true پر سیٹ کریں۔

ایک API کلید حاصل کریں

Brevo میں سائن ان کریں → Settings → SMTP & API → API Keys → ایک نئی کلید بنائیں۔ یہ xkeysib-... کی طرح نظر آتی ہے۔ آپ اسے ہر درخواست پر api-key HTTP ہیڈر کے طور پر پاس کریں گے۔ اسے ایک پاس ورڈ کی طرح سمجھیں، اس کے پاس آپ کے اکاؤنٹ پر مکمل پڑھنے/لکھنے کی اجازت ہے۔

ایک صاف ستھرا پیٹرن: اسے ایک ماحولیاتی متغیر میں رکھیں تاکہ یہ کبھی آپ کے سورس ٹری میں نہ آئے۔

Terminal window
export BREVO_API_KEY="xkeysib-..."

Python: ایک CSV پڑھیں، اسے Brevo میں پش کریں

یہ ممکنہ سب سے آسان اسکرپٹ ہے: معیاری لائبریری کے ساتھ ایک مقامی CSV پڑھیں، باڈی کو سیدھا Brevo کو بھیجیں۔ requests کے علاوہ تیسرے فریق SDK کی ضرورت نہیں۔

import_csv_to_brevo.py
import csv
import io
import os
import sys
import requests
API_KEY = os.environ["BREVO_API_KEY"]
LIST_ID = 42 # the Brevo list to add contacts to
INPUT_FILE = sys.argv[1] if len(sys.argv) > 1 else "contacts.csv"
# Brevo wants semicolon-separated CSV. If your file uses commas (most do),
# convert it on the fly so you don't have to edit the source spreadsheet.
def to_brevo_csv(path: str) -> str:
with open(path, newline="", encoding="utf-8") as f:
reader = csv.reader(f) # default: comma-separated
out = io.StringIO()
writer = csv.writer(out, delimiter=";")
for row in reader:
writer.writerow(row)
return out.getvalue()
body = {
"fileBody": to_brevo_csv(INPUT_FILE),
"listIds": [LIST_ID],
"updateExistingContacts": True,
"emptyContactsAttributes": False,
"emailBlacklist": False,
"smsBlacklist": False,
}
resp = requests.post(
"https://api.brevo.com/v3/contacts/import",
json=body,
headers={"api-key": API_KEY, "Content-Type": "application/json"},
timeout=60,
)
if resp.status_code != 202:
print(f"Import failed: {resp.status_code} {resp.text}")
sys.exit(1)
process_id = resp.json()["processId"]
print(f"Import accepted. Process ID: {process_id}")

اسے چلائیں:

Terminal window
python import_csv_to_brevo.py contacts.csv

آپ کے CSV کی پہلی قطار ہیڈر ہے۔ کالم کے نام Brevo اٹریبیوٹس میں بڑے حروف، صحیح میچ سے میپ ہوتے ہیں: EMAIL، FIRSTNAME، LASTNAME، علاوہ کسی بھی کسٹم اٹریبیوٹ کے جو آپ نے بنائی ہو۔ EMAIL لازمی ہے۔

EMAIL,FIRSTNAME,LASTNAME,COMPANY,CITY
[email protected],Jane,Doe,Acme,Berlin
[email protected],John,Smith,Globex,Paris

یہ پورا فلو ہے۔ اسکرپٹ ایک سیکنڈ کے اندر واپس آ جاتا ہے؛ اصل امپورٹ سرور سائیڈ پر چلتا ہے اور حجم کے مطابق چند سیکنڈ سے چند منٹ تک لیتا ہے۔

Excel فائلیں: تین قابل عمل راستے

Brevo کا امپورٹ اینڈ پوائنٹ .xlsx کو براہ راست نہیں پڑھتا، تو آپ کے پاس تین حقیقی اختیارات ہیں جس پر منحصر ہے کہ کام کہاں رہنا چاہیے:

  1. ورک بک کے اندر ایک VBA میکرو چلائیں: Excel سے ہی ایک کلک سنک، کوئی بیرونی اسکرپٹ نہیں۔ یہ صحیح جواب ہے جب فائل ڈیسک ٹاپ پر رہتی ہے اور آپ کی ٹیم شیٹ پر ایک بٹن چاہتی ہے۔ مکمل کوڈ Excel سے Brevo VBA میکرو گائیڈ میں۔
  2. Office Scripts + Power Automate: اگر ورک بک OneDrive/SharePoint میں ہے اور آپ بغیر نگرانی کے شیڈولڈ سنک چاہتے ہیں۔ Excel گائیڈ میں بھی شامل ہے۔
  3. اسکرپٹ سے .xlsx کو CSV میں تبدیل کریں: اس سیکشن کا باقی حصہ یہی احاطہ کرتا ہے۔ بہترین ہے اگر آپ پہلے ہی سرور پر Python یا Node چلا رہے ہیں اور صرف دن میں ایک بار ورک بک پل کرنا چاہتے ہیں۔

اختیار 3 کے لیے، pandas اسے ایک لائن کا کام بناتا ہے:

# pip install pandas openpyxl
import pandas as pd
def xlsx_to_brevo_csv(path: str, sheet_name: str | int = 0) -> str:
df = pd.read_excel(path, sheet_name=sheet_name)
return df.to_csv(sep=";", index=False)
body["fileBody"] = xlsx_to_brevo_csv("contacts.xlsx")

اگر آپ pandas کو بطور ڈیپینڈنسی نہیں چاہتے، تو اکیلا openpyxl کام کرتا ہے:

from openpyxl import load_workbook
import csv, io
def xlsx_to_brevo_csv(path: str) -> str:
wb = load_workbook(path, read_only=True)
ws = wb.active
out = io.StringIO()
writer = csv.writer(out, delimiter=";")
for row in ws.iter_rows(values_only=True):
writer.writerow(["" if v is None else v for v in row])
return out.getvalue()

Node.js: وہی کام، آفیشل SDK

Brevo Node کے لیے @getbrevo/brevo پبلش کرتا ہے۔ یہ آتھ، ری ٹرائز، اور ٹائپ شدہ درخواست کی شکل کو سنبھالتا ہے:

import-csv-to-brevo.mjs
// npm install @getbrevo/brevo
import fs from 'node:fs/promises';
import { BrevoClient } from '@getbrevo/brevo';
const API_KEY = process.env.BREVO_API_KEY;
const LIST_ID = 42;
const INPUT_FILE = process.argv[2] ?? 'contacts.csv';
const client = new BrevoClient({ apiKey: API_KEY });
// Read the CSV and convert commas to semicolons if needed
const raw = await fs.readFile(INPUT_FILE, 'utf-8');
const csv = raw.includes(';') ? raw : raw.replace(/,/g, ';');
const result = await client.contacts.importContacts({
fileBody: csv,
listIds: [LIST_ID],
updateExistingContacts: true,
emptyContactsAttributes: false,
});
console.log(`Import accepted. Process ID: ${result.processId}`);

یا، اگر آپ SDK نہیں چاہتے، تو سادہ fetch اسی طرح کام کرتا ہے:

const resp = await fetch('https://api.brevo.com/v3/contacts/import', {
method: 'POST',
headers: {
'api-key': process.env.BREVO_API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({
fileBody: csv,
listIds: [42],
updateExistingContacts: true,
}),
});
if (resp.status !== 202) {
throw new Error(`Import failed: ${resp.status} ${await resp.text()}`);
}
const { processId } = await resp.json();
console.log(`Process ID: ${processId}`);

cURL: عارضی امپورٹس کے لیے ایک ون لائنر

جب آپ صرف اینڈ پوائنٹ کو ٹیسٹ کرنا چاہتے ہیں یا ایک چھوٹی فائل کو ہاتھ سے دھکیلنا چاہتے ہیں:

Terminal window
# Convert commas to semicolons, then send the file inline
csv=$(sed 's/,/;/g' contacts.csv | jq -Rs .)
curl -X POST https://api.brevo.com/v3/contacts/import \
-H "api-key: $BREVO_API_KEY" \
-H "Content-Type: application/json" \
-d "{\"fileBody\": $csv, \"listIds\": [42], \"updateExistingContacts\": true}"

jq -Rs . پوری فائل کو نگل لیتا ہے اور JSON-escape کرتا ہے، آپ کو نئی لائنوں اور کوٹس کو دستی طور پر escape کرنے سے بچاتا ہے۔

10 MB سے بڑی فائلیں: fileUrl استعمال کریں

fileBody کی حد 10 MB ہے۔ اگر آپ کا کانٹیکٹ ڈمپ بڑا ہے، تو فائل کو ایسے URL پر ہوسٹ کریں جو Brevo حاصل کر سکے اور اسے پاس کریں:

body = {
"fileUrl": "https://files.example.com/contacts/2026-04-30.csv",
"listIds": [42],
"updateExistingContacts": True,
}

عوامی HTTPS URL کے ذریعے قابل رسائی کوئی بھی چیز کام کرتی ہے: پری سائنڈ S3 URLs، GCS، آپ کا اپنا اسٹیٹک ہوسٹ، حتیٰ کہ ایک بار کے امپورٹس کے لیے ایک GitHub raw URL بھی۔ Brevo فائل کو آپ کے URL سے فیچ کرتا ہے، پھر امپورٹ چلاتا ہے۔ قبول شدہ فارمیٹس: .csv، .txt، .json۔

CSV کے بجائے JSON بھیجیں

اگر آپ پہلے ہی ڈیٹا بیس سے گاہک کھینچ رہے ہیں، تو آپ کو CSV کے ذریعے راؤنڈ ٹرپ کرنے کی ضرورت نہیں، انہیں براہ راست JSON کے طور پر بھیجیں:

body = {
"jsonBody": [
{
"email": "[email protected]",
"attributes": {
"FIRSTNAME": "Jane",
"LASTNAME": "Doe",
"COMPANY": "Acme",
},
},
{
"email": "[email protected]",
"attributes": {
"FIRSTNAME": "John",
"LASTNAME": "Smith",
"COMPANY": "Globex",
},
},
],
"listIds": [42],
}

وہی 10 MB کی حد۔ وہی ایسنکرونس رویہ۔

مکمل ہونے کے لیے Polling

امپورٹ ایسنکرونس ہے، processId اسے ٹریک کرنے کا آپ کا ہینڈل ہے۔ پراسس اسٹیٹس چیک کرنے کے لیے ایک علیحدہ اینڈ پوائنٹ ہے:

def wait_for_import(process_id: int, timeout_s: int = 600) -> dict:
import time
deadline = time.time() + timeout_s
while time.time() < deadline:
r = requests.get(
f"https://api.brevo.com/v3/processes/{process_id}",
headers={"api-key": API_KEY},
timeout=30,
)
r.raise_for_status()
status = r.json()
if status["status"] in ("completed", "failed"):
return status
time.sleep(5)
raise TimeoutError(f"Import {process_id} did not finish in {timeout_s}s")
result = wait_for_import(process_id)
print(f"Import {result['status']}: {result}")

طویل چلنے والی جابز کے لیے، صاف ستھرا پیٹرن notifyUrl ہے: ایک HTTPS اینڈ پوائنٹ پاس کریں جسے Brevo امپورٹ ختم ہونے پر POST کرے گا، اور پولنگ کو چھوڑ دیں۔

body["notifyUrl"] = "https://your-app.example.com/webhooks/brevo-import"

عام غلطیاں اور انہیں کیسے ٹھیک کریں

بغیر کسی واضح وجہ کے 400 Bad Request: تقریباً ہمیشہ CSV میں سیمی کولن بمقابلہ کاما کا معاملہ ہوتا ہے۔ Brevo کا امپورٹ ; کی توقع کرتا ہے، , کی نہیں۔ اپنے کنورژن سٹیپ کے بعد fileBody کو دوبارہ چیک کریں۔

کسٹم اٹریبیوٹ ویلیوز غائب ہو جاتی ہیں: اٹریبیوٹ آپ کے اکاؤنٹ میں موجود نہیں ہے۔ امپورٹ سے پہلے اسے Contacts → Settings → Contact attributes کے تحت بنائیں، یا اپنی اسکرپٹ کے حصے کے طور پر اسے بنانے کے لیے Attributes API استعمال کریں۔

401 Unauthorized: غلط ہیڈر کا نام۔ یہ api-key ہے (چھوٹے حروف، ہائیفن)، نہ کہ Authorization یا X-API-Key۔

امپورٹ “کامیاب” ہوا لیکن گاہک فہرست میں ظاہر نہیں ہوئے: چیک کریں کہ listIds صحیح فہرست پر مشتمل ہے۔ اس کے علاوہ: اگر updateExistingContacts false ہے اور گاہک پہلے سے موجود ہیں، تو Brevo انہیں دوبارہ فہرست میں شامل کرنے کے بجائے خاموشی سے چھوڑ دیتا ہے۔

کچھ قطاریں امپورٹ ہوئیں، کچھ نہیں: Brevo امپورٹ ختم ہونے کے بعد آپ کو ہر قطار کی ایرر رپورٹ ای میل کرتا ہے (جب تک کہ آپ نے disableNotification: true سیٹ نہ کیا ہو)۔ رپورٹ آپ کو بتاتی ہے کہ کن قطاروں میں خراب ای میلز، گمشدہ مطلوبہ فیلڈز، یا فارمیٹنگ کے مسائل تھے۔

کب اسکرپٹ کریں اور کب UI استعمال کریں

UI ایک ہزار سے کم قطاروں کے ون آف امپورٹس کے لیے ٹھیک ہے۔ ایک اسکرپٹ جیتتا ہے جیسے ہی:

  • آپ ایک سے زیادہ بار امپورٹ کر رہے ہیں (مثلاً اپنے CRM سے ہفتہ وار ایکسپورٹ)
  • ماخذ ڈیٹا کو Brevo میں آنے سے پہلے صاف کرنے کی ضرورت ہے (ڈی ڈپلیکیشن، فون نمبروں کی فارمیٹنگ، فل نام کو پہلے/آخری نام میں تقسیم کرنا)
  • آپ چاہتے ہیں کہ یہ کسی کے بٹن پر کلک کیے بغیر شیڈول پر چلے
  • فائل UI کے کمفرٹ زون سے بڑی ہے

اوپر دی گئی اسکرپٹ کو ایک cron جاب یا GitHub Action میں لپیٹیں اور آپ کے پاس خودکار گاہک سنک ہے۔ اس سیریز کی اگلی پوسٹ دکھاتی ہے کہ اپنے Apps Script کا استعمال کرتے ہوئے براہ راست Google Sheet سے یہی کام کیسے کیا جائے، کوئی سرور درکار نہیں۔

مزید پڑھنے کے لیے

Frequently Asked Questions

بلک گاہک امپورٹ کے لیے Brevo کا API اینڈ پوائنٹ کیا ہے؟
POST https://api.brevo.com/v3/contacts/import۔ یہ CSV مواد (fileBody)، ایک ریموٹ فائل URL (fileUrl)، یا ایک JSON ارے (jsonBody) قبول کرتا ہے۔ یہ اینڈ پوائنٹ ایسنکرونس ہے، یہ فوراً ایک processId واپس کرتا ہے اور بیک گراؤنڈ میں امپورٹ مکمل کرتا ہے۔
زیادہ سے زیادہ فائل سائز کیا ہے؟
ان لائن CSV (fileBody) یا JSON (jsonBody) کے لیے 10 MB۔ بڑی فائلوں کے لیے، فائل کو کہیں قابل رسائی جگہ ہوسٹ کریں اور اس کے بجائے fileUrl کے ذریعے اس کا URL پاس کریں۔ اس راستے کی کوئی دستاویز شدہ سائز کی حد نہیں ہے۔
میں .xlsx فائل کیسے امپورٹ کروں؟
Brevo کا امپورٹ API صرف .csv، .txt، یا .json قبول کرتا ہے۔ پہلے .xlsx کو .csv میں تبدیل کریں۔ pandas، openpyxl، یا LibreOffice headless یہ ایک لائن میں کر سکتے ہیں۔ اس گائیڈ میں اسکرپٹ ایک xlsx سے csv کنورژن شامل کرتا ہے۔
کیا یہ موجودہ گاہکوں کو اوور رائٹ کرے گا؟
ڈیفالٹ کے طور پر، ہاں۔ updateExistingContacts ڈیفالٹ true ہے اور ای میل پر میچ کرتا ہے۔ پہلے سے موجود گاہکوں کو چھوڑنے کے لیے اسے false پر سیٹ کریں۔ اگر آپ چاہتے ہیں کہ خالی CSV سیلز موجودہ ویلیوز کو مٹا دیں تو emptyContactsAttributes کو true پر سیٹ کریں (ورنہ خالی سیلز کو نظر انداز کیا جاتا ہے)۔
Brevo کے ساتھ مفت شروع کریں