package org.apereo.cas.support.sms;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.StringUtils;
import org.apereo.cas.util.io.SmsSender;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpEntity;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import java.io.StringWriter;
import java.net.URI;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* This is {@link ClickatellSmsSender}.
*
* @author Misagh Moayyed
* @since 5.1.0
*/
public class ClickatellSmsSender implements SmsSender {
private static final Logger LOGGER = LoggerFactory.getLogger(ClickatellSmsSender.class);
private final String token;
private final String serverUrl;
private final ObjectMapper mapper = new ObjectMapper();
private final RestTemplate restTemplate = new RestTemplate();
public ClickatellSmsSender(final String token, final String serverUrl) {
this.token = token;
this.serverUrl = serverUrl;
mapper.findAndRegisterModules();
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
}
@Override
public boolean send(final String from, final String to, final String message) {
try {
final MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
headers.add("Authorization", this.token);
headers.add("Content-Type", MediaType.APPLICATION_JSON_VALUE);
headers.add("Accept", MediaType.APPLICATION_JSON_VALUE);
final Map<String, Object> map = new HashMap<>();
map.put("content", message);
map.put("to", Arrays.asList(to));
map.put("from", from);
final StringWriter stringify = new StringWriter();
mapper.writeValue(stringify, map);
final HttpEntity<String> request = new HttpEntity<>(stringify.toString(), headers);
final ResponseEntity<Map> response = restTemplate.postForEntity(new URI(this.serverUrl), request, Map.class);
if (response.hasBody()) {
final List<Map> messages = (List<Map>) response.getBody().get("messages");
final String error = (String) response.getBody().get("error");
if (StringUtils.isNotBlank(error)) {
LOGGER.error(error);
return false;
}
final List<String> errors = messages.stream()
.filter(m -> m.containsKey("accepted") && !Boolean.valueOf(m.get("accepted").toString()) && m.containsKey("error"))
.map(m -> (String) m.get("error"))
.collect(Collectors.toList());
if (errors.isEmpty()) {
return true;
}
errors.forEach(LOGGER::error);
}
} catch (final Exception e) {
LOGGER.error(e.getMessage(), e);
}
return false;
}
}