Skip to content

Commit

Permalink
Merge pull request #11 from QuantGeekDev/feature/contact-me-about-thi…
Browse files Browse the repository at this point in the history
…s-property

Feature/contact me about this property
  • Loading branch information
QuantGeekDev authored Jan 5, 2024
2 parents 512681d + f8f0f0b commit 94788ca
Show file tree
Hide file tree
Showing 9 changed files with 2,539 additions and 134 deletions.
2,513 changes: 2,424 additions & 89 deletions package-lock.json

Large diffs are not rendered by default.

9 changes: 7 additions & 2 deletions src/config/database.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
import { MongoClient } from "mongodb";
import type { Chat, Database, Property, User } from "../types/database.js";
import type {
Chat,
Database,
PropertyFromDb,
User
} from "../types/database.js";

export async function connectToDb() {
const client = new MongoClient(process.env.DB_CONNECTION_STRING);
await client.connect();
const mongoDb = client.db();
const user = mongoDb.collection<User>("user");
const chat = mongoDb.collection<Chat>("chat");
const property = mongoDb.collection<Property>("properties");
const property = mongoDb.collection<PropertyFromDb>("properties");
const database: Database = { user, chat, property };
return database;
}
11 changes: 9 additions & 2 deletions src/controllers/contactSales.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
import { Composer } from "grammy";
import type { CustomContext } from "../types/context.js";
import { notifySalesTeam } from "../services/Admin/notifySalesTeam.js";
import { notifySalesTeam } from "../services/Notifications/notifySalesTeam.js";

export const contactSalesController = new Composer<CustomContext>();
contactSalesController.callbackQuery("contact-sales", async ctx => {

contactSalesController.callbackQuery(/contact-sales/, async ctx => {
ctx.answerCallbackQuery("");
ctx.reply(
"Your request has been registered - an agent will contact you shortly"
);
notifySalesTeam(ctx);
});

contactSalesController.callbackQuery(/^contact_property_(.+)$/, async ctx => {
await ctx.answerCallbackQuery();
const propertyId = ctx.match[1];
notifySalesTeam(ctx, propertyId);
});
6 changes: 4 additions & 2 deletions src/controllers/properties.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { Composer } from "grammy";
import type { CustomContext } from "../types/context.js";
import type { Property } from "../types/database.js";
import type { PropertyFromDb } from "../types/database.js";
import { displayProperty } from "../services/Property/property.service.js";

export const propertiesController = new Composer<CustomContext>();
let currentPropertyIndex = 0;

propertiesController.command("properties", async ctx => {
const properties = (await ctx.db.property.find({}).toArray()) as Property[];
const properties = (await ctx.db.property
.find({})
.toArray()) as PropertyFromDb[];
await displayProperty(ctx, properties, currentPropertyIndex);

propertiesController.callbackQuery("next-property", async ctx => {
Expand Down
50 changes: 37 additions & 13 deletions src/menus/propertyMenu.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,41 @@
import { InlineKeyboard } from "grammy";

export const fullPropertyControlKeyboard = new InlineKeyboard()
.text("« Previous Property", "previous-property")
.text("Next Property » ", "next-property")
.row()
.text("Contact me about this property", "contact-sales");
export const fullPropertyControlKeyboard = (
propertyId: string
): InlineKeyboard => {
const keyboard = new InlineKeyboard()
.text("« Previous Property", "previous-property")
.text("Next Property » ", "next-property")
.row()
.text(
"📞 Contact me about this property",
`contact_property_${propertyId}`
);
return keyboard;
};

export const nextPropertyControlKeyboard = new InlineKeyboard()
.text("Next Property » ", "next-property")
.row()
.text("Contact me about this property", "contact-sales");
export const nextPropertyControlKeyboard = (
propertyId: string
): InlineKeyboard => {
const keyboard = new InlineKeyboard()
.text("Next Property » ", "next-property")
.row()
.text(
"📞 Contact me about this property",
`contact_property_${propertyId}`
);
return keyboard;
};

export const previousPropertyControlKeyboard = new InlineKeyboard()
.text("« Previous Property", "previous-property")
.row()
.text("Contact me about this property", "contact-sales");
export const previousPropertyControlKeyboard = (
propertyId: string
): InlineKeyboard => {
const keyboard = new InlineKeyboard()
.text("« Previous Property", "previous-property")
.row()
.text(
"📞 Contact me about this property",
`contact_property_${propertyId}`
);
return keyboard;
};
17 changes: 0 additions & 17 deletions src/services/Admin/notifySalesTeam.ts

This file was deleted.

29 changes: 29 additions & 0 deletions src/services/Notifications/notifySalesTeam.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { ObjectId } from "mongodb";
import type { CustomContext } from "../../types/context";
import type { PropertyFromDb } from "../../types/database";

export const notifySalesTeam = async (
ctx: CustomContext,
propertyId?: string
) => {
const adminGroupId = process.env.ADMIN_GROUP_ID;
const userId = ctx.config.user.userId;
const userName = ctx.config.user.name;

const propertyMongoId = new ObjectId(propertyId);
const propertyOfInterest = (await ctx.db.property.findOne({
_id: propertyMongoId
})) as PropertyFromDb;

const userClickable = `[${userName}](tg://user?id=${userId})`;

const formattedNotificationMessage = `A new client is requesting information:\nName: ${userName}\nUser: @${userClickable}\n${
propertyOfInterest
? `Interested in ${propertyOfInterest.collection} ${propertyOfInterest.name}`
: ""
}`;

await ctx.api.sendMessage(adminGroupId, formattedNotificationMessage, {
parse_mode: "MarkdownV2"
});
};
19 changes: 12 additions & 7 deletions src/services/Property/property.service.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import { type InputMediaPhoto } from "grammy/types";
import { InputMediaBuilder } from "grammy";
import type { Property } from "../../types/database.js";
import type { PropertyFromDb } from "../../types/database.js";
import {
fullPropertyControlKeyboard,
nextPropertyControlKeyboard,
previousPropertyControlKeyboard
} from "../../menus/propertyMenu.js";
import type { CustomContext } from "../../types/context.js";

export const generatePropertyDescription = (property: Property): string => {
export const generatePropertyDescription = (
property: PropertyFromDb
): string => {
const {
name,
collection,
Expand Down Expand Up @@ -43,23 +45,26 @@ export const generatePropertyPhotoAlbum = (

export const displayProperty = async (
ctx: CustomContext,
properties: Property[],
properties: PropertyFromDb[],
currentPropertyIndex: number
) => {
const totalProperties = properties.length;
const currentProperty = properties[currentPropertyIndex];
const { videoFileId, albumUrls } = currentProperty;
const currentPropertyId = currentProperty._id.toString();

let controlKeyboard;
if (currentPropertyIndex == 0) {
controlKeyboard = nextPropertyControlKeyboard;
controlKeyboard = nextPropertyControlKeyboard(currentPropertyId);
} else if (currentPropertyIndex + 1 < totalProperties) {
controlKeyboard = fullPropertyControlKeyboard;
controlKeyboard = fullPropertyControlKeyboard(currentPropertyId);
} else {
controlKeyboard = previousPropertyControlKeyboard;
controlKeyboard = previousPropertyControlKeyboard(currentPropertyId);
}

const propertyDescription = generatePropertyDescription(currentProperty);
const propertyDescription = generatePropertyDescription(
currentProperty as PropertyFromDb
);
const propertyPhotoAlbum = generatePropertyPhotoAlbum(albumUrls);

await ctx.reply(`Property ${currentPropertyIndex + 1}/${totalProperties}`);
Expand Down
19 changes: 17 additions & 2 deletions src/types/database.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Collection } from "mongodb";
import type { Collection, ObjectId } from "mongodb";

export interface User {
userId: number;
Expand All @@ -21,6 +21,21 @@ export interface Property {
websiteUrl: string;
}

export interface PropertyFromDb {
_id: ObjectId;
collection: "SaliSol Hills" | "SaliSol Resort" | "SaliSol Golf";
name: string;
price: number;
availability: boolean;
videoFileId: string;
thumbnailUrl: string;
albumUrls: string[];
builtMetersSquared: number;
plotMetersSquared: number;
dropboxUrl: string;
telegramContactUrl: string;
websiteUrl: string;
}
export interface Chat {
chatId: number;
title: string;
Expand All @@ -29,5 +44,5 @@ export interface Chat {
export interface Database {
user: Collection<User>;
chat: Collection<Chat>;
property: Collection<Property>;
property: Collection<PropertyFromDb>;
}

0 comments on commit 94788ca

Please sign in to comment.