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.
Fork
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(undefined, { 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");
};

I never actually tried this out, but I think it or something like it should work based on the docs found here: https://telegram-bot-sdk.readme.io/reference/removewebhook

Readme
1
2
3
4
5
6
7
import { telegramSetWebhook } from "https://esm.town/v/stevekrouse/telegramSetWebhook";
console.log(
await telegramSetWebhook(Deno.env.get("telegramBotToken"), {
remove: true,
}),
);
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
export let date_me_docs_cache = [{
"Name": "Kamil",
"Profile": "https://docs.google.com/document/d/1kQgNZ7ikgKAxyxbsLSC2bBhXQgxv6Em340-ht5R5sjo/edit?usp=sharing",
"Gender": ["M"],
"Age": "24",
"Contact": "postreduxx gmail",
"LastUpdated": "2023-10-19T12:50:00.000Z",
"InterestedIn": ["M"],
"Location": ["Central Europe"],
"Style": ["mono"],
"LocationFlexibility": "Some",
"Community": ["Rationalism"],
}, {
"Name": "Zak Kallenborn",
"Profile": "zkallenborn.com/dateme",
"Gender": ["M"],
"Age": "33",
"Contact": "zkallenborn@gmail.com",
"LastUpdated": "2023-10-18T04:22:00.000Z",
"InterestedIn": ["F"],
"Location": ["DC"],
"Style": ["mono"],
"LocationFlexibility": "Some",
"Community": ["Tech", "EA"],
}, {
"Name": "Frazer Kirkman",
"Profile": "https://www.okcupid.com/profile/frazerkirkman",
"Gender": ["M"],
"Age": "44",
"Contact": "Frazerkirkman@gmail.com",
"LastUpdated": "2023-10-16T20:02:00.000Z",
"InterestedIn": ["F"],
"Location": ["San Francisco Bay Area"],
"Style": ["poly"],
"LocationFlexibility": "Some",
"Community": ["Tech", "Rationalism", "EA"],
}, {
"Name": "Mitchell Reynolds",
"Profile": "https://tundra-shell-d74.notion.site/Mitchell-s-Date-Me-Doc-9325999704f347a4b2515df774b3c7ff",
"Gender": ["M"],
"Age": "32",
"Contact": "https://www.facebook.com/mitchellsreynolds/",
"LastUpdated": "2023-10-14T06:43:00.000Z",
"InterestedIn": ["F"],
"Location": ["San Francisco Bay Area", "Berkeley"],
"Style": ["mono"],
"LocationFlexibility": "Flexible",
"Community": ["EA"],
}, {
"Name": "Sarah Hirner",

Bluesky keyword alerts

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

1. Query

Specify your queries in the queries variable.

Bluesky doesn't support boolean OR yet so we do a separate search for each keyword.

2. 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.

Readme
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
import { blob } from "https://esm.town/v/std/blob";
import { discordWebhook } from "https://esm.town/v/stevekrouse/discordWebhook";
import { fetchJSON } from "https://esm.town/v/stevekrouse/fetchJSON";
import { searchBlueskyPosts } from "https://esm.town/v/stevekrouse/searchBlueskyPosts";
const encounteredIDs_KEY = "bluesky_encounteredIDs";
const queries = ["val town", "val.town"];
export const blueskyAlert = async () => {
let posts = (await Promise.all(queries.map(searchBlueskyPosts))).flat();
// filter for new posts
let encounteredIDs = await blob.getJSON(encounteredIDs_KEY) ?? [];
let newPosts = posts.filter((post) => !encounteredIDs.includes(post.tid));
await blob.setJSON(encounteredIDs_KEY, [
...encounteredIDs,
...newPosts.map((post) => post.tid),
]);
if (newPosts.length === 0) return;
// format
const content = posts.map(
post => `https://bsky.app/profile/${post.user.handle}/post/${post.tid.split("/")[1]}`,
).join(
"\n",
);
// notify
await discordWebhook({
url: Deno.env.get("mentionsDiscord"),
content,
});
return newPosts;
};

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.

Readme
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://twitter.com/${author_username}/status/${id}`)
.join("\n");
// notify
await discordWebhook({
url: Deno.env.get("mentionsDiscord"),
content,
});
}
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
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
import { blob } from "https://esm.town/v/std/blob";
import { telegramSendMessage } from "https://esm.town/v/vtdocs/telegramSendMessage?v=5";
import process from "node:process";
const DB_KEY = "telegram_Chotillo";
const LS = "/ls";
const X = "/x";
const X_ = X + " ";
const initBlob = async () => {
let exist = await blob.getJSON(DB_KEY);
if (!exist) {
await blob.setJSON(DB_KEY, []);
exist = [];
}
return exist;
};
const send = async (chatId: number, msg: string) => {
await telegramSendMessage(
process.env.telegramBotToken,
{ chat_id: chatId, text: msg },
);
};
export const telegramWebhookEchoMessage = async (req: Request) => {
const db: string[] = await initBlob();
// Verify this webhook came from our bot
if (
req.headers.get("x-telegram-bot-api-secret-token")
!== process.env.telegramWebhookSecret
) {
return new Response(undefined, { 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;
if (text.startsWith(LS)) {
await send(chatId, db.join("\n"));
return Response.json("ok");
}
1
2
3
4
5
6
import { telegramGetMe } from "https://esm.town/v/vtdocs/telegramGetMe";
import process from "node:process";
export const getMeExample = telegramGetMe(
process.env.telegramBotToken,
);

Telegram to DallE Bot

Set up

  1. First you'll need to set yourself up to send and receive messages on Telegram. Follow all 5 steps here: https://www.val.town/v/stevekrouse.telegram

  2. Fork this @telegramBotHandler val below. Make sure you click Run to save it to your account.

  3. On your forked val, click the ⋮ menu > Endpoints > Copy express endpoint

  4. Message @ValTownBot /webhook

  5. Message @ValTownBot the express endpoint you copied

  6. You'll also need an openai key in your secrets for this particular DallE bot to work

Readme
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
import { t } from "https://esm.town/v/stevekrouse/t";
import { textToImageDalle } from "https://esm.town/v/stevekrouse/textToImageDalle";
import process from "node:process";
export async function telegramBotHandler(req, res) {
let text = req.body.message.text;
res.status(200).send("{}");
if (text.startsWith("/dalle")) {
await t("Loading...");
try {
let resp = await textToImageDalle(
process.env.openai,
text.replace("/dalle", ""),
1,
"1024x1024",
);
if ("error" in resp)
return t("DallE Error: " + resp.error.message);
else
return t(null, { photo: resp.data[0].url });
}
catch (e) {
// report any errors via telegram
await t("Error: " + e.message);
// also throw so we can check in https://www.val.town/settings/evaluations
throw e;
}
// Forked from @hootz.telegramDalleBot
} else if (text.startsWith("/gpt")) {
await t("hi");
}
else {
await t("Unkown command: " + text);
}
}
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
export const theme = {
semanticTokens: {
colors: {
"chakra-body-text": {
_light: "gray.800",
_dark: "whiteAlpha.900",
},
"chakra-body-bg": {
_light: "white",
_dark: "gray.800",
},
"chakra-border-color": {
_light: "gray.200",
_dark: "whiteAlpha.300",
},
"chakra-subtle-bg": {
_light: "gray.100",
_dark: "gray.700",
},
"chakra-placeholder-color": {
_light: "gray.500",
_dark: "whiteAlpha.400",
},
},
},
direction: "ltr",
breakpoints: {
base: "0em",
sm: "30em",
md: "48em",
lg: "62em",
xl: "80em",
"2xl": "96em",
},
zIndices: {
hide: -1,
auto: "auto",
base: 0,
docked: 10,
dropdown: 1000,
sticky: 1100,
banner: 1200,
overlay: 1300,
modal: 1400,
popover: 1500,
skipLink: 1600,
toast: 1700,
tooltip: 1800,
},
radii: {

Usage in bash:

# Can be in .bashrc or .zsrhc:
to-tg() {
  local input=""

  if [[ -p /dev/stdin ]]; then
    input="$(cat -)"
  else
    input="${@}"
  fi

  if [[ -z "${input}" ]]; then
    return 1
  fi

  local chat_id="-1001826545120" # Set chat_id where your bot is
  local message="$input"

  curl -G https://api.val.town/v1/run/dpetrouk.notifyInTg --data-urlencode 'args=["'"$chat_id"'", "'"$message"'"]'
}
# You will get notification where command is succesfully finished
<command in bash> && to-tg Success
# Can be like that?
<command in bash> | to-tg Success
Readme
1
2
3
4
5
6
7
8
9
10
import process from "node:process";
import { telegramSendMessage } from "https://esm.town/v/vtdocs/telegramSendMessage?v=5";
export async function notifyInTg(chatId, text) {
telegramSendMessage(
process.env.telegramBotToken,
{ chat_id: chatId, text },
);
return `Sent message '${text}' to Telegram chat ${chatId}`;
}
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
import { sendToTelegram } from "https://esm.town/v/pomdtr/sendToTelegram";
import { secretToTelegramChat } from "https://esm.town/v/pomdtr/secretToTelegramChat";
export async function telegramWelcome(req: express.Request, res: express.Response) {
const { message } = req.body;
let secret: string;
// check if the secret is already set
for (
const [key, chatID] of Object.entries(
secretToTelegramChat,
)
) {
if (chatID == message.from.id) {
secret = key;
break;
}
}
if (secret == "") {
const { nanoid } = await import("npm:nanoid");
secret = nanoid();
secretToTelegramChat[secret] = message.from.id;
}
sendToTelegram(
secret,
`Your Secret is ${secret} - Instructions: https://www.val.town/v/pomdtr.telegram`,
);
}
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
25
26
27
28
29
30
31
import { telegramSendMessage } from "https://esm.town/v/vtdocs/telegramSendMessage?v=5";
import { fetchTweet } from "https://esm.town/v/dpetrouk/fetchTweet";
import process from "node:process";
export const telegramWebhookEchoMessage = async (
req: express.Request,
res: express.Response,
) => {
// Verify this webhook came from our bot
if (
req.get("x-telegram-bot-api-secret-token") !==
process.env.telegramWebhookSecret
) {
return res.status(401);
}
// Echo back the user's message
const { created_at, text, user } = await fetchTweet(
req.body.message.text,
);
const dateTime = created_at.slice(0, 19).split("T").join(" ");
const messageText = [
[dateTime, `${user.name}${user.screen_name}`].join("\n"),
text.replaceAll(req.body.message.text, ""),
].join("\n\n");
const chatId: number = req.body.message.chat.id;
telegramSendMessage(
process.env.telegramBotToken,
{ chat_id: chatId, text: messageText },
);
};
// Forked from @vtdocs.telegramWebhookEchoMessage
1
2
3
4
5
6
7
8
9
10
11
12
13
import process from "node:process";
import { telegramSetWebhook } from "https://esm.town/v/vtdocs/telegramSetWebhook?v=2";
export const setWebhookExample = telegramSetWebhook(
process.env.telegramBotToken,
{
// Replace this with _your_ web endpoint
url: "https://neverstew-telegramWebhookEchoMessage.web.val.run",
// Optionally, filter what kind of updates you want to receive here
allowed_updates: ["message"],
secret_token: process.env.telegramWebhookSecret,
},
);
1
2
3
4
5
6
7
8
9
import process from "node:process";
import { telegram as telegram2 } from "https://esm.town/v/stevekrouse/telegram?v=4";
export let telegram = (message, options = undefined) =>
telegram2(
process.env.telegram_me,
message,
options,
);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import { fetchJSON } from "https://esm.town/v/stevekrouse/fetchJSON?v=41";
export const telegramSetWebhook = async (botToken: string, options: {
url: string;
certificate?: string;
ip_address?: string;
max_connections?: number;
allowed_updates?: string[];
secret_token?: string;
}) =>
fetchJSON(
`https://api.telegram.org/bot${botToken}/setWebhook`,
{
method: "POST",
body: JSON.stringify({ ...options }),
},
);