webshot.ts 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. import * as log4js from 'log4js';
  2. import * as webshot from 'webshot';
  3. import * as read from 'read-all-stream';
  4. import {PNG} from 'pngjs';
  5. const logger = log4js.getLogger('webshot');
  6. logger.level = 'info';
  7. function renderWebshot(url: string, height: number): Promise<string> {
  8. let promise = new Promise<{ data: string, boundary: null | number }>(resolve => {
  9. const options = {
  10. windowSize: {
  11. width: 1080,
  12. height: height,
  13. },
  14. userAgent: 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36',
  15. renderDelay: 5000,
  16. quality: 100,
  17. customCSS: 'html{zoom:2}header{display:none!important}',
  18. };
  19. webshot(url, options).pipe(new PNG({
  20. filterType: 4
  21. }))
  22. .on('parsed', function () {
  23. let boundary = null;
  24. for (let y = 0; y < this.height; y++) {
  25. const x = 0;
  26. let idx = (this.width * y + x) << 2;
  27. if (this.data[idx] !== 255) {
  28. boundary = y;
  29. break;
  30. }
  31. }
  32. if (boundary != null) {
  33. this.data = this.data.slice(0, (this.width * boundary) << 2);
  34. this.height = boundary;
  35. read(this.pack(), 'base64').then(data => {
  36. resolve({ data, boundary });
  37. });
  38. } else {
  39. resolve({ data: '', boundary });
  40. }
  41. });
  42. });
  43. return promise.then(data => {
  44. if (data.boundary != null) return renderWebshot(url, height * 2);
  45. else return data.data;
  46. })
  47. }
  48. /*function fetchImage(): Promise<string> {
  49. }*/
  50. export default function (twitter, callback) {
  51. twitter.forEach(twi => {
  52. const url = `https://mobile.twitter.com/${twi.user.screen_name}/status/${twi.id_str}`;
  53. renderWebshot(url, 1920)
  54. .then(base64Webshot => {
  55. console.log(base64Webshot);
  56. })
  57. });
  58. }