All files / src/components/Messaging/Message index.js

87.04% Statements 47/54
87.5% Branches 35/40
83.33% Functions 10/12
89.36% Lines 42/47
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134                20x 1x   19x 19x 19x 19x 19x 19x 18x 18x 18x 18x       29x                             8x       14x 14x       1x   1x       15x 29x   29x 4x   25x           48x 115x   48x       15x       11x   1x 1x           1x       1x   1x       10x       10x           10x 10x 10x     11x                       11x       11x 11x          
import FormData from 'form-data';
import Recipient from './Recipient';
import { MESSAGING_TYPE, MAX_QUICK_REPLIES } from '../constants';
 
class Message {
  children = [];
 
  constructor(root, props) {
    if (!props.recipient) {
      throw new Error('Message must have recipient');
    }
    this.root = root;
    this.props = props;
    this.texts = [];
    this.attachment = null;
    this.type = props.type || MESSAGING_TYPE.RESPONSE;
    this.recipient = new Recipient(props.recipient);
    this.notificationType = props.notificationType || false;
    this.tag = props.tag || false;
    this.formData = null;
    this.quick_replies = [];
  }
 
  appendChild(child) {
    this.children.push(child);
  }
 
  removeChild(child) {
    this.children.splice(
      this.children.indexOf(child),
      1
    );
  }
 
  addText(text) {
    this.texts.push(text);
  }
 
  addAttachment(attachment) {
    this.attachment = attachment;
  }
 
  addQuickreply(quickreply) {
    this.quick_replies.push(quickreply);
    if (this.quick_replies.length > MAX_QUICK_REPLIES) throw new Error('Exceed max quickreplies allow');
  }
 
  useFormdata(formOptions = {}) {
    this.formData = new FormData(formOptions);
 
    return this.formData;
  }
 
  renderChildren() {
    this.children.forEach((child) => {
      Iif (typeof child === 'string') {
        this.texts.push(child);
      } else if (child.constructor.name === 'Text') {
        this.texts.push(child.render(this));
      } else {
        child.render(this);
      }
    });
  }
 
  removeEmpty(obj) {
    Object.keys(obj).forEach(key =>
      (obj[key] && typeof obj[key] === 'object') && this.removeEmpty(obj[key]) ||
      (obj[key] === undefined) && delete obj[key]); // eslint-disable-line
    return obj;
  }
 
  render() {
    this.renderChildren();
 
    let output;
 
    if (this.formData) {
      // handle upload method
      this.formData.append('recipient', JSON.stringify(this.recipient));
      Iif (this.quick_replies.length) {
        this.formData.append('message', JSON.stringify({
          attachment: this.attachment.attachment,
          quick_replies: this.quick_replies
        }));
      } else {
        this.formData.append('message', JSON.stringify({
          attachment: this.attachment.attachment
        }));
      }
      this.formData.append('filedata', this.attachment.filedata);
 
      output = this.formData;
    } else {
      // normal json object
 
      Iif (this.texts.length && this.attachment) {
        throw new Error('Message will only accept Text or Attachment, not both');
      }
 
      output = {
        messaging_type: this.type,
        recipient: this.recipient,
        message: {}
      };
 
      if (this.texts.length) output.message.text = this.texts.join('\n');
      if (this.attachment) output.message = this.attachment;
      if (this.quick_replies.length) output.message.quick_replies = this.quick_replies;
    }
 
    Iif (this.notificationType) output.notifciation_type = this.notificationType;
 
    // this.formData.append('recipient', this.recipient);
    /*
      Todo:
      implements:
      Supported Message Types
      Only generic template messages can be sent with tags other than ISSUE_RESOLUTION.
      ISSUE_RESOLUTION tag can be used with either generic template messages or text messages.
 
      ref: https://developers.facebook.com/docs/messenger-platform/send-messages/message-tags
    */
    Iif (this.tag) output.tag = this.tag;
 
 
    // sanity the ouput
    if (!this.formData) this.removeEmpty(output);
    return output;
  }
}
 
export default Message;