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.*; 034import com.restfb.types.webhook.whatsapp.WhatsappMessagesValue; 035 036/** 037 * Factory to convert the value field of the change into a class with special fields 038 */ 039public class ChangeValueFactory { 040 041 private String field; 042 043 private JsonValue value; 044 045 private ChangeValue.Verb userObjectVerb; 046 047 public ChangeValueFactory setField(String field) { 048 this.field = field; 049 return this; 050 } 051 052 public ChangeValueFactory setValue(String value) { 053 if (value != null && (value.startsWith("{") || value.startsWith("["))) { 054 this.value = Json.parse(value); 055 } else { 056 this.value = Json.value(value); 057 } 058 059 return this; 060 } 061 062 public ChangeValueFactory setUserObjectVerb(ChangeValue.Verb userObjectVerb) { 063 this.userObjectVerb = userObjectVerb; 064 return this; 065 } 066 067 public ChangeValue buildWithMapper(JsonMapper mapper) { 068 069 if (value.isString()) { 070 return new SimpleStringChangeValue(value.asString()); 071 } 072 073 if (value.isArray()) { 074 return new ListJsonChangeValue(value.asArray().values()); 075 } 076 077 if (value.isObject()) { 078 079 JsonObject objValue = value.asObject(); 080 String classDefinition; 081 if (objValue != null && field != null) { 082 classDefinition = field.toUpperCase(); 083 if (objValue.get("item") != null) { 084 classDefinition += "_" + objValue.get("item").asString().toUpperCase(); 085 } 086 if (objValue.get("verb") != null) { 087 classDefinition += "_" + objValue.get("verb").asString().toUpperCase(); 088 } 089 if (userObjectVerb != null) { 090 classDefinition += "_" + userObjectVerb.name(); 091 } 092 if (objValue.get("messaging_product") != null) { 093 classDefinition += "_" + objValue.get("messaging_product").asString().toUpperCase(); 094 } 095 096 // special handling for permissions 097 String verbString = (objValue.get("verb") != null && objValue.get("verb").isString()) ? objValue.get("verb").asString() : ""; 098 if (verbString.equals("granted") || verbString.equals("revoked")) { 099 classDefinition = verbString.toUpperCase(); 100 } 101 102 try { 103 ChangeValueEnumeration changeValueEnum = ChangeValueEnumeration.valueOf(classDefinition); 104 return mapper.toJavaObject(objValue.toString(), changeValueEnum.getValueClass()); 105 } catch (IllegalArgumentException iae) { 106 VALUE_FACTORY_LOGGER.warn("undefined change value detected: {}", classDefinition); 107 VALUE_FACTORY_LOGGER.warn("please provide this information to the restfb team: {}", objValue.toString()); 108 return new FallBackChangeValue(objValue); 109 } 110 } 111 } 112 113 return null; 114 } 115 116 enum ChangeValueEnumeration { 117 FEED_ALBUM_ADD(FeedAlbumAddValue.class), // 118 FEED_ALBUM_EDITED(FeedAlbumEditedValue.class), // 119 FEED_COMMENT_ADD(FeedCommentValue.class), // 120 FEED_COMMENT_EDITED(FeedCommentValue.class), // 121 FEED_COMMENT_REMOVE(FeedCommentValue.class), // 122 FEED_COMMENT_HIDE(FeedCommentValue.class), // 123 FEED_COMMENT_UNHIDE(FeedCommentValue.class), // 124 FEED_EVENT_ADD(FeedEventValue.class), // 125 FEED_PHOTO_ADD(FeedPhotoAddValue.class), // 126 FEED_PHOTO_REMOVE(FeedPhotoRemoveValue.class), // 127 FEED_PHOTO_EDITED(FeedPhotoAddValue.class), // 128 FEED_PHOTO_HIDE(FeedPhotoAddValue.class), // 129 FEED_PHOTO_UNHIDE(FeedPhotoAddValue.class), // 130 FEED_VIDEO_ADD(FeedVideoValue.class), // 131 FEED_VIDEO_EDITED(FeedVideoValue.class), // 132 FEED_VIDEO_HIDE(FeedVideoValue.class), // 133 FEED_VIDEO_UNHIDE(FeedVideoValue.class), // 134 FEED_VIDEO_REMOVE(FeedVideoRemoveValue.class), // 135 FEED_VIDEO_UNBLOCK(FeedVideoBlockMute.class), // 136 FEED_VIDEO_BLOCK(FeedVideoBlockMute.class), // 137 FEED_VIDEO_MUTE(FeedVideoBlockMute.class), // 138 FEED_STATUS_ADD(FeedStatusValue.class), // 139 FEED_STATUS_EDITED(FeedStatusValue.class), // 140 FEED_STATUS_HIDE(FeedStatusValue.class), // 141 FEED_STATUS_UNHIDE(FeedStatusValue.class), // 142 FEED_POST_ADD(FeedPostValue.class), // 143 FEED_POST_EDITED(FeedPostValue.class), // 144 FEED_POST_EDIT(FeedPostValue.class), // 145 FEED_POST_HIDE(FeedPostValue.class), // 146 FEED_POST_REMOVE(FeedPostValue.class), // 147 FEED_POST_UNHIDE(FeedPostValue.class), // 148 FEED_REACTION_ADD(FeedReactionValue.class), // 149 FEED_REACTION_EDIT(FeedReactionValue.class), // 150 FEED_REACTION_REMOVE(FeedReactionValue.class), // 151 FEED_SHARE_ADD(FeedShareValue.class), // 152 FEED_SHARE_EDITED(FeedShareValue.class), // 153 FEED_SHARE_HIDE(FeedShareValue.class), // 154 FEED_SHARE_REMOVE(FeedShareValue.class), // 155 FEED_SHARE_UNHIDE(FeedShareValue.class), // 156 FEED_LIKE_ADD(FeedLikeValue.class), // 157 FEED_LIKE_REMOVE(FeedLikeValue.class), // 158 MENTION_POST_ADD(MentionPostAddValue.class), // 159 MENTION_COMMENT_ADD(MentionCommentAddValue.class), // 160 RATINGS_RATING_ADD(RatingsRatingValue.class), // 161 RATINGS_RATING_EDIT(RatingsRatingValue.class), // 162 RATINGS_RATING_REMOVE(RatingsRatingValue.class), // 163 RATINGS_COMMENT_ADD(RatingsCommentValue.class), // 164 RATINGS_COMMENT_EDITED(RatingsCommentValue.class), // 165 RATINGS_COMMENT_REMOVE(RatingsCommentValue.class), // 166 RATINGS_LIKE_ADD(RatingsLikeValue.class), // 167 RATINGS_LIKE_REMOVE(RatingsLikeValue.class), // 168 RATINGS_REACTION_ADD(RatingsReactionValue.class), // 169 RATINGS_REACTION_REMOVE(RatingsReactionValue.class), // 170 RATINGS_REACTION_EDIT(RatingsReactionValue.class), // 171 LEADGEN(PageLeadgen.class), // 172 173 // Instagram 174 STORY_INSIGHTS(InstagramStoryInsightsValue.class), // 175 MENTIONS(InstagramMentionsValue.class), // 176 COMMENTS(InstagramCommentsValue.class), // 177 LIVE_COMMENTS(InstagramCommentsValue.class), // 178 179 // User 180 HOMETOWN_ADD(UserPageValue.class), // 181 MOVIES_ADD(UserPageValue.class), // 182 LIKES_ADD(UserPageValue.class), // 183 LOCATION_ADD(UserPageValue.class), // 184 TELEVISION_ADD(UserPageValue.class), // 185 GRANTED(PermissionChangeValue.class), // 186 REVOKED(PermissionChangeValue.class), // 187 188 // Whatsapp Business Account 189 MESSAGE_TEMPLATE_STATUS_UPDATE(MessageTemplateStatusUpdateValue.class), // 190 PHONE_NUMBER_NAME_UPDATE(PhoneNumberNameUpdateValue.class), // 191 PHONE_NUMBER_QUALITY_UPDATE(PhoneNumberQualityUpdateValue.class), // 192 ACCOUNT_UPDATE(AccountUpdateValue.class), // 193 ACCOUNT_REVIEW_UPDATE(AccountReviewUpdateValue.class),// 194 195 // Whatsapp Business Platform 196 MESSAGES_WHATSAPP(WhatsappMessagesValue.class); 197 198 private Class<ChangeValue> valueClass; 199 200 ChangeValueEnumeration(Class valueClass) { 201 this.valueClass = valueClass; 202 } 203 204 public Class<ChangeValue> getValueClass() { 205 return valueClass; 206 } 207 } 208}