Kasus penggunaan

Sepuluh contoh implementasi Python lengkap, dari ekspor massal dan otomatisasi ulasan hingga laporan analitik, audit profil bisnis, dan publikasi massal.

Tetapkan kunci API Anda sekali sebelum menjalankan contoh apa pun:

bash
export LISTINGSAPI_KEY="your-api-key"

1. Tampilkan daftar lokasi Anda

Hubungkan dan cetak halaman pertama dari daftar lokasi Anda.

01_quickstart.py
import listingsapi client = listingsapi.ListingsAPI() page = client.locations.list(first=5)for loc in page:  print(loc.name, "--", getattr(loc, "city", "N/A"), getattr(loc, "stateIso", "N/A")) print(f"Locations on page: {len(page)}, has_more: {page.has_more}")

2. Ekspor massal ke CSV

Unduh semua lokasi ke CSV menggunakan auto_paging_iter().

02_bulk_export_locations.py
import csvimport listingsapi client = listingsapi.ListingsAPI() locations = list(client.locations.list(first=100).auto_paging_iter())print(f"Fetched {len(locations)} locations") fields = ["id", "name", "storeId", "street", "city", "stateIso", "postalCode", "countryIso", "phone"] with open("locations_export.csv", "w", newline="") as f:  writer = csv.DictWriter(f, fieldnames=fields, extrasaction="ignore")  writer.writeheader()  for loc in locations:      writer.writerow(loc.to_dict()) print("Exported to locations_export.csv")

auto_paging_iter() menangani semua halaman berbasis kursor secara otomatis. Lihat Lokasi untuk referensi metode lengkap.


3. Buat lokasi

locations.add() menerima setiap field wajib sebagai argumen kata kunci dan memvalidasi payload di sisi klien, sehingga permintaan yang tidak valid segera gagal dengan pesan yang jelas sebelum panggilan jaringan apa pun dilakukan. Cari sub_category_id yang valid dengan client.subcategories() (gunakan databaseId).

03_create_location.py
import listingsapifrom listingsapi import ValidationError client = listingsapi.ListingsAPI() subcategories = client.subcategories()dental = [s for s in subcategories if "dentist" in (s.get("name") or "").lower()]sub_category_id = dental[0].databaseId if dental else 1432 try:  result = client.locations.add(      name="Acme Dental",      description=(          "Acme Dental is a family-owned dental practice serving downtown "          "New York for over fifteen years. Our team offers preventive care, "          "cosmetic dentistry, orthodontics, and emergency appointments, with "          "weekend hours and a patient-first approach that keeps every visit "          "comfortable and affordable for the whole family."      ),      sub_category_id=sub_category_id,      country_iso="US",      city="New York",      street="123 Jump Street",      state_iso="NY",      postal_code="10013",      phone="6443859313",      store_id="NYC-001",  )except ValidationError as e:  print(f"Fix the payload: {e}")else:  print(f"Created location: {result.location.id}")

Deskripsi harus berisi setidaknya 200 karakter; platform publikasi menggunakannya sebagai teks utama profil bisnis. client.countries() mencantumkan kode ISO negara dan negara bagian yang didukung, dan client.plan_sites() menunjukkan direktori tujuan publikasi yang tercakup dalam paket Anda.


4. Pemantauan ulasan

Pindai ulasan terbaru dan tandai ulasan negatif yang memerlukan balasan.

04_review_monitoring.py
import listingsapi client = listingsapi.ListingsAPI() page = client.locations.list(first=5) for loc in page:  print(f"\n--- {loc.name} ---")  reviews = client.reviews.list(loc.id, first=10)  if not reviews:      print("  No recent reviews")      continue   for review in reviews:      rating = getattr(review, "rating", "N/A")      author = getattr(review, "authorName", "Anonymous")      site = getattr(review, "siteName", "Unknown")      responded = bool(getattr(review, "responses", None))      flag = " ** NEEDS ATTENTION **" if isinstance(rating, (int, float)) and rating <= 2 else ""      status = "Responded" if responded else "No reply"      print(f"  [{rating}] {author} on {site} ({status}){flag}")

Lihat Ulasan untuk opsi filter, termasuk rating_filters, site_urls, dan rentang tanggal.


5. Balas ulasan secara otomatis

workflows.auto_reply_to_reviews() mengambil ulasan terbaru, memfilternya berdasarkan rating dan status balasan, lalu memublikasikan balasan dari templat Anda dalam satu panggilan. Lihat pratinjau dengan dry_run=True terlebih dahulu. Placeholder {rating} diganti dengan rating bintang setiap ulasan.

05_auto_reply_reviews.py
import listingsapi client = listingsapi.ListingsAPI() LOCATION_ID = 16808  # Replace with your location IDTEMPLATE = "Thanks for the {rating}-star review! We appreciate you taking the time." # Preview what would be sentpreview = client.workflows.auto_reply_to_reviews(  LOCATION_ID,  template=TEMPLATE,  min_rating=4,  dry_run=True,)for entry in preview:  print(f"  Would reply to {entry['id']} ({entry['rating']} stars)") # Post the replies for realresults = client.workflows.auto_reply_to_reviews(  LOCATION_ID,  template=TEMPLATE,  min_rating=4,)sent = [r for r in results if r["status"] == "sent"]print(f"Replied to {len(sent)} of {len(results)} matching reviews")

min_rating=4 bawaan sengaja melewati ulasan negatif: ulasan tersebut perlu dibalas secara personal. Tangani satu per satu dengan reviews.respond():

05b_respond_to_negative.py
import listingsapifrom listingsapi import APIError client = listingsapi.ListingsAPI() negative = client.reviews.list(16808, rating_filters=[1, 2], first=20)for review in negative:  if getattr(review, "responses", None):      continue  try:      client.reviews.respond(          review.interactionId,          "We are sorry to hear about your experience. Please reach out "          "directly so we can make it right.",      )      print(f"Replied to {getattr(review, 'authorName', 'Anonymous')}")  except APIError as e:      print(f"Failed: {e}")

6. Laporan analitik

Ambil analitik profil Google dan statistik ulasan untuk setiap lokasi.

06_analytics_report.py
import listingsapi client = listingsapi.ListingsAPI() FROM_DATE = "2026-01-01"TO_DATE = "2026-06-30" all_locations = list(client.locations.list(first=100).auto_paging_iter())print(f"Generating report for {len(all_locations)} locations ({FROM_DATE} to {TO_DATE})\n") for loc in all_locations[:10]:  print(f"--- {loc.name} ---")   google = client.analytics.google(loc.id, from_date=FROM_DATE, to_date=TO_DATE)  if google:      print(f"  Google: {google.to_dict()}")   review_stats = client.reviews.analytics.overview(loc.id, start_date=FROM_DATE, end_date=TO_DATE)  if review_stats:      print(f"  Reviews: {review_stats.to_dict()}")   sites = client.reviews.analytics.sites_stats(loc.id, start_date=FROM_DATE, end_date=TO_DATE)  if sites:      print(f"  Sites: {sites.to_dict()}")   print()

Lihat Analitik untuk metrik profil bing() dan facebook().


7. Laporan reputasi mingguan

workflows.weekly_reputation_report() menggabungkan ulasan, analitik ulasan, analitik profil Google dan Bing, serta status sinkronisasi profil bisnis ke dalam satu objek laporan.

07_reputation_report.py
import listingsapi client = listingsapi.ListingsAPI() report = client.workflows.weekly_reputation_report(  16808,  start_date="2026-06-29",  end_date="2026-07-05",) summary = report.review_summaryprint(f"Average rating: {summary.get('averageRating')}")print(f"Recent reviews: {len(report.recent_reviews)}") analytics = report.analyticsprint(f"Google: {analytics.get('google')}")print(f"Bing: {analytics.get('bing')}") health = report.listings_healthprint(f"Listings synced: {health.get('synced')}/{health.get('total')} ({health.get('sync_rate')})")

8. Audit kondisi profil bisnis

workflows.listings_health_audit() memeriksa profil bisnis premium, profil bisnis untuk pencarian suara, dan duplikat untuk suatu lokasi, lalu menghitung skor kondisi pada skala 0-100.

08_listings_audit.py
import listingsapi client = listingsapi.ListingsAPI() page = client.locations.list(first=10)print(f"Auditing listings for {len(page)} locations\n") for loc in page:  audit = client.workflows.listings_health_audit(loc.id)  print(f"--- {loc.name} ---")  print(f"  Health score: {audit.health_score}%")  print(f"  Synced: {audit.synced_count}, issues: {audit.issue_count}")  print(f"  Voice listings: {len(audit.voice)}, duplicates: {len(audit.duplicates)}")  for issue in audit.issues:      print(f"    [{issue.get('syncStatus')}] {issue.get('site')}")  print()

Lihat Profil bisnis untuk metode dasar premium, voice, duplicates, dan metode untuk menandai sebagai duplikat.


9. Publikasikan postingan secara massal

posts.bulk_publish() memublikasikan satu postingan di banyak lokasi, dengan Google dan Facebook sebagai tujuan bawaan. ID lokasi dikodekan secara otomatis dan payload divalidasi di sisi klien sebelum panggilan jaringan apa pun dilakukan.

09_bulk_publish_post.py
import listingsapi client = listingsapi.ListingsAPI() result = client.posts.bulk_publish(  name="Summer hours 2026",  location_ids=[16808, 16809, 16810],  message="We are open late all summer! Come see us until 9pm, Monday through Saturday.",  media_url="https://cdn.example.com/summer-hours.jpg",  cta_type="LEARN_MORE",  cta_url="https://www.acmedental.com/hours",) post = result.get("socialPost") or {}print(f"Created bulk post: {post.get('id')}")

Berikan dict sebagai message untuk menyesuaikan teks per situs:

09b_per_site_message.py
result = client.posts.bulk_publish(  name="July whitening offer",  location_ids=[16808],  message={      "GOOGLE": "20% off teeth whitening this July. Book online today!",      "FACEBOOK": "July special: 20% off teeth whitening. Tap to book your visit!",  },  sites=["GOOGLE", "FACEBOOK"],)

Untuk postingan bertipe khusus bagi satu situs, gunakan posts.create_announcement(), posts.create_event(), atau posts.create_offer().


10. Alur koneksi Google

Buat URL OAuth, tampilkan daftar akun yang terhubung, dan tinjau saran kecocokan.

10_google_connect_flow.py
import time import listingsapi client = listingsapi.ListingsAPI() # Step 1: Generate an OAuth URL (valid 24 hours)result = client.connected_accounts.connect_google(  success_url="https://yourapp.com/connect/success",  error_url="https://yourapp.com/connect/error",)print(f"Redirect user to: {result.get('url', 'N/A')}") # Step 2: List connected Google accounts. The payload is an offset page:# records[] plus pageInfo, not a bare list.accounts = client.connected_accounts.list(publisher="GoogleAccount", page=1, per_page=20)for acc in accounts.get("records") or []:  account_id = acc["connectedAccountId"]  print(f"{acc['email']} -- status: {acc['status']}")   # Step 3: Kick off the fetch-and-match job for this account.  client.connected_accounts.trigger_matches([account_id])   # Step 4: Matching is asynchronous. Poll the account's details until it  # reports MATCH_COMPLETED, with a bounded number of attempts so a stuck  # job cannot hang the script.  status = None  for _ in range(20):      details = client.connected_accounts.details(account_id)      status = (details.get("details") or {}).get("requestMatchesStatus")      if status == "MATCH_COMPLETED":          break      time.sleep(15)   if status != "MATCH_COMPLETED":      print(f"  matching still {status!r}, skipping for now")      continue   # Step 5: Only now are suggestions populated. Same offset-page shape.  suggestions = client.connected_accounts.suggestions(account_id, page=1, per_page=10)  records = suggestions.get("records") or []  print(f"  Suggestions: {len(records)} matches found")

Membaca saran sebelum requestMatchesStatus mencapai MATCH_COMPLETED akan mengembalikan array records kosong, yang tidak dapat dibedakan dari kondisi "tidak ada kecocokan", sehingga polling memastikan contoh ini berjalan dengan benar dan bukan sekadar kebetulan berhasil. Lihat Picu pencocokan lokasi untuk nilai status.

Konfirmasikan kecocokan dengan connected_accounts.confirm_matches() dengan memberikan ID record kecocokan yang dibentuk dari matchedDataDatabaseId dan accountType setiap record (lihat Konfirmasikan kecocokan koneksi), lalu tautkan profil bisnis tertentu ke lokasi dengan listings.connect().


Langkah berikutnya