aboutsummaryrefslogtreecommitdiff
path: root/apps/web/app/api/telegram/route.ts
blob: 5f824b79b8e5a7b46c8da0ac7860caecc11bb431 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import { db } from "@/server/db";
import { storedContent, users } from "@/server/db/schema";
import { cipher } from "@/server/encrypt";
import { eq } from "drizzle-orm";
import { Bot, webhookCallback } from "grammy";
import { User } from "grammy/types";

export const runtime = "edge";

if (!process.env.TELEGRAM_BOT_TOKEN) {
  throw new Error("TELEGRAM_BOT_TOKEN is not defined");
}

console.log("Telegram bot activated");
const token = process.env.TELEGRAM_BOT_TOKEN;

const bot = new Bot(token);

bot.command("start", async (ctx) => {
  const user: User = (await ctx.getAuthor()).user;

  const cipherd = cipher(user.id.toString());
  await ctx.reply(
    `Welcome to Supermemory bot. I am here to help you remember things better. Click here to create and link your account: https://supermemory.ai/signin?telegramUser=${cipherd}`,
  );
});

bot.on("message", async (ctx) => {
  const user: User = (await ctx.getAuthor()).user;

  const cipherd = cipher(user.id.toString());

  const dbUser = await db.query.users
    .findFirst({
      where: eq(users.telegramId, user.id.toString()),
    })
    .execute();

  if (!dbUser) {
    await ctx.reply(
      `Welcome to Supermemory bot. I am here to help you remember things better. Click here to create and link your account: https://supermemory.ai/signin?telegramUser=${cipherd}`,
    );

    return;
  }

  const message = await ctx.reply("I'm thinking...");

  const response = await fetch(
    `${process.env.BACKEND_BASE_URL}/api/autoChatOrAdd?query=${ctx.message.text}&user=${dbUser.id}`,
    {
      method: "POST",
      headers: {
        Authorization: "Bearer " + process.env.BACKEND_SECURITY_KEY,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        // TODO: we can use the conversations API to get the last 5 messages
        // get chatHistory from this conversation.
        // Basically the last 5 messages between the user and the assistant.
        // In ths form of [{role: 'user' | 'assistant', content: string}]
        // https://grammy.dev/plugins/conversations
        chatHistory: [],
      }),
    },
  );

  if (response.status !== 200) {
    console.log("Failed to get response from backend");
    console.log(response.status);
    console.log(await response.text());
    await ctx.reply(
      "Sorry, I am not able to process your request at the moment.",
    );
    return;
  }

  const data = (await response.json()) as {
    status: string;
    response: string;
    contentAdded: {
      type: string;
      content: string;
      url: string;
    };
  };

  // TODO: we might want to enrich this data with more information
  if (data.contentAdded) {
    await db
      .insert(storedContent)
      .values({
        content: data.contentAdded.content,
        title: `${data.contentAdded.content.slice(0, 30)}... (Added from chatbot)`,
        description: "",
        url: data.contentAdded.url,
        baseUrl: data.contentAdded.url,
        image: "",
        savedAt: new Date(),
        userId: dbUser.id,
        type: data.contentAdded.type,
      })
      .returning({ id: storedContent.id });
  }

  await ctx.api.editMessageText(ctx.chat.id, message.message_id, data.response);
});

export const POST = webhookCallback(bot, "std/http");

export const GET = async () => {
  return new Response("OK", { status: 200 });
};