Back to APIs list

Telegram API examples & templates

Use these vals as a playground to view and fork Telegram API examples and templates on Val Town. Run any example below or find templates that can be used as a pre-built solution.
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
const API_KEY = Deno.env.get("OPENWEATHERMAP_APP_ID");
const LATITUDE = Deno.env.get("LATITUDE");
const LONGITUDE = Deno.env.get("LONGITUDE");
const CHAT_ID = Deno.env.get("TELEGRAM_CHAT_ID");
const TELEGRAM_TOKEN = Deno.env.get("TELEGRAM_TOKEN");
const THINGSPEAK_CHANNEL_ID = Deno.env.get("THINGSPEAK_CHANNEL_ID");
const fetchLatestTemperatureFromThingSpeak = async (channelId = THINGSPEAK_CHANNEL_ID, resultsCount = 1) => {
const baseUrl = "https://api.thingspeak.com/channels";
const url = `${baseUrl}/${channelId}/feeds.json?results=${resultsCount}`;
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
const temperature = data.feeds[0]?.field3;
const createdAt = new Date(data.feeds[0]?.created_at);
const currentTime = new Date();
const oneHourAgo = new Date(currentTime.getTime() - (60 * 60 * 1000));
if (temperature === undefined || createdAt < oneHourAgo) {
throw new Error("Temperature data not found in the feed.");
}
return temperature;
} catch (error) {
// console.error("Failed to fetch temperature:", error);
return null; // or handle the error in another way
}
};
const weatherToEmoticon = {
"clear sky": "☀️",
"few clouds": "🌤",
"scattered clouds": "⛅",
"broken clouds": "☁️",
"shower rain": "🌧",
"rain": "🌧",
"thunderstorm": "⛈",
"snow": "❄️",
"mist": "🌫",
};
const fetchDataFromOpenWeatherMap = async () => {
const response = await fetch(
`https://api.openweathermap.org/data/2.5/weather?lat=${LATITUDE}&lon=${LONGITUDE}&units=metric&appid=${API_KEY}`,
);
const weatherForecastData = await response.json();
const condition = weatherForecastData.weather[0].icon;
// const weatherIcon = fetch(`https://openweathermap.org/img/wn/${condition}@2x.png`); // https://openweathermap.org/img/wn/10d@2x.png
const weatherCondition = weatherForecastData.weather[0].description;
const temperature = weatherForecastData.main.temp;
const humidity = weatherForecastData.main.humidity;
const wind = weatherForecastData.wind;
return {
temperature,
humidity,
weatherCondition,
wind,
};
};
const sendTextWithTelegram = async (text: string) => {
const telegramSendUrl =
`https://api.telegram.org/bot${TELEGRAM_TOKEN}/sendMessage?chat_id=${CHAT_ID}&parse_mode=HTML&text=${text}`;
await fetch(telegramSendUrl);
};
export default async function(interval: Interval) {
const temperature = await fetchLatestTemperatureFromThingSpeak();
const weatherCondition = await fetchDataFromOpenWeatherMap();
const windspeedInKmh = Math.ceil(weatherCondition.wind.speed * 3.6);
const formattedWeatherData = `<b>Temperature:</b> <i>${temperature || weatherCondition.temperature} °C</i>%0A
<b>Humidity:</b> <i>${weatherCondition.humidity}%</i>%0A
<b>Weather:</b> <i>${weatherCondition.weatherCondition}</i>%0A
<b>Wind Speed:</b> <i>${windspeedInKmh} km/h</i>%0A
<b>Wind Direction:</b> <i>${weatherCondition.wind.deg}°</i>%0A${
!temperature ? `<b>Status:</b> On-site sensor OFFLINE%0A` : ""
}`;
sendTextWithTelegram(
formattedWeatherData,
);
}
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
const TELEGRAM_CHAT_ID = Deno.env.get("TELEGRAM_CHAT_ID");
const TELEGRAM_TOKEN = Deno.env.get("TELEGRAM_TOKEN");
const latitude = Deno.env.get("LATITUDE");
const longitude = Deno.env.get("LONGITUDE");
const openWeatherMapAppId = Deno.env.get("OPENWEATHERMAP_APP_ID");
type WeatherData = {
date: string;
minTemperature: string;
maxTemperature: string;
willItRain: string;
willItSnow: string;
totalRain: string;
};
type Forecast = {
today: WeatherData;
tomorrow: WeatherData;
dayAfterTomorrow: WeatherData;
};
const formatWeatherForecast = (forecast: Forecast): string => {
const formatDate = (data: WeatherData) => `
<b>Date:</b> ${data.date}%0A
<b>Min Temperature:</b> <i>${data.minTemperature} °C</i>%0A
<b>Max Temperature:</b> <i>${data.maxTemperature} °C</i>%0A
${data.willItRain === "Yes" ? `<b>Rain:</b> ${data.willItRain} (${data.totalRain})%0A` : ""}
${data.willItSnow === "Yes" ? `<b>Snow:</b> ${data.willItSnow}%0A` : ""}`;
return `
<b>Weather Forecast</b>🌤️%0A
<u>Today:</u>%0A
${formatDate(forecast.today)}
<u>Tomorrow:</u>%0A
${formatDate(forecast.tomorrow)}
<u>Day After Tomorrow:</u>%0A
${formatDate(forecast.dayAfterTomorrow)}
`;
};
const extractForecast = (weatherData, date) => {
const forecasts = weatherData.list.filter(entry => entry.dt_txt.startsWith(date));
let minTemp = forecasts[0].main.temp_min;
let maxTemp = forecasts[0].main.temp_max;
let willRain = false;
let willSnow = false;
let totalRain = 0; // Initialize total rain
// Iterate over the forecasts to find min, max temperatures and rain/snow status
forecasts.forEach(entry => {
if (entry.main.temp_min < minTemp) minTemp = entry.main.temp_min;
if (entry.main.temp_max > maxTemp) maxTemp = entry.main.temp_max;
if (entry.weather.some(w => w.main.toLowerCase() === "rain")) {
willRain = true;
if (entry.rain && entry.rain["3h"]) {
totalRain += entry.rain["3h"]; // Add the rain volume from this forecast to the total
}
}
if (entry.weather.some(w => w.main.toLowerCase() === "snow")) {
willSnow = true;
}
});
const result = {
date,
minTemperature: minTemp.toFixed(2),
maxTemperature: maxTemp.toFixed(2),
willItRain: willRain ? "Yes" : "No",
willItSnow: willSnow ? "Yes" : "No",
totalRain: willRain ? totalRain.toFixed(2) + " mm" : "0 mm", // Always include totalRain, set to "0 mm" if no rain
};
return result;
};
const fetchForecast = async () => {
const response = await fetch(
`https://api.openweathermap.org/data/2.5/forecast?lat=${latitude}&lon=${longitude}&units=metric&appid=${openWeatherMapAppId}`,
);
const data = await response.json();
const today = new Date();
const tomorrow = new Date(today);
tomorrow.setDate(today.getDate() + 1);
const dayAfterTomorrow = new Date(today);
dayAfterTomorrow.setDate(today.getDate() + 2);
const todayForecast = extractForecast(data, today.toISOString().slice(0, 10));
const tomorrowForecast = extractForecast(data, tomorrow.toISOString().slice(0, 10));
const dayAfterTomorrowForecast = extractForecast(data, dayAfterTomorrow.toISOString().slice(0, 10));
const forecastString = {
today: todayForecast,
tomorrow: tomorrowForecast,
dayAfterTomorrow: dayAfterTomorrowForecast,
};
return forecastString;

Twitter 𝕏 keyword Alerts

Custom notifications for when you, your company, or anything you care about is mentioned on Twitter.

1. Authentication

You'll need a Twitter Bearer Token. Follow these instructions to get one.

Unfortunately it costs $100 / month to have a Basic Twitter Developer account. If you subscribe to Val Town Pro, I can let you "borrow" my token. Just comment on this val and I'll hook you up.

2. Query

Change the query variable for what you want to get notified for.

You can use Twitter's search operators to customize your query, for some collection of keywords, filtering out others, and much more!

3. Notification

Below I'm sending these mentions to a private channel in our company Discord, but you can customize that to whatever you want, @std/email, Slack, Telegram, whatever.

Runs every 1 hrs
Fork
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import { discordWebhook } from "https://esm.town/v/stevekrouse/discordWebhook";
import { twitterSearch } from "https://esm.town/v/stevekrouse/twitterSearch";
const query = "\"val.town\" OR \"val town\" -_ValTown_";
export async function twitterAlert({ lastRunAt }: Interval) {
const results = await twitterSearch({
query,
start_time: lastRunAt,
bearerToken: Deno.env.get("twitter"),
});
if (!results.length) return;
// format results
let content = results
.map(({ author_name, author_username, text, id }) => `https://fxtwitter.com/${author_username}/status/${id}`)
.join("\n");
// notify
await discordWebhook({
url: Deno.env.get("mentionsDiscord"),
content,
});
}

Message yourself on Telegram

This val lets you send yourself Telegram messages via ValTownBot. This ValTownBot saves you from creating your own Telegram Bot.

However if I'm being honest, it's really simple and fun to make your own Telegram bot. (You just message BotFather.) I'd recommend most folks going that route so you have an unmediated connection to Telegram. However if you want to have the simplest possible setup to just send yourself messages, read on...

Installation

It takes less than a minute to set up!

  1. Start a conversation with ValTownBot

  2. Copy the secret it gives you

  3. Save it in your Val Town Environment Variables under telegram

  4. Send a message!

Usage

telegramText

Create valimport { telegramText } from "https://esm.town/v/stevekrouse/telegram?v=14"; const statusResponse = await telegramText("Hello from Val.Town!!"); console.log(statusResponse);

telegramPhoto

Create valimport { telegramPhoto } from "https://esm.town/v/stevekrouse/telegram?v=14"; const statusResponse = await telegramPhoto({ photo: "https://placekitten.com/200/300", }); console.log(statusResponse);

ValTownBot Commands

  • /roll - Roll your secret in case you accidentally leak it.
  • /webhook - Set a webhook to receive messages you send to @ValTownBot

Receiving Messages

If you send /webhook to @ValTownBot, it will let you specify a webhook URL. It will then forward on any messages (that aren't recognized @ValTownBot commands) to that webhook. It's particularly useful for creating personal chatbots, like my telegram <-> DallE bot.

How it works

Telegram has a lovely API.

  1. I created a @ValTownBot via Bot Father.
  2. I created a webhook and registered it with telegram
  3. Whenever someone new messages @ValTownBot, I generate a secret and save it along with their Chat Id in @stevekrouse/telegramValTownBotSecrets (a private val), and message it back to them
  4. Now whenever you call this val, it calls telegramValTownAPI, which looks up your Chat Id via your secret and sends you a message

Telegram Resources

Credits

This val was originally made by pomdtr.

Todo

  • Store user data in Val Town SQLite
  • Parse user data on the API side using Zod
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
import { runVal } from "https://esm.town/v/std/runVal";
import type { TelegramSendMessageOptions } from "https://esm.town/v/stevekrouse/telegramSendMessage";
import type { TelegramSendPhotoOptions } from "https://esm.town/v/stevekrouse/telegramSendPhoto";
/**
* Send a text message to yourself from the ValTownBot Telegram bot
* Message https://t.me/ValTownBot to get started
* @param text
* @param options
* @param authorization
*/
export async function telegramText(text: string, options?: TextOptions, authorization?: string) {
return telegramRequest("text", { text, options }, authorization);
}
/**
* Send a photo to yourself from the ValTownBot Telegram bot
* Message https://t.me/ValTownBot to get started
* @param options
* @param authorization
*/
export async function telegramPhoto(options: PhotoOptions, authorization?: string) {
return telegramRequest("photo", { options }, authorization);
}
async function telegramRequest(path, body, authorization?: string) {
const response = await fetch("https://stevekrouse-telegramValTownAPI.web.val.run/" + path, {
method: "POST",
body: JSON.stringify(body),
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${authorization ?? Deno.env.get("telegram")}`,
},
});
if (!response.ok) {
const error = await response.text();
throw new Error(error);
} else {
return "SUCCESS";
}
}
type TextOptions = Omit<TelegramSendMessageOptions, "chat_id">;
type PhotoOptions = Omit<TelegramSendPhotoOptions, "chat_id">;
/**
* @deprecated since 4/20/2024
*/
export async function telegram(secret: string, text: string, options?: MergedOptions) {
return runVal("stevekrouse.telegramValTownBot", secret, text, options);
}
export type MergedOptions = TextOptions & PhotoOptions;
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
import { telegramValTownBotSecrets } from "https://esm.town/v/stevekrouse/telegramValTownBotSecrets";
import { telegramSendMessage } from "https://esm.town/v/vtdocs/telegramSendMessage?v=5";
import { telegramSendPhoto } from "https://esm.town/v/vtdocs/telegramSendPhoto?v=1";
export let telegramValTownBot = async (req: Request) => {
// Authentication
const bearerString = req.headers.get("authorization");
const token = bearerString?.replace("Bearer ", "");
let chat = telegramValTownBotSecrets.find((c) => c.secret === token);
if (!chat) {
return new Response("Unauthorized", { status: 401 });
}
const url = new URL(req.url);
try {
if (url.pathname === "/text") {
const { text, options } = await req.json();
// TODO validate with Zod
const response = await telegramSendMessage(
Deno.env.get("telegramBot"),
{
...options,
chat_id: chat.chatId,
text,
},
);
return handleTelegramResponse(response);
} else if (url.pathname === "/photo") {
const { options } = await req.json();
console.log(options);
// TODO validate with Zod
const response = await telegramSendPhoto(Deno.env.get("telegramBot"), {
...options,
chat_id: chat.chatId,
});
return handleTelegramResponse(response);
}
return new Response("Not found", { status: 404 });
} catch (e) {
console.log(e);
return new Response("Error sending", { status: 500 });
}
};
function handleTelegramResponse(response) {
console.log(response);
if (response.ok) {
return new Response("OK", { status: 200 });
} else {
return new Response("Error sending: " + response.description, { status: 500 });
}
}
1
2
3
4
5
6
import { telegramPhoto } from "https://esm.town/v/stevekrouse/telegram";
const statusResponse = await telegramPhoto({
photo: "https://placekitten.com/200/300",
});
console.log(statusResponse);
1
2
3
4
import { telegramText } from "https://esm.town/v/stevekrouse/telegram";
const statusResponse = await telegramText("Hello from Val.Town!!");
console.log(statusResponse);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import { fetchJSON } from "https://esm.town/v/stevekrouse/fetchJSON?v=41";
export const telegramSendMessage = async (botToken: string, options: TelegramSendMessageOptions) =>
fetchJSON(
`https://api.telegram.org/bot${botToken}/sendMessage`,
{
method: "POST",
body: JSON.stringify({ ...options }),
},
);
export type TelegramSendMessageOptions = {
chat_id: string | number;
text: string;
message_thread_id?: number;
parse_mode?: string;
entities?: any[];
disable_web_page_preview?: boolean;
disable_notification?: boolean;
protect_content?: boolean;
reply_to_message_id?: number;
allow_sending_without_reply?: boolean;
reply_markup?: any[];
};
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
import { fetchJSON } from "https://esm.town/v/stevekrouse/fetchJSON?v=41";
export const telegramSendPhoto = async (botToken: string, options: TelegramSendPhotoOptions) =>
fetchJSON(
`https://api.telegram.org/bot${botToken}/sendPhoto`,
{
method: "POST",
body: JSON.stringify({ ...options }),
},
);
export type TelegramSendPhotoOptions = {
chat_id: string | number;
message_thread_id?: number;
photo: string;
caption?: string;
parse_mode?: string;
caption_entities?: any[];
has_spoiler?: boolean;
disable_notification?: boolean;
protect_content?: boolean;
reply_to_message_id?: number;
allow_sending_without_reply?: boolean;
reply_markup?: any[];
};

Twitter 𝕏 keyword Alerts

Custom notifications for when you, your company, or anything you care about is mentioned on Twitter.

1. Authentication

You'll need a Twitter Bearer Token. Follow these instructions to get one.

Unfortunately it costs $100 / month to have a Basic Twitter Developer account. If you subscribe to Val Town Pro, I can let you "borrow" my token. Just comment on this val and I'll hook you up.

2. Query

Change the query variable for what you want to get notified for.

You can use Twitter's search operators to customize your query, for some collection of keywords, filtering out others, and much more!

3. Notification

Below I'm sending these mentions to a private channel in our company Discord, but you can customize that to whatever you want, @std/email, Slack, Telegram, whatever.

Runs every 1 hrs
Fork
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import { discordWebhook } from "https://esm.town/v/stevekrouse/discordWebhook";
import { twitterSearch } from "https://esm.town/v/stevekrouse/twitterSearch";
const query = "\"val.town\" OR \"val town\" -_ValTown_";
export async function twitterAlert({ lastRunAt }: Interval) {
const results = await twitterSearch({
query,
start_time: lastRunAt,
bearerToken: Deno.env.get("twitter"),
});
if (!results.length) return;
// format results
let content = results
.map(({ author_name, author_username, text, id }) => `https://fxtwitter.com/${author_username}/status/${id}`)
.join("\n");
// notify
await discordWebhook({
url: Deno.env.get("mentionsDiscord"),
content,
});
}
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
import { fetchJSON } from "https://esm.town/v/stevekrouse/fetchJSON?v=41";
import axios from "npm:axios";
import formData from "npm:form-data";
export const telegramSendMessage = async (botToken: string, options: {
chat_id: string | number;
text: string;
message_thread_id?: number;
parse_mode?: string;
entities?: any[];
disable_web_page_preview?: boolean;
disable_notification?: boolean;
protect_content?: boolean;
reply_to_message_id?: number;
allow_sending_without_reply?: boolean;
reply_markup?: any[];
}) =>
fetchJSON(
`https://api.telegram.org/bot${botToken}/sendMessage`,
{
method: "POST",
body: JSON.stringify({ ...options }),
},
);
export async function telegramSendAudioMessage(chatId: string, audioData: Uint8Array, botToken: string): Promise<void> {
const url = `https://api.telegram.org/bot${botToken}/sendAudio`;
// Assuming FormData is available or correctly polyfilled
let data = new FormData();
data.append("chat_id", chatId);
// Directly use the Uint8Array with Blob constructor
data.append("audio", new Blob([audioData], { type: "audio/mpeg" }), "feedback.mpga");
try {
// Replace axios with Deno's fetch API, adapted for your setup
const response = await fetch(url, {
method: "POST",
body: data, // FormData instance directly as the body
// Headers are set automatically by the browser, so they're omitted here
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const result = await response.json();
console.log(result);
} catch (error) {
console.error("Error sending audio message:", error.message);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import { telegramSendMessage } from "https://esm.town/v/vtdocs/telegramSendMessage?v=5";
export const telegramWebhookEchoMessage = async (req: Request) => {
// Verify this webhook came from our bot
if (
req.headers.get("x-telegram-bot-api-secret-token")
!== Deno.env.get("telegramWebhookSecret")
) {
return new Response("Not Allowed", { status: 401 });
}
// Echo back the user's message
const body = await req.json();
const text: string = body.message.text;
const chatId: number = body.message.chat.id;
await telegramSendMessage(
Deno.env.get("telegramBotToken"),
{ chat_id: chatId, text },
);
return Response.json("ok");
};

Twitter 𝕏 keyword Alerts

Custom notifications for when you, your company, or anything you care about is mentioned on Twitter.

1. Authentication

You'll need a Twitter Bearer Token. Follow these instructions to get one.

Unfortunately it costs $100 / month to have a Basic Twitter Developer account. If you subscribe to Val Town Pro, I can let you "borrow" my token. Just comment on this val and I'll hook you up.

2. Query

Change the query variable for what you want to get notified for.

You can use Twitter's search operators to customize your query, for some collection of keywords, filtering out others, and much more!

3. Notification

Below I'm sending these mentions to a private channel in our company Discord, but you can customize that to whatever you want, @std/email, Slack, Telegram, whatever.

Runs every 1 hrs
Fork
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import { discordWebhook } from "https://esm.town/v/stevekrouse/discordWebhook";
import { twitterSearch } from "https://esm.town/v/stevekrouse/twitterSearch";
const query = "\"val.town\" OR \"val town\" -_ValTown_";
export async function twitterAlert({ lastRunAt }: Interval) {
const results = await twitterSearch({
query,
start_time: lastRunAt,
bearerToken: Deno.env.get("twitter"),
});
if (!results.length) return;
// format results
let content = results
.map(({ author_name, author_username, text, id }) => `https://fxtwitter.com/${author_username}/status/${id}`)
.join("\n");
// notify
await discordWebhook({
url: Deno.env.get("mentionsDiscord"),
content,
});
}

Twitter 𝕏 keyword Alerts

Custom notifications for when you, your company, or anything you care about is mentioned on Twitter.

1. Authentication

You'll need a Twitter Bearer Token. Follow these instructions to get one.

Unfortunately it costs $100 / month to have a Basic Twitter Developer account. If you subscribe to Val Town Pro, I can let you "borrow" my token. Just comment on this val and I'll hook you up.

2. Query

Change the query variable for what you want to get notified for.

You can use Twitter's search operators to customize your query, for some collection of keywords, filtering out others, and much more!

3. Notification

Below I'm sending these mentions to a private channel in our company Discord, but you can customize that to whatever you want, @std/email, Slack, Telegram, whatever.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import { discordWebhook } from "https://esm.town/v/stevekrouse/discordWebhook";
import { twitterSearch } from "https://esm.town/v/stevekrouse/twitterSearch";
const query = "\"val.town\" OR \"val town\" -_ValTown_";
export async function twitterAlert({ lastRunAt }: Interval) {
const results = await twitterSearch({
query,
start_time: lastRunAt,
bearerToken: Deno.env.get("twitter"),
});
if (!results.length) return;
// format results
let content = results
.map(({ author_name, author_username, text, id }) => `https://fxtwitter.com/${author_username}/status/${id}`)
.join("\n");
// notify
await discordWebhook({
url: Deno.env.get("mentionsDiscord"),
content,
});
}
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
import { epicTvDiscounts } from "https://esm.town/v/marksteve/epicTvDiscounts";
import { getEpicTvProduct } from "https://esm.town/v/marksteve/getEpicTvProduct";
import { set } from "https://esm.town/v/std/set?v=11";
import { telegram } from "https://esm.town/v/stevekrouse/telegram?v=4";
export const checkEpicTvDiscounts = async (user: string, secret: string, watchList: {
url: string;
targetDiscount: number;
}[]) => {
for (let { url, targetDiscount } of watchList) {
const product = await getEpicTvProduct(url);
console.log({ product });
const discount = parseFloat(product.discount);
if (isNaN(discount)) {
console.log(`No discount for ${product.name}`);
continue;
}
if (epicTvDiscounts[url] === discount) {
console.log(`No discount change for ${product.name}`);
continue;
}
else {
epicTvDiscounts[url] = discount;
}
if (parseFloat(product.discount) < targetDiscount) {
console.log(`Target discount not met for ${product.name}`);
continue;
}
telegram(
secret,
`${product.name} is ${product.discount} off!\n${product.oldPrice} ➡️ ${product.price}`,
);
}
await set("epicTvDiscounts", epicTvDiscounts);
return epicTvDiscounts;
};