text: 
  const RichEmbed = require('./RichEmbed.js');
  
  
  /**
   * Represents a Message on Discord.
   * @class
   * @param {String} data The raw data gotten from Discord
   * @param {String} client The client the Message belongs to
   */
  class Message {
  
  	constructor(data, client) {
  
  		// Message info
  
  		/**
           * The ID of a Message
           * @type {String}
           * @readonly
           */
  		this.id = data.id;
  
  		/**
           * Whether or not the Message is pinned
           * @type {Boolean}
           * @readonly
           */
  		this.isPinned = data.pinned;
  
  		/**
           * The ISO8601 timestamp of the Message
           * @type {Timestamp}
           * @readonly
           */
  		this.timestamp = data.timestamp;
  
  		/**
           * The content of the Message
           * @type {String}
           * @readonly
           */
  		this.content = data.content;
  
  		// Booleans that are undefined sometimes
  
  		/**
           * Whether or not the message is TTS (Text To Speech)
           * @type {Boolean}
           * @readonly
           */
  		data.tss ?
  			this.isTTS = true : this.isTTS = false;
  
  		/**
           * Whether or not the Message was edited
           * @type {Boolean}
           * @readonly
           */
  		data.edited_timestamp ?
  			this.isEdited = true : this.isEdited = false;
  
  		// Just a single channel thing, maybe add full channel at one point if i add the cache
  
  		/**
           * The ID of the Channel the Message was sent in
           * @type {String}
           * @readonly
           */
  		this.channelId = data.channel_id;
  
  		// Idem to channel
  
  		/**
           * The ID of the Guild (server) the Message was sent in
           * @type {?String}
           * @readonly
           */
  		this.guildId = data.guild_id;
  
  		// User and Member shit
  
  		/**
           * The Member who sent the Message
           * @type {?Member}
           * @readonly
           */
  		this.member = data.member;
  
  		/**
           * The User who sent the Message
           * @type {User}
           * @readonly
           */
  		this.user = data.author;
  
  		// TODO: make classes for channels, members, users and roles
  		// TODO: make class for attachments
  		// Mention shit, made it for loop cuz it needs to push a class eventually
  
  		/**
           * The mentions that Message had, further split up into Members, Channels, and Roles
           * @type {Object}
           * @readonly
           */
  		this.mentions = new Object();
  
  		/**
           * The Member mentions the Message had
           * @type {Array<Member>}
           * @readonly
           */
  		this.mentions.members = [ ];
  
  		/**
           * The Channel mentions the Message had
           * @type {Array<Channel>}
           * @readonly
           */
  		this.mentions.channels = [ ];
  
  		/**
           * The Role mentions the Message had
           * @type {Array<Role>}
           * @readonly
           */
  		this.mentions.roles = [ ];
  
  		// TODO: Create subclasses for these
  		if(data.mentions) {
  			for(let i = 0; i < data.mentions.length; ++i)
  				this.mentions.members.push(data.mentions[i]);
  		}
  
  		if(data.mention_channels) {
  			for(let i = 0; i < data.mention_channels.length; ++i)
  				this.mentions.channels.push(data.mention_channels[i]);
  		}
  
  		if(data.mention_roles) {
  			for(let i = 0; i < data.mention_roles.length; ++i)
  				this.mentions.roles.push(data.mention_roles[i]);
  		}
  
  		// Attachments, idem to mentions
  
  		/**
           * The Attachments the Message had
           * @type {Array<Attachment>}
           * @readonly
           */
  		this.attachments = [ ];
  
  		// TODO: Add Attachments class and push those
  		if(data.attachments) {
  			for(let i = 0; i < data.attachments.length; ++i)
  				this.attachments.push(data.attachments[i]);
  		}
  
  
  		/**
  		 * All rich embeds in a message
  		 * @type {Array<RichEmbed>}
  		 * @readonly
  		 */
  		this.richEmbeds = [ ];
  
  		if(data.embeds) {
  			for(let i = 0; i < data.embeds.length; ++i)
  				data.embeds[i].type === 'rich' ? this.richEmbeds.push(new RichEmbed(data.embeds[i])) : null;
  		}
  
  		// Pass on client for convinience
  
  		/**
           * The Client of the Message
           * @type {Client}
           * @readonly
           */
  		this.client = client;
  	}
  
  	/**
  	 * Convenience method to get Message links
  	 * @returns {String} The resolved message link
  	 *
  	 * @example
  	 * client.on('message', (message) => {
  	 * 	console.log(`Got message, link: ${message}`);
  	 * 	// => Got message, link: LINK_TO_MESSAGE
  	 * });
  	 */
  	toString() {
  		return `https://discord.com/channels/${this.guildId}/${this.channelId}/${this.id}`;
  	}
  
  	/**
       * Send a Message to the same Channel the Message was sent in
       * @param {string|RichEmbed} content The Message or Embed to send
       * @param {Object} options The options, see {@link RawManager#createMessage}
       * @returns {Promise<Message>} The sent Message
       */
  	async return(content, opts = { }) {
  		if(content instanceof RichEmbed) {
  			opts.embed = content;
  			content = '';
  		}
  
  		opts.guildId = this.guildId;
  		opts.member = this.member;
  
  		return (await this.client.req.createMessage(this.channelId, content, opts));
  	}
  
  	/**
       * Edits a Message on discord
       * @param {string|RichEmbed} content The new Message or Embed to update the Message with
       * @param {Object} options The options
       * @returns {Promise<Message>} The Message that was edited
       */
  	async edit(content, opts = { }) {
  		// If its an embed...
  		if(content instanceof RichEmbed) {
  			opts.embed = content;
  			content = '';
  		}
  
  		const data = await this.client.req.perform('editMessage', { channelid: this.channelId, messageid: this.id,
  			body: {
  				content: content,
  				embed: opts.embed,
  			} });
  		return new Message({ ...this, ...data.body }, this.client);
  	}
  
  	/**
       * Deletes the Message
       * @returns {Promise<void>} Resolves when the Message is deleted
       */
  	async delete() {
  		return (await this.client.req.perform('deleteMessage', { channelid: this.channelId, messageid: this.id }));
  	}
  
  	/**
       * Pins the Message to the Channel it's in
       * @returns {Promise<void>} Resolves when Message is pinned
       */
  	async pin() {
  		return (await this.client.req.perform('pinMessage', { channelid: this.channelId, messageid: this.id }));
  	}
  
  	/**
       * Unpins the Message from the Channel it's in
       * @returns {Promise<void>} Resolves when the Message is unpinned
       */
  	async unpin() {
  		return (await this.client.req.perform('unpinMessage', { channelid: this.channelId, messageid: this.id }));
  	}
  
  	/**
  	 * A shortcut to {@link Client#fetchChannel}
  	 * @returns {Promise<Channel>}
  	 */
  	async fetchChannel() {
  		return (await this.client.fetchChannel(this.channelId));
  	}
  
  	/**
  	 * Crossposts the Message
  	 * @returns {Promise<Message>} The Message that was crossposted
  	 */
  	crosspost() {
  		const data = this.client.req.perform('crosspost', { channelid: this.channelId, messageid: this.id });
  		return new Message(data, this.client);
  	}
  
  	/**
       * Quote the Message and send another Message back
       * @param {string|RichEmbed} content The Message or Embed to send
       * @param {Object} options The options
       * @returns {Promise<Message>} The Message that was sent
       */
  	async quote(content, opts = { }) {
  		if(content instanceof RichEmbed) {
  			opts.embed = content;
  			content = `> ${this.content}\n<@${this.user.id}> `;
  		}
  		else {
  			content = `> ${this.content}\n<@${this.user.id}> ${content}`;
  		}
  
  		return (await this.return(content, opts));
  	}
  
  }
  
  
  module.exports = Message;