Cách tạo hình ảnh từ HTML để tạo thẻ thông tin chi tiết động

Một trong những loại nội dung mạnh mẽ và linh hoạt nhất trong RCS Business Messaging là thẻ thông tin. Với thẻ rich, bạn có thể gửi nhiều phần thông tin có liên quan trong một thư, bao gồm hình ảnh hoặc video, tiêu đề, mô tả và tối đa bốn câu trả lời hoặc hành động đề xuất.

Thẻ thông tin độc lập và băng chuyền thẻ thông tin phong phú là những tính năng mạnh mẽ có thể giúp bạn tạo nên những trải nghiệm hấp dẫn cho người dùng. Những hình ảnh này sẽ có hiệu quả miễn là hình ảnh bạn cần chia sẻ là hình ảnh tĩnh như phiếu giảm giá hoặc sản phẩm. Nhưng điều gì sẽ xảy ra nếu bạn cần gửi nội dung động dựa trên thông tin về người dùng, chẳng hạn như thẻ lên máy bay?

Trong bài viết này, tôi sẽ chỉ cho bạn cách nhanh chóng tạo hình ảnh bằng HTML và nhúng những hình ảnh đó vào thẻ rich mà nhân viên hỗ trợ của bạn gửi. Hãy bắt đầu bằng cách xem cách chuyển đổi HTML thành hình ảnh.

Từ HTML đến hình ảnh

HTML là công cụ tuyệt vời để bố trí kết hợp văn bản và phương tiện. Là nhà phát triển, nếu chúng tôi cần xây dựng một sản phẩm để gửi cho người dùng điều gì đó như thẻ lên máy bay, biểu đồ sử dụng dữ liệu hoặc bất kỳ loại thông tin dành riêng cho người dùng nào khác, thì HTML được tạo động có thể là công cụ chúng tôi sẽ sử dụng. Trong RCS Business Messaging, thẻ thông tin chỉ hỗ trợ các loại hình ảnh và video, vì vậy, để tận dụng sức mạnh của HTML cho việc tạo nội dung động, trước tiên, HTML cần được chuyển đổi thành hình ảnh.

May mắn thay, hầu hết các ngôn ngữ lập trình hiện đại đều hỗ trợ thư viện để chụp ảnh màn hình các trang web hoặc thành phần có thể hiển thị ít nhất là HTML cơ bản (ví dụ: JEditorPane) mà bạn có thể sử dụng để tạo hình ảnh.

Ngoài ra còn có API để chụp ảnh trang web. Ví dụ: API Thông tin chi tiết về trang của Google có thể tự động tạo ảnh chụp màn hình từ URL.

Ví dụ:

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

Trong phần tiếp theo, chúng tôi sẽ dùng ứng dụng Node.js express để tạo thẻ lên máy bay dành riêng cho người dùng bằng HTML, chuyển đổi thẻ thành hình ảnh, tải lên URL có thể truy cập công khai, sau đó đính kèm hình ảnh trong thẻ thông tin để gửi cho người dùng.

Tạo thẻ lên máy bay linh động

Để bắt đầu, chúng ta cần HTML để tạo thẻ lên máy bay như hình dưới đây.

Mẫu thẻ lên máy bay

Có nhiều cách để thực hiện việc này, nhưng chúng ta sẽ xác định điểm cuối URL trong ứng dụng Node.js có tên là /getTicket?msisdn=+12223334444. Công cụ này sẽ hiển thị HTML mà chúng ta cần cho thẻ lên máy bay bằng cách sử dụng công cụ chế độ xem EJS.

Giả sử rằng có một hàm tên là getUserTicket. Hàm này sẽ lấy số điện thoại của người dùng và trả về một đối tượng vé chứa các thông tin như thời gian khởi hành, ghế ngồi, loại vé, vị trí xuất phát, v.v.

Trong bộ định tuyến của ứng dụng express, chúng ta xác định điểm cuối getTicket, gọi hàm getUserTicket và truyền vé vào mẫu 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});
});

Mẫu vé EJS xác định HTML sau đây để hiển thị vé Bonjour Rail mẫu.

<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>

Tạo hình ảnh từ HTML

Chúng ta đã xác định HTML để tạo thẻ lên máy bay, nhưng chúng ta cần có một cách để chuyển đổi nó thành hình ảnh.

Có nhiều mô-đun Node.js nguồn mở có sẵn để chuyển đổi cả HTML thô và URL thành hình ảnh. Để minh hoạ cho ví dụ này, chúng ta sẽ sử dụng nút chụp web, là một trình bao bọc ánh sáng xung quanh PhantomJS.

PhantomJS là một trình duyệt không có tập lệnh, có thể tạo tập lệnh có thể hiển thị HTML thành hình ảnh. Vì PhantomJS dựa vào WebKit để hiển thị nên nó có thể xử lý các trang phức tạp với hình ảnh, CSS và JavaScript.

Sau khi cài đặt ảnh chụp nhanh nút (npm install --save node-webshot), việc chuyển đổi HTML thành hình ảnh rất đơn giản.

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
});

Lưu trữ tệp vào URL có thể truy cập công khai

Để sử dụng hình ảnh do webshot tạo, chúng tôi cần một URL có thể truy cập công khai. Nếu bạn đang tạo hình ảnh trên máy chủ web chuyên dụng, bạn có thể chỉ cần lưu tệp vào thư mục công cộng, nhưng trong ví dụ này, chúng tôi sẽ tải tệp lên Google Cloud Storage.

Hàm dưới đây sẽ lấy một vị trí hình ảnh cục bộ rồi tải lên Google Cloud Storage, trả về đường liên kết nội dung nghe nhìn mới tạo.

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

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

    // Define the Cloud storage location and file name
    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);
            });
    });
}

Tiếp theo, chúng ta cần thay thế TODO trước đó bằng một lệnh gọi để sử dụng hàm uploadImage này.

// 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
      });
});

Gửi một thẻ thông tin chi tiết kèm theo hình ảnh

Chúng tôi sắp hoàn tất. Hãy hoàn tất bước cuối cùng bằng cách xác định hàm sendBoardingPass(imageUrl, msisdn). Hàm này sẽ tạo một thẻ thông tin chi tiết về RBM bằng cách sử dụng hình ảnh đã tạo ở bước trước và gửi cho người dùng.

Để gửi thẻ rich bằng RBM, tôi sử dụng cùng một SDK Node.js có sẵn trong First Agent Sample.

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);
}

Dưới đây là ảnh chụp màn hình kết quả cuối cùng.

Hình ảnh động trong thẻ rich

Tóm tắt & TL;DR

Cách đơn giản nhất để thẻ đa phương tiện linh hoạt hơn là tận dụng HTML động và chuyển đổi HTML thành hình ảnh. Hầu hết các ngôn ngữ lập trình hiện đại đều hỗ trợ các thư viện hoặc API giúp bạn hoàn tất lượt chuyển đổi. Bạn có thể cần thử thay đổi kích thước hình ảnh để có được kích thước phù hợp với trường hợp sử dụng của mình. Tuy nhiên, đây là một phương pháp tuyệt vời để tạo hình ảnh hấp dẫn hơn trong nhân viên hỗ trợ RBM.

Chúc bạn may mắn và lập trình vui vẻ!