v7
Applicabile solo a Campaign Classic v7

API orientate ai dati data-oriented-apis

Le API orientate ai dati consentono di indirizzare l’intero modello dati.

Panoramica del modello dati overview-of-the-datamodel

Adobe Campaign non offre un’API di lettura dedicata per entità (nessuna funzione getRecipient o getDelivery, ecc.). Utilizzare i metodi di lettura e modifica dei dati QUERY & WRITER per accedere ai dati del modello.

Adobe Campaign consente di gestire le raccolte: le query consentono di recuperare un set di informazioni raccolte in tutta la base. A differenza dell’accesso in modalità SQL, le API di Adobe Campaign restituiscono una struttura XML anziché colonne di dati. Adobe Campaign crea quindi documenti compositi con tutti i dati raccolti.

Questa modalità operativa non offre il mapping uno-a-uno tra gli attributi e gli elementi dei documenti XML e le colonne delle tabelle nel database.

I documenti XML vengono memorizzati nei campi di tipo MEMO del database.

Descrizione del modello description-of-the-model

Per poter gestire i campi del database negli script, è necessario avere familiarità con il modello dati di Adobe Campaign.

Per una presentazione del modello dati, consulta Descrizione del modello dati di Adobe Campaign.

Query e writer query-and-writer

Il seguente schema introduttivo descrive gli scambi di basso livello per la lettura (ExecuteQuery) e la scrittura (Writer) tra database e cliente (pagine web o console client di Adobe Campaign).

ExecuteQuery executequery

Per le colonne e le condizioni, è possibile utilizzare le query.

In questo modo è possibile isolare l'istruzione SQL sottostante. Il linguaggio di query non dipende dal motore sottostante: alcune funzioni verranno nuovamente mappate, il che potrebbe generare diversi ordini SELECT SQL.

Per ulteriori informazioni, consulta Esempio sul metodo 'ExecuteQuery' dello schema 'xtk:queryDef'.

Il ExecuteQuery il metodo è presentato in ExecuteQuery (xtk:queryDef).

Scrittura write

I comandi di scrittura consentono di scrivere documenti semplici o complessi, con voci in una o più tabelle della base.

Le API transazionali consentono di gestire le riconciliazioni tramite updateOrInsert comando: un comando consente di creare o aggiornare dati. Puoi anche configurare l’unione di modifiche (unione): con questa modalità operativa puoi autorizzare aggiornamenti parziali.

La struttura XML offre una vista logica dei dati e consente di ignorare la struttura fisica della tabella SQL.

Il metodo Write è presentato in Write/WriteCollection (xtk:session).

ExecuteQuery (xtk:queryDef) executequery--xtk-querydef-

Questo metodo consente di eseguire query dai dati associati a uno schema. Richiede una stringa di autenticazione (deve aver effettuato l’accesso) e un documento XML che descriva la query da inviare come parametri. Il parametro restituito è un documento XML contenente il risultato della query nel formato dello schema a cui la query fa riferimento.

Definizione del metodo "ExecuteQuery" nello schema "xtk:queryDef":

<method name="ExecuteQuery" const="true">
  <parameters>
    <param desc="Output XML document" name="output" type="DOMDocument" inout="out"/>
  </parameters>
</method>
NOTE
Si tratta di un metodo "const". I parametri di input vengono inclusi in un documento XML nel formato dello schema "xtk:queryDef".

Formato del documento XML della query di input format-of-the-xml-document-of-the-input-query

La struttura del documento XML della query è descritta nello schema "xtk:queryDef". Questo documento descrive le clausole di una query SQL: "select", "where", "order by", "group by", "HAVING".

<queryDef schema="schema_key" operation="operation_type">
  <select>
    <node expr="expression1">
    <node expr="expression2">
    ...
  </select>
  <where>
    <condition expr="expression1"/>
    <condition expr="expression2"/>
    ...
  </where>
  <orderBy>
    <node expr="expression1">
    <node expr="expression2">
    ...
  </orderBy>
  <groupBy>
    <node expr="expression1">
    <node expr="expression2">
    ...
  </groupBy>
  <having>
    <condition expr="expression1"/>
    <condition expr="expression2"/>
    ...
  </having>
</queryDef>

Una sottoquery ( <subquery> ) può essere definito in una <condition> elemento. La sintassi per un <subquery> è basato sulla sintassi di un elemento <querydef>.

Esempio di <subquery> : </subquery>

<condition setOperator="NOT IN" expr="@id" enabledIf="$(/ignored/@ownerType)=1">
  <subQuery schema="xtk:operatorGroup">
     <select>
       <node expr="[@operator-id]" />
     </select>
     <where>
       <condition expr="[@group-id]=$long(../@owner-id)"/>
     </where>
   </subQuery>
</condition>

Una query deve fare riferimento a uno schema iniziale da schema attributo.

Il tipo di operazione desiderata viene immesso nel operazione e contiene uno dei seguenti valori:

  • ottenere: recupera un record dalla tabella e restituisce un errore se i dati non esistono,
  • getIfExists: recupera un record dalla tabella e restituisce un documento vuoto se i dati non esistono,
  • seleziona: crea un cursore per restituire diversi record e restituisce un documento vuoto se non sono presenti dati,
  • count: restituisce un conteggio di dati.

Il XPath La sintassi viene utilizzata per individuare i dati in base allo schema di input. Per ulteriori informazioni su XPaths, fare riferimento a Schemi di dati.

Esempio con l’operazione "get" example-with-the--get--operation

Recupera il cognome e il nome di un destinatario (schema "nms:recipient") con un filtro nell’e-mail.

<queryDef schema="nms:recipient" operation="get">
  <!-- fields to retrieve -->
  <select>
    <node expr="@firstName"/>
    <node expr="@lastName"/>
  </select>

  <!-- condition on email -->
  <where>
    <condition expr="@email= 'john.doe@aol.com'"/>
  </where>
</queryDef>

Esempio con l’operazione "select" example-with-the--select--operation

Restituisce l’elenco dei destinatari filtrati su una cartella e il dominio e-mail con un ordinamento decrescente alla data di nascita.

<queryDef schema="nms:recipient" operation="select">
  <select>
    <node expr="@email"/>
    <!-- builds a string with the concatenation of the last name and first name separated by a dash -->
    <node expr="@lastName+'-'+@firstName"/>
    <!-- get year of birth date -->
    <node expr="Year(@birthDate)"/>
  </select>

  <where>
     <condition expr="[@folder-id] = 1234 and @domain like 'Adobe%'"/>
  </where>

  <!-- order by birth date -->
  <orderBy>
    <node expr="@birthDate" sortDesc="true"/> <!-- by default sortDesc="false" -->
  </orderBy>
</queryDef>

Le espressioni possono essere campi semplici o espressioni complesse, ad esempio operazioni aritmetiche o concatenazione di stringhe.

Per limitare il numero di record da restituire, aggiungere lineCount attribuire a <querydef> elemento.

Per limitare a 100 il numero di record restituiti dalla query:

<queryDef schema="nms:recipient" operation="select" lineCount="100">
...

Per recuperare i 100 record successivi, eseguire nuovamente la stessa query, aggiungendo startLine attributo.

<queryDef schema="nms:recipient" operation="select" lineCount="100" startLine="100">
...

Esempio con l’operazione "count" example-with-the--count--operation

Per contare il numero di record in una query:

<queryDef schema="nms:recipient" operation="count"">
  <!-- condition on the folder and domain of the email -->
  <where>
    <condition expr="[@folder-id] = 1234" and @domain like 'Adobe%'"/>
  </where>
</queryDef>
NOTE
Anche in questo caso, utilizziamo la condizione dell’esempio precedente. Il <select> Le clausole e non vengono utilizzate. </select>

Raggruppamento di dati data-grouping

Per recuperare gli indirizzi e-mail a cui si fa riferimento più di una volta:

<queryDef schema="nms:recipient" operation="select">
  <select>
    <node expr="@email"/>
    <node expr="count(@email)"/>
  </select>

  <!-- email grouping clause -->
  <groupby>
    <node expr="@email"/>
  </groupby>

  <!-- grouping condition -->
  <having>
    <condition expr="count(@email) > 1"/>
  </having>

</queryDef>

La query può essere semplificata aggiungendo groupBy attribuire direttamente al campo da raggruppare:

<select>
  <node expr="@email" groupBy="true"/>
</select>
NOTE
Non è più necessario compilare il <groupby> elemento.

Parentesi quadra in condizioni bracketing-in-conditions

Di seguito sono riportati due esempi di parentesi quadre nella stessa condizione.

  • La versione semplice in una singola espressione:

    code language-none
    <where>
      <condition expr="(@age > 15 or @age <= 45) and  (@city = 'Newton' or @city = 'Culver City') "/>
    </where>
    
  • La versione strutturata con <condition> elementi:

    code language-none
    <where>
      <condition bool-operator="AND">
        <condition expr="@age > 15" bool-operator="OR"/>
        <condition expr="@age <= 45"/>
      </condition>
      <condition>
        <condition expr="@city = 'Newton'" bool-operator="OR"/>
        <condition expr="@city = 'Culver City'"/>
      </condition>
    </where>
    

È possibile sostituire l’operatore "OR" con l’operazione "IN" quando più condizioni si applicano allo stesso campo:

<where>
  <condition>
    <condition expr="@age IN (15, 45)"/>
    <condition expr="@city IN ('Newton', 'Culver City')"/>
  </condition>
</where>

Questa sintassi semplifica la query quando nella condizione vengono utilizzati più di due dati.

  • Collegamenti 1-1 o N1: quando la tabella ha la chiave esterna (il collegamento inizia dalla tabella), i campi della tabella collegata possono essere filtrati o recuperati direttamente.

    Esempio di filtro sull’etichetta della cartella:

    code language-none
    <where>
      <condition expr="[folder/@label] like 'Segment%'"/>
    </where>
    

    Per recuperare i campi della cartella dallo schema "nms:recipient":

    code language-none
    <select>
      <!-- label of recipient folder -->
      <node expr="[folder/@label]"/>
      <!-- displays the string count of the folder -->
      <node expr="partition"/>
    </select>
    
  • Collegamenti alle raccolte (1N): il filtro sui campi di una tabella di raccolta deve essere eseguito tramite ESISTE o NON ESISTE operatore.

    Per filtrare i destinatari abbonati al servizio di informazioni "Newsletter":

    code language-none
    <where>
      <condition expr="subscription" setOperator="EXISTS">
        <condition expr="@name = 'Newsletter'"/>
      </condition>
    </where>
    

    Recupero diretto dei campi di un collegamento di raccolta dal <select> non è consigliata perché la query restituisce un prodotto cardinale. Viene utilizzato solo quando la tabella collegata contiene un solo record (ad esempio <node expr="">).

    Esempio sul collegamento di raccolta "subscription":

    code language-none
    <select>
      <node expr="subscription/@label"/>
    </select>
    

    È possibile recuperare un sottoelenco contenente gli elementi di un collegamento di raccolta nel <select> clausola. Gli XPaths dei campi a cui si fa riferimento sono contestuali rispetto all'elemento di raccolta.

    Il filtro ( <orderby> ) e restrizione ( <where> ) possono essere aggiunti all'elemento raccolta.

    In questo esempio, per ogni destinatario la query restituisce l’e-mail e l’elenco dei servizi di informazione a cui il destinatario si abbona:

    code language-none
    <queryDef schema="nms:recipient" operation="select">
      <select>
        <node expr="@email"/>
    
        <!-- collection table (unbound type) -->
        <node expr="subscription">
          <node expr="[service/@label]"/>
          <!-- sub-condition on the collection table -->
          <where>
            <condition expr="@expirationDate >= GetDate()"/>
          </where>
          <orderBy>
            <node expr="@expirationDate"/>
          </orderBy>
        </node>
      </select>
    </queryDef>
    

Associazione dei parametri delle clausole 'where' e 'select' binding-the-parameters-of-the--where--and--select--clause

L’associazione dei parametri consente al motore di impostare i valori dei parametri utilizzati nella query. Questo è molto utile, poiché il motore è responsabile dell’escape dei valori e c’è il vantaggio aggiuntivo di una cache per i parametri da recuperare.

Quando viene creata una query, i valori "associati" vengono sostituiti da un carattere (? in ODBC, #[index]# in postgres… nel corpo della query SQL.

<select>
  <!--the value will be bound by the engine -->
  <node expr="@startDate = #2002/02/01#"/>
  <!-- the value will not be bound by the engine but visible directly in the query -->
  <node expr="@startDate = #2002/02/01#" noSqlBind="true"/>
</select>

Per evitare di associare un parametro, l'attributo "noSqlBind" deve essere compilato con il valore "true".

IMPORTANT
Se la query include istruzioni "ordina per" o "raggruppa per", i motori di database non saranno in grado di "associare" i valori. È necessario inserire l'attributo @noSqlBind="true" nelle istruzioni "select" e/o "where" della query.

Suggerimento per creazione query: query-building-tip-

Per semplificare la sintassi di una query, puoi scriverla utilizzando l’editor di query generico nella console client di Adobe Campaign ( Tools/ Generic query editor… menu). Per eseguire questa operazione:

  1. Seleziona i dati da recuperare:

  2. Definisci la condizione del filtro:

  3. Eseguire la query e premere CTRL+F4 per visualizzare il codice sorgente della query.

Formato documento di output output-document-format

Il parametro restituito è un documento XML nel formato dello schema associato alla query.

Esempio di ritorno dallo schema "nms:recipient" su un’operazione "get":

<recipient email="john.doe@adobe.com" lastName"Doe" firstName="John"/>

In un’operazione di "selezione", il documento restituito è un’enumerazione di elementi:

<!-- the name of the first element does not matter -->
<recipient-collection>
  <recipient email="john.doe@adobe.com" lastName"Doe" firstName="John"/>
  <recipient email="peter.martinez@adobe.com" lastName"Martinez" firstName="Peter"/>
  <recipient...
</recipient-collection>

Esempio di documento restituito per l'operazione di tipo "conteggio":

<recipient count="3"/>

Alias alias

Un alias consente di modificare la posizione dei dati nel documento di output. Il alias L'attributo deve specificare un XPath nel campo corrispondente.

<queryDef schema="nms:recipient" operation="get">
  <select>
    <node expr="@firstName" alias="@firstName"/>
    <node expr="@lastName"/>
    <node expr="[folder/@label]" alias="@My_folder"/>
  </select>
</queryDef>

Restituisce:

<recipient My_folder="Recipients" First name ="John" lastName="Doe"/>

Invece di:

<recipient firstName="John" lastName="Doe">
  <folder label="Recipients"/>
</recipient>

Esempio di messaggi SOAP example-of-soap-messages

  • Query:

    code language-none
    <?xml version='1.0' encoding='ISO-8859-1'?>
    <SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='http://xml.apache.org/xml-soap' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
      <SOAP-ENV:Body>
        <ExecuteQuery xmlns='urn:xtk:queryDef' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
          <__sessiontoken xsi:type='xsd:string'/>
          <entity xsi:type='ns:Element' SOAP-ENV:encodingStyle='http://xml.apache.org/xml-soap/literalxml'>
            <queryDef operation="get" schema="nms:recipient" xtkschema="xtk:queryDef">
              <select>
                <node expr="@email"/>
                <node expr="@lastName"/>
                <node expr="@firstName"/>
              </select>
              <where>
                <condition expr="@id = 3599"/>
              </where>
            </queryDef>
          </entity>
        </ExecuteQuery>
      </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>
    
  • Risposta:

    code language-none
    <?xml version='1.0' encoding='ISO-8859-1'?>
    <SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='http://xml.apache.org/xml-soap' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
      <SOAP-ENV:Body>
        <ExecuteQueryResponse xmlns='urn:xtk:queryDef' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
          <pdomOutput xsi:type='ns:Element' SOAP-ENV:encodingStyle='http://xml.apache.org/xml-soap/literalxml'>
            <recipient email="john.doe@adobe.com" lastName"Doe" firstName="John"/>
          </pdomOutput>
        </ExecuteQueryResponse>
      </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>
    

Write/WriteCollection (xtk:session) write---writecollection--xtk-session-

Questi servizi vengono utilizzati per inserire, aggiornare o eliminare un'entità (metodo "Write") o un insieme di entità (metodo "WriteCollection").

Le entità da aggiornare sono associate a uno schema di dati. I parametri di input sono una stringa di autenticazione (deve essere effettuato l'accesso) e un documento XML contenente i dati da aggiornare.

Questo documento è completato da istruzioni per la configurazione delle procedure di scrittura.

La chiamata non restituisce alcun dato, ad eccezione degli errori.

Definizione dei metodi "Write" e "WriteCollection" nello schema "xtk:session":

<method name="Write" static="true">
  <parameters>
    <param name="doc" type="DOMDocument" desc="Difference document"/>
  </parameters>
</method>
<method name="WriteCollection" static="true">
  <parameters>
    <param name="doc" type="DOMDocument" desc="Difference collection document"/>
  </parameters>
</method>
NOTE
Si tratta di un metodo "statico". I parametri di input vengono inclusi in un documento XML nel formato dello schema da aggiornare.

Panoramica overview

La riconciliazione dei dati funziona in base alla definizione delle chiavi immesse nello schema associato. La procedura di scrittura cerca la prima chiave idonea in base ai dati immessi nel documento di input. L’entità viene inserita o aggiornata in base alla sua esistenza nel database.

La chiave dello schema dell’entità da aggiornare viene completata in base alla xtkschema attributo.

La chiave di riconciliazione può quindi essere forzata con _chiave attributo contenente l'elenco di XPaths che compongono la chiave (separati da virgole).

È possibile forzare il tipo di operazione compilando il _operation con i seguenti valori:

  • inserire: forza l’inserimento del record (la chiave di riconciliazione non viene utilizzata),
  • insertOrUpdate: aggiorna o inserisce il record a seconda della chiave di riconciliazione (modalità predefinita),
  • aggiorna: aggiorna il record; non esegue alcuna operazione se i dati non esistono,
  • eliminare: elimina i record,
  • nessuno: utilizzato solo per la riconciliazione dei collegamenti, senza aggiornamento o inserimento.

Esempio con il metodo 'Write' example-with-the--write--method

Aggiornamento o inserimento di un destinatario (operazione implicita "insertOrUpdate") con indirizzo e-mail, data di nascita e città:

<recipient xtkschema="nms:recipient" email="john.doe@adobe.com" birthDate="1956/05/04" folder-id=1203 _key="@email, [@folder-id]">
  <location city="Newton"/>
</recipient>

Eliminazione di un destinatario:

<recipient xtkschema="nms:recipient" _operation="delete" email="rene.dupont@adobe.com" folder-id=1203 _key="@email, [@folder-id]"/>
NOTE
Per un’operazione di eliminazione, il documento di input deve contenere solo i campi che compongono la chiave di riconciliazione.

Esempio con il metodo 'WriteCollection' example-with-the--writecollection--method

Aggiornamento o inserimento per più destinatari:

<recipient-collection xtkschema="nms:recipient">
  <recipient email="john.doe@adobe.com" firstName="John" lastName="Doe" _key="@email"/>
  <recipient email="peter.martinez@adobe.com" firstName="Peter" lastName="Martinez" _key="@email"/>
  <recipient ...
</recipient-collection>

Esempio 1 example-1

Associazione della cartella a un destinatario in base al suo nome interno (@name).

<recipient _key="[folder/@name], @email" email="john.doe@adobe.net" lastName="Doe" firstName="John" xtkschema="nms:recipient">
  <folder name="Folder2" _operation="none"/>
</recipient>

Gli attributi "_key" e "_operation" possono essere immessi in un elemento collegato. Il comportamento di questo elemento è lo stesso dell’elemento principale dello schema di input.

La definizione della chiave dell’entità principale ("nms:recipient") è costituita da un campo di una tabella collegata (elemento <folder> schema "xtk:folder") e l’e-mail.

NOTE
L’operazione "none" immessa sull’elemento cartella definisce una riconciliazione sulla cartella senza aggiornamento o inserimento.

Esempio 2 example-2

Aggiornamento della società (tabella collegata nello schema "cus:company") da un destinatario:

<recipient _key="[folder/@name], @email" email="john.doe@adobe.net" lastName="Doe" firstName="John" xtkschema="nms:recipient">
  <company name="adobe" code="ERT12T" _key="@name" _operation="update"/>
</recipient>

Esempio 3 example-3

Aggiunta di un destinatario a un gruppo con la tabella delle relazioni di gruppo ("nms:rcpGrpRel"):

<recipient _key="@email" email="martin.ledger@adobe.net" xtkschema="nms:recipient">
  <rcpGrpRel _key="[rcpGroup/@name]">
    <rcpGroup name="GRP1"/>
  </rcpGrpRel>
</recipient>
NOTE
La definizione della chiave non viene immessa nel <rcpgroup> perché nello schema "nms:group" è definita una chiave implicita basata sul nome del gruppo.

Elementi della raccolta XML xml-collection-elements

Per impostazione predefinita, per aggiornare gli elementi di raccolta XML è necessario compilare tutti gli elementi di raccolta. I dati del database verranno sostituiti con i dati del documento di input. Se il documento contiene solo gli elementi da aggiornare, è necessario compilare l'attributo "_operation" su tutti gli elementi di raccolta da aggiornare per forzare un'unione con i dati XML del database.

Esempio di messaggi SOAP example-of-soap-messages-1

  • Query:

    code language-none
    <?xml version='1.0' encoding='ISO-8859-1'?>
    <SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='http://xml.apache.org/xml-soap' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
      <SOAP-ENV:Body>
        <Write xmlns='urn:xtk:persist' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
          <__sessiontoken xsi:type='xsd:string'/>
          <domDoc xsi:type='ns:Element' SOAP-ENV:encodingStyle='http://xml.apache.org/xml-soap/literalxml'>
            <recipient xtkschema="nms:recipient" email="rene.dupont@adobe.com" firstName="René" lastName="Dupont" _key="@email">
          </domDoc>
        </Write>
      </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>
    
  • Risposta:

    code language-none
    <?xml version='1.0' encoding='ISO-8859-1'?>
    <SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='http://xml.apache.org/xml-soap' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
      <SOAP-ENV:Body>
        <WriteResponse xmlns='urn:' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
        </WriteResponse>
      </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>
    

    Restituisci con errore:

    code language-none
    <?xml version='1.0'?>
    <SOAP-ENV:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
      <SOAP-ENV:Body>
        <SOAP-ENV:Fault>
          <faultcode>SOAP-ENV:Server</faultcode>
          <faultstring xsi:type="xsd:string">Error while executing the method 'Write' of service 'xtk:persist'.</faultstring>
          <detail xsi:type="xsd:string">PostgreSQL error: ERROR:  duplicate key violates unique constraint &quot;nmsrecipient_id&quot;Impossible to save document of type 'Recipients (nms:recipient)'</detail>
        </SOAP-ENV:Fault>
      </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>
    
recommendation-more-help
601d79c3-e613-4db3-889a-ae959cd9e3e1