const Utils = require("../utils/Utils.js");
const Util = new Utils();
/**
* Create a custom embed
*
* @example
* const { Embed } = require("interactions.js");
*
* const embed = new Embed()
* .setTitle('This is a Title')
* .setURL('https://github.com/fb-sean/interactions.js')
* .setColor('#31B505')
* .setAuthor("This is a Author", null, "https://github.com/fb-sean/interactions.js");
*
*/
class Embed {
constructor() {
/**
* The data of this embed
* @type {{image: Object, thumbnail: Object, color: (string|number), footer: Object, author: Object, description: ?string, title: ?string, fields: Array, url: ?string, timestamp: (number|null)}}
* @private
*/
this.data = {
/**
* the id of this user
* @type {string|number}
* @private
*/
color: 0x585858,
/**
* the title of the embed
* @type {?string}
* @private
*/
title: null,
/**
* the url of the title in the embed
* @type {?string}
* @private
*/
url: null,
/**
* the author object in the embed
* @type {object}
* @private
*/
author: {
name: null,
icon_url: null,
url: null
},
/**
* the description of the embed
* @type {?string}
* @private
*/
description: null,
/**
* the thumbnail of the embed
* @type {object}
* @private
*/
thumbnail: {
url: null
},
/**
* An array of fields for the embed
* @type {array}
* @private
*/
fields: [],
/**
* the image of the embed
* @type {object}
* @private
*/
image: {
url: null
},
/**
* the timestamp for the embed
* @type {number|null}
* @private
*/
timestamp: null,
/**
* the footer of the embed
* @type {object}
* @private
*/
footer: {
text: null,
icon_url: null
}
};
}
/**
* Sets the title of this embed
*
* @param {String} title The title
* @return {Embed}
*/
setTitle(title) {
if (!title || typeof title != 'string') {
throw new Error("[Interactions.js => <Embed>.setTitle] The Title need to be a string.");
}
this.data.title = title;
return this;
}
/**
* Sets the URL of this embed
*
* @param {String} url The URL
* @return {Embed}
*/
setURL(url) {
if (!Util.checkURL(url)) {
throw new Error("[Interactions.js => <Embed>.setURL] The URL isn't a valid URL. (Need to start with 'http' or 'https')");
}
this.data.url = url;
return this;
}
/**
* Sets the color of this embed
*
* @param {String} color The color of the embed
* @return {Embed}
*/
setColor(color) {
if (!color) {
throw new Error("[Interactions.js => <Embed>.setColor] You need to provide a color.");
}
this.data.color = Util.resolveColor(color);
return this;
}
/**
* Sets the author of this embed
*
* @param {String} name The name for the author
* @param {String} iconUrl The icon url for the author
* @param {String} url The url for the author
* @return {Embed}
*/
setAuthor(name, iconUrl, url) {
if (!name || typeof name != 'string') {
throw new Error("[Interactions.js => <Embed>.setAuthor] The Author Name need to be a String.");
}
if (url && !Util.checkURL(url)) {
throw new Error("[Interactions.js => <Embed>.setAuthor] The Author URL isn't a valid URL. (Need to start with 'http' or 'https')");
}
if (iconUrl && !Util.checkURL(iconUrl)) {
throw new Error("[Interactions.js => <Embed>.setAuthor] The Author Icon URL isn't a valid URL. (Need to start with 'http' or 'https')");
}
this.data.author = {
name: name ?? null,
icon_url: iconUrl ?? null,
url: url ?? null,
};
return this;
}
/**
* Sets the description of this embed
*
* @param {String} desc The description
* @return {Embed}
*/
setDescription(desc) {
if (!desc || typeof desc != 'string') {
throw new Error("[Interactions.js => <Embed>.setDescription] The Description need to be a String.");
}
if (desc.length > 4096) {
throw new Error("[Interactions.js => <Embed>.setDescription] The Description is too long (4096 is the max length).");
}
this.data.description = desc;
return this;
}
/**
* Sets the thumbnail of this embed
*
* @param {String} url The URL of the thumbnail
* @return {Embed}
*/
setThumbnail(url) {
if (!url || !Util.checkURL(url, true)) {
throw new Error("[Interactions.js => <Embed>.setThumbnail] The Thumbnail isn't a valid Image URL. (Need to start with 'attachment', 'http' or 'https')");
}
this.data.thumbnail = {
url: url,
};
return this;
}
/**
* Sets the embed's fields
* You can set a maximum of 25 fields.
*
* @param {Array} ArrayOfFields fields The fields to set
* @return {Embed}
*/
setFields(ArrayOfFields) {
if (!ArrayOfFields || !Array.isArray(ArrayOfFields)) {
throw new Error("[Interactions.js => <Embed>.setFields] The input need to be an array.");
}
if (ArrayOfFields.length >= 25) {
throw new Error("[Interactions.js => <Embed>.setFields] You try to set an array that is over max fields value. [max 25 fields]");
}
const wrongFields = [];
for (let i = 0; i < ArrayOfFields.length; i++) {
const field = ArrayOfFields[i];
let noName = false;
if (!field?.name || typeof field?.name != 'string') {
noName = true;
}
let noValue = false;
if (!field?.value || typeof field?.value != 'string') {
noValue = true;
}
if (noValue || noName) {
wrongFields.push(`${i}`);
}
}
if (wrongFields.length > 0) {
throw new Error("[Interactions.js => <Embed>.setFields] Found some problems in the Array at postition: " + wrongFields.join(", ") + ".");
}
this.data.fields = ArrayOfFields;
return this;
}
/**
* Appends fields to the embed
* You can have a maximum of 25 fields.
*
* @example
* const embed = new Embed()
* .addFields(ArrayOfFields);
*
* @param {Array} ArrayOfFields fields The fields to add
* @return {Embed}
*/
addFields(ArrayOfFields) {
if (!ArrayOfFields || !Array.isArray(ArrayOfFields)) {
throw new Error("[Interactions.js => <Embed>.addFields] The input need to be an array.");
}
if (this.data.fields.length >= 25) {
throw new Error("[Interactions.js => <Embed>.addFields] This embed reached the max value for fields. [max 25 fields]");
}
if ((this.data.fields.length + ArrayOfFields.length) >= 25) {
throw new Error("[Interactions.js => <Embed>.addFields] By adding this array it would go over the max value of fields. [max 25 fields]");
}
const wrongFields = [];
for (let i = 0; i < ArrayOfFields.length; i++) {
const field = ArrayOfFields[i];
let noName = false;
if (!field?.name || typeof field?.name != 'string') {
noName = true;
}
let noValue = false;
if (!field?.value || typeof field?.value != 'string') {
noValue = true;
}
if (noValue || noName) {
wrongFields.push(`${i}`);
}
}
if (wrongFields.length > 0) {
throw new Error("[Interactions.js => <Embed>.addFields] Found some problems in the Array at postition: " + wrongFields.join(", ") + ".");
}
this.data.fields = this.data.fields.concat(ArrayOfFields);
return this;
}
/**
* Add a field to the embed
*
* You can have a maximum of 25 fields.
*
* @param {String} name The field name
* @param {String} value The field value
* @param {Boolean} inline boolean if the embed should be inline
* @return {Embed}
*/
addField(name, value, inline = false) {
if (this.data.fields.length >= 25) {
throw new Error("[Interactions.js => <Embed>.addField] This embed reached the max value for fields. [max 25 fields]");
}
if (!name || typeof name != 'string') {
throw new Error("[Interactions.js => <Embed>.addField] The Field Name need to be a string.");
}
if (!value || typeof value != 'string') {
throw new Error("[Interactions.js => <Embed>.addField] The Field Value need to be a string.");
}
this.data.fields = this.data.fields.concat([{
name,
value,
inline
},]);
return this;
}
/**
* Sets the image of this embed
*
* @param {String} url The URL of the image
* @return {Embed}
*/
setImage(url) {
if (!url || !Util.checkURL(url, true)) {
throw new Error("[Interactions.js => <Embed>.setImage] The Image isn't a valid Image URL. (Need to start with 'attachment', 'http' or 'https')");
}
this.data.image = {
url: url,
};
return this;
}
/**
* Sets the timestamp of this embed
*
* @param {String} timestamp The timestamp or date
* @return {Embed}
*/
setTimestamp(timestamp) {
if (!timestamp) timestamp = new Date();
this.data.timestamp = timestamp ? new Date(timestamp).toISOString() : undefined;
return this;
}
/**
* Sets the footer of this embed
*
* @param {String} text The name for the footer
* @param {String} iconUrl The iconUrl for the footer
* @return {Embed}
*/
setFooter(text, iconUrl) {
if (!text || typeof text != 'string') {
throw new Error("[Interactions.js => <Embed>.setFooter] The Author text need to be a String.");
}
if (iconUrl && !Util.checkURL(iconUrl)) {
throw new Error("[Interactions.js => <Embed>.setFooter] The Author Icon URL isn't a valid URL. (Need to start with 'http' or 'https')");
}
this.data.footer = {
text: text ?? null,
icon_url: iconUrl ?? null,
};
return this;
}
/**
* return the embed as json
* @return {Object} The embed as json
* @private
*/
toJSON() {
return { ...this.data };
}
}
module.exports = Embed;