本文详细介绍了如何利用 Helios Webhooks 和 Cloudflare Workers 设置一个 Telegram 机器人,以实时跟踪 Solana 区块链上的交易更新,包括 NFT 销售和转移。
8分钟阅读
2023年9月28日
在Solana区块链上大约每秒发生400笔交易。这些包括代币转账、NFT销售、代币交换、出价、DAO投票、投注等等。但在如此多的数据中,如何跟踪你关心的变化呢?这就是webhooks的用武之地。Webhooks允许你跟踪这些变化,并随时掌握你关心的事情。本指南将向你展示如何设置一个Telegram机器人,以使用Cloudflare worker直接将链上的更新发送到用户或频道。
Telegram机器人是自动化某些任务,尤其是更新的好方法。以下是设置机器人的步骤。
在Telegram的搜索栏中搜索' BotFather'并点击它开始对话。
输入并发送'/newbot'。BotFather将指导你命名你的机器人并给它一个用户名。
完成后,BotFather将提供一个访问Token。
请安全记录下来,因为我们将在后面的教程中使用到它。
转到菜单(☰)并选择'新频道'。
设置好频道后,点击频道名称,选择'管理员'并将你的机器人添加为管理员。
要确定你频道的聊天ID,请按照以下步骤进行:
首先,向你创建的频道发送一条消息。
在返回的数据中,你会找到一个名为chat
的字段,里面有一个id
,即你的频道的聊天ID。
请记住安全记录此聊天ID,因为在后续配置中需要它。
Cloudflare worker允许你部署代码,该代码托管在线并将长期运行,以便始终保持对来自webhook的更新的警觉。
首先,登录到你的Cloudflare账户。如果你还没有账户,可以免费注册。
在Cloudflare仪表板的“Workers”选项卡中导航。
点击“创建Worker”按钮。这将把你带到Worker编辑器。
在编辑器中,你会看到一个脚本模板。用为你的Telegram机器人提供的Cloudflare代码替换默认代码。
在代码中找到BOT_TOKEN
和CHAT_ID
的变量。这些是占位符,将用于通过机器人将消息发送到正确的聊天。
在Cloudflare Workers仪表板中,导航到你的worker的“设置”选项卡。
此处可以将机器人的Token、聊天ID和你的Helius API密钥作为环境变量添加。这有助于将敏感数据保存在你的主代码之外并确保安全。
确保这些环境变量的命名正确,以匹配代码中所需的内容(如BOT_TOKEN
、CHAT_ID
等)。
确保你的代码和环境变量设置正确后,点击“保存并部署”按钮。你的worker将被部署并分配一个独特的公共URL。
部署后,请务必记下分配给你的worker的公共URL。此URL将用于作为你的Telegram机器人的webhook端点。
代码
const TELEGRAM_BOT_TOKEN = BOT_TOKEN;
const TELEGRAM_CHAT_ID = CHAT_ID;
const HELIUS_API_KEY=API_KEY;
const HELIUS_RPC_URL = `https://mainnet.helius-rpc.com/?api-key=${HELIUS_API_KEY}`;
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request))
})
async function handleRequest(request) {
if (request.method === 'POST') {
const requestBody = await request.json();
console.log('收到的POST请求体:', requestBody);
//这是NFT更新(如果正在做其他事情,请注释掉此部分)
// 提取交易描述、时间戳、签名和铸造地址
// const NFTdescription = requestBody[0].description;
// const NFTtimestamp = new Date(requestBody[0].timestamp * 1000).toLocaleString(); // 将Unix时间戳转换为可读的日期时间
// const NFTsignature = `https://solscan.io/tx/${requestBody[0].signature}`
// const NFTmintAddress = requestBody[0].events.nft.nfts[0].mint;
// const NFTimageUrl = await getAssetImageUrl(NFTmintAddress);// 获取NFT图像URL
// // 构造消息
// const messageToSendNFT =
// `----新更新---\n`+
// `描述:\n${NFTdescription}\n` +
// `铸造地址:\n${NFTmintAddress}\n` +
// `签名:\n${NFTsignature}\n` +
// `时间戳:\n${NFTtimestamp}`;
// await sendToTelegramNFT(messageToSendNFT, NFTimageUrl); // 发送到Telegram
//这是转账更新(如果正在做其他事情,请注释掉此部分)
// 提取交易描述、时间戳、签名
const Transferdescription = requestBody[0].description;
const Transfertimestamp = new Date(requestBody[0].timestamp * 1000).toLocaleString(); // 将Unix时间戳转换为可读的日期时间
const Transfersignature = `https://xray.helius.xyz/tx/${requestBody[0].signature}`
// 构造消息
const messageToSendTransfer =
`----新更新---\n`+
`描述:\n${Transferdescription}\n` +
`签名:\n${Transfersignature}\n` +
`时间戳:\n${Transfertimestamp}`;
await sendToTelegramTransfer(messageToSendTransfer); // 发送到Telegram
return new Response('记录了POST请求体。', {status: 200});
} else {
return new Response('不允许该方法。', {status: 405});
}
}
// 该函数用于将NFT更新发送到机器人
async function sendToTelegramNFT(message, imageUrl) {
const telegramUrl = `https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendPhoto`;
const response = await fetch(telegramUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
chat_id: TELEGRAM_CHAT_ID,
photo: imageUrl,
caption: message,
parse_mode: "HTML"
}),
});
const responseData = await response.json();
if (!response.ok) {
console.error('向Telegram发送照片失败:', responseData);
}
}
//该函数用于将转账更新发送到Bot
async function sendToTelegramTransfer(message) {
const telegramUrl = `https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage`;
const response = await fetch(telegramUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
chat_id: TELEGRAM_CHAT_ID,
text: message,
parse_mode: "HTML"
}),
});
const responseData = await response.json();
if (!response.ok) {
console.error('向Telegram发送消息失败:', responseData);
}
}
//该函数获取与更新中提到的NFT相关的图像。
async function getAssetImageUrl(mintAddress) {
const response = await fetch(HELIUS_RPC_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
jsonrpc: '2.0',
id: 'my-id',
method: 'getAsset',
params: {
id: mintAddress,
},
}),
});
const { result } = await response.json();
return result.content.links.image;
}
Helius webhooks连接Solana区块链上的变化和你的Telegram频道。在这个例子中,我将设置一个webhook来跟踪某个钱包的所有交易。
访问 dashboard.helius.dev 并创建一个免费账户。
在你的仪表板中,选择创建一个新的webhook。你需要选择它的类型 - 原始、增强、Discord或账户。对于具体分类的更新,建议选择“增强”。选择此选项时,指定你感兴趣的更新,如NFT_SALES
或NFT_LISTING
。
完整的列表可在 这里 找到。
确保你提供部署好的Cloudflare worker的链接。此外,提到你想监控的特定Solana账户地址(可以是用户的钱包或来自某个集合的铸造列表)。
如果你想跟踪某个集合,在该集合中的NFT发生变化时获取更新,你将需要将所有NFT铸造地址作为账户添加到你的webhook中。为此,你需要使用Helius webhook端点来编辑你最初创建的webhook。一旦设置好,你将能够跟踪销售、上市、出价、焚烧以及任何NFT参与的其他交易。
你需要做的第一件事就是获得要跟踪的集合的铸造/哈希列表。你可以使用以下代码通过DAS获得铸造列表。你需要做的只是添加你的Helius API密钥,并将creatorAddress替换为NFT的第一个经过验证的创作者的地址。你可以通过访问你喜欢的探索工具 xray.helius.xyz 来查找第一个经过验证的创作者,查找元数据,并在创作者部分下找到地址:
代码
const fs = require('fs');
const url = `https://mainnet.helius-rpc.com/?api-key=`;
const getAssetsByCreator = async () => {
let page = 1;
let allMintAddresses = [];
while (true) {
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
jsonrpc: '2.0',
id: `my-id-page-${page}`,
method: 'getAssetsByCreator',
params: {
creatorAddress: 'GFQBHxuNcAwYwHtEpggMwbH5kwV6Ne4JowHbLVfsMC6C',
onlyVerified: true,
page: page,
limit: 1000
},
}),
});
const { result } = await response.json();
// 如果没有更多项目,则中断循环
if (!response.ok) {
throw new Error(`HTTP error! 状态: ${response.status}`);
}else{
if (!result.items || result.items.length === 0) {
break;
}
}
// 提取铸造地址并将其添加到列表中
const mintAddresses = result.items.map(item => item.id);
allMintAddresses.push(...mintAddresses);
// 检查结果是否少于1000以停止进一步请求
if (result.items.length < 1000) {
break;
}
page++;
}
// 通过逗号连接地址
const addressesString = allMintAddresses.join(',');
console.log("所有铸造地址: ", addressesString);
fs.writeFileSync('addresses.json', JSON.stringify(allMintAddresses, null, 2));
};
getAssetsByCreator();
获得这个后,你可以通过打开终端,导航到包含脚本的目录并运行node snapshot.js来运行脚本。这将在该目录中创建一个名为addresses.json的JSON文件。或者,你可以使用像 Magic Eden快照工具 这样的工具来获取哈希列表。
一旦你有了哈希列表,你可以更新webhook跟踪的账户列表。为此,你需要使用Helius webhooks端点。我附上了一些代码来简化此操作。只需创建一个名为webhookUpdate.js的新JavaScript文件(与哈希列表在同一目录中)并添加以下代码。然后你可以编辑代码以加入你的Helius API密钥和webhook ID(此信息可以在开发者门户中找到)。接下来需要编辑请求的主体以匹配你创建webhook时使用的数据。因此,如果你选择跟踪NFT上市和销售,请确保包括那些数据。不要编辑accountAddresses字段,因为它设置为使用我们之前创建的哈希列表。
一旦做出这些更改,你可以通过终端运行此脚本,使用node webhookUpdate.js。运行此代码后,你应该会在终端收到确认。
代码
const fs = require('fs');
const editWebhook = async () => {
try {
// 读取JSON文件
const addresses = JSON.parse(fs.readFileSync('addresses.json', 'utf8'));
const response = await fetch(
"https://api.helius.xyz/v0/webhooks/?api-key=",
{
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
webhookURL: "",
transactionTypes: ["NFT_LISTING","NFT_SALE"],
accountAddresses: addresses, // 使用文件中的地址
webhookType: "enhanced"
}),
}
);
const data = await response.json();
console.log({ data });
} catch (e) {
console.error("错误", e);
}
};
editWebhook();
更新webhook后,你可以返回Cloudflare worker并编辑代码,以返回与NFT相关的特定细节。所需的代码已经包含在内,你只需要注释掉发送转账更新的部分,并取消注释发送NFT更新的部分。
当你跟踪的事件在链上发生时,webhook将向Cloudflare worker发送更新。此更新将以json格式发送,通常包含大量信息,如所有相关账户、每个账户的变化以及与事件类型相关的信息。在提供的代码中,我们提取我们认为重要的部分。
如果你想自定义发送的消息或更改从webhook更新中提取的数据,可以更改messageToSend变量。如果你想跟踪转账和NFT事件以外的内容,你仍然可以这样做。你可以修改Cloudflare代码以发送整个requestBody[0]。这将转发完整的webhook JSON响应到你的Telegram机器人,让你查看响应结构。然后你可以查看并决定哪些部分要包含在你的消息中。
通过这个设置,你的Telegram频道成为来自Solana区块链实时更新的中心,这一切都得益于Helius webhooks。我们希望你觉得本指南有用,如果你有任何问题或疑虑,请随时在Discord或Twitter上联系我们的团队。
- 原文链接: helius.dev/blog/solana-t...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!