async def update_messages(logger, bot): channel = chat1.ChatChannel(name=bot.username, public=True) pagination = chat1.Pagination(num=MESSAGES_TO_CHECK) all_posts = await retry_if_timeout(logger, bot.chat.read, channel=channel, pagination=pagination) for m in reversed(all_posts): msg_id = m.id body = "" try: content_type = m.content.type_name if content_type not in ('edit', 'text'): # e.g. a `deletehistory` logger.debug(f"message {msg_id} is a {content_type} - skip") continue stamped_root = StampedMerkleRoot.from_json((m.content.text or m.content.edit).body) except Exception as e: # any errors in here we should probably fix logger.error(f"message {msg_id} doesn't parse as a stamped root ({e}) - skip - {m}") continue if stamped_root.version != 0: logger.debug(f"message {msg_id} has an old version - skip") continue if stamped_root.status is StampStatus.VERIFIABLE: logger.debug(f"message {msg_id} is already verifiable - skip") elif stamped_root.status is StampStatus.PRELIMINARY: await update_ots_for_msg(logger, bot, msg_id, stamped_root) await asyncio.sleep(1) # necessary for broadcasting to succeed :/ else: logger.error(f"message {m.id} does not have a valid status: {stamped_root}")
def alert(msg): if msg in sent and time.time() - sent[msg] < SENT_TIMEOUT: return print(time.strftime("%a, %d %b %Y %H:%M:%S", time.gmtime()), msg) sent[msg] = int(time.time()) if KEYBASE_BOT_KEY: try: channel = chat1.ChatChannel(**KEYBASE_BOT_CHANNEL) asyncio.run(keybaseBot.chat.send(channel, msg)) except Exception as e: print('keybase error', e) if TELEGRAM_BOT_KEY: try: payload = json.dumps({ "chat_id": TELEGRAM_BOT_CHANNEL, "text": msg }) headers = { 'content-type': "application/json", 'cache-control': "no-cache" } url = f'https://api.telegram.org/bot{TELEGRAM_BOT_KEY}/sendMessage' requests.post(url, data=payload, headers=headers) except Exception as e: print('telegram error', e)
async def update_ots_for_msg(logger, bot, msg_id, stamped_root): seqno = stamped_root.root.seqno ots_data = b64decode(stamped_root.ots) try: completed_ots, is_final = await kb_ots.upgrade( identifier=msg_id, raw_data=stamped_root.root.data_to_stamp, ots_data=ots_data, ) except (kb_ots.VerifyError, kb_ots.UpgradeError) as e: logger.info(f"message {msg_id} failed to verify: {e}") return if not is_final: logger.info(f"message {msg_id} is not yet on chain") return verifiable_stamp = replace(stamped_root, status=StampStatus.VERIFIABLE, ots=completed_ots, ) channel = chat1.ChatChannel(name=bot.username, public=True) # edit the message with the new deets seqno = verifiable_stamp.root.seqno try: res = await retry_if_timeout(logger, bot.chat.edit, channel, msg_id, verifiable_stamp.to_json()) except Exception as e: logger.error(f"message {msg_id} error broadcasting verifiable stamp: {e}") raise logger.info(f"message {msg_id} is now verifiable") await last_success.update(bot, seqno)
async def __call__(self, bot, event): if event.type != EventType.WALLET: return if (event.notification.summary.status_description != stellar1.PaymentStatusStrings.COMPLETED.value): return usd = parse_usd_amount(event.notification.summary.amount_description) sender = event.notification.summary.from_username channel = chat1.ChatChannel(name=f"{bot.username},{sender}") message = "thank you so much for the ${0:.2f} :moneybag:".format(usd) await bot.chat.send(channel, message)
async def async_send(topic, message, msg_id=0): channel = chat1.ChatChannel(name=CONFIG['keybase']['TEAM'], topic_name=topic, members_type="team") if msg_id > 0: app.logger.info(f"async_send('{topic}', {msg_id}, edit '{message}')") await bot.chat.edit(channel, msg_id, message) return msg_id else: app.logger.info(f"async_send('{topic}', {msg_id}, send '{message}')") result = await bot.chat.send(channel, message) return result.message_id
def test_read(fixture_path): result = get_result(f"{fixture_path}/read_result.json") thread = chat1.Thread.from_dict(result) assert thread == chat1.Thread( messages=[ chat1.Message( msg=chat1.MsgSummary( id=3, conv_id="00001bca4f13b0a7b81bfbc2acd7f8cf829bf53845ac87cdd8b62617d5aaa084", channel=chat1.ChatChannel( name="alice,bob", members_type="impteamnative", topic_type="chat", ), sender=chat1.MsgSender( uid="8440bf65b0e77107c12e0350fc905e19", username="******", device_id="011e2994f419d748d751a449ae17e218", device_name="alice's phone", ), sent_at=1_544_140_065, sent_at_ms=1_544_140_065_815, content=chat1.MsgContent( type_name="text", text=chat1.MessageText( body="hello", payments=None, user_mentions=None, team_mentions=None, ), ), prev=[ chat1.MessagePreviousPointer( id=2, hash="A40VOjV7PVK7KcGZwOL/BOhPvn/a0jWg1JUltv7OLaQ=" ) ], unread=False, channel_mention="none", ) ) ], pagination=chat1.Pagination( num=469, next="AQ==", previous="zQHV", last=True, force_first_page=None ), )
async def scrolling_message(message, before="", after=""): channel = chat1.ChatChannel(name="yourcompany.marketing", topic_name="lunchtalk", members_type="team") def noop_handler(*args, **kwargs): pass bot = Bot( # you don't need to pass in a username or paperkey if you're already logged in handler=noop_handler) result = await bot.chat.send(channel, f"{before}{message}{after}") msg_id = result.message_id while True: message = rotate(message) await bot.chat.edit(channel, msg_id, f"{before}{message}{after}") await asyncio.sleep(0.5)
async def make_a_poll(): channel = chat1.ChatChannel(name="yourcompany.marketing", topic_name="lunchtalk", members_type="team") def noop_handler(*args, **kwargs): pass # you don't need to pass in a username or paperkey if you're already logged in bot = Bot(handler=noop_handler) result = await bot.chat.send(channel, "what are y'all feeling for lunch?") msg_id = result.message_id await asyncio.gather( bot.chat.react(channel, msg_id, ":burrito:"), bot.chat.react(channel, msg_id, ":sandwich:"), bot.chat.react(channel, msg_id, "other"), )
def test_list(fixture_path): result = get_result(f"{fixture_path}/list_result.json") chat_list = chat1.ChatList.from_dict(result) assert chat_list == chat1.ChatList( offline=False, conversations=[ chat1.ConvSummary( id="0000d5ba71470610a40b4d32af53a52775cc561589525d7b21bad9ec057b6aac", channel=chat1.ChatChannel( name="keybasefriends", members_type="team", topic_type="chat", topic_name="general", ), unread=True, active_at=1_572_402_097, active_at_ms=1_572_402_097_456, member_status="active", ) ], )
async def broadcast_new_root(logger, bot): merkle_root = fetch_keybase_merkle_root() logger.debug(f"fetched and validated {merkle_root.seqno}") try: ots = await kb_ots.stamp(merkle_root.data_to_stamp) except kb_ots.StampError as e: logger.error(f"error stamping {merkle_root.seqno}: {e}") return stamped_root = StampedMerkleRoot( version=0, root=merkle_root, ots=ots, status=StampStatus.PRELIMINARY, ) my_public_channel = chat1.ChatChannel(name=bot.username, public=True) try: res = await retry_if_timeout(logger, bot.chat.send, my_public_channel, stamped_root.to_json()) except Exception as e: logger.error(f"error broadcasting preliminary stamp: {e}") raise logger.info(f"broadcasted {merkle_root.seqno} at msg_id {res.message_id}")
def test_read(fixture_path): result = get_result(f"{fixture_path}/read_result.json") thread = chat1.Thread.from_dict(result) assert thread == chat1.Thread( messages=[ chat1.Message( msg=chat1.MsgSummary( id=3, channel=chat1.ChatChannel( name="alice,bob", public=None, members_type="impteamnative", topic_type="chat", topic_name=None, ), sender=chat1.MsgSender( uid="8440bf65b0e77107c12e0350fc905e19", device_id="011e2994f419d748d751a449ae17e218", username="******", device_name="alice's phone", ), sent_at=1_544_140_065, sent_at_ms=1_544_140_065_815, content=chat1.MsgContent( type_name="text", flip=None, attachment=None, edit=None, reaction=None, delete=None, metadata=None, text=chat1.MsgTextContent( body="hello", payments=None, reply_to=None, reply_to_uid=None, user_mentions=None, team_mentions=None, live_location=None, emojis=None, ), attachment_uploaded=None, system=None, send_payment=None, request_payment=None, unfurl=None, headline=None, ), unread=False, conv_id= "00001bca4f13b0a7b81bfbc2acd7f8cf829bf53845ac87cdd8b62617d5aaa084", bot_info=None, revoked_device=None, prev=[ chat1.MessagePreviousPointer( id=2, hash="A40VOjV7PVK7KcGZwOL/BOhPvn/a0jWg1JUltv7OLaQ=" ) ], kbfs_encrypted=None, is_ephemeral=None, is_ephemeral_expired=None, e_time=None, reactions=None, has_pairwise_macs=None, at_mention_usernames=None, channel_mention="none", channel_name_mentions=None, offline=None, ), error=None, ) ], pagination=chat1.Pagination(num=469, next="AQ==", previous="zQHV", last=True, force_first_page=None), offline=None, identify_failures=None, rate_limits=None, )
def channel(config): return chat1.ChatChannel( name= f"{config['bots']['alice']['username']},{config['bots']['bob']['username']}" )
def _debug_channel(config): if not config.debug_team or not config.debug_topic: return None return chat1.ChatChannel(name=config.debug_team, members_type="team", topic_name=config.debug_topic)