3 באפריל 2011

כיצד לשלב את רב-מסר במערכת ניהול לקוחות

שילוב של ה-CRM של כספית ומערכת רב-מסר
אנחנו משתמשים במערכת רב-מסר בכדי לדוור לללקוחות ולמתעניינים בכספית התוכנה הקלה והמשתלמת להנהלת חשבונות.

במסגרת שיפורים שבצענו במערכת ניהול הלקוחות של כספית (CRM)  עלה הרעיון לשלב את ה-CRM ואת רב-מסר. הרעיון הבסיסי הוא שלאחר שלקוח חדש ירכוש רישיון לכספית נרשום אותו אוטומטית לרב-מסר.

ברשימה ברב-מסר נגדיר סדרת מסרים שרלוונטית ללקוחות חדשים של כספית. לדוגמה:
  • היום ה-0: ברכה על הצטרפות לכספית.
  • לאחר חודש: הצעה לגיבוי מקוון.
  • לאחר 1/2 שנה: שאלה על שביעות הרצון מכספית.
  • וכו'.
שימוש נוסף שרצינו לעשות ברשימה בר-מסר הוא להגדיר מסרים תלוי תאריך שישלחו כך:
  • 10 ימים לפני שפג הרישיון לשימוש בכספית.
  • 10 ימים לפני שפג הרישיון לשימוש בגיבוי המקוון.
  • וכו'.
לצורך כך בנינו רשימה ברב מסר ובה כל השדות הרלוונטיים למשלוח המיילים. לדוגמה: שם הלקוח, תאריך סיום הרישיון, תאריך סיום הגיבוי וכו'.

החלק הטכני
ועכשיו לחלק הטכני בפוסט. כיצד מבצעים רישום אוטומטי של לקוח למערכת רב-מסר מתוך קוד "שרת" המערכת מבוססת .Net?

האתגרים הם אלה:
  • לבצע POST לאתר של רב מסר מתוך קוד צד שרת.
  • לקדד את הנתונים ואת שמות השדות באופן נכון כך שרב מסר ידע לקרוא אותם.
הנה הפיתרון שהגענו אליו.

כמה מילות הסבר:
  1.  הקידוד שרב-מסר מצפה לו (לפחות במקרה שלנו) הוא Windows-1255 .  הקידוד של Windows-1255  הוא לא url encoding ולא UTF, אלא קידוד נפרד.
  2. שדות מסוג תאריך מעבירים ב-3 חלקים: d[field name], m[field name], y[fields name]
  3. את השדות האחרים מעבירים כך: fields[field name]=field_vale

public void AddToRavMeser()
 {
  const string RAV_MESER = "http://cp.responder.co.il/subscribe.php";
  string postData = "";
 
  DateTime datLicense = (this.License != null) ? this.License.validDate : new DateTime(0);
        string licensComments = (this.License != null) ? this.License.licenseComments : "";
 
        if (string.IsNullOrEmpty(this.email)) throw new Exception("לא ניתן להוסיף לרב מסר לקוח ללא כתובת מייל.");
        
                                                                                    ס  ו  ג   
  postData = string.Format("fields%5Bsubscribers_email%5D={0}&fields%5Bsubscribers_name%5D={1}&fields%5B%F1%E5%E2+%E4%F8%E9%F9%E9%E5%EF%5D={2}&fields%5B%EE%F1%F4%F8+%EC%F7%E5%E7%5D={3}&d%5B%FA%E5%F7%F3+%E4%F8%E9%F9%E9%E5%EF%5D={4}&m%5B%FA%E5%F7%F3+%E4%F8%E9%F9%E9%E5%EF%5D={5}&y%5B%FA%E5%F7%F3+%E4%F8%E9%F9%E9%E5%EF%5D={6}&fields%5B%F2%E5%F1%F7+%EE%E5%F8%F9%E4%5D={7}&fields%5B%F9%ED+%E4%F2%F1%F7%5D={8}&form_id=99999&encoding=windows-1255",
   this.email,
   ToWindows1255(this.firstName),
            ToWindows1255(licensComments), //סוג הרישיון
   this.iClientsID,
   datLicense.Day, datLicense.Month, datLicense.Year, //תוקף הרישיון
   this.OsekMorshe,
   ToWindows1255(this.BusinessName)
   );
 
  HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create("http://cp.responder.co.il/subscribe.php");
  myHttpWebRequest.CookieContainer = new CookieContainer();
  myHttpWebRequest.Method = "POST";
 
  ASCIIEncoding encoding = new ASCIIEncoding();
  byte[] byte1 = encoding.GetBytes(postData);
 
  // Set the content type of the data being posted.
  myHttpWebRequest.ContentType = "application/x-www-form-urlencoded";
 
  // Set the content length of the string being posted.
  myHttpWebRequest.ContentLength = byte1.Length;
 
  Stream newStream = myHttpWebRequest.GetRequestStream();
 
  newStream.Write(byte1, 0, byte1.Length);
 
  // Close the Stream object.
  newStream.Close();
 }
 
 string ToWindows1255(string s)
 {
  //Can not user UrlEncode since it encodes in Unicode and not in Windows-1255
  //string s1 = HttpContext.Current.Server.UrlEncode(s);
  //return s1;
 
  Encoding win1255 = Encoding.GetEncoding(1255);
 
  //Transfer for Unicode to Windows-1255
  byte[] win1255Bytes = win1255.GetBytes(s);
 
  StringBuilder sb = new StringBuilder();
  for (int i = 0; i < win1255Bytes.Length; i++)
  {
   sb.AppendFormat("%{0:x}", win1255Bytes[i]);
  }
return sb.ToString(); 
 }
בעיה ברישום מחדש לרב-מסר
לצערינו נתקלנו בבעיה אחת מציקה. מתברר שכאשר מבצעים רישום מחודש של לקוח שכבר קיים ברשימה ברב מסר הוותק שלו מתאפס. כלומר הוא יתחיל לקבל מחדש את כל המיילים בסדרת המסרים שמיועדת ללקוח חדש.

פנינו לרב-מסר בעניין. הנה המייל ששלחנו:

Title: יצירת קשר ממערכת רב מסר

            Description: מספר חשבון ראשי:3052 שם משתמש:caspit תוכן הפניה:אנא ציינו את שם הרשימה בה קיימת הבעיה:
כל הרשימות

אנא ציינו את שם המסר בו קיימת הבעיה:
לא רלוונטי

אנא רשמו את הבעיה בפירוט הרב ביותר האפשרי (מה בדיוק עשיתם שלב אחרי שלב ומה קרה אז?):
1. ביום 1/1/2011 אני נרשם לרשימה X כלשהיא. תאריך הרישום הוא 1/1/2011 והוותק שלי הוא 0.

2. ביום 1/3/2011 אני נרשם שוב לרשימה X (לצורך עדכון פרטים). תאריך הרישום מתעדכן ל-1/3/2011 והוותק שלי מתאפס ל-0.

נניח שברשימה X יש סדרת מסרים מבוססת וותק: ביום ה-0 נשלחת ברכה ללקוח חדש, אחרי 10 ימים נשלח מסר שמתעניין איך התוכנה פועלת וכו'.

האם המסרים האלה ישלחו שוב מההתחלה?

אם כן, זו בעיה משום שהמסרים הרי לא רלוונטיים, כי אני למעשה לקוח עם וותק של 3 חודשים ולא לקוח חדש.

אם לא, מה יקרה למסר שאמור להשלח ביום ה-100 (פחות או יותר 10 ימים אחרי שעדכנתי את הנתונים שלי והוותק התאפס)? האם הוא ישלח?

נראה לי שהפיתרון לבעיה שלי הוא לא לאפס את הוותק במקרה של עדכון נתונים. האם זה נכון?

התשובה שקיבלנו מרב-מסר היא:

From: responder@sysaidcss.com [mailto:responder@sysaidcss.com]
Sent: Sunday, April 03, 2011 9:26 AM
To: dror@caspit.biz
Subject: בנוגע לבקשת שירות #12,068 יצירת קשר ממערכת רב מסר

היי,
נמסר לנו ממחלקת התוכנה שהפיתרון לשאלה שהצגת ייענה במסגרת פיתוח כלי חדש ליצירת טפסים עליו אנו עובדים.
עם זאת, אין לנו צפי קונקרטי לגבי השקת אותו כלי.
________________________________________________

בכבוד רב,
איציק ארז.
רב מסר – צוות תמיכה טכנית.

הפיתרון שאנחנו נממש בשלב זה
מאחר שאין כרגע פיתרון לבעיה החלטנו לממש "work around".
במקום שסדרת המסרים ללקוח החדש תהיה מבוססת על וותק, נבסס אותה על שדה תאריך שנוסיף לרשימה בשם "תאריך רישום".

כלומר סדרת המסרים ללקוח החדש תהיה סדרת מסרים מבוססת תאריך, והיות והתאריך הזה נמצא בשליטה של ה-CRM, נוכל לעקוף את הבעיה של איפוס הוותק.

כיצד לשלוח טופס (Form) לאתר רב-מסר מאתר מבוסס .Net

אנחנו משלימים בימים אלה את הפיתוח של האתר החדש של כספית התוכנה הקלה והמשתלמת להנהלת חשבונות .
האתר החדש מבוסס על Microsoft .Net , ולכן נוצרה לנו בעיה לשלוח פרטי הרשמה לאתר של רב מסר.

מדוע?

הטפסים שרב מסר מייצר באופן אוטומטי נראים כך:

<!-- Generated by responder.co.il -->
<script type="text/javascript">
<!--
function responder_validation(form) {
  var inputs = form.getElementsByTagName('input');
  var selects = form.getElementsByTagName('select');
...
  return true;
}
//-->
</script>

<form method="post" action="http://cp.responder.co.il/subscribe.php" onsubmit="return responder_validation(this);">
...
<input type="submit" value="שלח" />
</form>

קל לשלב את הטופס באתר מבוסס ASP, אבל באתר מבוסס .Net הטופס של רב מסר יתנגש בטופס ברירת מחדל שמייצרת מערכת .Net.

מה הפיתרון?
מתברר שהפיתרון אינו מסובך ודורש שינויים מעטים בטופס של רב מסר:
1. מסירים את התגים של ה-form סביב הטופס של רב מסר. כלומר משאירים את הטבלה והשדות שהוא יוצר אבל מוחקים את <form>  ואת </form>.
2. משנים את הכפתור "שלח" כך:
<input type="button" value="הרשם" onclick="responder_validation(this);"/>

3. משנים את בדיקת הנכונות כך:

<script type="text/javascript">
<!--
function responder_validation(btn) {
  var form1 = btn.form;
  var inputs = form1.getElementsByTagName('input');
  var selects = form1.getElementsByTagName('select');
...
  form1.action = 'http://cp.responder.co.il/subscribe.php';
  form1.submit();
}
//-->
</script>

השינויים די ברורים, אבל הנה הסבר קצר:
  1. הסרנו את תג ה-form  בכדי להשאיר רק את ה-form של .Net.
  2. ה-function של רב מסר מצפה ל-form. במקום זה שלחנו לו button. לכן הוצאנו את ה-form מה-button.
  3. שמו של המשתנה הוא form1, לכן לקחנו את המערך של ה-inputs ושל ה-selects מ-form1.
  4. הטופס של .Net מבצע POST לעצמו, לכן שינינו את ה-action שלו לאתר של רב-מסר.