/**
* Contacts API object
*
* @property {Array<Object>} contacts The contacts of the message
* @property {String} _ The type of the object, for internal use only
*/
class Contacts {
/**
* Create a Contacts object for the API
*
* @param {...Array<(Address|Birthday|Email|Name|Organization|Phone|Url)>} contact Array of contact's components
* @throws {Error} If contact is not provided
* @throws {Error} If contact contains more than one name component
* @throws {Error} If contact contains more than one birthday component
* @throws {Error} If contact contains more than one organization component
*/
constructor(...contact) {
if (!contact.length) throw new Error("Contacts must have at least one contact");
this.contacts = [];
for (const components of contact) {
const contact = {};
for (const component of components) {
const name = component._;
delete component._;
if (name === "birthday") if (!contact.birthday) contact.birthday = component.birthday; else throw new Error("Contacts can only have one birthday component");
else if (name === "name") if (!contact.name) contact.name = component; else throw new Error("Contacts can only have one name component");
else if (name === "org") if (!contact.org) contact.org = component; else throw new Error("Contacts can only have one organization component");
else {
if (!contact[name]) contact[name] = [];
contact[name].push(component);
}
}
if (!contact.name) throw new Error("Contact must have a name component");
this.contacts.push(contact);
}
this._ = "contacts";
}
}
/**
* Address API object
*
* @property {String} [country] The country of the address
* @property {String} [country_code] The country code of the address
* @property {String} [state] The state of the address
* @property {String} [city] The city of the address
* @property {String} [street] The street of the address
* @property {String} [zip] The zip code of the address
* @property {String} [type] The type of the address
* @property {String} _ The type of the object, for internal use only
*/
class Address {
/**
* Builds an address object for a contact.
* A contact can contain multiple addresses objects.
*
* @param {String} [country] Full country name
* @param {String} [country_code] Two-letter country abbreviation
* @param {String} [state] State abbreviation
* @param {String} [city] City name
* @param {String} [street] Street number and name
* @param {String} [zip] ZIP code
* @param {String} [type] Address type. Standard Values: HOME, WORK
*/
constructor(country, country_code, state, city, street, zip, type) {
if (country) this.country = country;
if (country_code) this.country_code = country_code;
if (state) this.state = state;
if (city) this.city = city;
if (street) this.street = street;
if (zip) this.zip = zip;
if (type) this.type = type;
this._ = "addresses";
}
}
/**
* Birthday API object
*
* @property {String} birthday The birthday of the contact
* @property {String} _ The type of the object, for internal use only
*/
class Birthday {
/**
* Builds a birthday object for a contact
*
* @param {String} year Year of birth (YYYY)
* @param {String} month Month of birth (MM)
* @param {String} day Day of birth (DD)
* @throws {Error} If the year, month, or day don't have a valid length
*/
constructor(year, month, day) {
if (year?.length !== 4) throw new Error("Year must be 4 digits");
if (month?.length !== 2) throw new Error("Month must be 2 digits");
if (day?.length !== 2) throw new Error("Day must be 2 digits");
this.birthday = `${year}-${month}-${day}`;
this._ = "birthday";
}
}
/**
* Email API object
*
* @property {String} [email] The email of the contact
* @property {String} [type] The type of the email
* @property {String} _ The type of the object, for internal use only
*/
class Email {
/**
* Builds an email object for a contact.
* A contact can contain multiple emails objects.
*
* @param {String} [email] Email address
* @param {String} [type] Email type. Standard Values: HOME, WORK
*/
constructor(email, type) {
if (email) this.email = email;
if (type) this.type = type;
this._ = "emails";
}
}
/**
* Name API object
*
* @property {String} formatted_name The formatted name of the contact
* @property {String} [first_name] The first name of the contact
* @property {String} [last_name] The last name of the contact
* @property {String} [middle_name] The middle name of the contact
* @property {String} [suffix] The suffix of the contact
* @property {String} [prefix] The prefix of the contact
* @property {String} _ The type of the object, for internal use only
*/
class Name {
/**
* Builds a name object for a contact, required for contacts.
* The object requires a formatted_name and at least another property.
*
* @param {String} formatted_name Full name, as it normally appears
* @param {String} [first_name] First name
* @param {String} [last_name] Last name
* @param {String} [middle_name] Middle name
* @param {String} [suffix] Name suffix
* @param {String} [prefix] Name prefix
* @throws {Error} If formatted_name is not defined
* @throws {Error} If no other component apart from formatted_name is defined
*/
constructor(formatted_name, first_name, last_name, middle_name, suffix, prefix) {
if (!formatted_name) throw new Error("Name must have a formatted_name");
this.formatted_name = formatted_name;
if (first_name) this.first_name = first_name;
if (last_name) this.last_name = last_name;
if (middle_name) this.middle_name = middle_name;
if (suffix) this.suffix = suffix;
if (prefix) this.prefix = prefix;
if (Object.keys(this).length < 2) throw new Error("Name must have at least one of the following: first_name, last_name, middle_name, prefix, suffix");
this._ = "name";
}
}
/**
* Organization API object
*
* @property {String} [company] The company of the contact
* @property {String} [department] The department of the contact
* @property {String} [title] The title of the contact
* @property {String} _ The type of the object, for internal use only
*/
class Organization {
/**
* Builds an organization object for a contact
*
* @param {String} [company] Name of the contact's company
* @param {String} [department] Name of the contact's department
* @param {String} [title] Contact's business title
*/
constructor(company, department, title) {
if (company) this.company = company;
if (department) this.department = department;
if (title) this.title = title;
this._ = "org";
}
}
/**
* Phone API object
*
* @property {String} [phone] The phone number of the contact
* @property {String} [type] The type of the phone number
* @property {String} [wa_id] The WhatsApp ID of the contact
* @property {String} _ The type of the object, for internal use only
*/
class Phone {
/**
* Builds a phone object for a contact.
* A contact can contain multiple phones objects.
*
* @param {String} [phone] Phone number, automatically populated with the wa_id value as a formatted phone number
* @param {String} [type] Phone type. Standard Values: CELL, MAIN, IPHONE, HOME, WORK
* @param {String} [wa_id] WhatsApp ID
*/
constructor(phone, type, wa_id) {
if (phone) this.phone = phone;
if (type) this.type = type;
if (wa_id) this.wa_id = wa_id;
this._ = "phones";
}
}
/**
* Url API object
*
* @property {String} [url] The URL of the contact
* @property {String} [type] The type of the URL
* @property {String} _ The type of the object, for internal use only
*/
class Url {
/**
* Builds an url object for a contact.
* A contact can contain multiple urls objects.
*
* @param {String} [url] URL
* @param {String} [type] URL type. Standard Values: HOME, WORK
*/
constructor(url, type) {
if (url) this.url = url;
if (type) this.type = type;
this._ = "urls";
}
}
module.exports = { Contacts, Address, Birthday, Email, Name, Organization, Phone, Url };