ニジカのスカトロ,ニジカトロ. https://bsky.app/profile/deerjika-bot.bsky.social
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

92 lines
3.2 KiB

  1. from datetime import datetime, timedelta
  2. import time
  3. import sys
  4. from atproto import Client, models
  5. from ai.talk import Talk
  6. import account
  7. def check_notifications (
  8. client: Client,
  9. ) -> list:
  10. (uris, last_seen_at) = ([], client.get_current_time_iso ())
  11. for notification in (client.app.bsky.notification.list_notifications ()
  12. .notifications):
  13. if ((not notification.is_read)
  14. and (notification.reason in ['mention', 'reply'])):
  15. uris += [notification.uri]
  16. client.app.bsky.notification.update_seen ({ 'seen_at': last_seen_at })
  17. return uris
  18. def get_thread_contents (
  19. client: Client,
  20. uri: str,
  21. parent_height: int,
  22. ) -> list:
  23. response = (client.get_post_thread (uri = uri,
  24. parent_height = parent_height)
  25. .thread)
  26. records = []
  27. while response is not None:
  28. records += [{ 'strong_ref': models.create_strong_ref (response.post),
  29. 'did': response.post.author.did,
  30. 'handle': response.post.author.handle,
  31. 'name': response.post.author.display_name,
  32. 'datetime': response.post.record.created_at,
  33. 'text': response.post.record.text }]
  34. response = response.parent
  35. return records
  36. def main () -> None:
  37. client = Client (base_url = 'https://bsky.social')
  38. client.login (account.USER_ID, account.PASSWORD)
  39. last_posted_at = datetime.now () - timedelta (hours = 6)
  40. has_got_snack_time = False
  41. while True:
  42. now = datetime.now ()
  43. for uri in check_notifications (client):
  44. records = get_thread_contents (client, uri, 20)
  45. if len (records) > 0:
  46. answer = Talk.main (records[0]['text'],
  47. records[0]['name'],
  48. [*map (lambda record: {
  49. 'role': ('assistant'
  50. if (record['handle']
  51. == account.USER_ID)
  52. else 'user'),
  53. 'content':
  54. record['text']},
  55. reversed (records[1:]))])
  56. client.send_post (answer,
  57. reply_to = models.AppBskyFeedPost.ReplyRef (
  58. parent = records[0]['strong_ref'],
  59. root = records[-1]['strong_ref']))
  60. if now.hour == 14 and has_got_snack_time:
  61. has_got_snack_time = False
  62. if now.hour == 15 and not has_got_snack_time:
  63. client.send_post (Talk.main ('おやつタイムだ!!!!'))
  64. last_posted_at = now
  65. has_got_snack_time = True
  66. if now - last_posted_at >= timedelta (hours = 6):
  67. client.send_post (Talk.main (''))
  68. last_posted_at = now
  69. if __name__ == '__main__':
  70. main (*sys.argv[1:])