Brevo Sync da Easy Store: differenze tra le versioni
| (14 versioni intermedie di uno stesso utente non sono mostrate) | |||
| Riga 10: | Riga 10: | ||
Brevo mette a disposizione i '''campi transazionali''' che permettono di associare ad un singolo contatto N transazioni specificando un ID.<br/> | Brevo mette a disposizione i '''campi transazionali''' che permettono di associare ad un singolo contatto N transazioni specificando un ID.<br/> | ||
Utilizzeremo questi campi per compilare i campi riguardanti l'acquisto. | Utilizzeremo questi campi per compilare i campi riguardanti l'acquisto. | ||
Il progetto si trova nella cartella <code>/opt/script-python/EasyBrevoSync/</code> della macchina <code>APACHE</code>. | |||
Parte con un '''cronjob''' configurato tramite | |||
<pre> | |||
sudo crontab -e | |||
</pre> | |||
== Brevo Account == | |||
Qui mettiamo le credenziali dei vari clienti che usufruiranno del programma. | |||
=== MAV Arreda === | |||
Api-key: <code>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</code><br/> | |||
account: <code>store@mavarreda.it</code><br/> | |||
pw: <code>Mavarreda2022</code><br/> | |||
== Complessità tecniche == | == Complessità tecniche == | ||
=== Codice custom a seconda del rivenditore === | === Codice custom a seconda del rivenditore === | ||
Il programma deve gestire la possibilità di eseguire un '''codice custom differente a seconda dell'account''' che viene sincronizzato. | Il programma deve gestire la possibilità di eseguire un '''codice custom differente a seconda dell'account''' che viene sincronizzato. | ||
| Riga 20: | Riga 31: | ||
Ad esempio '''MAV Arreda''' dopo aver sincronizzato i campi statici deve effettuare delle chiamate alle ''EasyAPI'' per recuperare dettagli della vendita e piazzarli in attributi specifici fatti ad hoc. | Ad esempio '''MAV Arreda''' dopo aver sincronizzato i campi statici deve effettuare delle chiamate alle ''EasyAPI'' per recuperare dettagli della vendita e piazzarli in attributi specifici fatti ad hoc. | ||
==== La Teoria ==== | |||
Si pensa di | Si pensa di | ||
* implementare una '''interfaccia''' con un metodo <code>customAction(account, easy, contactData)</code> | * implementare una '''interfaccia''' con un metodo <code>customAction(account, easy, contactData)</code> | ||
* implementare questi comportamenti ognuno in una diversa classe che implementi l'interfaccia precedente | * implementare questi comportamenti ognuno in una diversa classe che implementi l'interfaccia precedente | ||
* stabilire da configurazione un'associazione <code>cliente->classe</code> | * stabilire da configurazione un'associazione <code>cliente->classe.py</code> | ||
* il ciclo principale controlla se nella configurazione c'è specificata una classe e nel caso la istanzia come nell'esempio di sotto e chiama la sua <code>istanza.customAction()</code> | * il ciclo principale controlla se nella configurazione c'è specificata una classe e nel caso la istanzia come nell'esempio di sotto e chiama la sua <code>istanza.customAction()</code> | ||
| Riga 36: | Riga 48: | ||
config[key] = value | config[key] = value | ||
modulo_nome = config.get('modulo_nome') | modulo_nome = config.get('modulo_nome.classe_nome') | ||
classe_nome = config.get('classe_nome') | classe_nome = config.get('classe_nome') | ||
| Riga 48: | Riga 60: | ||
miavariabile = Classe() | miavariabile = Classe() | ||
</syntaxhighlight> | </syntaxhighlight> | ||
==== La Pratica ==== | |||
Abbiamo piazzato all'interno del file <code>appsettings.json</code> un valore <code>CustomActionClass</code> | |||
<syntaxhighlight lang="json"> | |||
"Accounts": [ | |||
{ | |||
"Name": "MAV Arreda", | |||
"CustomActionClass": "Mav", | |||
"EasyConfigs": { | |||
"baseUrl": "https://easyapi5.eswportal.it", | |||
"dbconnection": "39_MAV", | |||
"X-ApiKey": "2iykhirW/U2/VIxqYU6H3kJ4YWJHWlY4N1VTTWYwM2NRZUZOSmc=" | |||
}, | |||
</syntaxhighlight> | |||
Per ogni '''Account''' presente in configurazione, se esiste il valore <code>CustomActionClass</code>, allora viene importata la classe specificata e chiamato il suo metodo <code>execute</code> | |||
<syntaxhighlight lang="python"> | |||
customAction = self.getCustomAction(account) | |||
if customAction: | |||
await customAction.execute(self.easy,self.brevo,contactData,an) | |||
</syntaxhighlight> | |||
Ogni <code>CustomActionClass</code> implementata deve rispettare le seguenti '''convenzioni''' | |||
* Essere definita all'interno della cartella di progetto <code>customclientaction</code> (nome del modulo) | |||
* Essere una classe senza costruttore che espone il metodo <code>async def execute(self,easyreq,brevoreq,contactData,anag)</code> | |||
=== Schedulamento === | |||
Creazione di un file <code>/opt/script-bash/easybrevosync.sh</code> con le istruzioni per runnare il programma. | |||
Viene runnato tramite <code>crontab</code> '''ogni giorno alle ore 00:01'''. | |||
Versione attuale delle 10:38, 5 mag 2025
Cliente richiedente: Mav Arreda
Programma da console in Python schedulato una volta al giorno che si occupa di sincronizzare i dati cliente delle vendite Easy Store con quelli dell'account Brevo.
Nel caso specifico di Mav Arreda, questo ha un sito in Magento nel quale ha installato un plugin che sincronizza i dati delle vendite con Easy Store.
Il programma si pone l'obiettivo di riportare i dati anagrafici di queste vendite anche sull'account Brevo del cliente (nei custom attributes).
In una riunione si è discusso di poter utilizzare attributi custom multiple-choice per poter selezionare più di una singola preferenza marketing per ogni utente (es. interessato a Kartèll e Magìs).
Brevo mette a disposizione i campi transazionali che permettono di associare ad un singolo contatto N transazioni specificando un ID.
Utilizzeremo questi campi per compilare i campi riguardanti l'acquisto.
Il progetto si trova nella cartella /opt/script-python/EasyBrevoSync/ della macchina APACHE.
Parte con un cronjob configurato tramite
sudo crontab -e
Brevo Account
[modifica]Qui mettiamo le credenziali dei vari clienti che usufruiranno del programma.
MAV Arreda
[modifica]Api-key: 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
account: store@mavarreda.it
pw: Mavarreda2022
Complessità tecniche
[modifica]Codice custom a seconda del rivenditore
[modifica]Il programma deve gestire la possibilità di eseguire un codice custom differente a seconda dell'account che viene sincronizzato.
Ad esempio MAV Arreda dopo aver sincronizzato i campi statici deve effettuare delle chiamate alle EasyAPI per recuperare dettagli della vendita e piazzarli in attributi specifici fatti ad hoc.
La Teoria
[modifica]Si pensa di
- implementare una interfaccia con un metodo
customAction(account, easy, contactData) - implementare questi comportamenti ognuno in una diversa classe che implementi l'interfaccia precedente
- stabilire da configurazione un'associazione
cliente->classe.py - il ciclo principale controlla se nella configurazione c'è specificata una classe e nel caso la istanzia come nell'esempio di sotto e chiama la sua
istanza.customAction()
import importlib
# Leggi il nome del modulo e della classe dal file di testo
with open('config.txt', 'r') as file:
config = {}
for line in file:
key, value = line.strip().split('=')
config[key] = value
modulo_nome = config.get('modulo_nome.classe_nome')
classe_nome = config.get('classe_nome')
# Importa dinamicamente il modulo
modulo = importlib.import_module(modulo_nome)
# Ottieni la classe dal modulo
Classe = getattr(modulo, classe_nome)
# Crea una nuova istanza della classe
miavariabile = Classe()
La Pratica
[modifica]Abbiamo piazzato all'interno del file appsettings.json un valore CustomActionClass
"Accounts": [
{
"Name": "MAV Arreda",
"CustomActionClass": "Mav",
"EasyConfigs": {
"baseUrl": "https://easyapi5.eswportal.it",
"dbconnection": "39_MAV",
"X-ApiKey": "2iykhirW/U2/VIxqYU6H3kJ4YWJHWlY4N1VTTWYwM2NRZUZOSmc="
},
Per ogni Account presente in configurazione, se esiste il valore CustomActionClass, allora viene importata la classe specificata e chiamato il suo metodo execute
customAction = self.getCustomAction(account)
if customAction:
await customAction.execute(self.easy,self.brevo,contactData,an)
Ogni CustomActionClass implementata deve rispettare le seguenti convenzioni
- Essere definita all'interno della cartella di progetto
customclientaction(nome del modulo) - Essere una classe senza costruttore che espone il metodo
async def execute(self,easyreq,brevoreq,contactData,anag)
Schedulamento
[modifica]Creazione di un file /opt/script-bash/easybrevosync.sh con le istruzioni per runnare il programma.
Viene runnato tramite crontab ogni giorno alle ore 00:01.