Oops, forgot to commit the work
All checks were successful
git.cronocide.net/bluebubbles-bot/pipeline/head This commit looks good
All checks were successful
git.cronocide.net/bluebubbles-bot/pipeline/head This commit looks good
This commit is contained in:
parent
6a307fbb69
commit
a1d83ed573
151
bin/bluebubbles_bot
Normal file
151
bin/bluebubbles_bot
Normal file
@ -0,0 +1,151 @@
|
||||
#!python3
|
||||
|
||||
import os
|
||||
import sys
|
||||
import yaml
|
||||
import uuid
|
||||
import logging
|
||||
import argparse
|
||||
import persona
|
||||
from typing import List
|
||||
from dataclasses import dataclass
|
||||
import datetime
|
||||
import requests
|
||||
from fastapi import FastAPI
|
||||
import uvicorn
|
||||
|
||||
class LoggingFormatter(logging.Formatter):
|
||||
def format(self, record):
|
||||
module_max_width = 30
|
||||
datefmt='%Y/%m/%d/ %H:%M:%S'
|
||||
level = f'[{record.levelname}]'.ljust(9)
|
||||
if 'log_module' not in dir(record) :
|
||||
modname = str(record.module)+'.'+str(record.name)
|
||||
else :
|
||||
modname = record.log_module
|
||||
modname = (f'{modname}'[:module_max_width-1] + ']').ljust(module_max_width)
|
||||
final = "%-7s %s [%s %s" % (self.formatTime(record, self.datefmt), level, modname, record.getMessage())
|
||||
return final
|
||||
|
||||
bot = FastAPI()
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
# Command-line client
|
||||
# Define constants
|
||||
config_template = {'bluebubbles_bot': {}}
|
||||
|
||||
# Gather Argument options
|
||||
EXAMPLE_TEXT='Example:\n\tbluebubbles_bot -h'
|
||||
parser = argparse.ArgumentParser(epilog=EXAMPLE_TEXT,formatter_class=argparse.RawDescriptionHelpFormatter)
|
||||
parser.add_argument('-l', '--log', action='store', help='Specify a file to log to.')
|
||||
parser.add_argument('-v', '--verbose', action='count', help='Include verbose information in the output. Add \'v\'s for more output.',default=0)
|
||||
args = parser.parse_args()
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
log = logging.LoggerAdapter(log,{'log_module':'bluebubbles_bot'})
|
||||
|
||||
# Configure logging
|
||||
log_options = [logging.ERROR, logging.WARNING, logging.INFO, logging.DEBUG]
|
||||
if not args.verbose :
|
||||
args.verbose = 0
|
||||
if args.verbose > 3 :
|
||||
args.verbose = 3
|
||||
if args.log :
|
||||
logging.basicConfig(level=log_options[args.verbose],filename=args.log)
|
||||
logging.getLogger().addHandler(logging.StreamHandler(sys.stderr))
|
||||
else :
|
||||
logging.basicConfig(level=log_options[args.verbose])
|
||||
logging.getLogger().handlers[0].setFormatter(LoggingFormatter())
|
||||
logging.propagate=True
|
||||
|
||||
# Check for missing environment variables
|
||||
for required_var in ['BB_SERVER_URL','BB_SERVER_PASSWORD'] :
|
||||
if required_var not in os.environ.keys() :
|
||||
log.error(f'Missing required ENV variable {required_var}')
|
||||
exit(1)
|
||||
|
||||
def send_message(message) :
|
||||
"""Send a message to the server, optionally with attachments."""
|
||||
# Use the private API instead of applescript
|
||||
if 'USE_PRIVATE_API' in os.environ.keys() and os.environ['USE_PRIVATE_API'].lower() in ['true', 'yes'] :
|
||||
method = 'private-api'
|
||||
else :
|
||||
method = 'apple-script'
|
||||
uid = str(uuid.uuid4()).upper()
|
||||
text = message.text
|
||||
chat_guid = message.chat_identifier
|
||||
url = os.environ['BB_SERVER_URL'].rstrip('/') + '/api/v1/message/text'
|
||||
params = {'password': os.environ['BB_SERVER_PASSWORD']}
|
||||
effect_id = ''
|
||||
subject = ''
|
||||
if 'effectId' in message.meta.keys() :
|
||||
effect_id = message.meta['effectId']
|
||||
if 'subject' in message.meta.keys() :
|
||||
subject = message.meta['subject']
|
||||
payload = {
|
||||
'chatGuid': chat_guid,
|
||||
'message': text,
|
||||
'tempGuid': uid,
|
||||
'method': method,
|
||||
'effectId': effect_id,
|
||||
'subject': subject,
|
||||
'selectedMessageGuid': ''
|
||||
}
|
||||
if len(message.attachments) > 0 :
|
||||
payload.update({'name': uid})
|
||||
payload.pop('text', None)
|
||||
attachments = []
|
||||
for attachment in message.attachments :
|
||||
file = {'file': (uid, message.attachments[attachment].data, message.attachments[attachment].mime_type)}
|
||||
attachments.append(file)
|
||||
payload.update({'attachments':attachments})
|
||||
url = os.environ['BB_SERVER_URL'].rstrip('/') + '/api/v1/message/attachment'
|
||||
requests.post(url,params=params,json=payload)
|
||||
# Create persona instance
|
||||
current_persona = persona.Persona()
|
||||
|
||||
# Create a fastAPI instance
|
||||
@bot.post('/message')
|
||||
async def message(content: dict):
|
||||
# print(content)
|
||||
if content['type'] == 'new-message' :
|
||||
message = content['data']
|
||||
# Determine sender and receiver
|
||||
if message['isFromMe'] :
|
||||
sender = message['handle']['address']
|
||||
recipients = []
|
||||
else :
|
||||
sender = None
|
||||
recipients = [message['handle']['address']]
|
||||
# Resolve attachments
|
||||
attachments = []
|
||||
for attachment in message['attachments'] :
|
||||
attachments.append(persona.Attachment(mime_type=message['attachments'][attachment]['mimeType'],data=message['attachments'][attachment]['guid']))
|
||||
# Get the date sent
|
||||
date_sent = datetime.datetime.fromtimestamp(message['dateCreated']/100)
|
||||
# Get any effects or subjects
|
||||
subject = ''
|
||||
effect_id = ''
|
||||
if 'subject' in message.keys() :
|
||||
subject = message['subject']
|
||||
if 'expressiveSendStyleId' in message.keys() :
|
||||
effect_id = message['expressiveSendStyleId']
|
||||
# Craft the message
|
||||
persona_message = persona.Message(
|
||||
text=message['text'],
|
||||
sender_identifier=sender,
|
||||
chat_identifier=message['chats'][-1]['guid'],
|
||||
identifier=message['guid'],
|
||||
timestamp=date_sent,
|
||||
recipients=recipients,
|
||||
attachments=attachments,
|
||||
meta={'subject': subject, 'effectId': effect_id}
|
||||
)
|
||||
responses = current_persona.receive_message(persona_message)
|
||||
for response in responses :
|
||||
prompt = persona_message
|
||||
send_message(response)
|
||||
return content
|
||||
|
||||
uvicorn.run(bot,host='0.0.0.0', port=8080)
|
Loading…
Reference in New Issue
Block a user