Una idea un proyecto: STEEM MESSENGER - STEEM <-> TELEGRAM PARTE 1
Registro 2: 26/07/2025 - Comunicación bidireccional entre STEEM y TELEGRAM
Versión de Python: 3.10
Modulo para interactuar: beem
Asistente AI (para programación): Microsoft Copilot
Objetivo: Reflejar en TELEGRAM interacciones ocurridas en STEEM y poder interactuar con STEEM desde TELEGRAM
Después de haber alcanzado el objetivo uno, que fue la fase más sencilla del proyecto, llegó el momento de conquistar el objetivo 2 pero no sin antes agradecer la receptividad que ha tenido el proyecto entre muchos usuarios.
En este objetivo queremos establecer un puente de datos entre STEEM y TELEGRAM de manera que pueda acceder a algunas funciones de STEEM en la aplicación TELEGRAM. ¿Por qué hacer esto y cómo puede ser útil al proyecto? te lo diré en el siguiente párrafo. 😉

Imagen generada por Microsoft Copilot con fines ilustrativos para este artículo
Esta es solo mi opinión personal y respetaría cualquier opinión opuesta:
La capacidad de un ente para comunicarse le abre puertas de crecimiento, una persona que habla varios idiomas puede estar en más países con menor dificultad que una que solo habla un idioma (capacidad de comunicación), una ciudad que tiene vías de comunicación (para tráfico de vehículos) con otras ciudades crecerá más rápido económicamente hablando que una ciudad a la que es difícil acceder. Y puedo seguir con los ejemplos...
En ese orden de idea, una red social tiene el deber de comunicar personas dentro de un entorno cómodo, agradable y entretenido. Actualmente hay algunas redes sociales muy populares y servicios de mensajería, rara vez puedes mezclar estas de forma nativa, es decir, no puede publicar en Facebook desde X, no puedes enviar un mensaje a Whatsapp desde Telegram, de alguna forma existe una rivalidad que hace a estas empresas establecer murallas de comunicación para clientes básicos, tal vez con la finalidad de que no miren a otra parte.
Podría crear una aplicación de mensajería interna en STEEM con CUSTOM_JSON y establecer las mismas barreras, pero creo que eso sería estúpido (lo de las barreras), Conocí a STEEM primero que Facebook, TELEGRAM, X, TIKTOK, INSTAGRAM, y otras redes sociales que han evolucionado mucho todo este tiempo, sin embargo, STEEM parece no haber tenido muchos cambios importantes. De las redes sociales mencionadas estoy seguro de que la mayoría de las personas con un smartphone tienen conocimiento sobre su existencia por no decir que forman parte de estas.
STEEM sin embargo no es tan popular como debería. Así que valdría la pena preguntarnos ¿cuáles son las capacidades que tiene STEEM como red social para comunicarse? La creación de artículos, comentarios y memos en transferencias diría yo, la mayoría de estas cosas son de dominio público y pareciera que la mayoría de los usuarios no miran a STEEM por sus capacidades de comunicación sino por su recompensa económica.
Lo que busco en estas fases previas es demostrar las capacidades de comunicación que puede tener STEEM derribando las barreras que tienen las empresas centralizadas, hacer que STEEM comience a ser nombrado entre usuarios de TELEGRAM y otras redes populares aumentará la popularidad de STEEM, además de brindarle a los usuarios actuales un abanico de opciones para interactuar con la blockchain.
Ya que aún no he desarrollado una app que los usuarios puedan usar para este proyecto, la conexión con aplicaciones como Telegram y Whatsapp servirán para ir haciendo pruebas durante el desarrollo.
INTERCONEXIÓN DE API's |
---|
Cuando lo miras a simple vista parece algo muy complicado de hacer, aunque ambos son sistemas que buscan comunicar personas la estructura de STEEM no parece compatible con TELEGRAM, no parece algo que se pueda hacer tan fácilmente.
Como dije, la capacidad de un sistema para comunicarse le abre puertas de crecimiento, aquí es donde las API's cobran importancia porque nos permiten interactuar con un sistema a través de un código de programa, en el artículo anterior (que citaré al final de este) pudimos notar como interactuamos con STEEM desde un simple script escrito en Python, se pudo crear un script para monitorear las transferencias de una cuenta e imprimirlas de forma instantánea al momento de ocurrir, no estaba en steemit.com, ni siquiera estaba usando el lenguaje de programación nativo de STEEM C++ (Corrígeme si me equivoco), solo entramos por la API y tomamos datos, así que la API es como esa pequeña ventana que da acceso a un mundo de posibilidades.
De la misma forma puedo usar un Script para comunicarme con TELEGRAM, pero aquí debemos preparar algunas cosas para poder acceder a hacer cosas desde Python.
Requisitos iniciales para conectar Python ↔ Telegram
- 🔑 Crear tu Bot de Telegram
- Abre Telegram y busca @BotFather
- Usa el comando /newbot
- 📦 Instalar librerías Python necesarias
- Para STEEM la librería necesaria es beem que se instala con pip install beem (ya la tengo instalada)
- Para TELEGRAM la librería necesaria es python-telegram-bot: permite enviar, recibir y procesar mensajes desde tu bot, se instala con pip install python-telegram-bot
Ahora vamos a crear un CHAT_ID en TELEGRAM, este servirá para que el bot pueda interactuar con el SCRIPT, es decir, identificaremos el chat donde interactuamos con STEEM mediante este código. Para obtenerlo hacemos lo siguiente:
🧑💻 Pasos para obtener tu chat_id
- Abre Telegram y busca el bot: @userinfobot
El siguiente paso es iniciar el bot que acabamos de crear, en mi caso "@steemmessenger_bot", debemos iniciar el chat con el.
En este punto ya tenemos un enlace entre STEEM y TELEGRAM, para ponerlo a prueba vamos a modificar el script del artículo anterior, ahora, cuando ocurra una transferencia los datos aparecerán reflejados en e chat con el bot de telegram:
#!/usr/bin/env python3
import time
from beem import Steem
from telegram import Bot
STEEM_NODE = "https://api.steemit.com"
ACCOUNT = "TU CUENTA DE STEEM AQUI"
POLL_INTERVAL = 3 # segundos entre chequeos
TELEGRAM_TOKEN = "EL TOKEN DE TELEGRAM QUE TE DIO BOTFHATHER AQUI"
CHAT_ID = "EL ID DE TELEGRAM QUE TE DIO USERINFOBOT AQUI"
bot = Bot(token=TELEGRAM_TOKEN)
def get_head_block_number(steem):
props = steem.rpc.get_dynamic_global_properties()
return props.get("head_block_number", 0)
def process_block(steem, block_num, account):
block = steem.rpc.get_block(block_num)
for trx in block.get("transactions", []):
for op in trx.get("operations", []):
if not (isinstance(op, (list, tuple)) and len(op) == 2):
continue
op_type, data = op
if op_type != "transfer":
continue
frm, to = data.get("from"), data.get("to")
amt, memo = data.get("amount"), data.get("memo")
if frm == account or to == account:
direction = "→" if frm == account else "←"
msg = f"[block {block_num}] {frm} {direction} {to} | {amt} | memo: {memo}"
print(msg)
import asyncio
asyncio.run(bot.send_message(chat_id=CHAT_ID, text=msg))
def listen_transfers_by_block(account, poll_interval=POLL_INTERVAL):
steem = Steem(node=[STEEM_NODE])
last_block = get_head_block_number(steem)
print(f"⏱️ Escuchando @ {account} a nivel de bloques. Comenzamos en {last_block}\n")
while True:
head = get_head_block_number(steem)
if head > last_block:
for bn in range(last_block + 1, head + 1):
process_block(steem, bn, account)
last_block = head
time.sleep(poll_interval)
if __name__ == "__main__":
listen_transfers_by_block(ACCOUNT)
Si llenas con los parámetros correspondientes a tus datos de STEEM (tu nombre de usuario sin @) y los datos obtenidos de telegram, mientras estes corriendo este script recibiras en tu cuenta de telegram las notificaciones de transferencias en tiempo real.
MENSAJES BIDIRECCIONALES ENCRIPTADOS |
---|
Eureka!
Tenemos un puente funcional entre STEEM y TELEGRAM, ahora podemos modificar nuestro script para enviar a TELEGRAM cualquier cosa que queramos relacionada con STEEM, si alguien escribió un artículo, si alguien voto por mi artículo, si alguien respondió un comentario entre un sin fin de cosas. No obstante, no quiero que la emoción me haga perder el norte, así que vamos a enfocarnos en el servicio de mensajería.
He decidido darle prioridad a las transferencias porque es el único método básico que conozco para enviar mensajes encriptados, si usara los comentarios entonces no tendría privacidad en mis conversaciones, así que puedo hacer que telegram me muestre todo lo que quiera de STEEM pero para efectos de un messenger me interesan más aquellas cosas que pueda escribir con un alto grado de privacidad.
También existe una forma de solo lectura que se puede usar, es mediante la CLAVE MEMO, creo que es una clave que nadie usa, pero esta ahí, su único propósito es cifrar y descifrar mensajes MEMO de las transferencias, así que preparare un script de solo lectura en el que pueden enviarte mensajes cifrados y puedes leerlos en TELEGRAM descifrados.
Para descifrar mensajes se me complicaron un poco las cosas debido a que mi modulo beem no vino con beemgraphenebase y no hubo manera de poderlo cargar, en este caso tuve que irme a pie, pero ya había una guía a seguir para comprender la estructura de encriptado y desencriptado de memos en STEEM.
Basado en ello construí mi propio script de desencriptado, fue necesario instalar el módulo base58 que se puede instalar con pip install base58
El siguiente código está orientado a desencriptar mensajes en los memos de las transferencias:
import base58, base64, struct
from hashlib import sha256, sha512
from ecdsa import SECP256k1, SigningKey, VerifyingKey
from binascii import unhexlify
from Crypto.Cipher import AES
def extract_privkey_wif(wif):
raw = base58.b58decode(wif)
payload = raw[:-4]
privkey = payload[1:]
if len(privkey) == 33 and privkey[-1] == 0x01:
privkey = privkey[:-1]
return privkey
def decode_steem_pubkey(pubkey_str):
raw = base58.b58decode(pubkey_str[3:])
payload = raw[:-4]
return VerifyingKey.from_string(payload, curve=SECP256k1).pubkey.point
def _unpad(s, bs):
count = s[-1]
if s[-count:] != bytes([count] * count):
return s # Padding incorrecto, devolver como está
return s[:-count]
def derive_aes_from_beem(shared_x, nonce):
ss = sha512(unhexlify(shared_x.hex())).digest()
seed = struct.pack("<Q", int.from_bytes(nonce, "little")) + ss
d = sha512(seed).digest()
key, iv = d[:32], d[32:48]
checksum = struct.unpack_from("<I", sha256(d).digest())[0]
return AES.new(key, AES.MODE_CBC, iv), checksum
def extract_memo_parts(memo_base58):
raw = base58.b58decode(memo_base58[1:])
from_key = raw[:33]
to_key = raw[33:66]
nonce = struct.unpack_from("<Q", raw[66:74])[0]
nonce_bytes = struct.pack("<Q", nonce)
checksum = struct.unpack_from("<I", raw[74:78])[0]
encrypted = raw[78:]
return from_key, to_key, nonce_bytes, checksum, encrypted
def descifrar_memo_beem_style(memo_b58, priv_wif, pubkey_emisor):
priv_bytes = extract_privkey_wif(priv_wif)
pub_point = decode_steem_pubkey(pubkey_emisor)
signer = SigningKey.from_string(priv_bytes, curve=SECP256k1)
shared = pub_point * signer.privkey.secret_multiplier
shared_x = shared.x().to_bytes(32, "big")
from_key, to_key, nonce_bytes, checksum_orig, encrypted = extract_memo_parts(memo_b58)
aes, checksum_calc = derive_aes_from_beem(shared_x, nonce_bytes)
if checksum_orig != checksum_calc:
return "[❌ Checksum mismatch — claves incorrectas o nonce alterado]"
# Desplazamiento Beem-style para alinear bloques
numBytes = 16 - len(encrypted) % 16
n = 16 - numBytes
cipher_data = encrypted[n:]
decrypted = aes.decrypt(cipher_data)
texto = _unpad(decrypted, 16)
try:
return texto.decode("utf-8")
except:
return texto.decode("utf-8", errors="replace")
La función encargada de desencriptar es "descifrar_memo_beem_style(memo_b58, priv_wif, pubkey_emisor)"
Cuando se llama; memo_b58 es el mensaje a descifrar, priv_wif es la clave memo privada del receptor y pubkey_emisor la clave memo publica del emisor.
Este archivo lo guardé aparte en la misma carpeta donde ejecuto el script donde me comunico con telegram, se puede incluir el código en un solo script pero no quiero afectar a los que puedan usar beemgrapheno sin problemas, así que solo hice un nuevo archivo desde el cual importo la función descifrar_memo_beem_style para decodificar los mensajes antes de enviarlos a telegram.
Además se cambió que solo se tomen en cuenta las transferencias entrantes, es decir, solo llegaran los entrantes y no cuando enviemos como ocurría antes, el formato también se cambió usando solo FROM por se supone que TO somos nosotros mismos 😄.
Luego de mucho trabajo te presento el script que te permitirá recibir los memos de tus transferencias entrantes como mensajes en telegram, incluso si están encriptados los presentara desencriptados.
#!/usr/bin/env python3
import time
import requests
from beem import Steem
from telegram import Bot
from beem.memo import Memo
from decrypt import descifrar_memo_beem_style # decrypt es el nombre con el que guardé mi archivo para desencriptar
STEEM_NODE = "https://api.steemit.com"
ACCOUNT = "aquí va tu usuario"
POLL_INTERVAL = 3 # segundos entre chequeos
TELEGRAM_TOKEN = "aquí va el token de telegram que te dio botfather"
CHAT_ID = "aquí va el ID que te dío userinfobot"
bot = Bot(token=TELEGRAM_TOKEN)
# Solo para cifrar/descifrar memos (no sirve para transferir)
STEEM_MEMO_KEY = "Aquí va tu memo KEY privada de steem"
memo_key_cache = {}
# ─── INICIALIZACIÓN ─────────────────────────────────────────────────────────
steem = Steem(nodes=[STEEM_NODE], keys=[STEEM_MEMO_KEY], timeout=10)
loop = asyncio.get_event_loop()
def send_telegram(chat_id: str, msg: str) -> bool:
"""
Envía un mensaje simple al chat indicado a través del bot de Telegram.
Retorna True si el envío fue exitoso, False en caso contrario.
"""
TELEGRAM_TOKEN = "aquí va el token de telegram que te dio botfather"
url = f"https://api.telegram.org/bot{TELEGRAM_TOKEN}/sendMessage"
payload = {
"chat_id": chat_id,
"text": msg
}
try:
response = requests.post(url, data=payload, timeout=5)
return response.status_code == 200
except Exception as e:
print(f"❌ Error al enviar a Telegram: {e}")
return False
def get_head_block_number(steem):
props = steem.rpc.get_dynamic_global_properties()
return props.get("head_block_number", 0)
def get_memo_pubkey(account):
if account not in memo_key_cache:
info_list = steem.rpc.get_accounts([account])
if not info_list:
print(f"[❌ Cuenta no encontrada en el nodo: {account}]")
return None
info = info_list[0]
memo_key_cache[account] = info["memo_key"]
return memo_key_cache[account]
def process_block(steem, block_num, account):
block = steem.rpc.get_block(block_num)
for trx in block.get("transactions", []):
for op in trx.get("operations", []):
if not (isinstance(op, (list, tuple)) and len(op) == 2):
continue
op_type, data = op
if op_type != "transfer":
continue
frm = data.get("from")
to = data.get("to")
amt = data.get("amount")
memo = data.get("memo", "")
# 🎯 Solo transferencias ENTRANTES
if to != account:
continue
# 🔐 Solo buscar clave si el memo está cifrado
if memo.startswith("#"):
pub_key = get_memo_pubkey(frm)
memo = descifrar_memo_beem_style(memo, STEEM_MEMO_KEY, pub_key) if pub_key else "[❌ Clave pública no disponible]"
msg = f"FROM: {frm}\nMSG: {memo}\nBID: {amt}"
print(msg)
send_telegram(chat_id=CHAT_ID, msg=msg)
def listen_transfers_by_block(account, poll_interval=POLL_INTERVAL):
steem = Steem(node=[STEEM_NODE])
last_block = get_head_block_number(steem)
print(f"⏱️ Escuchando @ {account} a nivel de bloques. Comenzamos en {last_block}\n")
while True:
head = get_head_block_number(steem)
if head > last_block:
for bn in range(last_block + 1, head + 1):
process_block(steem, bn, account)
last_block = head
time.sleep(poll_interval)
if __name__ == "__main__":
listen_transfers_by_block(ACCOUNT)
Mientras estés corriendo el script ocurrirá lo siguiente:
En el bot de Telegram
En STEEM (Aunque esta parte no la hice yo 😊)
- Si recibes una transferencia con un memo encriptado
En el script
En Steem habiendo iniciado sesión
En STEEM para el resto de los mortales 😃
Como puedes notar, se puede usar la encriptación de los memos para usar un messenger con una privacidad inigualable, al ser STEEM una red descentralizada nadie mas que tú y el receptor tendrán acceso al mensaje. Esto es algo grande de steem que puede ser explotado para catapultarlo a las estrellas.
Ya que el contenido se me está sobrecargando dejaré la parte en la que podemos escribirle a un usuario de Steem desde Telegram para el siguiente apartado.
Si puedes hacer pruebas en busca de fallos que se necesiten corregir te lo agradecería, aunque he pasado todo el día hoy probándolo.
La verdad estoy feliz con los avances que he conseguido y cada vez me siento más animado con esto. Espero que pueda ser de utilidad, quedo atento a los comentarios. Las imágenes en las que no he colocado fuente son capturas de pantalla hechas por mi
Te puede interesar: Una idea un proyecto: STEEM MESSENGER
_
Un proyecto ambicioso, respeto por lo que ya has conseguido. Buena suerte y que continúe el éxito.
0.00 SBD,
0.32 STEEM,
0.32 SP
Gracias, ahora mismo la comunicación vía telegram está completa (enviar y recibir mensajes entre usuarios de steem usando solo telegram), solo estoy tratando de compilar un .exe sencillo para que lo pueda usar cualquiera sin necesidad de tener python instalado (ni los modulos requeridos). Termino ese detalle y para el siguiente articulo ya tendremos algo útil 100% operativo.
0.00 SBD,
1.18 STEEM,
1.18 SP
Hola hola querido amigo, feliz domingo espero que estés muy bien. 🙂
Ciertamente la plataforma no ha tenido tantos avances como las demás que mencionas, y pues sinceramente es porque a sus dueños o personas a cargo no les importa mucho que digamos, sino la historia seria otra a mí parecer. Como por ejemplo lo han hecho con tron, pero está genial que otras personas quieran hacer algo distinto y crear aplicaciones para mejorar el sistema.
Gracias por compartirlo, saludos! 😊
Y además te sugerimos votar por @cotina como Witness, sino sabes cómo hacerlo, podrías revisar estas publicaciones:
https://steemit.com/hive-113376/@colombiaoriginal/colombia-original-apoyando-a-cotina-como-witness.
0.00 SBD,
0.10 STEEM,
0.10 SP
Aquí entre nos.... llevo tiempo observando eso con rabia, siento que si BTC hace uno de esos bajones que suele hacer STEEM va a desaparecer, tal vez faltan solo meses para que BTC tenga una fuerte corrección, pero sinceramente me cansé de solo rabiar, tal vez esta sea mi última temporada aquí pero no quiero irme con cargo de conciencia sino estar tranquilo de que hice mi parte, o al menos cuanto pude para que las cosas fuesen mejor.
Tal vez no necesitamos que "los dueños" tengan interés, tal vez si todos ponemos un granito de arena podemos lograr grandes cosas, después de todo nosotros somos steem, sin nosotros no existe y nosotros por él estamos aquí, no por los dueños. Así que, no quiero pensar en eso porque tiro la toalla jeje... solo quiero enfocarme en que todo cambiará para bien y que mi enfoque se materialice, me acompañarías en eso?
chriddi, moecki and/or the-gorilla
0.00 SBD,
0.09 STEEM,
0.09 SP