Post
Pubblica annunci, eventi e offerte su Google e Facebook tramite client.posts.
Tutti i metodi per i post si trovano in client.posts. I metodi che ricevono un location_id accettano ID numerici o codificati in base64; vedi ID delle sedi.
I post vengono pubblicati su due siti: GOOGLE e FACEBOOK. I tipi di post sono ANNOUNCEMENT, EVENT, OFFER, COVID19 e PRODUCT. I tipi di invito all'azione sono BOOK, ORDER, SHOP, LEARN_MORE, SIGN_UP e GET_OFFER; cta_type e cta_url devono sempre essere forniti insieme.
Pubblicazione asincrona
La pubblicazione è asincrona. Le chiamate di creazione restituiscono status: INPROGRESS; interroga periodicamente posts.retrieve() (o posts.bulk_retrieve() per le campagne collettive) finché lo stato non è SUCCESS e controlla publishDetails[].submissionError per individuare eventuali errori sui singoli siti.
Messaggi per sito
Ogni metodo di creazione accetta message come stringa semplice, che pubblica lo stesso testo su tutti i siti, oppure come dict che associa ciascun sito al relativo testo:
message = { "GOOGLE": "Book your summer checkup today!", "FACEBOOK": "Summer checkups are here. Tag a friend who needs one!",}Quando message è un dict, deve contenere una voce per ogni sito in sites; se ne manca una, l'SDK solleva ValidationError prima di qualsiasi chiamata di rete.
posts.bulk_publish
Pubblica un unico post per più sedi su Google e Facebook con una sola chiamata. Questo è il modo consigliato per pubblicare post: sites include entrambi per impostazione predefinita, il singolo messaggio (o il dict con il testo per ciascun sito) viene espanso in una voce per sito, gli ID delle sedi vengono codificati automaticamente e il payload viene convalidato lato client prima di qualsiasi chiamata di rete.
client.posts.bulk_publish( *, name: str, location_ids: list[str | int], message: str | dict[str, str], sites: list[str] | None = None, post_type: str = "ANNOUNCEMENT", cta_type: str | None = None, cta_url: str | None = None, media_url: str | None = None, scheduled_dates: dict | None = None, context_info: dict | None = None, additional_fields: dict | None = None,) -> APIObjectresult = client.posts.bulk_publish( name="Holiday hours", location_ids=[16808, 16809, 16810], message="Open until 10pm through the holidays!", media_url="https://cdn.example.com/holiday.jpg", cta_type="LEARN_MORE", cta_url="https://example.com/holiday-hours",)print(result.socialPost.id, result.socialPost.status) # INPROGRESS, publishes asyncposts.create_announcement
Crea un post ANNOUNCEMENT: un messaggio semplice con CTA e contenuti multimediali facoltativi. Il valore predefinito di sites è ["GOOGLE"].
client.posts.create_announcement( *, name: str, location_ids: list[str | int], message: str | dict[str, str], sites: list[str] | None = None, cta_type: str | None = None, cta_url: str | None = None, media_url: str | None = None, scheduled_dates: dict | None = None, additional_fields: dict | None = None,) -> APIObjectresult = client.posts.create_announcement( name="Grand Opening", location_ids=[16808], message="Acme Dental is now open!", sites=["GOOGLE"], cta_type="LEARN_MORE", cta_url="https://acmedental.example.com/opening",)print(result.socialPost.id)posts.create_event
Crea un post EVENT con un titolo e un intervallo temporale con inizio e fine. Google richiede il titolo dell'evento; l'SDK solleva ValidationError se manca. start_day e end_day sono date (YYYY-MM-DD); start_time e end_time sono stringhe da visualizzare, come "10:00am".
client.posts.create_event( *, name: str, location_ids: list[str | int], message: str | dict[str, str], title: str, start_day: str, end_day: str, start_time: str | None = None, end_time: str | None = None, sites: list[str] | None = None, cta_type: str | None = None, cta_url: str | None = None, media_url: str | None = None, scheduled_dates: dict | None = None, additional_fields: dict | None = None,) -> APIObjectresult = client.posts.create_event( name="Free checkup day", location_ids=[16808], message="Join us for free dental checkups!", title="Free Checkup Day", start_day="2026-08-01", end_day="2026-08-01", start_time="10:00am", end_time="4:00pm", cta_type="BOOK", cta_url="https://acmedental.example.com/book",)print(result.socialPost.id)posts.create_offer
Crea un post OFFER con un coupon, uno sconto e le condizioni. title assegna un nome all'offerta ed è obbligatorio; start_day e end_day (YYYY-MM-DD) ne delimitano il periodo di validità.
client.posts.create_offer( *, name: str, location_ids: list[str | int], message: str | dict[str, str], title: str, coupon_code: str | None = None, discount: str | None = None, redeem_url: str | None = None, terms_conditions: str | None = None, start_day: str | None = None, end_day: str | None = None, sites: list[str] | None = None, cta_type: str | None = None, cta_url: str | None = None, media_url: str | None = None, scheduled_dates: dict | None = None, additional_fields: dict | None = None,) -> APIObjectresult = client.posts.create_offer( name="Summer whitening sale", location_ids=[16808], message="20% off teeth whitening all week!", title="Summer Whitening Sale", coupon_code="SUMMER20", discount="20%", redeem_url="https://acmedental.example.com/sale", terms_conditions="One per patient. Not valid with other offers.", start_day="2026-08-01", end_day="2026-08-07",)print(result.socialPost.id)posts.create
Crea un post a partire da un dict contenente il corpo grezzo della richiesta. Passa i campi senza annidarli in camelCase e la funzione ausiliaria li racchiude nell'oggetto input richiesto dall'API prima dell'invio: il corpo trasmesso è {"input": {...}}, mai un corpo con campi non annidati. locationIds deve essere già codificato in base64. Preferisci i metodi di creazione tipizzati riportati sopra per usare argomenti con nome, codifica automatica degli ID e convalida lato client.
client.posts.create(body: dict) -> APIObjectObbligatori: postName, locationIds (base64), postType, postSites.
result = client.posts.create({ "postName": "Grand Opening", "locationIds": ["TG9jYXRpb246MTY4MDg="], "postType": "ANNOUNCEMENT", "postSites": ["GOOGLE"], "postMessage": [{"site": "GOOGLE", "message": "We are now open!"}],})print(result.socialPost.id)posts.retrieve
Recupera un post con il suo contenuto, lo stato di pubblicazione per ciascun sito e i dati analitici. Interroga periodicamente questo metodo dopo una creazione finché status non è SUCCESS.
client.posts.retrieve(post_id: str) -> APIObjectpost = client.posts.retrieve("U29jaWFsUG9zdDo0NDEyMg==")print(post.status)for detail in post.publishDetails: print(detail.site, detail.submissionError)posts.delete
Elimina un post e rimuovilo da tutti i siti su cui è stato pubblicato.
client.posts.delete(post_id: str) -> APIObjectclient.posts.delete("U29jaWFsUG9zdDo0NDEyMg==")posts.list_for_location
Elenca le campagne di post destinate a una sede. La paginazione usa un offset: il risultato contiene .records e .pageInfo con totalPages, totalRecords e hasNextPage. La risposta si trova in postsByLocation.
Questo endpoint rifiuta un tag, quindi dalla versione 0.5.3 l'SDK accetta l'argomento per compatibilità con le versioni precedenti e non lo trasmette mai. Usa posts.bulk_list_for_location quando devi filtrare per tag.
client.posts.list_for_location( location_id: str | int, *, tag: str = "all", page: int | None = None, per_page: int | None = None, filters: dict | None = None, sort_fields: dict | None = None,) -> APIObjectresult = client.posts.list_for_location(16808, page=1, per_page=10)for post in result.records: print(post.id, post.name)print(result.pageInfo.totalRecords)posts.bulk_retrieve
Recupera una campagna collettiva (per più sedi) con lo stato di pubblicazione e i dati analitici per ciascuna sede.
client.posts.bulk_retrieve(bulk_post_id: str) -> APIObjectbulk = client.posts.bulk_retrieve("QnVsa1Bvc3Q6OTk=")print(bulk.status)posts.bulk_list_for_location
Elenca le campagne collettive (per più sedi) che includono una sede. I parametri e la struttura del risultato sono gli stessi di posts.list_for_location.
client.posts.bulk_list_for_location( location_id: str | int, *, tag: str = "all", page: int | None = None, per_page: int | None = None, filters: dict | None = None, sort_fields: dict | None = None,) -> APIObjectresult = client.posts.bulk_list_for_location(16808, page=1, per_page=10)for campaign in result.records: print(campaign.id, campaign.name)