Skip to content

Commit

Permalink
resolved conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
BohdanTrue committed Jan 16, 2024
2 parents 8fb39a8 + 4baea23 commit 86b82d7
Show file tree
Hide file tree
Showing 12 changed files with 255 additions and 12 deletions.
132 changes: 124 additions & 8 deletions src/main/java/com/application/bookingservice/bot/NotificationBot.java
Original file line number Diff line number Diff line change
@@ -1,28 +1,57 @@
package com.application.bookingservice.bot;

import com.application.bookingservice.dto.customer.CustomerLoginRequestDto;
import com.application.bookingservice.exception.TelegramMessageException;
import com.application.bookingservice.model.Customer;
import com.application.bookingservice.repository.customer.CustomerRepository;
import jakarta.persistence.EntityNotFoundException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.stereotype.Component;
import org.telegram.telegrambots.bots.TelegramLongPollingBot;
import org.telegram.telegrambots.meta.api.methods.send.SendMessage;
import org.telegram.telegrambots.meta.api.methods.updatingmessages.DeleteMessage;
import org.telegram.telegrambots.meta.api.objects.Update;
import org.telegram.telegrambots.meta.exceptions.TelegramApiException;

@Component
public class NotificationBot extends TelegramLongPollingBot {
private static final Long CHAT_ID = -1002107651145L;
private static final String START_COMMAND = "/start";
private static final String CANT_HANDLE_START_MESSAGE = "Can't handle start command";
private static final String AUTH_COMMAND = "/auth";
private static final String CANCEL_COMMAND = "/cancel";
private static final String CANT_LOG_MESSAGE = "Can't send logs to chat text: %s";
private static final String CANT_SEND_MESSAGE = "Can't send message to user chatId: %d";
private static final String START_MESSAGE = "Hello, I am a bot for logging in BINOV booking";
private static final String START_MESSAGE = "hello im BINOV_booking_bot use /auth command "
+ "if you haven't done it yet to receive notification "
+ "or /cancel to stop receive messages";
private static final String DELETE_MESSAGE = "Can't delete user message";
private final String botName;
private final CustomerRepository customerRepository;
private CustomerLoginRequestDto requestDto;
private final AuthenticationManager authenticationManager;
private Map<Long, AuthState> authStates = new HashMap<>();
private Map<Long, CustomerLoginRequestDto> loginData = new HashMap<>();

private enum AuthState {
STARTED,
LOGIN,
PASSWORD
}

public NotificationBot(
@Value("${bot.token}") String token,
@Value("${bot.name}") String botName
@Value("${bot.name}") String botName,
CustomerRepository customerRepository,
AuthenticationManager authenticationManager
) {
super(token);
this.customerRepository = customerRepository;
this.authenticationManager = authenticationManager;
this.botName = botName;
}

Expand All @@ -33,12 +62,87 @@ public String getBotUsername() {

@Override
public void onUpdateReceived(Update update) {
Long chatId = update.getMessage().getChatId();
AuthState currentState = authStates.getOrDefault(chatId, AuthState.STARTED);
String recivedText = update.getMessage().getText();
if (recivedText.equals(START_COMMAND)) {
handleStartCommand(update);
} else if (authStates.containsKey(chatId)) {
authProcess(currentState, chatId, update);
} else if (recivedText.equals(AUTH_COMMAND)) {
sendTextMessage(chatId, "Please enter your login:");
authStates.put(chatId, AuthState.LOGIN);
} else if (recivedText.equals(CANCEL_COMMAND)) {
Customer customer = customerRepository.findByChatId(chatId).orElseThrow(
() -> new EntityNotFoundException("can't find customer by chat id")
);
customer.setChatId(null);
customerRepository.save(customer);
sendTextMessage(chatId, "notification canceled successful");
} else {
sendTextMessage(chatId, START_MESSAGE);
}
}

private void authProcess(AuthState currentState, Long chatId, Update update) {
String text = update.getMessage().getText();
switch (currentState) {
case STARTED:
sendTextMessage(chatId, "Please enter your login:");
authStates.put(chatId, AuthState.LOGIN);
break;
case LOGIN:
requestDto = loginData.getOrDefault(chatId, new CustomerLoginRequestDto());
requestDto.setEmail(text);
sendTextMessage(chatId, "Password:");
loginData.put(chatId, requestDto);
authStates.put(chatId, AuthState.PASSWORD);
break;
case PASSWORD:
requestDto = loginData.getOrDefault(chatId, new CustomerLoginRequestDto());
requestDto.setPassword(text);
deletePreviousMessage(chatId, update);
try {
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(
requestDto.getEmail(), requestDto.getPassword()
));
Customer customer = customerRepository.findByEmail(
requestDto.getEmail()).orElseThrow(
() -> new EntityNotFoundException("Can't find customer")
);
customer.setChatId(chatId);
customerRepository.save(customer);
sendTextMessage(chatId, "Successful, now you will receive "
+ "notifications from BINOV_booking");
} catch (Exception e) {
sendTextMessage(chatId, "Wrong password or login please try again");
} finally {
authStates.remove(chatId);
requestDto.setPassword("");
}
break;
default:
authStates.put(chatId, AuthState.STARTED);
break;
}
}

public void sendTextMessageToAll(String text) {
List<Customer> allByChatIdNotNull = customerRepository.findAllByChatIdNotNull();
for (int i = 0; i < allByChatIdNotNull.size(); i++) {
sendTextMessage(allByChatIdNotNull.get(i).getChatId(), text);
}
}

public void sendTextMessage(long chatId, String text) {
SendMessage message = new SendMessage();
message.setChatId(chatId);
message.setText(text);

try {
if (update.getMessage().getText().equals(START_COMMAND)) {
handleStartCommand(update);
}
} catch (Exception e) {
throw new TelegramMessageException(CANT_HANDLE_START_MESSAGE, e);
execute(message);
} catch (TelegramApiException e) {
throw new RuntimeException();
}
}

Expand All @@ -65,4 +169,16 @@ private void handleStartCommand(Update update) {
}
}

private void deletePreviousMessage(Long chatId, Update update) {
int messageId = update.getMessage().getMessageId();
DeleteMessage deleteMessage = new DeleteMessage();
deleteMessage.setChatId(chatId);
deleteMessage.setMessageId(messageId);
try {
execute(deleteMessage);
} catch (TelegramApiException e) {
throw new TelegramMessageException(DELETE_MESSAGE, e);
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.application.bookingservice.controller;

import com.application.bookingservice.dto.bot.BotRequestDto;
import com.application.bookingservice.service.bot.NotificationService;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequiredArgsConstructor
@RequestMapping("/telegram")
public class BotController {
private final NotificationService notificationService;

@PreAuthorize("hasRole('ROLE_MANAGER')")
@PostMapping
@ResponseStatus(HttpStatus.OK)
@Operation(summary = "Send notification",
description = "Permits to send message to all users")
public void sendNotification(@RequestBody @Valid BotRequestDto botRequestDto) {
notificationService.sendToAllUsers(botRequestDto.getMessage());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.application.bookingservice.dto.bot;

import jakarta.validation.constraints.NotBlank;
import lombok.Data;

@Data
public class BotRequestDto {
@NotBlank
private String message;
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ public class Customer implements UserDetails {
inverseJoinColumns = @JoinColumn(name = "role_id")
)
private Set<Role> roles = new HashSet<>();
@Column(name = "chat_id")
private Long chatId;
@Column(name = "is_deleted", nullable = false)
private Boolean isDeleted = false;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.application.bookingservice.repository.customer;

import com.application.bookingservice.model.Customer;
import java.util.List;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
Expand All @@ -13,4 +14,8 @@ public interface CustomerRepository extends JpaRepository<Customer, Long> {

@Query("SELECT c FROM Customer c JOIN FETCH c.roles r WHERE c.id = :id")
Optional<Customer> findById(Long id);

Optional<Customer> findByChatId(Long chatId);

List<Customer> findAllByChatIdNotNull();
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public AccommodationResponseDto save(AccommodationRequestDto accommodationReques
AccommodationResponseDto savedAccommodationDto
= accommodationMapper.toDto(accommodationRepository.save(accommodation));

notificationService.sendToUserNewAccommodation(savedAccommodationDto);
notificationService.accommodationCreatedMessage(savedAccommodationDto);
return savedAccommodationDto;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import com.application.bookingservice.exception.UnauthorizedActionException;
import com.application.bookingservice.mapper.BookingMapper;
import com.application.bookingservice.model.Booking;
import com.application.bookingservice.model.Customer;
import com.application.bookingservice.repository.booking.BookingRepository;
import com.application.bookingservice.repository.booking.spec.BookingSpecificationBuilder;
import com.application.bookingservice.repository.customer.CustomerRepository;
Expand Down Expand Up @@ -81,6 +82,12 @@ public BookingResponseDto save(Long customerId, BookingRequestDto requestBooking
));
BookingResponseDto savedBookingDto = bookingMapper
.toDto(bookingRepository.save(bookingToSave));
Customer customer = customerRepository.findById(customerId).orElseThrow(
() -> new EntityNotFoundException(CUSTOMER_NOT_FOUND_MESSAGE)
);
if (customer.getChatId() != null) {
notificationService.sendToUserBookingSuccessful(customer.getChatId(), savedBookingDto);
}
notificationService.bookingsCreatedMessage(savedBookingDto);
return savedBookingDto;
}
Expand Down Expand Up @@ -167,8 +174,8 @@ private void checkBookingDate() {
LocalDate nowDate = LocalDate.now();
List<Booking> bookings = bookingRepository.findAll();
for (Booking booking : bookings) {
if (booking.getCheckOut().isAfter(nowDate)
|| booking.getCheckOut().isEqual(nowDate)) {
if ((booking.getCheckOut().isAfter(nowDate)
|| booking.getCheckOut().isEqual(nowDate)) && booking.getStatus() != EXPIRED) {
booking.setStatus(EXPIRED);
bookingRepository.save(booking);
expired = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,12 @@ public interface NotificationService {
Boolean paymentMessage(Payment payment);

Boolean bookingExpiredMessage(String text);

Boolean sendToUserBookingSuccessful(Long chatId, BookingResponseDto responseDto);

Boolean sendToUserPayment(Long chatId, Payment payment);

Boolean sendToUserNewAccommodation(AccommodationResponseDto responseDto);

Boolean sendToAllUsers(String text);
}
Original file line number Diff line number Diff line change
Expand Up @@ -153,4 +153,47 @@ public Boolean bookingExpiredMessage(String text) {
return true;
}

@Override
public Boolean sendToUserBookingSuccessful(Long chatId, BookingResponseDto responseDto) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("Dear user your booking was successful \n you check in data: ")
.append(responseDto.getCheckIn())
.append("\nyour check out date :")
.append(responseDto.getCheckOut())
.append("\nThanks for picking BINOVO_booking!");
notificationBot.sendTextMessage(chatId, stringBuilder.toString());
return true;
}

@Override
public Boolean sendToUserPayment(Long chatId, Payment payment) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(" Dear user your payment was ")
.append(payment.getStatus())
.append("\ntotal :")
.append(payment.getTotal())
.append("\nThanks for picking BINOVO_booking!");
notificationBot.sendTextMessage(chatId, stringBuilder.toString());
return true;
}

@Override
public Boolean sendToUserNewAccommodation(AccommodationResponseDto responseDto) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("Dear users we added new accommodation \naddress: ")
.append(responseDto.getAddress())
.append("\ntype: ")
.append(responseDto.getType())
.append("\nbest price :")
.append(responseDto.getPrice());
notificationBot.sendTextMessageToAll(stringBuilder.toString());
return true;
}

@Override
public Boolean sendToAllUsers(String text) {
notificationBot.sendTextMessageToAll(text);
return true;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.application.bookingservice.exception.EntityNotFoundException;
import com.application.bookingservice.mapper.PaymentMapper;
import com.application.bookingservice.model.Booking;
import com.application.bookingservice.model.Customer;
import com.application.bookingservice.model.Payment;
import com.application.bookingservice.repository.booking.BookingRepository;
import com.application.bookingservice.repository.payment.PaymentRepository;
Expand Down Expand Up @@ -44,7 +45,10 @@ public void succeed(String sessionId) {
Booking booking = payment.getBooking();
booking.setStatus(Booking.Status.CONFIRMED);
bookingRepository.save(booking);

Customer customer = booking.getCustomer();
if (customer.getChatId() != null) {
notificationService.sendToUserPayment(customer.getChatId(), payment);
}
notificationService.paymentMessage(payment);
}

Expand All @@ -60,7 +64,10 @@ public void cancel(String sessionId) {
Booking booking = payment.getBooking();
booking.setStatus(Booking.Status.REJECTED);
bookingRepository.save(booking);

Customer customer = booking.getCustomer();
if (customer.getChatId() != null) {
notificationService.sendToUserPayment(customer.getChatId(), payment);
}
notificationService.paymentMessage(payment);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
databaseChangeLog:
- changeSet:
id: add-column-customer-table
author: BINOV_team
changes:
- addColumn:
tableName: customers
columns:
- column:
name: chat_id
type: bigint
2 changes: 2 additions & 0 deletions src/main/resources/db/changelog/db.changelog-master.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,5 @@ databaseChangeLog:
file: db/changelog/changes/09-insert-customers.yaml
- include:
file: db/changelog/changes/10-insert-demo-customers-roles.yaml
- include:
file: db/changelog/changes/11-add-column-customer-table.yaml

0 comments on commit 86b82d7

Please sign in to comment.