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; } }