initial commit by dev prasad
This commit is contained in:
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
/target/
|
||||
/.idea/
|
||||
*.iml
|
||||
.DS_Store
|
||||
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"java.compile.nullAnalysis.mode": "automatic"
|
||||
}
|
||||
310
README.md
Normal file
310
README.md
Normal file
@@ -0,0 +1,310 @@
|
||||
# WhatsApp Automation
|
||||
|
||||
WhatsApp Automation is a Spring Boot backend for WhatsApp Business messaging workflows. It receives webhook events from Meta, runs bot-driven conversation logic, and persists booking/state data in PostgreSQL.
|
||||
|
||||
## About The Project
|
||||
|
||||
This project provides automation features around WhatsApp messaging:
|
||||
|
||||
- Webhook verification and message handling (`/webhook`)
|
||||
- Chatbot conversation flow
|
||||
- PostgreSQL persistence for appointments, service bookings, test bookings, and user state
|
||||
|
||||
The application is a **Java 21** Maven service built with Spring Boot.
|
||||
|
||||
## Tech Stack
|
||||
|
||||
- Spring Boot 3.3.2
|
||||
- Java 21
|
||||
- Spring Web
|
||||
- Spring Data JPA
|
||||
- PostgreSQL
|
||||
- ngrok (for local webhook tunneling to Meta)
|
||||
|
||||
## Requirements
|
||||
|
||||
| Tool | Purpose |
|
||||
|------|---------|
|
||||
| **Java 21** | Runtime for the Spring Boot app |
|
||||
| **Maven 3.9+** | Build and run the project |
|
||||
| **PostgreSQL** | Application database |
|
||||
| **ngrok** | Expose local backend to the public internet so Meta can call your webhook |
|
||||
| **Meta / WhatsApp Business API access** | Access token, webhook configuration, and test messaging |
|
||||
|
||||
---
|
||||
|
||||
## How to Run the Backend (Full Setup)
|
||||
|
||||
Follow these steps in order.
|
||||
|
||||
### 1. Clone the repository
|
||||
|
||||
```bash
|
||||
git clone <repository-url>
|
||||
cd "WhatsApp Automation"
|
||||
```
|
||||
|
||||
Replace `<repository-url>` with the actual Git remote URL for this project.
|
||||
|
||||
---
|
||||
|
||||
### 2. Install ngrok
|
||||
|
||||
ngrok creates a public HTTPS URL that tunnels to your local Spring Boot server so Meta can deliver WhatsApp webhooks.
|
||||
|
||||
1. Go to [https://ngrok.com](https://ngrok.com)
|
||||
2. Sign up or sign in
|
||||
3. Install ngrok for your OS (macOS example with Homebrew):
|
||||
|
||||
```bash
|
||||
brew install ngrok
|
||||
```
|
||||
|
||||
Or download the binary from the ngrok dashboard and follow their install instructions.
|
||||
|
||||
---
|
||||
|
||||
### 3. Authenticate ngrok with your access token
|
||||
|
||||
After signing in to ngrok, copy your **authtoken** from the ngrok dashboard, then run:
|
||||
|
||||
```bash
|
||||
ngrok config add-authtoken <YOUR_NGROK_AUTHTOKEN>
|
||||
```
|
||||
|
||||
Without this step, ngrok will not start a usable tunnel.
|
||||
|
||||
---
|
||||
|
||||
### 4. Log in to the WhatsApp Business / Meta developer dashboard
|
||||
|
||||
1. Open the [WhatsApp Business API / Meta for Developers](https://developers.facebook.com/) dashboard
|
||||
2. Log in with the account that has access to this app
|
||||
3. Use the project’s WhatsApp / Meta credentials (app ID, business ID, phone number ID, etc.) as configured for your team
|
||||
|
||||
Relevant app links used by this project:
|
||||
|
||||
- **API testing / access token:**
|
||||
[Generate WhatsApp access token](https://developers.facebook.com/apps/1054675710401577/use_cases/customize/api-testing-v2/?product_route=whatsapp-business&business_id=1051413880774512&use_case_enum=WHATSAPP_BUSINESS_MESSAGING&selected_tab=api-testing-v2)
|
||||
|
||||
- **Webhooks configuration:**
|
||||
[Configure webhooks](https://developers.facebook.com/apps/1054675710401577/use_cases/customize/webhooks/?product_route=webhooks&business_id=1051413880774512&use_case_enum=WHATSAPP_BUSINESS_MESSAGING&selected_tab=webhooks)
|
||||
|
||||
---
|
||||
|
||||
### 5. Generate a WhatsApp access token and configure the app
|
||||
|
||||
1. Open the API testing page:
|
||||
[https://developers.facebook.com/apps/1054675710401577/use_cases/customize/api-testing-v2/?product_route=whatsapp-business&business_id=1051413880774512&use_case_enum=WHATSAPP_BUSINESS_MESSAGING&selected_tab=api-testing-v2](https://developers.facebook.com/apps/1054675710401577/use_cases/customize/api-testing-v2/?product_route=whatsapp-business&business_id=1051413880774512&use_case_enum=WHATSAPP_BUSINESS_MESSAGING&selected_tab=api-testing-v2)
|
||||
2. Generate a **new Access Token**
|
||||
3. Open the project config file:
|
||||
|
||||
```text
|
||||
src/main/resources/application.properties
|
||||
```
|
||||
|
||||
4. Paste the token into the access-token property:
|
||||
|
||||
```properties
|
||||
whatsapp.access-token=<YOUR_WHATSAPP_ACCESS_TOKEN>
|
||||
```
|
||||
|
||||
> **Note:** Temporary tokens from Meta expire. If outbound WhatsApp API calls start failing with auth errors, generate a new token and update this property.
|
||||
|
||||
---
|
||||
|
||||
### 6. Create the PostgreSQL database and set credentials
|
||||
|
||||
1. Ensure PostgreSQL is installed and running locally
|
||||
2. Create the database used by this project (default name: `rmc_bot`):
|
||||
|
||||
```bash
|
||||
createdb rmc_bot
|
||||
```
|
||||
|
||||
Or via `psql`:
|
||||
|
||||
```sql
|
||||
CREATE DATABASE rmc_bot;
|
||||
```
|
||||
|
||||
3. Update database settings in `src/main/resources/application.properties`:
|
||||
|
||||
```properties
|
||||
spring.datasource.url=jdbc:postgresql://localhost:5432/rmc_bot
|
||||
spring.datasource.username=<YOUR_POSTGRES_USERNAME>
|
||||
spring.datasource.password=<YOUR_POSTGRES_PASSWORD>
|
||||
```
|
||||
|
||||
Default values currently in the file (change these for your machine):
|
||||
|
||||
| Property | Default / example |
|
||||
|----------|-------------------|
|
||||
| `spring.datasource.url` | `jdbc:postgresql://localhost:5432/rmc_bot` |
|
||||
| `spring.datasource.username` | `postgres` |
|
||||
| `spring.datasource.password` | *(your local password)* |
|
||||
|
||||
The app uses:
|
||||
|
||||
```properties
|
||||
spring.jpa.hibernate.ddl-auto=update
|
||||
```
|
||||
|
||||
so tables are created/updated automatically on startup.
|
||||
|
||||
---
|
||||
|
||||
### 7. Start the Spring Boot backend
|
||||
|
||||
The server listens on **port 8085** (`server.port=8085`).
|
||||
|
||||
From the project root:
|
||||
|
||||
```bash
|
||||
mvn spring-boot:run
|
||||
```
|
||||
|
||||
Confirm the app started successfully (no datasource or port-binding errors). Leave this process running.
|
||||
|
||||
You can also run tests with:
|
||||
|
||||
```bash
|
||||
mvn test
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 8. Start ngrok and point it at the backend
|
||||
|
||||
**Important:** Start the Spring Boot backend *before* configuring Meta webhooks, and keep both the backend and ngrok running while testing.
|
||||
|
||||
In a **new terminal**:
|
||||
|
||||
```bash
|
||||
ngrok http 8085
|
||||
```
|
||||
|
||||
ngrok will print a public HTTPS URL, for example:
|
||||
|
||||
```text
|
||||
https://abcd-1234.ngrok-free.app
|
||||
```
|
||||
|
||||
Copy that base URL (the `https://...` forwarding address).
|
||||
|
||||
> Free ngrok URLs change every time you restart ngrok. When the URL changes, you must update the Callback URL in Meta again.
|
||||
|
||||
---
|
||||
|
||||
### 9. Configure the Meta webhook
|
||||
|
||||
1. Open the webhooks page:
|
||||
[https://developers.facebook.com/apps/1054675710401577/use_cases/customize/webhooks/?product_route=webhooks&business_id=1051413880774512&use_case_enum=WHATSAPP_BUSINESS_MESSAGING&selected_tab=webhooks](https://developers.facebook.com/apps/1054675710401577/use_cases/customize/webhooks/?product_route=webhooks&business_id=1051413880774512&use_case_enum=WHATSAPP_BUSINESS_MESSAGING&selected_tab=webhooks)
|
||||
|
||||
2. Set **Callback URL** to:
|
||||
|
||||
```text
|
||||
https://<YOUR_NGROK_HOST>/webhook
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```text
|
||||
https://abcd-1234.ngrok-free.app/webhook
|
||||
```
|
||||
|
||||
3. Set **Verify Token** to exactly:
|
||||
|
||||
```text
|
||||
my_whatsapp_verify_token_123
|
||||
```
|
||||
|
||||
This must match `whatsapp.verify-token` in `application.properties`:
|
||||
|
||||
```properties
|
||||
whatsapp.verify-token=my_whatsapp_verify_token_123
|
||||
```
|
||||
|
||||
4. Click **Verify and Save** (or equivalent). Meta will send a `GET` request to `/webhook` with `hub.mode`, `hub.verify_token`, and `hub.challenge`. The backend validates the token and returns the challenge.
|
||||
|
||||
5. Subscribe to the webhook fields you need (typically **messages** for inbound WhatsApp traffic).
|
||||
|
||||
---
|
||||
|
||||
## Configuration reference
|
||||
|
||||
All runtime secrets and connection settings live in:
|
||||
|
||||
```text
|
||||
src/main/resources/application.properties
|
||||
```
|
||||
|
||||
| Property | Description |
|
||||
|----------|-------------|
|
||||
| `server.port` | Backend HTTP port (default `8085`) |
|
||||
| `whatsapp.access-token` | Meta WhatsApp Cloud API access token |
|
||||
| `whatsapp.verify-token` | Token Meta uses to verify your webhook (`my_whatsapp_verify_token_123`) |
|
||||
| `spring.datasource.url` | JDBC URL for PostgreSQL |
|
||||
| `spring.datasource.username` | PostgreSQL username |
|
||||
| `spring.datasource.password` | PostgreSQL password |
|
||||
| `spring.jpa.hibernate.ddl-auto` | Schema mode (`update`) |
|
||||
| `spring.jpa.properties.hibernate.dialect` | PostgreSQL dialect |
|
||||
| `spring.jpa.show-sql` | Log SQL statements |
|
||||
|
||||
Webhook endpoint exposed by the app:
|
||||
|
||||
| Method | Path | Purpose |
|
||||
|--------|------|---------|
|
||||
| `GET` | `/webhook` | Meta webhook verification |
|
||||
| `POST` | `/webhook` | Inbound WhatsApp events / messages |
|
||||
|
||||
---
|
||||
|
||||
## Quick checklist
|
||||
|
||||
Use this when bringing the stack up on a new machine:
|
||||
|
||||
1. [ ] Clone the repo
|
||||
2. [ ] Install and authenticate ngrok
|
||||
3. [ ] Log in to Meta / WhatsApp Business dashboard
|
||||
4. [ ] Generate access token → set `whatsapp.access-token`
|
||||
5. [ ] Create PostgreSQL DB → set datasource username/password
|
||||
6. [ ] `mvn spring-boot:run` (port **8085**)
|
||||
7. [ ] `ngrok http 8085`
|
||||
8. [ ] Meta Callback URL = `https://<ngrok-host>/webhook`
|
||||
9. [ ] Verify token = `my_whatsapp_verify_token_123`
|
||||
10. [ ] Verify webhook + subscribe to message events
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
| Problem | What to check |
|
||||
|---------|----------------|
|
||||
| Webhook verification fails | Verify token must be exactly `my_whatsapp_verify_token_123`. Backend must be running. Callback URL must end with `/webhook`. |
|
||||
| Meta cannot reach the server | ngrok must be running (`ngrok http 8085`). Use the current ngrok HTTPS URL, not an old one. |
|
||||
| Database connection errors | PostgreSQL is running; database `rmc_bot` exists; username/password in `application.properties` are correct. |
|
||||
| Cannot send WhatsApp messages | Access token may have expired — generate a new one and update `whatsapp.access-token`. |
|
||||
| Port already in use | Something else is bound to `8085`, or change `server.port` and point ngrok at the new port. |
|
||||
| Not receiving messages on webhook | Your WhatsApp Business Account (WABA) might not be subscribed to your developer App. Link them via API: `curl -X POST "https://graph.facebook.com/v20.0/<WABA_ID>/subscribed_apps" -H "Authorization: Bearer <your_access_token>"` |
|
||||
|
||||
---
|
||||
|
||||
## Project structure (high level)
|
||||
|
||||
```text
|
||||
src/main/java/com/example/whatsappautomation/
|
||||
WhatsAppAutomationApplication.java
|
||||
controller/WhatsAppWebhookController.java
|
||||
service/ChatbotService.java
|
||||
entity/ # Appointment, ServiceBooking, TestBooking, UserState
|
||||
repository/ # Spring Data JPA repositories
|
||||
src/main/resources/
|
||||
application.properties
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## License
|
||||
|
||||
Internal / project use unless otherwise specified.
|
||||
63
fix_args.py
Normal file
63
fix_args.py
Normal file
@@ -0,0 +1,63 @@
|
||||
import re
|
||||
|
||||
with open('src/main/java/com/example/whatsappautomation/service/ChatbotService.java', 'r') as f:
|
||||
content = f.read()
|
||||
|
||||
# We want to match: sendPaginatedButtons(state, arg2, arg3, new String[]{...}, new String[]{...})
|
||||
# and replace it with: sendPaginatedButtons(state, arg2, new String[]{...}, new String[]{...})
|
||||
# Note: arg2 and arg3 might be getMessage(...) or "string".
|
||||
# It's safest to match: sendPaginatedButtons(state, (whatever), (whatever), new String[]{
|
||||
|
||||
def replacer(match):
|
||||
# match.group(1) is the part from `state, ` up to `, new String[]{`
|
||||
# this part contains `arg2, arg3`. We need to split by comma from the right, but arg2 or arg3 might have commas!
|
||||
# Wait, getting the last argument before `new String[]{` is the best way.
|
||||
# Actually, the button text (arg3) is almost always `getMessage("something.btn", state)` or `"View Options"` or similar.
|
||||
# Let's just use regex to match the third argument which is always followed by `, new String\[\]\{`
|
||||
pass
|
||||
|
||||
# Let's write a simple python parser for the arguments of sendPaginatedButtons
|
||||
new_content = ""
|
||||
idx = 0
|
||||
while True:
|
||||
start_idx = content.find('sendPaginatedButtons(state, ', idx)
|
||||
if start_idx == -1:
|
||||
new_content += content[idx:]
|
||||
break
|
||||
|
||||
new_content += content[idx:start_idx]
|
||||
|
||||
# find the start of `new String[]{`
|
||||
arrays_start = content.find('new String[]{', start_idx)
|
||||
|
||||
# The text between `start_idx + len('sendPaginatedButtons(state, ')` and `arrays_start` is `arg2, arg3, `
|
||||
# We want to remove `arg3, `.
|
||||
# `arg3` is either a string literal `"..."` or a `getMessage(...)` call.
|
||||
args_str = content[start_idx + len('sendPaginatedButtons(state, '):arrays_start].strip()
|
||||
# args_str ends with `,`. Let's remove the trailing comma.
|
||||
args_str = args_str[:-1].strip()
|
||||
|
||||
# Now we need to split args_str into arg2 and arg3.
|
||||
# If it ends with `state)`, arg3 is `getMessage(..., state)`.
|
||||
# If it ends with `"`, arg3 is a string literal.
|
||||
|
||||
# Actually, we can just find the LAST comma that is NOT inside parentheses!
|
||||
# A simple comma split works if we respect parens.
|
||||
def rsplit_args(s):
|
||||
depth = 0
|
||||
for i in range(len(s)-1, -1, -1):
|
||||
if s[i] == ')': depth += 1
|
||||
elif s[i] == '(': depth -= 1
|
||||
elif s[i] == ',' and depth == 0:
|
||||
return s[:i].strip(), s[i+1:].strip()
|
||||
return s, ""
|
||||
|
||||
arg2, arg3 = rsplit_args(args_str)
|
||||
|
||||
new_content += f"sendPaginatedButtons(state, {arg2}, "
|
||||
idx = arrays_start
|
||||
|
||||
with open('src/main/java/com/example/whatsappautomation/service/ChatbotService.java', 'w') as f:
|
||||
f.write(new_content)
|
||||
|
||||
print("Fixed arguments")
|
||||
38
fix_tamil.py
Normal file
38
fix_tamil.py
Normal file
@@ -0,0 +1,38 @@
|
||||
replacements = {
|
||||
"காய்ச்சல் பரிசோதனைகள்": "காய்ச்சல் பரிசோதனை",
|
||||
"மூட்டு மற்றும் எலும்பு": "மூட்டு & எலும்பு",
|
||||
"முழுமையான உடல் பரிசோதனை": "முழு உடல் பரிசோதனை",
|
||||
"காய்ச்சல் அல்ட்ரா பேனல்": "காய்ச்சல் அல்ட்ரா",
|
||||
"மலம் பரிசோதனை (Stool Occult Blood)": "மலம் பரிசோதனை",
|
||||
"அமயா இன்ட் கார்டியாக்": "அமயா கார்டியாக்",
|
||||
"கார்டியாக் பேக்கேஜ் - அமயா": "அமயா பேக்கேஜ்",
|
||||
"உயர் இரத்த அழுத்தம் தொகுப்பு": "உயர் ரத்த அழுத்தம்",
|
||||
"மாஸ்டர் ஹெல்த் பேசிக்": "மாஸ்டர் பேசிக்",
|
||||
"மாஸ்டர் ஹெல்த் எக்ஸிகியூட்டிவ்": "மாஸ்டர் எக்ஸிகியூட்",
|
||||
"மாஸ்டர் ஹெல்த் பிரீமியம்": "மாஸ்டர் பிரீமியம்",
|
||||
"கர்ப்ப காலம் அட்வான்ஸ்டு": "கர்ப்ப அட்வான்ஸ்டு",
|
||||
"சர்க்கரை கட்டுப்பாடு பேசிக்": "சர்க்கரை பேசிக்",
|
||||
"சர்க்கரை கட்டுப்பாடு பிளஸ்": "சர்க்கரை பிளஸ்",
|
||||
"பெண்கள் நல்வாழ்வு பேசிக்": "பெண்கள் பேசிக்",
|
||||
"பெண்கள் நல்வாழ்வு அட்வான்ஸ்டு": "பெண்கள் அட்வான்ஸ்டு",
|
||||
"புதிய சந்திப்பை முன்பதிவு செய்ய": "புதிய முன்பதிவு",
|
||||
"சந்திப்புகளைப் பார்க்க": "சந்திப்புகளை பார்",
|
||||
"சந்திப்பை மாற்றியமைக்க": "மாற்றியமைக்க",
|
||||
"சந்திப்பை ரத்து செய்ய": "ரத்து செய்ய",
|
||||
"முன்பதிவை உறுதிப்படுத்தவும்": "உறுதிப்படுத்துக",
|
||||
"சந்திப்பை ரத்து செய்யவும்": "ரத்து செய்க",
|
||||
"கட்டு போடுதல் (Dressing)": "கட்டு போடுதல்",
|
||||
"வடிகுழாய் (Catheterization)": "வடிகுழாய்",
|
||||
"வீட்டு பராமரிப்பு தொகுப்புகள்": "வீட்டு பராமரிப்பு"
|
||||
}
|
||||
|
||||
with open('src/main/resources/messages_ta.properties', 'r', encoding='utf-8') as f:
|
||||
content = f.read()
|
||||
|
||||
for old, new in replacements.items():
|
||||
content = content.replace(f"={old}", f"={new}")
|
||||
|
||||
with open('src/main/resources/messages_ta.properties', 'w', encoding='utf-8') as f:
|
||||
f.write(content)
|
||||
|
||||
print("Replaced lengths.")
|
||||
15
length_check.py
Normal file
15
length_check.py
Normal file
@@ -0,0 +1,15 @@
|
||||
import re
|
||||
|
||||
# Keys that are used for buttons (options)
|
||||
button_keys = ['opt', 'btn', 'yes', 'no', 'confirm', 'change', 'cancel']
|
||||
|
||||
with open('src/main/resources/messages_ta.properties', 'r', encoding='utf-8') as f:
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
if not line or line.startswith('#'):
|
||||
continue
|
||||
if '=' in line:
|
||||
key, val = line.split('=', 1)
|
||||
is_button = any(bk in key for bk in button_keys)
|
||||
if is_button and len(val) > 20:
|
||||
print(f"{key}={val} ({len(val)} chars)")
|
||||
56
pom.xml
Normal file
56
pom.xml
Normal file
@@ -0,0 +1,56 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>3.3.2</version>
|
||||
<relativePath/>
|
||||
</parent>
|
||||
|
||||
<groupId>com.example</groupId>
|
||||
<artifactId>whatsapp-automation</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>WhatsApp Automation</name>
|
||||
<description>Spring Boot application for WhatsApp automation</description>
|
||||
|
||||
<properties>
|
||||
<java.version>21</java.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
54
replace.py
Normal file
54
replace.py
Normal file
@@ -0,0 +1,54 @@
|
||||
import re
|
||||
|
||||
with open('src/main/java/com/example/whatsappautomation/service/ChatbotService.java', 'r') as f:
|
||||
content = f.read()
|
||||
|
||||
# Pattern to match sendInteractiveList(...) up to the null);
|
||||
# We need to capture bodyText (arg 1), ids (arg 4), titles (arg 5).
|
||||
# Using a python script to parse the balanced parentheses might be better.
|
||||
|
||||
def replace_calls(text):
|
||||
start = 0
|
||||
while True:
|
||||
idx = text.find('sendInteractiveList(', start)
|
||||
if idx == -1:
|
||||
break
|
||||
|
||||
# find the end of this statement
|
||||
end_idx = text.find(');', idx)
|
||||
if end_idx == -1:
|
||||
break
|
||||
|
||||
call_str = text[idx:end_idx+2]
|
||||
|
||||
# We need to extract the parts. It's safer to just split by "new String[]{"
|
||||
# because we know args 4 and 5 are array allocations.
|
||||
|
||||
parts = call_str.split('new String[]{')
|
||||
if len(parts) == 3:
|
||||
# parts[0] has 'sendInteractiveList(bodyText, buttonText, sectionTitle, \n'
|
||||
# parts[1] has 'ids...}, \n'
|
||||
# parts[2] has 'titles...}, null);'
|
||||
|
||||
# Extract bodyText from parts[0]
|
||||
# sendInteractiveList(arg1, arg2, arg3,
|
||||
# We want just arg1!
|
||||
p0 = parts[0][len('sendInteractiveList('):].strip()
|
||||
# It's tricky to parse commas.
|
||||
pass
|
||||
|
||||
print("Doing regex...")
|
||||
|
||||
# Actually, let's just use a simple regex if they are formatted consistently.
|
||||
# Almost all of them are:
|
||||
# sendInteractiveList( BODY, BTN, TITLE,
|
||||
# new String[]{IDS},
|
||||
# new String[]{TITLES}, null);
|
||||
|
||||
pattern = r'sendInteractiveList\((.*?),\s*[^,]+,\s*[^,]+,\s*(new String\[\]\{.*?\})\s*,\s*(new String\[\]\{.*?\})\s*,\s*null\);'
|
||||
replaced = re.sub(pattern, r'sendPaginatedButtons(state, \1, \2, \3);', content, flags=re.DOTALL)
|
||||
|
||||
with open('src/main/java/com/example/whatsappautomation/service/ChatbotService.java', 'w') as f:
|
||||
f.write(replaced)
|
||||
|
||||
print("Done")
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.example.whatsappautomation;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class WhatsAppAutomationApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(WhatsAppAutomationApplication.class, args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
package com.example.whatsappautomation.controller;
|
||||
|
||||
import com.example.whatsappautomation.service.ChatbotService;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.*;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/webhook")
|
||||
public class WhatsAppWebhookController {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(WhatsAppWebhookController.class);
|
||||
|
||||
@Value("${whatsapp.verify-token}")
|
||||
private String verifyToken;
|
||||
|
||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
private final ChatbotService chatbotService;
|
||||
|
||||
public WhatsAppWebhookController(ChatbotService chatbotService) {
|
||||
this.chatbotService = chatbotService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Webhook verification endpoint for Meta/WhatsApp.
|
||||
*/
|
||||
@GetMapping
|
||||
public ResponseEntity<String> verifyWebhook(
|
||||
@RequestParam("hub.mode") String mode,
|
||||
@RequestParam("hub.challenge") String challenge,
|
||||
@RequestParam("hub.verify_token") String token) {
|
||||
|
||||
logger.info("Received verification request: mode={}, token={}", mode, token);
|
||||
|
||||
if ("subscribe".equals(mode) && verifyToken.equals(token)) {
|
||||
logger.info("Webhook verified successfully!");
|
||||
return ResponseEntity.ok(challenge);
|
||||
} else {
|
||||
logger.warn("Webhook verification failed. Provided token: {}", token);
|
||||
return ResponseEntity.status(HttpStatus.FORBIDDEN).body("Verification failed");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Webhook event handler endpoint.
|
||||
*/
|
||||
@PostMapping
|
||||
public ResponseEntity<String> receive(@RequestBody String body) {
|
||||
System.out.println("Received:");
|
||||
System.out.println(body);
|
||||
|
||||
try {
|
||||
JsonNode payload = objectMapper.readTree(body);
|
||||
if (payload.has("entry")) {
|
||||
JsonNode entryArray = payload.get("entry");
|
||||
if (entryArray.isArray() && entryArray.size() > 0) {
|
||||
JsonNode changesArray = entryArray.get(0).get("changes");
|
||||
if (changesArray != null && changesArray.isArray() && changesArray.size() > 0) {
|
||||
JsonNode value = changesArray.get(0).get("value");
|
||||
if (value != null && value.has("messages")) {
|
||||
JsonNode messagesArray = value.get("messages");
|
||||
if (messagesArray.isArray() && messagesArray.size() > 0) {
|
||||
JsonNode message = messagesArray.get(0);
|
||||
String from = message.get("from").asText();
|
||||
|
||||
// Avoid processing status changes/read receipts as incoming messages
|
||||
String textBody = null;
|
||||
if (message.has("text")) {
|
||||
textBody = message.get("text").get("body").asText();
|
||||
} else if (message.has("interactive")) {
|
||||
JsonNode interactive = message.get("interactive");
|
||||
if (interactive.has("button_reply")) {
|
||||
textBody = interactive.get("button_reply").get("id").asText();
|
||||
} else if (interactive.has("list_reply")) {
|
||||
textBody = interactive.get("list_reply").get("id").asText();
|
||||
}
|
||||
}
|
||||
if (textBody != null) {
|
||||
String phoneNumberId = value.get("metadata").get("phone_number_id").asText();
|
||||
// Delegate to Chatbot Service
|
||||
chatbotService.processMessage(from, textBody, phoneNumberId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("Error processing webhook payload", e);
|
||||
}
|
||||
|
||||
return ResponseEntity.ok("EVENT_RECEIVED");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.example.whatsappautomation.entity;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
|
||||
@Entity
|
||||
@Table(name = "appointment")
|
||||
public class Appointment {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
private String phoneNumber;
|
||||
private String patientId;
|
||||
private String appointmentId;
|
||||
private String department;
|
||||
private String doctor;
|
||||
private String appointmentDate;
|
||||
private String appointmentTime;
|
||||
private String fee;
|
||||
private String status;
|
||||
|
||||
// Getters and Setters
|
||||
public Long getId() { return id; }
|
||||
public void setId(Long id) { this.id = id; }
|
||||
public String getPhoneNumber() { return phoneNumber; }
|
||||
public void setPhoneNumber(String phoneNumber) { this.phoneNumber = phoneNumber; }
|
||||
public String getPatientId() { return patientId; }
|
||||
public void setPatientId(String patientId) { this.patientId = patientId; }
|
||||
public String getAppointmentId() { return appointmentId; }
|
||||
public void setAppointmentId(String appointmentId) { this.appointmentId = appointmentId; }
|
||||
public String getDepartment() { return department; }
|
||||
public void setDepartment(String department) { this.department = department; }
|
||||
public String getDoctor() { return doctor; }
|
||||
public void setDoctor(String doctor) { this.doctor = doctor; }
|
||||
public String getAppointmentDate() { return appointmentDate; }
|
||||
public void setAppointmentDate(String appointmentDate) { this.appointmentDate = appointmentDate; }
|
||||
public String getAppointmentTime() { return appointmentTime; }
|
||||
public void setAppointmentTime(String appointmentTime) { this.appointmentTime = appointmentTime; }
|
||||
public String getFee() { return fee; }
|
||||
public void setFee(String fee) { this.fee = fee; }
|
||||
public String getStatus() { return status; }
|
||||
public void setStatus(String status) { this.status = status; }
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.example.whatsappautomation.entity;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
|
||||
@Entity
|
||||
@Table(name = "service_booking")
|
||||
public class ServiceBooking {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
private String phoneNumber;
|
||||
private String patientId;
|
||||
private String bookingId;
|
||||
private String serviceName;
|
||||
private String price;
|
||||
private String address;
|
||||
private String bookingDate;
|
||||
private String bookingTime;
|
||||
private String status;
|
||||
|
||||
// Getters and Setters
|
||||
public Long getId() { return id; }
|
||||
public void setId(Long id) { this.id = id; }
|
||||
public String getPhoneNumber() { return phoneNumber; }
|
||||
public void setPhoneNumber(String phoneNumber) { this.phoneNumber = phoneNumber; }
|
||||
public String getPatientId() { return patientId; }
|
||||
public void setPatientId(String patientId) { this.patientId = patientId; }
|
||||
public String getBookingId() { return bookingId; }
|
||||
public void setBookingId(String bookingId) { this.bookingId = bookingId; }
|
||||
public String getServiceName() { return serviceName; }
|
||||
public void setServiceName(String serviceName) { this.serviceName = serviceName; }
|
||||
public String getPrice() { return price; }
|
||||
public void setPrice(String price) { this.price = price; }
|
||||
public String getAddress() { return address; }
|
||||
public void setAddress(String address) { this.address = address; }
|
||||
public String getBookingDate() { return bookingDate; }
|
||||
public void setBookingDate(String bookingDate) { this.bookingDate = bookingDate; }
|
||||
public String getBookingTime() { return bookingTime; }
|
||||
public void setBookingTime(String bookingTime) { this.bookingTime = bookingTime; }
|
||||
public String getStatus() { return status; }
|
||||
public void setStatus(String status) { this.status = status; }
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.example.whatsappautomation.entity;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
|
||||
@Entity
|
||||
@Table(name = "test_booking")
|
||||
public class TestBooking {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
private String phoneNumber;
|
||||
private String bookingId;
|
||||
private String packageName;
|
||||
private String price;
|
||||
private String collectionType;
|
||||
private String address;
|
||||
private String bookingDate;
|
||||
private String bookingTime;
|
||||
private String patientId;
|
||||
private String status;
|
||||
|
||||
// Getters and Setters
|
||||
public Long getId() { return id; }
|
||||
public void setId(Long id) { this.id = id; }
|
||||
public String getPhoneNumber() { return phoneNumber; }
|
||||
public void setPhoneNumber(String phoneNumber) { this.phoneNumber = phoneNumber; }
|
||||
public String getBookingId() { return bookingId; }
|
||||
public void setBookingId(String bookingId) { this.bookingId = bookingId; }
|
||||
public String getPackageName() { return packageName; }
|
||||
public void setPackageName(String packageName) { this.packageName = packageName; }
|
||||
public String getPrice() { return price; }
|
||||
public void setPrice(String price) { this.price = price; }
|
||||
public String getCollectionType() { return collectionType; }
|
||||
public void setCollectionType(String collectionType) { this.collectionType = collectionType; }
|
||||
public String getAddress() { return address; }
|
||||
public void setAddress(String address) { this.address = address; }
|
||||
public String getBookingDate() { return bookingDate; }
|
||||
public void setBookingDate(String bookingDate) { this.bookingDate = bookingDate; }
|
||||
public String getBookingTime() { return bookingTime; }
|
||||
public void setBookingTime(String bookingTime) { this.bookingTime = bookingTime; }
|
||||
public String getPatientId() { return patientId; }
|
||||
public void setPatientId(String patientId) { this.patientId = patientId; }
|
||||
public String getStatus() { return status; }
|
||||
public void setStatus(String status) { this.status = status; }
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
package com.example.whatsappautomation.entity;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name = "user_state")
|
||||
public class UserState {
|
||||
|
||||
@Id
|
||||
private String phoneNumber;
|
||||
|
||||
private String patientId;
|
||||
private String state;
|
||||
private String category;
|
||||
private String subCategory;
|
||||
private String selectedItem;
|
||||
private String price;
|
||||
private String address;
|
||||
private String bookingDate;
|
||||
private String bookingTime;
|
||||
private String languagePreference = "en";
|
||||
private int menuPage = 0;
|
||||
|
||||
public UserState() {}
|
||||
|
||||
public UserState(String phoneNumber) {
|
||||
this.phoneNumber = phoneNumber;
|
||||
this.state = "LANGUAGE_SELECTION";
|
||||
this.patientId = "PAT-" + (100000 + new java.util.Random().nextInt(900000));
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
this.state = "LANGUAGE_SELECTION";
|
||||
this.category = null;
|
||||
this.subCategory = null;
|
||||
this.selectedItem = null;
|
||||
this.price = null;
|
||||
this.address = null;
|
||||
this.bookingDate = null;
|
||||
this.bookingTime = null;
|
||||
this.menuPage = 0;
|
||||
}
|
||||
|
||||
public String getPhoneNumber() {
|
||||
return phoneNumber;
|
||||
}
|
||||
|
||||
public void setPhoneNumber(String phoneNumber) {
|
||||
this.phoneNumber = phoneNumber;
|
||||
}
|
||||
|
||||
public String getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public void setState(String state) {
|
||||
if (!state.equals(this.state)) {
|
||||
this.menuPage = 0;
|
||||
}
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public String getCategory() {
|
||||
return category;
|
||||
}
|
||||
|
||||
public void setCategory(String category) {
|
||||
this.category = category;
|
||||
}
|
||||
|
||||
public String getSubCategory() {
|
||||
return subCategory;
|
||||
}
|
||||
|
||||
public void setSubCategory(String subCategory) {
|
||||
this.subCategory = subCategory;
|
||||
}
|
||||
|
||||
public String getSelectedItem() {
|
||||
return selectedItem;
|
||||
}
|
||||
|
||||
public void setSelectedItem(String selectedItem) {
|
||||
this.selectedItem = selectedItem;
|
||||
}
|
||||
|
||||
public String getPrice() {
|
||||
return price;
|
||||
}
|
||||
|
||||
public void setPrice(String price) {
|
||||
this.price = price;
|
||||
}
|
||||
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress(String address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
public String getBookingDate() {
|
||||
return bookingDate;
|
||||
}
|
||||
|
||||
public void setBookingDate(String bookingDate) {
|
||||
this.bookingDate = bookingDate;
|
||||
}
|
||||
|
||||
public String getBookingTime() {
|
||||
return bookingTime;
|
||||
}
|
||||
|
||||
public void setBookingTime(String bookingTime) {
|
||||
this.bookingTime = bookingTime;
|
||||
}
|
||||
|
||||
public String getPatientId() {
|
||||
return patientId;
|
||||
}
|
||||
|
||||
public void setPatientId(String patientId) {
|
||||
this.patientId = patientId;
|
||||
}
|
||||
|
||||
public String getLanguagePreference() {
|
||||
return languagePreference;
|
||||
}
|
||||
|
||||
public void setLanguagePreference(String languagePreference) {
|
||||
this.languagePreference = languagePreference;
|
||||
}
|
||||
|
||||
public int getMenuPage() {
|
||||
return menuPage;
|
||||
}
|
||||
|
||||
public void setMenuPage(int menuPage) {
|
||||
this.menuPage = menuPage;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.example.whatsappautomation.repository;
|
||||
|
||||
import com.example.whatsappautomation.entity.Appointment;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Repository
|
||||
public interface AppointmentRepository extends JpaRepository<Appointment, Long> {
|
||||
List<Appointment> findByPhoneNumber(String phoneNumber);
|
||||
Optional<Appointment> findByAppointmentId(String appointmentId);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.example.whatsappautomation.repository;
|
||||
|
||||
import com.example.whatsappautomation.entity.ServiceBooking;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface ServiceBookingRepository extends JpaRepository<ServiceBooking, Long> {
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.example.whatsappautomation.repository;
|
||||
|
||||
import com.example.whatsappautomation.entity.TestBooking;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface TestBookingRepository extends JpaRepository<TestBooking, Long> {
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.example.whatsappautomation.repository;
|
||||
|
||||
import com.example.whatsappautomation.entity.UserState;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface UserStateRepository extends JpaRepository<UserState, String> {
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
17
src/main/resources/application.properties
Normal file
17
src/main/resources/application.properties
Normal file
@@ -0,0 +1,17 @@
|
||||
spring.application.name=whatsapp-automation
|
||||
server.port=8085
|
||||
|
||||
whatsapp.access-token=EAAOZCONMSXCkBSIUAa6NJVDZAgN6yC6DyrsBefMhijoVWZA7613gQecnXtvEYFZASHR933rDPh3fjnLzUqbS8Qgbcy0bfZCGTDyq3ceB2zA4c3ZBn4LzYZC622K1PRQGWGyuuESnTk3cwGeJE6IsesTAcJZB7wtwbkvHGLJAVqtqo41HCLWjrCHjZCI12NrFmmgPQiZCEx8mz3fBMJLEOovhVZAvGZCwTOj0agXfaeUXu3sFGHlLN3ZCO3lIEhUkNMu0bcgv02nhUCWYqbJJCZBKJNmGpygDcZD
|
||||
whatsapp.verify-token=my_whatsapp_verify_token_123
|
||||
|
||||
spring.datasource.url=jdbc:postgresql://localhost:5432/rmc_bot
|
||||
spring.datasource.username=postgres
|
||||
spring.datasource.password=postgres
|
||||
spring.jpa.hibernate.ddl-auto=update
|
||||
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
|
||||
spring.jpa.show-sql=true
|
||||
|
||||
|
||||
|
||||
|
||||
spring.messages.encoding=UTF-8
|
||||
8
src/main/resources/messages.properties
Normal file
8
src/main/resources/messages.properties
Normal file
@@ -0,0 +1,8 @@
|
||||
welcome.body=👋 Welcome to Rajalakshmi Medical College! I'm your virtual healthcare assistant. Please choose one of the following options:
|
||||
menu.btn.services=My Services
|
||||
menu.btn.tests=My Tests
|
||||
menu.btn.booking=Book Appointment
|
||||
menu.services=🩺 My Services\n\nPlease choose a category:\n1️⃣ Nursing Services\n2️⃣ Attender Services\n3️⃣ Physiotherapy\n4️⃣ Medical Procedures\n5️⃣ Digital Consultation\n6️⃣ Home Care Packages\n\nReply with the option number.
|
||||
menu.tests=🏥 Rajalakshmi Medical College\nWelcome to Laboratory Services.\n\nPlease choose a Health Package Category.\n1️⃣ Fever Panel Tests\n2️⃣ Heart Health\n3️⃣ Joint & Bone\n4️⃣ Master Health Check Plans\n5️⃣ Pregnancy\n6️⃣ Sugar Control Series\n7️⃣ Women's Wellness Plans\n8️⃣ Search Test\n\nReply with the option number.
|
||||
menu.doctor=👨⚕️ Doctor Appointment\nPlease choose an option\n1️⃣ Book New Appointment\n2️⃣ View My Appointments\n3️⃣ Reschedule Appointment\n4️⃣ Cancel Appointment\n\nReply with the option number.
|
||||
invalid.option=Invalid option. Please try again.
|
||||
209
src/main/resources/messages_en.properties
Normal file
209
src/main/resources/messages_en.properties
Normal file
@@ -0,0 +1,209 @@
|
||||
welcome.body=👋 Welcome to Rajalakshmi Medical College! I'm your virtual healthcare assistant. Please choose one of the following options:
|
||||
menu.btn.services=My Services
|
||||
menu.btn.tests=My Tests
|
||||
menu.btn.booking=Book Appointment
|
||||
menu.services=🩺 My Services\n\nPlease choose a category:\n1️⃣ Nursing Services\n2️⃣ Attender Services\n3️⃣ Physiotherapy\n4️⃣ Medical Procedures\n5️⃣ Digital Consultation\n6️⃣ Home Care Packages\n\nReply with the option number.
|
||||
menu.tests=🏥 Rajalakshmi Medical College\nWelcome to Laboratory Services.\n\nPlease choose a Health Package Category.\n1️⃣ Fever Panel Tests\n2️⃣ Heart Health\n3️⃣ Joint & Bone\n4️⃣ Master Health Check Plans\n5️⃣ Pregnancy\n6️⃣ Sugar Control Series\n7️⃣ Women's Wellness Plans\n8️⃣ Search Test\n\nReply with the option number.
|
||||
menu.doctor=👨⚕️ Doctor Appointment\nPlease choose an option\n1️⃣ Book New Appointment\n2️⃣ View My Appointments\n3️⃣ Reschedule Appointment\n4️⃣ Cancel Appointment\n\nReply with the option number.
|
||||
invalid.option=Invalid option. Please try again.
|
||||
|
||||
# Tests Menu
|
||||
tests.main.title=🩺 My Tests\n\nPlease choose a category:
|
||||
tests.main.btn=View Tests
|
||||
tests.main.list=Test Categories
|
||||
tests.main.opt1=Fever Panel
|
||||
tests.main.opt2=Heart Health
|
||||
tests.main.opt3=Joint & Bone
|
||||
tests.main.opt4=Master Health
|
||||
tests.main.opt5=Pregnancy
|
||||
tests.main.opt6=Sugar Control
|
||||
tests.main.opt7=Women's Wellness
|
||||
|
||||
tests.fever.title=🌡️ Fever Panel Tests
|
||||
tests.fever.btn=View Tests
|
||||
tests.fever.list=Tests
|
||||
tests.fever.opt1=Fever Ultra Panel
|
||||
tests.fever.opt2=CBC
|
||||
tests.fever.opt3=IgE Total Serum
|
||||
tests.fever.opt4=LFT
|
||||
tests.fever.opt5=Stool Occult Blood
|
||||
tests.fever.desc1=₹1,999 (11 Tests)
|
||||
tests.fever.desc2=₹300
|
||||
tests.fever.desc3=₹400
|
||||
tests.fever.desc4=₹500
|
||||
tests.fever.desc5=₹250
|
||||
|
||||
tests.heart.title=❤️ Heart Health Packages
|
||||
tests.heart.btn=View Packages
|
||||
tests.heart.list=Packages
|
||||
tests.heart.opt1=Heart Health Plus
|
||||
tests.heart.opt2=Amaya Int Cardiac
|
||||
tests.heart.opt3=Cardiac Pkg - Amaya
|
||||
tests.heart.opt4=Healthy Heart Basic
|
||||
tests.heart.opt5=Heart Basic
|
||||
tests.heart.opt6=Heart Master
|
||||
tests.heart.opt7=Hypertension Comp
|
||||
|
||||
tests.joint.title=🦴 Joint & Bone Packages
|
||||
tests.joint.opt1=Joint Care Plus
|
||||
tests.joint.opt2=Arthritis Package
|
||||
|
||||
tests.master.title=🩺 Master Health Check Plans
|
||||
tests.master.btn=View Plans
|
||||
tests.master.list=Plans
|
||||
tests.master.opt1=Master Health Basic
|
||||
tests.master.opt2=Master Health Exec
|
||||
tests.master.opt3=Master Health Prem
|
||||
|
||||
tests.preg.title=🤰 Pregnancy Packages
|
||||
tests.preg.opt1=Pregnancy Basic
|
||||
tests.preg.opt2=Pregnancy Advanced
|
||||
|
||||
tests.sugar.title=🩸 Sugar Control Series
|
||||
tests.sugar.btn=View Packages
|
||||
tests.sugar.list=Packages
|
||||
tests.sugar.opt1=Sugar Control Basic
|
||||
tests.sugar.opt2=Sugar Control Plus
|
||||
tests.sugar.opt3=Diabetes Monitoring
|
||||
tests.sugar.opt4=HbA1c Comprehensive
|
||||
|
||||
tests.women.title=👩 Women's Wellness Plans
|
||||
tests.women.opt1=Wellness Basic
|
||||
tests.women.opt2=Wellness Advanced
|
||||
|
||||
# Doctor Menu
|
||||
doc.main.title=🩺 Doctor Appointments
|
||||
doc.main.btn=View Options
|
||||
doc.main.list=Options
|
||||
doc.main.opt1=Book New Appointment
|
||||
doc.main.opt2=View Appointments
|
||||
doc.main.opt3=Reschedule Appointment
|
||||
doc.main.opt4=Cancel Appointment
|
||||
|
||||
doc.dept.title=Please select a department.
|
||||
doc.dept.btn=View Departments
|
||||
doc.dept.list=Departments
|
||||
doc.dept.opt1=General Medicine
|
||||
doc.dept.opt2=Cardiology
|
||||
doc.dept.opt3=Orthopedics
|
||||
doc.dept.opt4=Neurology
|
||||
doc.dept.opt5=Pediatrics
|
||||
doc.dept.opt6=Gynecology
|
||||
doc.dept.opt7=Dermatology
|
||||
doc.dept.opt8=ENT
|
||||
doc.dept.opt9=Ophthalmology
|
||||
|
||||
doc.sel.title=Available Doctors
|
||||
doc.sel.btn=Select Doctor
|
||||
doc.sel.list=Doctors
|
||||
|
||||
doc.date.title=Available Dates
|
||||
doc.date.btn=Select Date
|
||||
doc.date.list=Dates
|
||||
|
||||
doc.time.title=Available Time Slots
|
||||
doc.time.btn=Select Time
|
||||
doc.time.list=Time Slots
|
||||
|
||||
doc.summary.title=Appointment Summary
|
||||
doc.summary.btn=Select Option
|
||||
doc.summary.list=Options
|
||||
doc.summary.confirm=Confirm Booking
|
||||
doc.summary.change=Change Time
|
||||
doc.summary.cancel=Cancel
|
||||
|
||||
doc.reschedule.ask=Please enter your Appointment ID.
|
||||
doc.cancel.ask=Please enter your Appointment ID.
|
||||
doc.no_apps=You have no upcoming appointments.
|
||||
|
||||
# Confirmations
|
||||
booking.service.confirm=✅ Booking Confirmed\nService: {0}\nAmount: {1}\n\nPlease share:\n📍 Service Address\nor\n📍 Live Location
|
||||
booking.ask_address=Please enter your address.
|
||||
booking.ask_date=Thank you.\nPlease reply with your preferred date.\n\n📅 DD/MM/YYYY
|
||||
booking.ask_time.title=Please choose the preferred start time.
|
||||
booking.ask_time.btn=Select Time
|
||||
booking.ask_time.list=Available Slots
|
||||
booking.ask_time.opt1=9 AM - 1 PM
|
||||
booking.ask_time.opt2=1 PM - 5 PM
|
||||
booking.ask_time.opt3=5 PM - 9 PM
|
||||
|
||||
booking.service.success=✅ Service Booked Successfully\nBooking ID:\n{0}\nPatient ID:\n{1}\n\nPlease provide your Patient ID at the hospital billing desk for payment.\n\nOur nursing team will contact you shortly.\nThank you for choosing Rajalakshmi Medical College.
|
||||
|
||||
booking.test.confirm_pkg=Selected Package\n\n{0}\nPrice:\n{1}\nWould you like to continue?
|
||||
booking.test.btn_book=Book Now
|
||||
booking.test.btn_back=Back
|
||||
booking.test.ask_coll=How would you like to provide your sample?
|
||||
booking.test.coll_home=Home Collection
|
||||
booking.test.coll_visit=Visit Laboratory
|
||||
booking.test.ask_date=Please reply with your preferred date.\n📅 DD/MM/YYYY
|
||||
booking.test.ask_time.title=Choose your preferred time slot.
|
||||
booking.test.ask_time.btn=Select Slot
|
||||
booking.test.ask_time.list=Time Slots
|
||||
booking.test.opt1=7 AM - 9 AM
|
||||
booking.test.opt2=9 AM - 11 AM
|
||||
booking.test.opt3=11 AM - 1 PM
|
||||
|
||||
booking.test.success=✅ Booking Successful\nBooking ID:\n{0}\nPatient ID:\n{1}\n\nPackage:\n{2}\nAmount:\n{3}\n\nPlease provide your Patient ID at the hospital billing desk for payment.\n\nCollection:\n{4}\nTechnician Visit\n{5}\n{6}\n\nThank you for choosing Rajalakshmi Medical College.
|
||||
|
||||
# Final Main Menu
|
||||
menu.final.title=Would you like to go back to the Main Menu?
|
||||
menu.final.yes=Main Menu
|
||||
menu.final.no=Exit
|
||||
|
||||
doc.booking.success=✅ Appointment Booked Successfully\n\nAppointment ID:\n{0}\n\nPatient ID:\n{1}\n\nPlease provide your Patient ID at the hospital billing desk for payment.\n\nDoctor:\n{2}\n\nDepartment:\n{3}\n\nDate:\n{4}\n\nTime:\n{5}\n\nPlease arrive 15 minutes before your appointment.\nThank you for choosing Rajalakshmi Medical College
|
||||
doc.view_apps.title=Your Upcoming Appointments
|
||||
doc.view_apps.item=Appointment ID:\n{0}\nDoctor:\n{1}\nDepartment:\n{2}\nDate:\n{3}\nTime:\n{4}\nStatus:\n✅ {5}
|
||||
doc.view_apps.btn=Select Option
|
||||
doc.view_apps.list=Options
|
||||
doc.view_apps.opt1=Cancel Appointment
|
||||
doc.view_apps.opt2=Reschedule
|
||||
doc.view_apps.opt3=Main Menu
|
||||
doc.invalid_id=Invalid Appointment ID. Please try again.
|
||||
doc.reschedule.time.title=Available New Time Slots
|
||||
doc.reschedule.time.btn=Select Time
|
||||
doc.reschedule.time.list=Time Slots
|
||||
doc.reschedule.success=✅ Appointment Rescheduled\nDoctor:\n{0}\nNew Time:\n{1}\nDate:\n{2}
|
||||
error.generic=Error. Please try again.
|
||||
doc.cancel.confirm_msg=Are you sure you want to cancel?
|
||||
doc.cancel.yes=Yes
|
||||
doc.cancel.no=No
|
||||
doc.cancel.success=✅ Appointment Cancelled Successfully.
|
||||
|
||||
pagination.next=Next ➡️
|
||||
# Services Menu
|
||||
services.nursing.title=💉 Nursing Services\n\nChoose:
|
||||
services.nursing.opt1=Male Nurse
|
||||
services.nursing.opt2=Female Nurse
|
||||
services.attender.title=🤝 Attender Services
|
||||
services.attender.opt1=Male Attender
|
||||
services.attender.opt2=Female Attender
|
||||
services.physio.title=🏃 Physiotherapy\n\nPrice: ₹700\n\nWould you like to book?
|
||||
services.physio.yes=Yes
|
||||
services.physio.no=No
|
||||
services.medproc.title=🩺 Medical Procedures
|
||||
services.medproc.btn=View Options
|
||||
services.medproc.list=Procedures
|
||||
services.medproc.opt1=IM Injection
|
||||
services.medproc.opt2=IV Injection
|
||||
services.medproc.opt3=Nebulization
|
||||
services.medproc.opt4=Dressing Charges
|
||||
services.medproc.opt5=Catheterization
|
||||
services.digital.title=💻 Digital Consultation\n\nConsultation Fee: ₹750\n\nWould you like to schedule?
|
||||
services.digital.yes=Yes
|
||||
services.digital.back=Back
|
||||
services.homecare.title=🏡 Home Care Packages
|
||||
services.homecare.btn=View Services
|
||||
services.homecare.list=Services
|
||||
services.homecare.opt1=Nursing Care
|
||||
services.homecare.opt2=Attender Care
|
||||
services.homecare.opt3=Physiotherapy
|
||||
services.homecare.opt4=Medical Procedures
|
||||
services.main.title=🩺 My Services\n\nPlease choose a category:
|
||||
services.main.btn=View Services
|
||||
services.main.list=Service Categories
|
||||
services.main.opt1=Nursing Services
|
||||
services.main.opt2=Attender Services
|
||||
services.main.opt3=Physiotherapy
|
||||
services.main.opt4=Medical Procedures
|
||||
services.main.opt5=Digital Consult
|
||||
services.main.opt6=Home Care Packages
|
||||
209
src/main/resources/messages_ta.properties
Normal file
209
src/main/resources/messages_ta.properties
Normal file
@@ -0,0 +1,209 @@
|
||||
welcome.body=👋 ராஜலட்சுமி மருத்துவக் கல்லூரிக்கு வரவேற்கிறோம்! நான் உங்கள் மெய்நிகர் சுகாதார உதவியாளர். தயவுசெய்து கீழ்க்கண்ட விருப்பங்களில் ஒன்றைத் தேர்ந்தெடுக்கவும்:
|
||||
menu.btn.services=என் சேவைகள்
|
||||
menu.btn.tests=பரிசோதனைகள்
|
||||
menu.btn.booking=முன்பதிவு செய்க
|
||||
menu.services=🩺 எனது சேவைகள்\n\nதயவுசெய்து ஒரு வகையைத் தேர்ந்தெடுக்கவும்:\n1️⃣ செவிலியர் சேவைகள்\n2️⃣ உதவியாளர் சேவைகள்\n3️⃣ பிசியோதெரபி\n4️⃣ மருத்துவ நடைமுறைகள்\n5️⃣ டிஜிட்டல் ஆலோசனை\n6️⃣ வீட்டு பராமரிப்பு தொகுப்புகள்\n\nவிருப்ப எண்ணுடன் பதிலளிக்கவும்.
|
||||
menu.tests=🏥 ராஜலட்சுமி மருத்துவக் கல்லூரி\nஆய்வக சேவைகளுக்கு வரவேற்கிறோம்.\n\nசுகாதாரத் தொகுப்பு வகையைத் தேர்ந்தெடுக்கவும்.\n1️⃣ காய்ச்சல் பரிசோதனைகள்\n2️⃣ இதய ஆரோக்கியம்\n3️⃣ மூட்டு மற்றும் எலும்பு\n4️⃣ முழுமையான உடல் பரிசோதனை\n5️⃣ கர்ப்ப காலம்\n6️⃣ சர்க்கரை கட்டுப்பாடு\n7️⃣ பெண்கள் நல்வாழ்வு\n8️⃣ பரிசோதனையைத் தேடுங்கள்\n\nவிருப்ப எண்ணுடன் பதிலளிக்கவும்.
|
||||
menu.doctor=👨⚕️ மருத்துவர் சந்திப்பு\nதயவுசெய்து ஒரு விருப்பத்தைத் தேர்ந்தெடுக்கவும்\n1️⃣ புதிய சந்திப்பை முன்பதிவு செய்ய\n2️⃣ எனது சந்திப்புகளைப் பார்க்க\n3️⃣ சந்திப்பை மாற்றியமைக்க\n4️⃣ சந்திப்பை ரத்து செய்ய\n\nவிருப்ப எண்ணுடன் பதிலளிக்கவும்.
|
||||
invalid.option=தவறான விருப்பம். தயவுசெய்து மீண்டும் முயற்சிக்கவும்.
|
||||
|
||||
# Tests Menu
|
||||
tests.main.title=🩺 எனது பரிசோதனைகள்\n\nதயவுசெய்து ஒரு வகையைத் தேர்ந்தெடுக்கவும்:
|
||||
tests.main.btn=பரிசோதனைகளை காண்க
|
||||
tests.main.list=பரிசோதனை பிரிவுகள்
|
||||
tests.main.opt1=காய்ச்சல் பரிசோதனை
|
||||
tests.main.opt2=இதய ஆரோக்கியம்
|
||||
tests.main.opt3=மூட்டு & எலும்பு
|
||||
tests.main.opt4=முழு உடல் பரிசோதனை
|
||||
tests.main.opt5=கர்ப்ப காலம்
|
||||
tests.main.opt6=சர்க்கரை கட்டுப்பாடு
|
||||
tests.main.opt7=பெண்கள் நல்வாழ்வு
|
||||
|
||||
tests.fever.title=🌡️ காய்ச்சல் பரிசோதனைகள்
|
||||
tests.fever.btn=பரிசோதனைகளை காண்க
|
||||
tests.fever.list=பரிசோதனைகள்
|
||||
tests.fever.opt1=காய்ச்சல் அல்ட்ரா
|
||||
tests.fever.opt2=CBC
|
||||
tests.fever.opt3=IgE Total Serum
|
||||
tests.fever.opt4=LFT
|
||||
tests.fever.opt5=மலம் பரிசோதனை
|
||||
tests.fever.desc1=₹1,999 (11 பரிசோதனைகள்)
|
||||
tests.fever.desc2=₹300
|
||||
tests.fever.desc3=₹400
|
||||
tests.fever.desc4=₹500
|
||||
tests.fever.desc5=₹250
|
||||
|
||||
tests.heart.title=❤️ இதய ஆரோக்கிய தொகுப்புகள்
|
||||
tests.heart.btn=தொகுப்புகளை காண்க
|
||||
tests.heart.list=தொகுப்புகள்
|
||||
tests.heart.opt1=ஹார்ட் ஹெல்த் பிளஸ்
|
||||
tests.heart.opt2=அமயா கார்டியாக்
|
||||
tests.heart.opt3=அமயா பேக்கேஜ்
|
||||
tests.heart.opt4=ஹெல்தி ஹார்ட் பேசிக்
|
||||
tests.heart.opt5=ஹார்ட் பேசிக்
|
||||
tests.heart.opt6=ஹார்ட் மாஸ்டர்
|
||||
tests.heart.opt7=உயர் ரத்த அழுத்தம்
|
||||
|
||||
tests.joint.title=🦴 மூட்டு மற்றும் எலும்பு தொகுப்புகள்
|
||||
tests.joint.opt1=ஜாயின்ட் கேர் பிளஸ்
|
||||
tests.joint.opt2=ஆர்த்ரிடிஸ் பேக்கேஜ்
|
||||
|
||||
tests.master.title=🩺 முழுமையான உடல் பரிசோதனை திட்டங்கள்
|
||||
tests.master.btn=திட்டங்களை காண்க
|
||||
tests.master.list=திட்டங்கள்
|
||||
tests.master.opt1=மாஸ்டர் பேசிக்
|
||||
tests.master.opt2=மாஸ்டர் எக்ஸிகியூட்
|
||||
tests.master.opt3=மாஸ்டர் பிரீமியம்
|
||||
|
||||
tests.preg.title=🤰 கர்ப்ப கால தொகுப்புகள்
|
||||
tests.preg.opt1=கர்ப்ப காலம் பேசிக்
|
||||
tests.preg.opt2=கர்ப்ப அட்வான்ஸ்டு
|
||||
|
||||
tests.sugar.title=🩸 சர்க்கரை கட்டுப்பாடு தொடர்
|
||||
tests.sugar.btn=தொகுப்புகளை காண்க
|
||||
tests.sugar.list=தொகுப்புகள்
|
||||
tests.sugar.opt1=சர்க்கரை பேசிக்
|
||||
tests.sugar.opt2=சர்க்கரை பிளஸ்
|
||||
tests.sugar.opt3=நீரிழிவு கண்காணிப்பு
|
||||
tests.sugar.opt4=HbA1c விரிவானது
|
||||
|
||||
tests.women.title=👩 பெண்கள் நல்வாழ்வு திட்டங்கள்
|
||||
tests.women.opt1=பெண்கள் பேசிக்
|
||||
tests.women.opt2=பெண்கள் அட்வான்ஸ்டு
|
||||
|
||||
# Doctor Menu
|
||||
doc.main.title=🩺 மருத்துவர் சந்திப்புகள்
|
||||
doc.main.btn=விருப்பங்களை காண்க
|
||||
doc.main.list=விருப்பங்கள்
|
||||
doc.main.opt1=புதிய முன்பதிவு
|
||||
doc.main.opt2=சந்திப்புகளை பார்
|
||||
doc.main.opt3=மாற்றியமைக்க
|
||||
doc.main.opt4=ரத்து செய்ய
|
||||
|
||||
doc.dept.title=தயவுசெய்து ஒரு துறையை தேர்ந்தெடுக்கவும்.
|
||||
doc.dept.btn=துறைகளை காண்க
|
||||
doc.dept.list=துறைகள்
|
||||
doc.dept.opt1=பொது மருத்துவம்
|
||||
doc.dept.opt2=இருதயவியல்
|
||||
doc.dept.opt3=எலும்பியல்
|
||||
doc.dept.opt4=நரம்பியல்
|
||||
doc.dept.opt5=குழந்தை மருத்துவம்
|
||||
doc.dept.opt6=மகப்பேறியல்
|
||||
doc.dept.opt7=தோல் மருத்துவம்
|
||||
doc.dept.opt8=காது மூக்கு தொண்டை
|
||||
doc.dept.opt9=கண் மருத்துவம்
|
||||
|
||||
doc.sel.title=கிடைக்கும் மருத்துவர்கள்
|
||||
doc.sel.btn=மருத்துவரை தேர்ந்தெடுங்கள்
|
||||
doc.sel.list=மருத்துவர்கள்
|
||||
|
||||
doc.date.title=கிடைக்கும் தேதிகள்
|
||||
doc.date.btn=தேதியை தேர்ந்தெடுங்கள்
|
||||
doc.date.list=தேதிகள்
|
||||
|
||||
doc.time.title=கிடைக்கும் நேரங்கள்
|
||||
doc.time.btn=நேரத்தை தேர்ந்தெடுங்கள்
|
||||
doc.time.list=நேரங்கள்
|
||||
|
||||
doc.summary.title=சந்திப்பு சுருக்கம்
|
||||
doc.summary.btn=விருப்பத்தை தேர்ந்தெடுங்கள்
|
||||
doc.summary.list=விருப்பங்கள்
|
||||
doc.summary.confirm=உறுதிப்படுத்துக
|
||||
doc.summary.change=நேரத்தை மாற்றவும்
|
||||
doc.summary.cancel=ரத்து செய்யவும்
|
||||
|
||||
doc.reschedule.ask=தயவுசெய்து உங்கள் சந்திப்பு ஐடியை உள்ளிடவும்.
|
||||
doc.cancel.ask=தயவுசெய்து உங்கள் சந்திப்பு ஐடியை உள்ளிடவும்.
|
||||
doc.no_apps=உங்களுக்கு வரவிருக்கும் சந்திப்புகள் ஏதும் இல்லை.
|
||||
|
||||
# Confirmations
|
||||
booking.service.confirm=✅ முன்பதிவு உறுதி செய்யப்பட்டது\nசேவை: {0}\nகட்டணம்: {1}\n\nதயவுசெய்து பகிரவும்:\n📍 சேவை முகவரி\nஅல்லது\n📍 நேரலை இருப்பிடம் (Live Location)
|
||||
booking.ask_address=தயவுசெய்து உங்கள் முகவரியை உள்ளிடவும்.
|
||||
booking.ask_date=நன்றி.\nஉங்கள் விருப்பமான தேதியை உள்ளிடவும்.\n\n📅 DD/MM/YYYY
|
||||
booking.ask_time.title=விருப்பமான தொடக்க நேரத்தை தேர்வு செய்யவும்.
|
||||
booking.ask_time.btn=நேரத்தை தேர்ந்தெடுக்கவும்
|
||||
booking.ask_time.list=கிடைக்கும் நேரங்கள்
|
||||
booking.ask_time.opt1=காலை 9 - மதியம் 1
|
||||
booking.ask_time.opt2=மதியம் 1 - மாலை 5
|
||||
booking.ask_time.opt3=மாலை 5 - இரவு 9
|
||||
|
||||
booking.service.success=✅ சேவை வெற்றிகரமாக முன்பதிவு செய்யப்பட்டது\nமுன்பதிவு எண்:\n{0}\nநோயாளி எண்:\n{1}\n\nபணம் செலுத்த உங்கள் நோயாளி எண்ணை மருத்துவமனை பில்லிங் டெஸ்கில் வழங்கவும்.\n\nஎங்கள் செவிலியர் குழு உங்களை விரைவில் தொடர்புகொள்ளும்.\nராஜலட்சுமி மருத்துவக் கல்லூரியை தேர்ந்தெடுத்ததற்கு நன்றி.
|
||||
|
||||
booking.test.confirm_pkg=தேர்ந்தெடுக்கப்பட்ட தொகுப்பு\n\n{0}\nவிலை:\n{1}\nநீங்கள் தொடர விரும்புகிறீர்களா?
|
||||
booking.test.btn_book=முன்பதிவு செய்
|
||||
booking.test.btn_back=பின்செல்
|
||||
booking.test.ask_coll=மாதிரியை எவ்வாறு வழங்க விரும்புகிறீர்கள்?
|
||||
booking.test.coll_home=வீட்டு மாதிரி சேகரிப்பு
|
||||
booking.test.coll_visit=ஆய்வகத்திற்கு வருகை
|
||||
booking.test.ask_date=உங்கள் விருப்பமான தேதியை உள்ளிடவும்.\n📅 DD/MM/YYYY
|
||||
booking.test.ask_time.title=விருப்பமான நேரத்தை தேர்வு செய்யவும்.
|
||||
booking.test.ask_time.btn=நேரத்தை தேர்ந்தெடுக்கவும்
|
||||
booking.test.ask_time.list=நேரங்கள்
|
||||
booking.test.opt1=காலை 7 - காலை 9
|
||||
booking.test.opt2=காலை 9 - காலை 11
|
||||
booking.test.opt3=காலை 11 - மதியம் 1
|
||||
|
||||
booking.test.success=✅ முன்பதிவு வெற்றிகரமாக முடிந்தது\nமுன்பதிவு எண்:\n{0}\nநோயாளி எண்:\n{1}\n\nதொகுப்பு:\n{2}\nகட்டணம்:\n{3}\n\nபணம் செலுத்த உங்கள் நோயாளி எண்ணை மருத்துவமனை பில்லிங் டெஸ்கில் வழங்கவும்.\n\nசேகரிப்பு:\n{4}\nதொழில்நுட்ப வல்லுநர் வருகை\n{5}\n{6}\n\nராஜலட்சுமி மருத்துவக் கல்லூரியை தேர்ந்தெடுத்ததற்கு நன்றி.
|
||||
|
||||
# Final Main Menu
|
||||
menu.final.title=நீங்கள் பிரதான மெனுவுக்குச் செல்ல விரும்புகிறீர்களா?
|
||||
menu.final.yes=பிரதான மெனு
|
||||
menu.final.no=வெளியேறு
|
||||
|
||||
doc.booking.success=✅ சந்திப்பு வெற்றிகரமாக முன்பதிவு செய்யப்பட்டது\n\nசந்திப்பு ஐடி:\n{0}\n\nநோயாளி ஐடி:\n{1}\n\nபணம் செலுத்த உங்கள் நோயாளி எண்ணை மருத்துவமனை பில்லிங் டெஸ்கில் வழங்கவும்.\n\nமருத்துவர்:\n{2}\n\nதுறை:\n{3}\n\nதேதி:\n{4}\n\nநேரம்:\n{5}\n\nஉங்கள் சந்திப்புக்கு 15 நிமிடங்களுக்கு முன்பு வரவும்.\nராஜலட்சுமி மருத்துவக் கல்லூரியை தேர்ந்தெடுத்ததற்கு நன்றி
|
||||
doc.view_apps.title=உங்கள் வரவிருக்கும் சந்திப்புகள்
|
||||
doc.view_apps.item=சந்திப்பு ஐடி:\n{0}\nமருத்துவர்:\n{1}\nதுறை:\n{2}\nதேதி:\n{3}\nநேரம்:\n{4}\nநிலை:\n✅ {5}
|
||||
doc.view_apps.btn=விருப்பத்தை தேர்ந்தெடுக்கவும்
|
||||
doc.view_apps.list=விருப்பங்கள்
|
||||
doc.view_apps.opt1=ரத்து செய்யவும்
|
||||
doc.view_apps.opt2=மாற்றியமைக்க
|
||||
doc.view_apps.opt3=பிரதான மெனு
|
||||
doc.invalid_id=தவறான சந்திப்பு ஐடி. தயவுசெய்து மீண்டும் முயற்சிக்கவும்.
|
||||
doc.reschedule.time.title=கிடைக்கும் புதிய நேரங்கள்
|
||||
doc.reschedule.time.btn=நேரத்தை தேர்ந்தெடுக்கவும்
|
||||
doc.reschedule.time.list=நேரங்கள்
|
||||
doc.reschedule.success=✅ சந்திப்பு மாற்றியமைக்கப்பட்டது\nமருத்துவர்:\n{0}\nபுதிய நேரம்:\n{1}\nதேதி:\n{2}
|
||||
error.generic=பிழை. தயவுசெய்து மீண்டும் முயற்சிக்கவும்.
|
||||
doc.cancel.confirm_msg=நிச்சயமாக ரத்து செய்ய விரும்புகிறீர்களா?
|
||||
doc.cancel.yes=ஆம்
|
||||
doc.cancel.no=இல்லை
|
||||
doc.cancel.success=✅ சந்திப்பு வெற்றிகரமாக ரத்து செய்யப்பட்டது.
|
||||
|
||||
pagination.next=அடுத்து ➡️
|
||||
# Services Menu
|
||||
services.nursing.title=💉 செவிலியர் சேவைகள்\n\nதேர்வு செய்க:
|
||||
services.nursing.opt1=ஆண் செவிலியர்
|
||||
services.nursing.opt2=பெண் செவிலியர்
|
||||
services.attender.title=🤝 உதவியாளர் சேவைகள்
|
||||
services.attender.opt1=ஆண் உதவியாளர்
|
||||
services.attender.opt2=பெண் உதவியாளர்
|
||||
services.physio.title=🏃 பிசியோதெரபி\n\nவிலை: ₹700\n\nநீங்கள் முன்பதிவு செய்ய விரும்புகிறீர்களா?
|
||||
services.physio.yes=ஆம்
|
||||
services.physio.no=இல்லை
|
||||
services.medproc.title=🩺 மருத்துவ நடைமுறைகள்
|
||||
services.medproc.btn=விருப்பங்களை காண்க
|
||||
services.medproc.list=நடைமுறைகள்
|
||||
services.medproc.opt1=IM ஊசி
|
||||
services.medproc.opt2=IV ஊசி
|
||||
services.medproc.opt3=நெபுலைசேஷன்
|
||||
services.medproc.opt4=கட்டு போடுதல்
|
||||
services.medproc.opt5=வடிகுழாய்
|
||||
services.digital.title=💻 டிஜிட்டல் ஆலோசனை\n\nஆலோசனை கட்டணம்: ₹750\n\nநீங்கள் முன்பதிவு செய்ய விரும்புகிறீர்களா?
|
||||
services.digital.yes=ஆம்
|
||||
services.digital.back=பின்செல்
|
||||
services.homecare.title=🏡 வீட்டு பராமரிப்பு தொகுப்புகள்
|
||||
services.homecare.btn=சேவைகளை காண்க
|
||||
services.homecare.list=சேவைகள்
|
||||
services.homecare.opt1=செவிலியர் பராமரிப்பு
|
||||
services.homecare.opt2=உதவியாளர் பராமரிப்பு
|
||||
services.homecare.opt3=பிசியோதெரபி
|
||||
services.homecare.opt4=மருத்துவ நடைமுறைகள்
|
||||
services.main.title=🩺 எனது சேவைகள்\n\nதயவுசெய்து ஒரு வகையைத் தேர்ந்தெடுக்கவும்:
|
||||
services.main.btn=சேவைகளை காண்க
|
||||
services.main.list=சேவை பிரிவுகள்
|
||||
services.main.opt1=செவிலியர் சேவைகள்
|
||||
services.main.opt2=உதவியாளர் சேவைகள்
|
||||
services.main.opt3=பிசியோதெரபி
|
||||
services.main.opt4=மருத்துவ நடைமுறைகள்
|
||||
services.main.opt5=டிஜிட்டல் ஆலோசனை
|
||||
services.main.opt6=வீட்டு பராமரிப்பு
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.example.whatsappautomation;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
@SpringBootTest
|
||||
class WhatsAppAutomationApplicationTests {
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user