ニジカのスカトロ,ニジカトロ. 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.

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