Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/contact me about this property #11

Merged
merged 2 commits into from
Jan 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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>;
}
Loading