001/* 002 * Copyright (c) 2010-2024 Mark Allen, Norbert Bartels. 003 * 004 * Permission is hereby granted, free of charge, to any person obtaining a copy 005 * of this software and associated documentation files (the "Software"), to deal 006 * in the Software without restriction, including without limitation the rights 007 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 008 * copies of the Software, and to permit persons to whom the Software is 009 * furnished to do so, subject to the following conditions: 010 * 011 * The above copyright notice and this permission notice shall be included in 012 * all copies or substantial portions of the Software. 013 * 014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 015 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 016 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 017 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 018 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 019 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 020 * THE SOFTWARE. 021 */ 022package com.restfb.types.webhook; 023 024import static com.restfb.logging.RestFBLogger.VALUE_FACTORY_LOGGER; 025 026import com.restfb.JsonMapper; 027import com.restfb.json.Json; 028import com.restfb.json.JsonObject; 029import com.restfb.json.JsonValue; 030import com.restfb.types.webhook.instagram.InstagramCommentsValue; 031import com.restfb.types.webhook.instagram.InstagramMentionsValue; 032import com.restfb.types.webhook.instagram.InstagramStoryInsightsValue; 033import com.restfb.types.webhook.whatsapp.*; 034 035/** 036 * Factory to convert the value field of the change into a class with special fields 037 */ 038public class ChangeValueFactory { 039 040 private String field; 041 042 private JsonValue value; 043 044 private ChangeValue.Verb userObjectVerb; 045 046 public ChangeValueFactory setField(String field) { 047 this.field = field; 048 return this; 049 } 050 051 public ChangeValueFactory setValue(String value) { 052 if (value != null && (value.startsWith("{") || value.startsWith("["))) { 053 this.value = Json.parse(value); 054 } else { 055 this.value = Json.value(value); 056 } 057 058 return this; 059 } 060 061 public ChangeValueFactory setUserObjectVerb(ChangeValue.Verb userObjectVerb) { 062 this.userObjectVerb = userObjectVerb; 063 return this; 064 } 065 066 public ChangeValue buildWithMapper(JsonMapper mapper) { 067 068 if (value.isString()) { 069 return new SimpleStringChangeValue(value.asString()); 070 } 071 072 if (value.isArray()) { 073 return new ListJsonChangeValue(value.asArray().values()); 074 } 075 076 if (value.isObject()) { 077 078 JsonObject objValue = value.asObject(); 079 String classDefinition; 080 if (objValue != null && field != null) { 081 classDefinition = field.toUpperCase(); 082 if (objValue.get("item") != null) { 083 classDefinition += "_" + objValue.get("item").asString().toUpperCase(); 084 } 085 if (objValue.get("verb") != null) { 086 classDefinition += "_" + objValue.get("verb").asString().toUpperCase(); 087 } 088 if (userObjectVerb != null) { 089 classDefinition += "_" + userObjectVerb.name(); 090 } 091 if (objValue.get("messaging_product") != null) { 092 classDefinition += "_" + objValue.get("messaging_product").asString().toUpperCase(); 093 } 094 095 // special handling for permissions 096 String verbString = (objValue.get("verb") != null && objValue.get("verb").isString()) ? objValue.get("verb").asString() : ""; 097 if (verbString.equals("granted") || verbString.equals("revoked")) { 098 classDefinition = verbString.toUpperCase(); 099 } 100 101 try { 102 ChangeValueEnumeration changeValueEnum = ChangeValueEnumeration.valueOf(classDefinition); 103 return mapper.toJavaObject(objValue.toString(), changeValueEnum.getValueClass()); 104 } catch (IllegalArgumentException iae) { 105 VALUE_FACTORY_LOGGER.warn("undefined change value detected: {}", classDefinition); 106 VALUE_FACTORY_LOGGER.warn("please provide this information to the restfb team: {}", objValue.toString()); 107 return new FallBackChangeValue(objValue); 108 } 109 } 110 } 111 112 return null; 113 } 114 115 enum ChangeValueEnumeration { 116 FEED_ALBUM_ADD(FeedAlbumAddValue.class), // 117 FEED_ALBUM_EDITED(FeedAlbumEditedValue.class), // 118 FEED_COMMENT_ADD(FeedCommentValue.class), // 119 FEED_COMMENT_EDITED(FeedCommentValue.class), // 120 FEED_COMMENT_REMOVE(FeedCommentValue.class), // 121 FEED_COMMENT_HIDE(FeedCommentValue.class), // 122 FEED_COMMENT_UNHIDE(FeedCommentValue.class), // 123 FEED_EVENT_ADD(FeedEventValue.class), // 124 FEED_PHOTO_ADD(FeedPhotoAddValue.class), // 125 FEED_PHOTO_REMOVE(FeedPhotoRemoveValue.class), // 126 FEED_PHOTO_EDITED(FeedPhotoAddValue.class), // 127 FEED_PHOTO_HIDE(FeedPhotoAddValue.class), // 128 FEED_PHOTO_UNHIDE(FeedPhotoAddValue.class), // 129 FEED_VIDEO_ADD(FeedVideoValue.class), // 130 FEED_VIDEO_EDITED(FeedVideoValue.class), // 131 FEED_VIDEO_HIDE(FeedVideoValue.class), // 132 FEED_VIDEO_UNHIDE(FeedVideoValue.class), // 133 FEED_VIDEO_REMOVE(FeedVideoRemoveValue.class), // 134 FEED_VIDEO_UNBLOCK(FeedVideoBlockMute.class), // 135 FEED_VIDEO_BLOCK(FeedVideoBlockMute.class), // 136 FEED_VIDEO_MUTE(FeedVideoBlockMute.class), // 137 FEED_STATUS_ADD(FeedStatusValue.class), // 138 FEED_STATUS_EDITED(FeedStatusValue.class), // 139 FEED_STATUS_HIDE(FeedStatusValue.class), // 140 FEED_STATUS_UNHIDE(FeedStatusValue.class), // 141 FEED_POST_ADD(FeedPostValue.class), // 142 FEED_POST_EDITED(FeedPostValue.class), // 143 FEED_POST_EDIT(FeedPostValue.class), // 144 FEED_POST_HIDE(FeedPostValue.class), // 145 FEED_POST_REMOVE(FeedPostValue.class), // 146 FEED_POST_UNHIDE(FeedPostValue.class), // 147 FEED_REACTION_ADD(FeedReactionValue.class), // 148 FEED_REACTION_EDIT(FeedReactionValue.class), // 149 FEED_REACTION_REMOVE(FeedReactionValue.class), // 150 FEED_SHARE_ADD(FeedShareValue.class), // 151 FEED_SHARE_EDITED(FeedShareValue.class), // 152 FEED_SHARE_HIDE(FeedShareValue.class), // 153 FEED_SHARE_REMOVE(FeedShareValue.class), // 154 FEED_SHARE_UNHIDE(FeedShareValue.class), // 155 FEED_LIKE_ADD(FeedLikeValue.class), // 156 FEED_LIKE_REMOVE(FeedLikeValue.class), // 157 MENTION_POST_ADD(MentionPostAddValue.class), // 158 MENTION_COMMENT_ADD(MentionCommentAddValue.class), // 159 RATINGS_RATING_ADD(RatingsRatingValue.class), // 160 RATINGS_RATING_EDIT(RatingsRatingValue.class), // 161 RATINGS_RATING_REMOVE(RatingsRatingValue.class), // 162 RATINGS_COMMENT_ADD(RatingsCommentValue.class), // 163 RATINGS_COMMENT_EDITED(RatingsCommentValue.class), // 164 RATINGS_COMMENT_REMOVE(RatingsCommentValue.class), // 165 RATINGS_LIKE_ADD(RatingsLikeValue.class), // 166 RATINGS_LIKE_REMOVE(RatingsLikeValue.class), // 167 RATINGS_REACTION_ADD(RatingsReactionValue.class), // 168 RATINGS_REACTION_REMOVE(RatingsReactionValue.class), // 169 RATINGS_REACTION_EDIT(RatingsReactionValue.class), // 170 LEADGEN(PageLeadgen.class), // 171 172 // Instagram 173 STORY_INSIGHTS(InstagramStoryInsightsValue.class), // 174 MENTIONS(InstagramMentionsValue.class), // 175 COMMENTS(InstagramCommentsValue.class), // 176 LIVE_COMMENTS(InstagramCommentsValue.class), // 177 178 // User 179 HOMETOWN_ADD(UserPageValue.class), // 180 MOVIES_ADD(UserPageValue.class), // 181 LIKES_ADD(UserPageValue.class), // 182 LOCATION_ADD(UserPageValue.class), // 183 TELEVISION_ADD(UserPageValue.class), // 184 GRANTED(PermissionChangeValue.class), // 185 REVOKED(PermissionChangeValue.class), // 186 187 // Whatsapp Business Account 188 MESSAGE_TEMPLATE_STATUS_UPDATE(MessageTemplateStatusUpdateValue.class), // 189 PHONE_NUMBER_NAME_UPDATE(PhoneNumberNameUpdateValue.class), // 190 PHONE_NUMBER_QUALITY_UPDATE(PhoneNumberQualityUpdateValue.class), // 191 ACCOUNT_UPDATE(AccountUpdateValue.class), // 192 ACCOUNT_REVIEW_UPDATE(AccountReviewUpdateValue.class),// 193 194 // Whatsapp Business Platform 195 MESSAGES_WHATSAPP(WhatsappMessagesValue.class); 196 197 private Class<ChangeValue> valueClass; 198 199 ChangeValueEnumeration(Class valueClass) { 200 this.valueClass = valueClass; 201 } 202 203 public Class<ChangeValue> getValueClass() { 204 return valueClass; 205 } 206 } 207}