איך יוצרים תמונות מ-HTML לצורך יצירה דינמית של כרטיסי עשירה

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

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

במסמך הזה אראה לכם איך ליצור תמונות במהירות באמצעות HTML תוכלו להטמיע את התמונות האלה בכרטיסים המתקדמים שהנציג שולח. איך ממירים HTML לתמונה בשלב הבא.

מ-HTML לתמונה

HTML הוא כלי מעולה לפריסת שילובים של טקסט ומדיה. בתור מפתחים, אנחנו צריכים לפתח מוצר כדי לשלוח למשתמש משהו כמו כרטיס עלייה למטוס, נתוני תרשים שימוש, או כל סוג אחר של מידע ספציפי למשתמש, באופן דינמי שהוא ה-HTML שנוצר, הוא הכלי שבו נשתמש. ב-RCS Business Messaging, אפשרויות מתקדמות הכרטיסים תומכים רק בסוגי מדיה של תמונה ווידאו, לכן כדי להשתמש ב-HTML ליצירת תוכן דינמי, ה-HTML קודם צריך להיות הומר לתמונה.

למרבה המזל, רוב שפות התכנות המודרניות תומכות בספריות לביצוע צילומי מסך של דפי אינטרנט או רכיבים שיכולים לעבד HTML בסיסי לפחות (ל לדוגמה, JEditorPane), שאפשר להשתמש בה כדי ליצור תמונה.

קיימים גם ממשקי API לצילום תמונות של דפי אינטרנט. לדוגמה, API לתובנות לגבי הדף של Google יכול ליצור צילומי מסך מכתובת אתר באופן אוטומטי.

דוגמה:

https://www.googleapis.com/pagespeedonline/v1/runPagespeed?url=https://www.google.com&screenshot=true

בשלבים הבאים נשתמש באפליקציית אקספרס של Node.js כדי ליצור אפליקציה ספציפית למשתמש כרטיס עלייה למטוס עם HTML, להמיר אותו לתמונה, להעלות אותו לקובץ שגלוי לכולם כתובת URL נגישה, ולאחר מכן מצרפים את התמונה בתוך כרטיס מתקדם כדי לשלוח למשתמש.

יצירת כרטיס עלייה למטוס דינמי

בתור התחלה, אנחנו צריכים את קוד ה-HTML כדי ליצור כרטיס עלייה למטוס, כמו בדוגמה הבאה תמונה.

דוגמה של כרטיס עלייה למטוס

יש הרבה דרכים לעשות זאת, אבל אנחנו נגדיר נקודת קצה בכתובת URL באפליקציית Node.js בשם /getTicket?msisdn=+12223334444, שמעבדת את ה-HTML שדרושים לכרטיס העלייה למטוס באמצעות המנוע של תצוגת EJS.

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

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

router.get('/getTicket', function(req, res, next) {
    // Get the passed in phone number
    let msisdn = req.body.msisdn;

    // Get the ticket object for this user
    let ticket = getUserTicket(msisdn);

    // Render the ticket in HTML using an EJS template
    res.render('ticket', {ticket: ticket});
});

תבנית ה-EJS של הכרטיס מגדירה את ה-HTML הבא כדי לעבד את Bonjour לדוגמה כרטיס רכבת.

<div>
  <div>
    <div class="left"><img width="200" src="/images/bonjour-rail-logo.png" /></div>
    <div class="right muted-text"><%= ticket.dateOfDeparture; %></div>
    <div class="cl"></div>
  </div>
  <div>
    <div class="left highlighted-text-color"><h2><%= ticket.startingLocation.city %></h2><br/><%= ticket.startingLocation.station %></div>
    <div class="right highlighted-text-color"><h2><%= ticket.endingLocation.city %></h2><br/><%= ticket.endingLocation.station %></div>
    <div class="cl"></div>
  </div>

  <div>
    <div class="left">
        <h3>PLATFORM <%= ticket.platform %></h3>
      <div>
        <div class="left">
          <div><h4>DEPART</h4></div>
          <div><%= ticket.departureTime %></div>
        </div>
        <div class="left">
          <div><h4>ARRIVE</h4></div>
          <div><%= ticket.arrivalTime %></div>
        </div>
        <div class="cl"></div>
      </div>
      <div>
        <div class="left">
          <div><h4>TICKET TYPE</h4></div>
          <div><%= ticket.ticketType %></div>
        </div>
        <div class="left">
          <div><h4>SEAT</h4></div>
          <div><%= ticket.seat %></div>
        </div>
        <div class="cl"></div>
      </div>
    </div>
    <div class="right">
      <img src="<%= ticket.qrCode %>" width="170" />
    </div>
    <div class="cl"></div>
  </div>
</div>

יצירת תמונה מ-HTML

הגדרנו את קוד ה-HTML כדי ליצור את כרטיס העלייה למטוס, אבל אנחנו צריכים דרך להמיר אותו לתמונה.

יש הרבה מודולים של Node.js בקוד פתוח שזמינים להמרה של שני מודולים גולמיים של HTML. וכתובות URL לתמונות. לצורך הדוגמה הזו נשתמש node-webshot, שהוא wrapper קל מסביב ל-PhantomJS.

PhantomJS הוא דפדפן ללא GUI שיכול לעבד HTML לתמונות. מכיוון ש-PhantomJS מסתמך על WebKit לעיבוד, הוא יכול לטפל בדפים מורכבים עם תמונות, CSS ו-JavaScript.

אחרי התקנת צומת Webshot (npm install --save node-webshot), מתבצעת המרה אפשר ליצור בקלות HTML לתמונה.

var webshot = require('node-webshot');
let url = '/getTicket?msisdn=' + msisdn;
let htmlAsImageFileLocation = 'ticket.png';

// Define screenshot options
var options = {
      screenSize: {
            width: 550,
            height: 450
      },
      shotSize: {
            width: 550,
            height: 450
      },
      userAgent: 'Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.20 (KHTML, like Gecko) Mobile/7B298g'
    };

// Save html as an image
webshot(url, htmlAsImageFileLocation, options, function(err) {
  // TODO: Upload image to a publicly accessible URL
});

אחסון קבצים בכתובת URL שגלויה לכולם

כדי להשתמש בתמונה שנוצרה באמצעות Webshot, אנחנו צריכים תמונה שגלויה לכולם כתובת URL. אם אתם יוצרים את התמונה בשרת אינטרנט ייעודי, יכול להיות שתוכלו כדי לשמור את הקובץ בתיקייה ציבורית, אבל בדוגמה הזו נעלה את הקובץ ב-Google Cloud Storage.

הפונקציה הבאה לוקחת מיקום של תמונה מקומית ומעלה אותה ל-Google Cloud Storage, החזרת הקישור החדש למדיה.

function uploadImage(imageLocation) {
    const {Storage} = require('@google-cloud/storage');

    // Creates a client
    const storage = new Storage();

    // Define the Cloud storage location and filename
    const bucketName = 'sample-image-uploads';
    const yourFileDestination = 'uploaded-image.png';

    // Set the options for the upload to be readable by anyone
    const options = {
        destination: yourFileDestination,
        predefinedAcl: 'publicRead'
    };

    // Return a promise that includes the storage upload
    return new Promise(function(resolve, reject) {
        // Uploads a local file to the bucket
        storage.bucket(bucketName).upload(imageLocation, options)
            .then(results => {
                // Return the image URL
                resolve(results[0].metadata.mediaLink);
            }).catch(error => {
                reject(error);
            });
    });
}

בשלב הבא, אנחנו צריכים להחליף את TODO התגובה הקודמת בקריאה לשימוש את פונקציית uploadImage הזו.

// Save html as image
webshot(url, htmlAsImageFileLocation, options, function(err) {
      let uploadRequest = uploadImage(filename);

      uploadRequest.then(function(imageUrl) {
         // TODO: Use the imageUrl in a rich card to send to the user
      });
});

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

כמעט סיימנו. משלימים את השלב האחרון ומגדירים הפונקציה sendBoardingPass(imageUrl, msisdn), שיוצרת כרטיס מתקדם של RBM באמצעות התמונה שנוצרה בשלב הקודם ושולחת אותה למשתמש.

כדי לשלוח את הכרטיס המתקדם באמצעות RBM, משתמשים באותו SDK של Node.js שזמין ב- דוגמה לאינטראקציה ראשונה של סוכן.

function sendBoardingPass(imageUrl, msisdn) {
    let title = 'Here is your boarding pass.';

    let suggestions = [
                {
                    reply: {
                        text: 'See more options',
                        postbackData: 'more_options',
                    }
                },
            ];

    let params = {
        messageText: title,
        msisdn: msisdn,
        imageUrl: imageUrl,
        suggestions: suggestions,
        height: 'TALL',
    };

    // Send the boarding pass
    rbmApiHelper.sendRichCard(params);
}

בהמשך מופיע צילום מסך של התוצאה הסופית.

תמונה דינמית בכרטיס מתקדם

סיכום ו סיכום

הדרך הפשוטה ביותר להפוך כרטיסים מתקדמים לגמישים יותר היא להשתמש ב-HTML דינמי ולהמיר את ה-HTML לתמונות. רוב שפות התכנות המודרניות תומכות ספריות או ממשקי API שיעזרו לכם להשלים את ההמרה. יכול להיות שתצטרכו: לשנות את גודל התמונה כדי להתאים את התמונה לתרחיש לדוגמה שלכם אבל זו גישה נהדרת ליצירת רכיבים חזותיים מושכים יותר נציגי RBM.

בהצלחה ושיהיה בהצלחה!