ShipmentNotifier/ShipmentNotifier.py

131 lines
4.9 KiB
Python
Raw Normal View History

2024-07-12 00:02:19 +01:00
import requests
import json
import yaml
import logging
from datetime import datetime, timedelta
SETTINGS = yaml.safe_load(open('settings.yaml'))
def log(log_message, level):
logger = logging.getLogger('sn-logger')
log_message_types = {
'debug': logger.debug,
'info': logger.info,
'warning': logger.warning,
'error': logger.error,
'critical': logger.critical
}
if not logger.handlers:
logger.setLevel(logging.DEBUG)
formatter = logging.Formatter('[%(levelname)s] %(message)s')
file_handler = logging.FileHandler('logs/' + 'log_' + datetime.now().strftime("%Y-%m-%d_%H:%M:%S") + '.log')
file_handler.setLevel(logging.DEBUG)
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
log_message_types[level](log_message)
def updateSentNotifications(inboundPlanId):
with open('SentNotifications.json') as NotificationsSentJson:
NotificationsSent = json.load(NotificationsSentJson)
NotificationsSent['NotificationsSent'].append(inboundPlanId)
with open('SentNotifications.json', mode='w') as outputNotificationsSent:
outputNotificationsSent.write(json.dumps(NotificationsSent, indent=4))
def isIDInSentNotifications(inboundPlanId):
with open('SentNotifications.json') as NotificationsSentJson:
NotificationsSent = json.load(NotificationsSentJson)
if inboundPlanId in NotificationsSent['NotificationsSent']:
return True
else:
return False
2024-07-12 19:55:03 +01:00
def isShipmentWithinSpecifiedDelta(shipmentCreationTime, delta=360):
2024-07-12 00:02:19 +01:00
currentTime = datetime.now()
shipmentTime = datetime.strptime(shipmentCreationTime, '%Y-%m-%dT%H:%M:%SZ')
timeDelta = currentTime - shipmentTime
log(f'Current time: {currentTime}', 'info')
log(f'Shipment creation time: {shipmentTime}', 'info')
log(f'Time delta: {timeDelta}', 'info')
2024-07-12 19:55:03 +01:00
if timeDelta < timedelta(minutes=delta):
2024-07-12 00:02:19 +01:00
return True
else:
return False
def getAccessToken(settings=SETTINGS):
AccessToken = requests.post(
'https://api.amazon.com/auth/o2/token',
{
'grant_type': 'refresh_token',
'refresh_token': settings['REFRESH_TOKEN'],
'client_id': settings['CLIENT_ID'],
'client_secret': settings['CLIENT_SECRET'],
}
)
return AccessToken.json()['access_token']
def sendDiscordNotification(settings=SETTINGS, content=None):
notification = {"content": content}
requests.post(settings['DISCORD_WEBHOOK'], json=notification)
def getInboundShipments(settings=SETTINGS):
InboundShipments = requests.get(
settings['SPAPI_ENDPOINT'] + '/inbound/fba/2024-03-20/inboundPlans?pageSize=10&sortBy=CREATION_TIME&sortOrder=DESC&status=SHIPPED',
headers = {
'x-amz-access-token': getAccessToken(),
}
)
return InboundShipments.json()['inboundPlans']
def parseInboundShipments(settings=SETTINGS):
log('\U0001F504 Getting shipments...', 'info')
2024-07-12 00:02:19 +01:00
InboundShipments = getInboundShipments()
inboundPlanIDs = []
shipmentData = {}
for shipment in InboundShipments:
log('Got shipment creation date: {}'.format(shipment['createdAt']), 'info')
if isShipmentWithinSpecifiedDelta(shipment['createdAt']):
2024-07-12 00:02:19 +01:00
log('Adding inbound plan to list: {}'.format(shipment['inboundPlanId']), 'info')
inboundPlanIDs.append(shipment['inboundPlanId'])
if inboundPlanIDs:
log('\U0001F440 Checking shipments...', 'info')
log(f'Shipments to check: {len(inboundPlanIDs)}', 'info')
2024-07-12 00:02:19 +01:00
for ID in inboundPlanIDs:
if isIDInSentNotifications(ID):
log(f'Ignoring {ID}, notification has already been sent', 'info')
elif not isIDInSentNotifications(ID):
getShipment = requests.get(
settings['SPAPI_ENDPOINT'] + f'/inbound/fba/2024-03-20/inboundPlans/{ID}/items',
headers = {
'x-amz-access-token': getAccessToken(),
}
)
if getShipment.json()['items']:
itemDict = {}
totalItemCount = 0
for item in getShipment.json()['items']:
itemDict.update({item.get('msku'): item.get('quantity')})
totalItemCount += item['quantity']
itemDict.update({'Total item count': totalItemCount})
shipmentData.update({ID: itemDict})
log(f'\U0001F514 Sending Discord notification for {ID}...', 'info')
newline = '\n'
sendDiscordNotification(content=f':package: New shipment detected :package:\nShipment contents:\n{newline.join(f"- {MSKU}: {Count}" for MSKU, Count in shipmentData[ID].items())}')
updateSentNotifications(ID)
2024-07-12 00:02:19 +01:00
parseInboundShipments()