001/*
002 *   Copyright 2024 Vonage
003 *
004 *   Licensed under the Apache License, Version 2.0 (the "License");
005 *   you may not use this file except in compliance with the License.
006 *   You may obtain a copy of the License at
007 *
008 *        http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *   Unless required by applicable law or agreed to in writing, software
011 *   distributed under the License is distributed on an "AS IS" BASIS,
012 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *   See the License for the specific language governing permissions and
014 *   limitations under the License.
015 */
016package com.vonage.client.messages.whatsapp;
017
018import com.fasterxml.jackson.annotation.JsonProperty;
019import com.vonage.client.messages.MessageType;
020import java.util.*;
021
022/**
023 * See <a href=https://developer.vonage.com/en/messages/concepts/whatsapp-product-messages>
024 * WhatsApp Product Messages documentation for details.</a>
025 *
026 * @since 7.2.0
027 */
028public final class WhatsappMultiProductRequest extends WhatsappRequest {
029
030        WhatsappMultiProductRequest(Builder builder) {
031                super(builder, MessageType.CUSTOM);
032                Map<String, Object> interactive = new LinkedHashMap<>(8);
033                interactive.put("type", "product_list");
034
035                Map<String, Object> header = new LinkedHashMap<>(4);
036                header.put("type", "text");
037                header.put("text", Objects.requireNonNull(
038                                builder.headerText, "Header text is required."
039                ));
040                interactive.put("header", header);
041
042                interactive.put("body", Collections.singletonMap("text", Objects.requireNonNull(
043                                builder.bodyText, "Body text is required."
044                )));
045                if (builder.footerText != null) {
046                        interactive.put("footer", Collections.singletonMap("text", builder.footerText));
047                }
048
049                Map<String, Object> action = new LinkedHashMap<>(4);
050                action.put("catalog_id", Objects.requireNonNull(
051                                builder.catalogId, "Catalog ID is required."
052                ));
053                if (builder.sections.isEmpty()) {
054                        throw new IllegalStateException("At least one product section should be specified.");
055                }
056                action.put("sections", builder.sections);
057                interactive.put("action", action);
058                custom.put("type", "interactive");
059                custom.put("interactive", interactive);
060        }
061
062        @JsonProperty("custom")
063        public Map<String, ?> getCustom() {
064                return custom;
065        }
066
067        public static Builder builder() {
068                return new Builder();
069        }
070
071        public static final class Builder extends WhatsappRequest.Builder<WhatsappMultiProductRequest, Builder> {
072                String bodyText, headerText, footerText, catalogId;
073                final List<ProductSection> sections = new ArrayList<>();
074
075                Builder() {}
076
077                /**
078                 * (REQUIRED)
079                 * ID for the catalog you want to use for this message. Retrieve this ID via Commerce Manager.
080                 *
081                 * @param catalogId The catalog ID.
082                 * @return This builder.
083                 */
084                public Builder catalogId(String catalogId) {
085                        this.catalogId = catalogId;
086                        return this;
087                }
088
089                /**
090                 * (REQUIRED)
091                 * Adds a grouping of products using their unique retail identifiers.
092                 * You must specify at least one section and at least one product per section.
093                 *
094                 * @param title The section title.
095                 * @param skus The list of product IDs in the catalog to include in the section.
096                 *
097                 * @return This builder.
098                 */
099                public Builder addProductsSection(String title, List<String> skus) {
100                        sections.add(new ProductSection(title, skus));
101                        return this;
102                }
103
104                /**
105                 * (REQUIRED)
106                 * Adds a grouping of products using their unique retail identifiers.
107                 * You must specify at least one section and at least one product per section.
108                 *
109                 * @param title The section title.
110                 * @param skus The list of product IDs in the catalog to include in the section.
111                 *
112                 * @return This builder.
113                 */
114                public Builder addProductsSection(String title, String... skus) {
115                        return addProductsSection(title, Arrays.asList(skus));
116                }
117
118                /**
119                 * (OPTIONAL)
120                 * Sets the message header's text field.
121                 *
122                 * @param headerText The header text.
123                 * @return This builder.
124                 */
125                public Builder headerText(String headerText) {
126                        this.headerText = headerText;
127                        return this;
128                }
129
130                /**
131                 * (REQUIRED)
132                 * The main message text.
133                 *
134                 * @param bodyText The body text.
135                 * @return This builder.
136                 */
137                public Builder bodyText(String bodyText) {
138                        this.bodyText = bodyText;
139                        return this;
140                }
141
142                /**
143                 * (OPTIONAL)
144                 * The text which appears at the end of the message.
145                 *
146                 * @param footerText The footer text.
147                 * @return This builder.
148                 */
149                public Builder footerText(String footerText) {
150                        this.footerText = footerText;
151                        return this;
152                }
153
154                @Override
155                public WhatsappMultiProductRequest build() {
156                        return new WhatsappMultiProductRequest(this);
157                }
158        }
159}