Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.github.messenger4j.Messenger Maven / Gradle / Ivy
// Generated by delombok at Tue May 07 22:31:27 CEST 2019
package com.github.messenger4j;
import static com.github.messenger4j.internal.gson.GsonUtil.Constants.PROP_ENTRY;
import static com.github.messenger4j.internal.gson.GsonUtil.Constants.PROP_MESSAGING;
import static com.github.messenger4j.internal.gson.GsonUtil.Constants.PROP_OBJECT;
import static com.github.messenger4j.internal.gson.GsonUtil.getPropertyAsJsonArray;
import static com.github.messenger4j.internal.gson.GsonUtil.getPropertyAsString;
import static com.github.messenger4j.spi.MessengerHttpClient.HttpMethod.DELETE;
import static com.github.messenger4j.spi.MessengerHttpClient.HttpMethod.GET;
import static com.github.messenger4j.spi.MessengerHttpClient.HttpMethod.POST;
import static java.util.Optional.empty;
import static java.util.Optional.of;
import com.github.messenger4j.exception.MessengerApiException;
import com.github.messenger4j.exception.MessengerApiExceptionFactory;
import com.github.messenger4j.exception.MessengerIOException;
import com.github.messenger4j.exception.MessengerVerificationException;
import com.github.messenger4j.internal.gson.GsonFactory;
import com.github.messenger4j.messengerprofile.DeleteMessengerSettingsPayload;
import com.github.messenger4j.messengerprofile.MessengerSettingProperty;
import com.github.messenger4j.messengerprofile.MessengerSettings;
import com.github.messenger4j.messengerprofile.SetupResponse;
import com.github.messenger4j.messengerprofile.SetupResponseFactory;
import com.github.messenger4j.send.MessageResponse;
import com.github.messenger4j.send.MessageResponseFactory;
import com.github.messenger4j.send.Payload;
import com.github.messenger4j.spi.MessengerHttpClient;
import com.github.messenger4j.spi.MessengerHttpClient.HttpMethod;
import com.github.messenger4j.spi.MessengerHttpClient.HttpResponse;
import com.github.messenger4j.userprofile.UserProfile;
import com.github.messenger4j.userprofile.UserProfileFactory;
import com.github.messenger4j.webhook.Event;
import com.github.messenger4j.webhook.SignatureUtil;
import com.github.messenger4j.webhook.factory.EventFactory;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Function;
import lombok.NonNull;
/**
* @author Max Grabenhorst
* @since 1.0.0
*/
public final class Messenger {
@java.lang.SuppressWarnings("all")
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(Messenger.class);
/** Constant for the {@code hub.mode} request parameter name. */
public static final String MODE_REQUEST_PARAM_NAME = "hub.mode";
/** Constant for the {@code hub.challenge} request parameter name. */
public static final String CHALLENGE_REQUEST_PARAM_NAME = "hub.challenge";
/** Constant for the {@code hub.verify_token} request parameter name. */
public static final String VERIFY_TOKEN_REQUEST_PARAM_NAME = "hub.verify_token";
/** Constant for the {@code X-Hub-Signature} header name. */
public static final String SIGNATURE_HEADER_NAME = "X-Hub-Signature";
private static final String OBJECT_TYPE_PAGE = "page";
private static final String HUB_MODE_SUBSCRIBE = "subscribe";
private static final String FB_GRAPH_API_URL_MESSAGES =
"https://graph.facebook.com/v3.2/me/messages?access_token=%s";
private static final String FB_GRAPH_API_URL_MESSENGER_PROFILE =
"https://graph.facebook.com/v3.2/me/messenger_profile?access_token=%s";
private static final String FB_GRAPH_API_URL_USER =
"https://graph.facebook.com/v3.2/%s?fields=first_name,last_name,profile_pic,locale,timezone,gender&access_token=%s";
private final String pageAccessToken;
private final String appSecret;
private final String verifyToken;
private final String messagesRequestUrl;
private final String messengerProfileRequestUrl;
private final MessengerHttpClient httpClient;
private final Gson gson;
private final JsonParser jsonParser;
private Messenger(
String pageAccessToken,
String appSecret,
String verifyToken,
Optional httpClient) {
this.pageAccessToken = pageAccessToken;
this.appSecret = appSecret;
this.verifyToken = verifyToken;
this.messagesRequestUrl = String.format(FB_GRAPH_API_URL_MESSAGES, pageAccessToken);
this.messengerProfileRequestUrl =
String.format(FB_GRAPH_API_URL_MESSENGER_PROFILE, pageAccessToken);
this.httpClient = httpClient.orElse(new DefaultMessengerHttpClient());
this.gson = GsonFactory.createGson();
this.jsonParser = new JsonParser();
}
public static Messenger create(
@NonNull String pageAccessToken, @NonNull String appSecret, @NonNull String verifyToken) {
if (pageAccessToken == null) {
throw new java.lang.IllegalArgumentException(
"pageAccessToken is marked @NonNull but is null");
}
if (appSecret == null) {
throw new java.lang.IllegalArgumentException("appSecret is marked @NonNull but is null");
}
if (verifyToken == null) {
throw new java.lang.IllegalArgumentException("verifyToken is marked @NonNull but is null");
}
return create(pageAccessToken, appSecret, verifyToken, empty());
}
public static Messenger create(
@NonNull String pageAccessToken,
@NonNull String appSecret,
@NonNull String verifyToken,
@NonNull Optional customHttpClient) {
if (pageAccessToken == null) {
throw new java.lang.IllegalArgumentException(
"pageAccessToken is marked @NonNull but is null");
}
if (appSecret == null) {
throw new java.lang.IllegalArgumentException("appSecret is marked @NonNull but is null");
}
if (verifyToken == null) {
throw new java.lang.IllegalArgumentException("verifyToken is marked @NonNull but is null");
}
if (customHttpClient == null) {
throw new java.lang.IllegalArgumentException(
"customHttpClient is marked @NonNull but is null");
}
return new Messenger(pageAccessToken, appSecret, verifyToken, customHttpClient);
}
public MessageResponse send(@NonNull Payload payload)
throws MessengerApiException, MessengerIOException {
if (payload == null) {
throw new java.lang.IllegalArgumentException("payload is marked @NonNull but is null");
}
return doRequest(POST, messagesRequestUrl, of(payload), MessageResponseFactory::create);
}
public void onReceiveEvents(
@NonNull String requestPayload,
@NonNull Optional signature,
@NonNull Consumer eventHandler)
throws MessengerVerificationException {
if (requestPayload == null) {
throw new java.lang.IllegalArgumentException("requestPayload is marked @NonNull but is null");
}
if (signature == null) {
throw new java.lang.IllegalArgumentException("signature is marked @NonNull but is null");
}
if (eventHandler == null) {
throw new java.lang.IllegalArgumentException("eventHandler is marked @NonNull but is null");
}
if (signature.isPresent()) {
if (!SignatureUtil.isSignatureValid(requestPayload, signature.get(), this.appSecret)) {
throw new MessengerVerificationException(
"Signature verification failed. Provided signature does not match calculated signature.");
}
} else {
log.warn(
"No signature provided, hence the signature verification is skipped. THIS IS NOT RECOMMENDED");
}
final JsonObject payloadJsonObject = this.jsonParser.parse(requestPayload).getAsJsonObject();
final Optional objectType = getPropertyAsString(payloadJsonObject, PROP_OBJECT);
if (!objectType.isPresent() || !objectType.get().equalsIgnoreCase(OBJECT_TYPE_PAGE)) {
throw new IllegalArgumentException(
"\'object\' property must be \'page\'. Make sure this is a page subscription");
}
final JsonArray entries =
getPropertyAsJsonArray(payloadJsonObject, PROP_ENTRY)
.orElseThrow(IllegalArgumentException::new);
for (JsonElement entry : entries) {
final JsonArray messagingEvents =
getPropertyAsJsonArray(entry.getAsJsonObject(), PROP_MESSAGING)
.orElseThrow(IllegalArgumentException::new);
for (JsonElement messagingEvent : messagingEvents) {
final Event event = EventFactory.createEvent(messagingEvent.getAsJsonObject());
eventHandler.accept(event);
}
}
}
public void verifyWebhook(@NonNull String mode, @NonNull String verifyToken)
throws MessengerVerificationException {
if (mode == null) {
throw new java.lang.IllegalArgumentException("mode is marked @NonNull but is null");
}
if (verifyToken == null) {
throw new java.lang.IllegalArgumentException("verifyToken is marked @NonNull but is null");
}
if (!mode.equals(HUB_MODE_SUBSCRIBE)) {
throw new MessengerVerificationException(
"Webhook verification failed. Mode \'" + mode + "\' is invalid.");
}
if (!verifyToken.equals(this.verifyToken)) {
throw new MessengerVerificationException(
"Webhook verification failed. Verification token \'" + verifyToken + "\' is invalid.");
}
}
public UserProfile queryUserProfile(@NonNull String userId)
throws MessengerApiException, MessengerIOException {
if (userId == null) {
throw new java.lang.IllegalArgumentException("userId is marked @NonNull but is null");
}
final String requestUrl = String.format(FB_GRAPH_API_URL_USER, userId, pageAccessToken);
return doRequest(GET, requestUrl, empty(), UserProfileFactory::create);
}
public SetupResponse updateSettings(@NonNull MessengerSettings messengerSettings)
throws MessengerApiException, MessengerIOException {
if (messengerSettings == null) {
throw new java.lang.IllegalArgumentException(
"messengerSettings is marked @NonNull but is null");
}
return doRequest(
POST, messengerProfileRequestUrl, of(messengerSettings), SetupResponseFactory::create);
}
public SetupResponse deleteSettings(
@NonNull MessengerSettingProperty property, @NonNull MessengerSettingProperty... properties)
throws MessengerApiException, MessengerIOException {
if (property == null) {
throw new java.lang.IllegalArgumentException("property is marked @NonNull but is null");
}
if (properties == null) {
throw new java.lang.IllegalArgumentException("properties is marked @NonNull but is null");
}
final List messengerSettingPropertyList =
new ArrayList<>(properties.length + 1);
messengerSettingPropertyList.add(property);
messengerSettingPropertyList.addAll(Arrays.asList(properties));
final DeleteMessengerSettingsPayload payload =
DeleteMessengerSettingsPayload.create(messengerSettingPropertyList);
return doRequest(DELETE, messengerProfileRequestUrl, of(payload), SetupResponseFactory::create);
}
private R doRequest(
HttpMethod httpMethod,
String requestUrl,
Optional payload,
Function responseTransformer)
throws MessengerApiException, MessengerIOException {
try {
final Optional jsonBody = payload.map(this.gson::toJson);
final HttpResponse httpResponse =
this.httpClient.execute(httpMethod, requestUrl, jsonBody.orElse(null));
final JsonObject responseJsonObject =
this.jsonParser.parse(httpResponse.body()).getAsJsonObject();
if (responseJsonObject.size() == 0) {
throw new MessengerApiException(
"The response JSON does not contain any key/value pair", empty(), empty(), empty());
}
if (httpResponse.statusCode() >= 200 && httpResponse.statusCode() < 300) {
return responseTransformer.apply(responseJsonObject);
} else {
throw MessengerApiExceptionFactory.create(responseJsonObject);
}
} catch (IOException e) {
throw new MessengerIOException(e);
}
}
}