Skip to content

Commit a2e428a

Browse files
authored
Merge pull request #692 from noxxspring/twilioServiceCall
Twilio service call
2 parents 4b95f55 + afd9fa3 commit a2e428a

File tree

9 files changed

+446
-0
lines changed

9 files changed

+446
-0
lines changed

pom.xml

+250
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,255 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
<parent>
7+
<groupId>org.springframework.boot</groupId>
8+
<artifactId>spring-boot-starter-parent</artifactId>
9+
<version>3.3.1</version>
10+
<relativePath/> <!-- lookup parent from repository -->
11+
</parent>
12+
<groupId>com.hng</groupId>
13+
<artifactId>hng-java-boilerplate</artifactId>
14+
<version>0.0.1-SNAPSHOT</version>
15+
<name>hng-java-boilerplate</name>
16+
<description>Hng java boiler plate</description>
17+
<url/>
18+
<licenses>
19+
<license/>
20+
</licenses>
21+
<developers>
22+
<developer/>
23+
</developers>
24+
<scm>
25+
<connection/>
26+
<developerConnection/>
27+
<tag/>
28+
<url/>
29+
</scm>
30+
<properties>
31+
<java.version>17</java.version>
32+
</properties>
33+
<dependencies>
34+
<dependency>
35+
<groupId>org.springframework.boot</groupId>
36+
<artifactId>spring-boot-starter-data-jpa</artifactId>
37+
</dependency>
38+
<dependency>
39+
<groupId>org.springframework.boot</groupId>
40+
<artifactId>spring-boot-starter-security</artifactId>
41+
</dependency>
42+
<dependency>
43+
<groupId>org.springframework.boot</groupId>
44+
<artifactId>spring-boot-devtools</artifactId>
45+
<scope>runtime</scope>
46+
<optional>true</optional>
47+
</dependency>
48+
<dependency>
49+
<groupId>com.twilio.sdk</groupId>
50+
<artifactId>twilio</artifactId>
51+
<version>10.6.4</version>
52+
</dependency>
53+
<dependency>
54+
<groupId>org.springframework.boot</groupId>
55+
<artifactId>spring-boot-starter-web</artifactId>
56+
</dependency>
57+
<dependency>
58+
<groupId>org.springframework.boot</groupId>
59+
<artifactId>spring-boot-starter-actuator</artifactId>
60+
</dependency>
61+
<dependency>
62+
<groupId>io.micrometer</groupId>
63+
<artifactId>micrometer-registry-prometheus</artifactId>
64+
<version>1.10.0</version>
65+
</dependency>
66+
<dependency>
67+
<groupId>org.flywaydb</groupId>
68+
<artifactId>flyway-core</artifactId>
69+
</dependency>
70+
<dependency>
71+
<groupId>org.flywaydb</groupId>
72+
<artifactId>flyway-database-postgresql</artifactId>
73+
</dependency>
74+
<dependency>
75+
<groupId>org.postgresql</groupId>
76+
<artifactId>postgresql</artifactId>
77+
<scope>runtime</scope>
78+
</dependency>
79+
<dependency>
80+
<groupId>org.projectlombok</groupId>
81+
<artifactId>lombok</artifactId>
82+
<optional>true</optional>
83+
</dependency>
84+
<dependency>
85+
<groupId>org.springframework.boot</groupId>
86+
<artifactId>spring-boot-starter-test</artifactId>
87+
<scope>test</scope>
88+
</dependency>
89+
<dependency>
90+
<groupId>org.springframework.security</groupId>
91+
<artifactId>spring-security-test</artifactId>
92+
<scope>test</scope>
93+
</dependency>
94+
<dependency>
95+
<groupId>com.fasterxml.jackson.core</groupId>
96+
<artifactId>jackson-databind</artifactId>
97+
<version>2.16.1</version>
98+
</dependency>
99+
<dependency>
100+
<groupId>com.fasterxml.jackson.dataformat</groupId>
101+
<artifactId>jackson-dataformat-xml</artifactId>
102+
<version>2.15.0</version>
103+
</dependency>
104+
<dependency>
105+
<groupId>com.fasterxml.jackson.core</groupId>
106+
<artifactId>jackson-core</artifactId>
107+
<version>2.16.1</version>
108+
</dependency>
109+
<dependency>
110+
<groupId>com.fasterxml.jackson.core</groupId>
111+
<artifactId>jackson-annotations</artifactId>
112+
<version>2.16.1</version>
113+
</dependency>
114+
<dependency>
115+
<groupId>io.jsonwebtoken</groupId>
116+
<artifactId>jjwt-impl</artifactId>
117+
<version>0.12.3</version>
118+
<scope>runtime</scope>
119+
</dependency>
120+
<dependency>
121+
<groupId>io.jsonwebtoken</groupId>
122+
<artifactId>jjwt-api</artifactId>
123+
<version>0.12.3</version>
124+
</dependency>
125+
<dependency>
126+
<groupId>io.jsonwebtoken</groupId>
127+
<artifactId>jjwt-jackson</artifactId>
128+
<version>0.12.3</version>
129+
<scope>runtime</scope>
130+
</dependency>
131+
<dependency>
132+
<groupId>org.springframework.boot</groupId>
133+
<artifactId>spring-boot-starter-validation</artifactId>
134+
</dependency>
135+
<dependency>
136+
<groupId>org.junit.jupiter</groupId>
137+
<artifactId>junit-jupiter-engine</artifactId>
138+
<version>5.10.2</version>
139+
<scope>test</scope>
140+
</dependency>
141+
<dependency>
142+
<groupId>org.junit.jupiter</groupId>
143+
<artifactId>junit-jupiter-api</artifactId>
144+
<version>5.10.2</version>
145+
<scope>test</scope>
146+
</dependency>
147+
<dependency>
148+
<groupId>org.mockito</groupId>
149+
<artifactId>mockito-core</artifactId>
150+
<version>5.12.0</version>
151+
<scope>test</scope>
152+
</dependency>
153+
<dependency>
154+
<groupId>org.mapstruct</groupId>
155+
<artifactId>mapstruct</artifactId>
156+
<version>1.4.2.Final</version>
157+
</dependency>
158+
<dependency>
159+
<groupId>org.mapstruct</groupId>
160+
<artifactId>mapstruct-processor</artifactId>
161+
<version>1.4.2.Final</version>
162+
<scope>provided</scope>
163+
</dependency>
164+
<dependency>
165+
<groupId>io.rest-assured</groupId>
166+
<artifactId>rest-assured</artifactId>
167+
<scope>test</scope>
168+
</dependency>
169+
<dependency>
170+
<groupId>jakarta.validation</groupId>
171+
<artifactId>jakarta.validation-api</artifactId>
172+
<version>3.0.2</version>
173+
</dependency>
174+
<dependency>
175+
<groupId>org.hibernate.validator</groupId>
176+
<artifactId>hibernate-validator</artifactId>
177+
<version>8.0.1.Final</version>
178+
</dependency>
179+
<dependency>
180+
<groupId>org.springdoc</groupId>
181+
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
182+
<version>2.5.0</version>
183+
</dependency>
184+
<dependency>
185+
<groupId>org.springframework.boot</groupId>
186+
<artifactId>spring-boot-starter-amqp</artifactId>
187+
</dependency>
188+
<dependency>
189+
<groupId>org.springframework.boot</groupId>
190+
<artifactId>spring-boot-starter-mail</artifactId>
191+
</dependency>
192+
<dependency>
193+
<groupId>com.restfb</groupId>
194+
<artifactId>restfb</artifactId>
195+
<version>2024.9.0</version>
196+
</dependency>
197+
<dependency>
198+
<groupId>com.google.api-client</groupId>
199+
<artifactId>google-api-client</artifactId>
200+
<version>2.6.0</version>
201+
</dependency>
202+
<dependency>
203+
<groupId>com.beust</groupId>
204+
<artifactId>jcommander</artifactId>
205+
<version>1.82</version>
206+
</dependency>
207+
<dependency>
208+
<groupId>com.stripe</groupId>
209+
<artifactId>stripe-java</artifactId>
210+
<version>26.7.0</version>
211+
</dependency>
212+
<dependency>
213+
<groupId>dev.samstevens.totp</groupId>
214+
<artifactId>totp</artifactId>
215+
<version>1.7.1</version>
216+
</dependency>
217+
<dependency>
218+
<groupId>org.projectlombok</groupId>
219+
<artifactId>lombok</artifactId>
220+
<scope>provided</scope>
221+
</dependency>
222+
</dependencies>
223+
<build>
224+
<plugins>
225+
<plugin>
226+
<groupId>org.springframework.boot</groupId>
227+
<artifactId>spring-boot-maven-plugin</artifactId>
228+
</plugin>
229+
<plugin>
230+
<groupId>org.apache.maven.plugins</groupId>
231+
<artifactId>maven-compiler-plugin</artifactId>
232+
<version>3.11.0</version>
233+
<configuration>
234+
<source>17</source>
235+
<target>17</target>
236+
</configuration>
237+
</plugin>
238+
<plugin>
239+
<groupId>org.apache.maven.plugins</groupId>
240+
<artifactId>maven-compiler-plugin</artifactId>
241+
<configuration>
242+
<annotationProcessorPaths>
243+
<path>
244+
<groupId>org.projectlombok</groupId>
245+
<artifactId>lombok</artifactId>
246+
<version>${lombok.version}</version>
247+
</path>
248+
</annotationProcessorPaths>
249+
</configuration>
250+
</plugin>
251+
</plugins>
252+
</build>
3253
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4254
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
5255
<modelVersion>4.0.0</modelVersion>

src/main/java/hng_java_boilerplate/config/WebSecurityConfig.java

+1
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ public SecurityFilterChain httpSecurity(HttpSecurity httpSecurity) throws Except
108108
"/api/v1/payment/plans",
109109
"/api/v1/payment/webhook",
110110
"/api/v1/notification-settings",
111+
"/api/call"
111112
"/api/v1/profile/upload-image"
112113
).permitAll()
113114
.requestMatchers(

src/main/java/hng_java_boilerplate/profile/service/ProfileService.java

+2
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,5 @@ public interface ProfileService {
1717
ProfileResponse getUserProfile(String userId);
1818
ResponseEntity<?> uploadProfileImage(MultipartFile file) throws IOException;
1919
}
20+
21+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package hng_java_boilerplate.twilio.CallLogs;
2+
3+
import jakarta.persistence.*;
4+
import lombok.AllArgsConstructor;
5+
import lombok.Builder;
6+
import lombok.Data;
7+
import lombok.NoArgsConstructor;
8+
9+
import java.time.LocalDateTime;
10+
11+
@jakarta.persistence.Entity
12+
@Table(name = "call_logs")
13+
@Data
14+
@AllArgsConstructor
15+
@NoArgsConstructor
16+
@Builder
17+
public class Entity {
18+
19+
@Id
20+
@GeneratedValue(strategy = GenerationType.IDENTITY)
21+
private Long id;
22+
23+
private String toNumber;
24+
private String fromNumber;
25+
private String callSid;
26+
private LocalDateTime timestamp;
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package hng_java_boilerplate.twilio.Controller;
2+
3+
import com.twilio.exception.TwilioException;
4+
import hng_java_boilerplate.comment.dto.ErrorResponse;
5+
import hng_java_boilerplate.exception.BadRequestException;
6+
import hng_java_boilerplate.exception.CustomError;
7+
import hng_java_boilerplate.exception.NotFoundException;
8+
import hng_java_boilerplate.twilio.RequestAndResponse.CallRequest;
9+
import hng_java_boilerplate.twilio.RequestAndResponse.CallResponse;
10+
import hng_java_boilerplate.twilio.Service.TwilioCallService;
11+
import lombok.RequiredArgsConstructor;
12+
import org.springframework.http.HttpStatus;
13+
import org.springframework.http.ResponseEntity;
14+
import org.springframework.web.bind.annotation.PostMapping;
15+
import org.springframework.web.bind.annotation.RequestBody;
16+
import org.springframework.web.bind.annotation.RequestMapping;
17+
import org.springframework.web.bind.annotation.RestController;
18+
19+
@RestController
20+
@RequestMapping("/api")
21+
@RequiredArgsConstructor
22+
public class TwillioCallController {
23+
24+
private final TwilioCallService twilioCallService;
25+
26+
@PostMapping("/call")
27+
public CallResponse makecall(@RequestBody CallRequest callRequest) {
28+
if (callRequest == null || callRequest.getToNumber() == null || callRequest.getFromNumber() == null) {
29+
throw new BadRequestException("Invalid request: Phone number is required");
30+
}
31+
32+
CallResponse response = twilioCallService.makeCall(callRequest);
33+
34+
if (response == null) {
35+
throw new NotFoundException("Twilio service error: Service not found/available");
36+
}
37+
return response;
38+
}
39+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package hng_java_boilerplate.twilio.Repository;
2+
3+
import hng_java_boilerplate.twilio.CallLogs.Entity;
4+
import org.springframework.data.jpa.repository.JpaRepository;
5+
import org.springframework.stereotype.Repository;
6+
7+
@Repository
8+
public interface TwilioCallRepo extends JpaRepository<Entity,Long> {
9+
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package hng_java_boilerplate.twilio.RequestAndResponse;
2+
3+
public class CallRequest {
4+
private String toNumber;
5+
private String fromNumber;
6+
private String messageUrl;
7+
8+
public String getFromNumber() {
9+
return fromNumber;
10+
}
11+
12+
public void setFromNumber(String fromNumber) {
13+
this.fromNumber = fromNumber;
14+
}
15+
16+
public String getToNumber() {
17+
return toNumber;
18+
}
19+
20+
public void setToNumber(String toNumber) {
21+
this.toNumber = toNumber;
22+
}
23+
24+
public String getMessageUrl() {
25+
return messageUrl;
26+
}
27+
28+
public void setMessageUrl(String messageUrl) {
29+
this.messageUrl = messageUrl;
30+
}
31+
}

0 commit comments

Comments
 (0)