2010-12-15 9 views
2

Guten Morgen zusammen,Erstellen eines neuen Lead-in Salesforce Mit TwilioForce APEX Bibliothek

In erster Linie erstellen zu, ist die Force.com IDE und Salesforce ein neues Skillset für mich. Ich versuche, die TwilioForce APEX-Bibliothek zu verwenden: https://www.twilio.com/docs/salesforce/install

, um einen neuen Salesforce-Lead für jeden eingehenden Anruf auf dem Twilio-Konto meines Kunden zu erstellen. Ich bin so weit gekommen, ein neues Force.com-Projekt in Eclipse zu erstellen und die Twilioforce-Komponenten, -Klassen und -Seiten in das Projekt zu kopieren, benötige jedoch eine Anleitung zum Schreiben der Logik zum Erstellen des Leads.

Fragen, die ich habe: 1. Können Sie Links zu Referenzmaterialien bereitstellen, die zeigen, wie Sie in Salesforce programmatisch einen neuen Lead erstellen? 2. Wie teste ich die TwilioForce-Komponenten, insbesondere die, die ich geändert habe, um die Twilio-Telefonnummer und das Token meines Kunden wiederzugeben? Sind diese aus dem Force.com-Projekt in Eclipse abrufbar oder müssen sie von meinem developer.org-Konto aus aufgerufen werden? 3. Sobald ich herausgefunden habe, wie die oben genannte Lead-Erstellung von eingehenden Twilio-Anrufen durchgeführt werden kann, wie stelle ich die von mir erstellte Codebasis auf meinem Client bereit?

Danke, Sid

EDIT: Eyescream, war Ihre Probe eine große Hilfe. Hier ist die TwilioRestResponse Klasse, die mit der TwilioForce Code-Basis kam:

public class TwilioRestResponse { 

private String responseText; 
private integer httpStatus; 
private String url; 
private String queryString; 
private boolean error; 


public TwilioRestResponse(String url, String text, integer status){ 
    Pattern p = Pattern.compile('([^?]+)\\??(.*)'); 
    Matcher m = p.matcher(url); 
    m.matches(); 
    this.url = m.group(1); 
    this.queryString = m.group(2); 
    this.responseText = text; 
    this.httpStatus=status; 
    this.error = (status>=400); 
} 

// getters and setters 
public String getResponseText() { 
    return responseText; 
} 
public void setResponseText(String responseText) { 
    this.responseText = responseText; 
} 
public integer getHttpStatus() { 
    return httpStatus; 
} 
public void setHttpStatus(integer httpStatus) { 
    this.httpStatus = httpStatus; 
} 
public String getUrl() { 
    return url; 
} 
public void setUrl(String url) { 
    this.url = url; 
} 
public String getQueryString() { 
    return queryString; 
} 
public void setQueryString(String queryString) { 
    this.queryString = queryString; 
} 
public boolean isError() { 
    return error; 
} 
public void setError(boolean error) { 
    this.error = error; 
} 
} 

Es gibt auch eine CallsXmlParser Klasse wie folgt:

public class CallsXmlParser{ 
//All Parsed records will be in this list 
public List<Call> listRecords = new List<Call>(); 
//Data Model to store all response elements 
public class Call{ 
    public string Sid{get;set;} 
    public string DateCreated{get;set;} 
    public string DateUpdated{get;set;} 
    public string CallSegmentSid{get;set;} 
    public string AccountSid{get;set;} 
    public string Called{get;set;} 
    public string Caller{get;set;} 
    public string PhoneNumberSid{get;set;} 
    public string Status{get;set;} 
    public string StartTime{get;set;} 
    public string EndTime{get;set;} 
    public string Duration{get;set;} 
    public string Price{get;set;} 
    public string Flags{get;set;} 
    public string Annotation{get;set;} 
} 
public CallsXmlParser(){ 

} 
public CallsXmlParser(string data){ 
    XmlStreamReader xsr = new XmlStreamReader(data); 
    listRecords = parse(xsr); 
} 
public Call[] parse(XmlStreamReader reader) { 
    Call[] members = new Call[0]; 
    while(reader.hasNext()) { 
     if (reader.getEventType() == XmlTag.START_ELEMENT) { 
      if ('Call' == reader.getLocalName()) {     
       Call member = parseMember(reader); 
       members.add(member); 
      } 
     } 
     reader.next(); 
    } 
    return members; 
} 
//Parsing Each Call Tag and its nested tags 
public Call parseMember(XmlStreamReader reader){ 
    Call callObject = new Call(); 
    while(reader.hasNext()) { 

     if ('Call' == reader.getLocalName() && reader.getEventType() == XmlTag.END_ELEMENT) { 
      break; 
     } 
     else if('Sid' == reader.getLocalName() && reader.getEventType() == XmlTag.START_ELEMENT){ 
      reader.next();     
      if(reader.getEventType() == XmlTag.CHARACTERS) { 
      callObject.Sid = reader.getText(); 
      } 
     }else if('DateCreated' == reader.getLocalName() && reader.getEventType() == XmlTag.START_ELEMENT){ 
      reader.next();     
      if(reader.getEventType() == XmlTag.CHARACTERS) { 
      callObject.DateCreated= reader.getText(); 
      } 
     }else if('DateUpdated' == reader.getLocalName() && reader.getEventType() == XmlTag.START_ELEMENT){ 
      reader.next();     
      if(reader.getEventType() == XmlTag.CHARACTERS) { 
      callObject.DateUpdated= reader.getText(); 
      } 
     }else if('CallSegmentSid' == reader.getLocalName() && reader.getEventType() == XmlTag.START_ELEMENT){ 
      reader.next();     
      if(reader.getEventType() == XmlTag.CHARACTERS) { 
      callObject.CallSegmentSid= reader.getText(); 
      } 
     }else if('AccountSid' == reader.getLocalName() && reader.getEventType() == XmlTag.START_ELEMENT){ 
      reader.next();     
      if(reader.getEventType() == XmlTag.CHARACTERS) { 
      callObject.AccountSid= reader.getText(); 
      } 
     }else if('Called' == reader.getLocalName() && reader.getEventType() == XmlTag.START_ELEMENT){ 
      reader.next();     
      if(reader.getEventType() == XmlTag.CHARACTERS) { 
      callObject.Called= reader.getText(); 
      } 
     }else if('Caller' == reader.getLocalName() && reader.getEventType() == XmlTag.START_ELEMENT){ 
      reader.next();     
      if(reader.getEventType() == XmlTag.CHARACTERS) { 
      callObject.Caller= reader.getText(); 
      } 
     }else if('PhoneNumberSid' == reader.getLocalName() && reader.getEventType() == XmlTag.START_ELEMENT){ 
      reader.next();     
      if(reader.getEventType() == XmlTag.CHARACTERS) { 
      callObject.PhoneNumberSid= reader.getText(); 
      } 
     }else if('Status' == reader.getLocalName() && reader.getEventType() == XmlTag.START_ELEMENT){ 
      reader.next();     
      if(reader.getEventType() == XmlTag.CHARACTERS) { 
      callObject.Status = reader.getText(); 
      } 
     }else if('StartTime' == reader.getLocalName() && reader.getEventType() == XmlTag.START_ELEMENT){ 
      reader.next();     
      if(reader.getEventType() == XmlTag.CHARACTERS) { 
      callObject.StartTime = reader.getText(); 
      } 
     }else if('EndTime' == reader.getLocalName() && reader.getEventType() == XmlTag.START_ELEMENT){ 
      reader.next();     
      if(reader.getEventType() == XmlTag.CHARACTERS) { 
      callObject.EndTime = reader.getText(); 
      } 
     }else if('Duration' == reader.getLocalName() && reader.getEventType() == XmlTag.START_ELEMENT){ 
      reader.next();     
      if(reader.getEventType() == XmlTag.CHARACTERS) { 
      callObject.Duration = reader.getText(); 
      } 
     }else if('Price' == reader.getLocalName() && reader.getEventType() == XmlTag.START_ELEMENT){ 
      reader.next();     
      if(reader.getEventType() == XmlTag.CHARACTERS) { 
      callObject.Price = reader.getText(); 
      } 
     }else if('Flags' == reader.getLocalName() && reader.getEventType() == XmlTag.START_ELEMENT){ 
      reader.next();     
      if(reader.getEventType() == XmlTag.CHARACTERS) { 
      callObject.Flags = reader.getText(); 
      } 
     }else if('Annotation' == reader.getLocalName() && reader.getEventType() == XmlTag.START_ELEMENT){ 
      reader.next();     
      if(reader.getEventType() == XmlTag.CHARACTERS) { 
      callObject.Annotation = reader.getText(); 
      } 
     } 

     reader.next(); 
    } 
    return callObject; 
} 
} 

Meine sehr grundlegende insertLead Klasse ist wie folgt:

public with sharing class insertLead { 
Lead1 = new Lead(Phone='TwilioRestResponse.GetResponseText'); 
} 

I Sie müssen die Telefonnummer und den CallerID-Namen aus der TwilioRestResponse- oder CallXmlParser-Klasse einlesen und in die entsprechenden Felder eines neuen Leads einfügen. Was ist die geeignete Syntax für die Referenzierung der CallObject.PhoneNumberSid in meinem neuen Lead? Alternativ ist es besser, die TwilioRestResponse zu analysieren? Wenn ja, wie würde ich nur die Telefonnummer und den CallerID-Namen aus dem GetResponseText auswählen?

Thanks again, Sid

Antwort

4

Antwort aktualisiert, blättern Sie bitte

public class SidTest { 

    // 1. How to create a new Lead programatically on Force.com (in Apex) 
    /* This method is marked as test method, meaning that you can use it to run tests but in the end no data will be saved 
     (transaction rollback). You'll need similar code in a class that intercepts messages from Twilio. 
    */ 
    public static testMethod void insertLead(){ 
     Lead l = new Lead(FirstName='Test', LastName='Lead', Email='[email protected]', Company='test', NumberofEmployees=7); 
     insert l; 

     // 2. How do I test the TwilioForce components, especially those I've changed to reflect my client's Twilio phone number and token? 
    /* Not sure what do you mean, but most likely by writing test classes like this one and checking their test code coverage. 
     See also http://stackoverflow.com/questions/4372202/how-to-unit-test-works-in-salesforce/4381941 
     Below sample test that checks if our insert above succeeded. 
     You can run it from Eclipse (preferred) or Salesforce GUI in Setup->Develop->Apex classes. 
    */ 
     Lead[] leads = [SELECT Name, Email FROM Lead WHERE Name = 'Test Lead']; 

     System.debug(leads); // if you want to see results in detailed debug log 
     System.assertEquals(1, leads.size()); 
     System.assertEquals('[email protected]', leads[0].Email); 
    } 
} 
unten

das Ergebnis hier, wenn Sie es in Eclipse ausgeführt werden: http://dl.dropbox.com/u/709568/stackoverflow/Sid.png

Was letzte Frage: Wenn Sie mit der in Ihrer Developer Edition getesteten Funktionalität zufrieden sind, sollten Sie den Client bitten, Ihnen Zugriff auf "Sandbox" seiner Organisation zu gewähren. Sie können in Eclipse ein neues Projekt erstellen, das auf diese Sandbox verweist, und einfach alle darin enthaltenen Klassen erstellen, Tests mit einer Teilmenge realer Daten usw. ausführen. Schließlich werden Sie oder jemand vom Client eine Deployment in die "Produktions" -Umgebung durchführen die Abdeckung in automatisierten Tests wird von Bedeutung sein.

Alternativ können Sie auch ein Paket mit Ihrem Code erstellen und es auf AppExchange wie ein Plug-in an Salesforce verkaufen, das jeder in seine Organisation herunterladen kann. Sie können natürlich dafür verlangen. Aber das sieht für den Moment wie ein zu großer Sprung aus ...

Hoffe, das kann Ihnen den Anfang machen.


Update: Hier ist eine schnelle & schmutzig Klasse basiert auf TestCallsXmlParser die im Code-Paket enthalten ist Sie verwenden:

public class TestCallsXmlParser{ 
    @isTest 
    public static void TestCallsXmlParserMethod1(){ 
     CallsXmlParser callxml = new CallsXmlParser(); 
     String xmlData = '<TwilioResponse> <Calls page=\"0\" numpages=\"1\" pagesize=\"50\" total=\"38\" start=\"0\" end=\"37\"> <Call> <Sid>CA42ed11f93dc08b952027ffbc406d0868</Sid> <DateCreated>Sat, 07 Feb 2009 13:15:19 -0800</DateCreated><DateUpdated>Sat, 07 Feb 2009 13:15:19 -0800</DateUpdated><CallSegmentSid/>'; 
     xmlData = xmlData + '<AccountSid>AC309475e5fede1b49e100272a8640f438</AccountSid><Called>4159633717</Called><Caller>4156767925</Caller><PhoneNumberSid>PN</PhoneNumberSid><Status>2</Status><StartTime>Thu, 03 Apr 2008 04:36:33 -0400</StartTime><EndTime>Thu, 03 Apr 2008 04:36:47 -0400</EndTime>'; 
     xmlData = xmlData + '<Duration>14</Duration><Price/><Flags>1</Flags></Call>'; 
     xmlData = xmlData + '<Call><Sid>CA751e8fa0a0105cf26a0d7a9775fb4bfb</Sid><DateCreated>Sat, 07 Feb 2009 13:15:19 -0800</DateCreated><DateUpdated>Sat, 07 Feb 2009 13:15:19 -0800</DateUpdated><CallSegmentSid/>'; 
     xmlData = xmlData + '<AccountSid>AC309475e5fede1b49e100272a8640f438</AccountSid><Called>2064287985</Called><Caller>4156767925</Caller><PhoneNumberSid>PNd59c2ba27ef48264773edb90476d1674</PhoneNumberSid><Status>2</Status>'; 
     xmlData = xmlData + '<StartTime>Thu, 03 Apr 2008 01:37:05 -0400</StartTime><EndTime>Thu, 03 Apr 2008 01:37:40 -0400</EndTime><Duration>35</Duration><Price/> <Flags>1</Flags> </Call></Calls></TwilioResponse> '; 
     CallsXmlParser callxml1 = new CallsXmlParser(xmlData); 

     // eyescream's modification starts here 

     // list to store our leads and bulk save them in blocks up to 100 records at 1 insert 
     List<Lead> leads = new List<Lead>(); 

     for(CallsXmlParser.Call c : callxml1.listRecords) { 
      System.debug('2 new Leads will be created from phone numbers: ' + c.Caller + ', ' + c.Called); 
      leads.add(new Lead(MobilePhone = c.Caller, Company='x', LastName='x')); // Company & Last Name are mandatory fields 
      leads.add(new Lead(MobilePhone = c.Called, Company='y', LastName='y')); // without them insert will fail. 

      if(leads.size() == 100) { // 100 is the limit of records saved at once. Inserting in batches speeds up execution. 
       insert leads; 
       leads.clear(); 
      } 
     } 

     // If we have any leftovers, we'll insert them too. 
     if(leads.size() > 0) { 
      insert leads; 
      leads.clear(); 
     } 
    } 
} 

Natürlich können Sie es weiter verbessern können, um Duplikate zu überprüfen, füllen mit echten Namen usw. ... aber das ist in etwa, wie Sie geparste Ergebnisse verwenden können. Ich denke nicht, dass das Parsen des XML selbst eine gute Option wäre ... Ihre Frage lässt darauf schließen, dass mehr Felder in das XML kommen (oder vorhandene werden zum Speichern anderer Daten verwendet), aber wahrscheinlich können Sie erweitern der Parser entsprechend.

+0

Leider bekomme ich einen Compiler-Fehler auf der Linie für (CallsXmlParser.Call c: callxml1.ListRecords) { erwartete Angabe geschweifte Klammer – SidC

+0

Ich habe gerade in meinem org 2 Klassen von Twilio Bibliothek erstellt: TestCallsXmlParser und CallsXmlParser. Beide in den neuesten Versionen von Trunk und es läuft ohne Probleme ... Vielleicht haben Sie einen Tippfehler in Klassennamen gemacht? Ist die innere Klasse eine öffentliche? Vielleicht ist deine Version von eclipse/force.com plugin alt? Ich bin in der Plugin-Version Sommer '10 (19.0.0) und meine vollständige Codebasis ist hier als Referenz: http://dl.dropbox.com/u/709568/stackoverflow/Sid%20-%20my%20Dev%20Edition. zip – eyescream

+0

Mein schlechtes :) Ich hatte eine rechte geschweifte Klammer am Ende der Datei fehlt. Nun, da dies erstellt wurde, wie gehe ich vor, es auf meinem Entwicklerforce-Konto auszuführen? Vielen Dank!! – SidC

0

Wenn jemand Probleme bei der Bereitstellung von Twilio-Bibliothek haben, werden hier gute Details zur Verfügung gestellt, die die meisten Aufgaben erledigen. Einige wie, wenn es helfen könnte http://redcurrantscloud.blogspot.in/

Danke.