datetime module is being ignored in zendesk python script script - python-3.x

In my code I'm trying to request ticket data from zendesk via zenpy wrapper. I've got a script that pulls all the data I want, but for some reason it's ignoring the part regarding the date. Any idea what I'm doing wrong?
from datetime import datetime, timedelta
creds = {
'email' : 'login',
'password' : 'info',
'subdomain': 'domain'
}
yesterday = datetime.now() - timedelta(hours=1)
today = datetime.now()
from zenpy import Zenpy
zenpy = Zenpy(**creds)
for ticket in zenpy.search("test", type="ticket", created_greater_than=(yesterday)):
print(ticket.id)
id = ticket.id
subj = ticket.subject
created = ticket.created_at
for comment in zenpy.tickets.comments(ticket.id):
body = comment.body

While it may not fix your problem, using variable names of yesterday and today when your timedelta is 1 hour is extremely misleading. You probably want
yesterday = datetime.now() - timedelta(days=1)
today = datetime.now()
instead of
yesterday = datetime.now() - timedelta(hours=1)
today = datetime.now()
This also has a subtle fail run if run at the exact moment the clock rolls over to a new day which can be avoided by setting today first
today = datetime.now()
yesterday = today - timedelta(days=1)

today = datetime.now()
yesterday = today - timedelta(days=1)
for ticket in Z.search(type='ticket', created_between=[yesterday, today]):
...
This worked for me last time I used zenpy.
Make sure zenpy is updated as zendesk has been known to add/change endpoints. So if created_greater_than is an accepted argument in the zendesk api than it's possible that zenpy hasn't added it, or you're not on the latest version.

Related

Python3 Datetime (delta) to Seconds (Including Days)

Hopefully just a simple question. I want to convert a datetime object to seconds and include the days. I've just noticed that my code skipped the day. Please note times are just an example and not 100% accurate.
Content of oldtime.txt (2 days ago):
2021-09-16 19:34:33.569827
Code:
oldtimefile = open('oldtime.txt', 'r+')
oldtme = oldtimefile.read()
datetimeobj = datetime.strptime(oldtme, "%Y-%m-%d %H:%M:%S.%f")
finaltime = datetime.now() - datetimeobj
print(finaltime.seconds)
If I just print finaltime then I get 1 day, 22:13:30.231916.
Now if we take today's date and time - just for argument sake - (2021-09-18 17:34:33.569827) as now then I actually get 80010 seconds instead of roughly 172800 seconds. It's ignoring the day part.
How can I include the day and convert the entire object to seconds?
Thanks.
Instead of .seconds you can use .total_seconds():
from datetime import datetime
oldtme = "2021-09-16 19:34:33.569827"
datetimeobj = datetime.strptime(oldtme, "%Y-%m-%d %H:%M:%S.%f")
finaltime = datetime.now() - datetimeobj
print(finaltime.total_seconds())
Prints:
164254.768354

Python Discord Bot - VPS Reboot Behaviors?

With a friend of mine we created a simple discord bot in python, first let me explain how it works :
We created 366 different usernames, one for each day of the year. Each day at 0:01AM the bot should automatically post a message with :
Current date (day, month, year) and the username we associated with it
The bot should also rename its own username with the username of the day
Here is the code we made :
#!/usr/bin/python
# -*- coding: utf-8 -*-
import os
import discord
from discord.ext import commands
from dotenv import load_dotenv
from datetime import datetime
load_dotenv()
TOKEN = os.getenv('DISCORD_TOKEN')
GUILD = os.getenv('DISCORD_GUILD')
client = discord.Client()
channel = client.get_channel(CHANNELID)
bissextileSpec = datetime.today().strftime('%m-%d') # To handle bissextile years
nickFile = open("nicknames.txt", "r")
nickList = nickFile.readlines()
dayNumber = datetime.now().timetuple().tm_yday
# We also made special dates
if bissextileSpec == '06-01' :
nickOfTheDay = 'SpecialNick1'
elif bissextileSpec == '07-14' :
nickOfTheDay = 'SpecialNick2'
elif bissextileSpec == '30-12' :
nickOfTheDay = 'SpecialNick3'
elif bissextileSpec == '17-06' :
nickOfTheDay = 'SpecialNick4'
elif bissextileSpec == '05-04' :
nickOfTheDay = 'SpecialNick5'
else :
nickOfTheDay = nickList[dayNumber - 1]
await channel.send('MSG CONTENT', nickOfTheDay, 'MSG CONTENT')
await client.user.edit(username=nickOfTheDay)
We know our way a bit around python but we don't really know how discord bots works :
We are not quite sure how to instruct it to auto-post at midnight each day : We thought of a While loop with a sleep(50) on its end BUT :
How is it going to handle the hazardous VPS reboots ? If the vps reboot mid sleep is it going to reset it and shift the next post time further than 0:00 ?
On the other end, if we don't use a While loop, but if we use the CRON system in Linux to check and start the script everyday at midnight, does it mean the bot will be shown offline 23h59/24 on Discord and stay online just to post the message ? => We want to add a few more features later so we need the bot to run 24/24
Aswell, do not hesitate to point it if we did something wrong in the code ( ͡° ͜ʖ ͡°)
You can make a loop that iterates every 24h and change the nickname of the bot, you can get the seconds till midnight with some simple math and sleep for those seconds
import asyncio
from discord.ext import tasks
from datetime import datetime
#tasks.loop(hours=24)
async def change_nickname(guild):
"""Loops every 24 hours and changes the bots nick"""
nick = "" # Get the nick of the corresponding day
await guild.me.edit(nick=nick)
#change_nickname.before_loop
async def before_change_nickname(guild):
"""Delays the `change_nickname` loop to start at 00:00"""
hour, minute = 0, 0
now = datetime.now()
future = datetime(now.year, now.month, now.day + 1, now.month, now.day, hour, minute)
delta = (future - now).seconds
await asyncio.sleep(delta)
To start it you need to pass a discord.Guild instance (the main guild where the nickname should be changed)
change_nickname.start(guild) # You can start it in the `on_ready` event or some command or in the global scope, don't forget to pass the guild instance
No matter what hour the bot started the loop will change the bots nick at 00:00 everyday
Reference:
tasks.loop
Loop.before_loop
Loop.start
Łukasz's code has a tiny flaw, the future variable is wrongly initialized but everything else is working accordingly! This should do the trick:
import asyncio
from discord.ext import tasks
from datetime import datetime
#tasks.loop(hours=24)
async def change_nickname(guild):
nick = ""
await guild.me.edit(nick=nick)
#change_nickname.before_loop
async def before_change_nickname():
hour, minute = 0, 0
now = datetime.now()
future = datetime(now.year, now.month, now.day + 1, hour, minute)
delta = (future - now).seconds
await asyncio.sleep(delta)

How do I make a snipe command that shows the timestamp in the footer

I am able to get the time in UTC using the 'pytz' library and 'datetime' library, but I need it in local time of the user. Say you run the snipe command from the USA, you should get your local time, and if I run it from say Italy, I should get Italy's time. I hope I made it clear.
x = message = {}
y = author = {}
z = author_avatar = {}
time = {}
#client.event
async def on_message_delete(msg):
UTC = pytz.utc
datetime_utc = datetime.now(UTC)
if msg.author.bot == False:
x[msg.channel.id] = msg.content
y[msg.channel.id] = msg.author
time[msg.channel.id] = datetime_utc.strftime('%H:%M UTC')
if msg.author == client.user:
x[msg.channel.id] = msg.content
y[msg.channel.id] = msg.author
time[msg.channel.id] = datetime_utc.strftime('%H:%M UTC')
#client.command(name = 'snipe')
async def snipe(ctx):
try:
em = discord.Embed(description = f" {x[ctx.channel.id]}" ,color = random.choice(colors_for_embeds1), timestamp = datetime.now())
em.set_author(name = y[ctx.channel.id] ,icon_url = (y[ctx.channel.id]).author.url)
em.set_footer(text = f"at {time[ctx.channel.id]}")
await ctx.send(embed = em)
except:
await ctx.send("There is nothing to snipe!")
This is how the command works. The deleted message gets added to a dictionary with the channel ID as the key, the author id gets saved in a dictionary with the channel ID.
I hope this answers your question.
UTC time updates for your location, so for you, it would show your time (example: Today at 8:00 AM) then for someone else that is somewhere else in the world would show (Today at 9:00 AM).
I don't know if I answered this well or not, or if you understood it.
But hope answers your question! :D
your bot has no way of knowing the timezone of the people running the command. The timestamp on discord embeds always show the time in the local format for the people who see the embed, so different people will see different times depending on their timezones.
A solution would be to record the user timezone with a different command and save it to a database.
Then on your command parse the time into the footer for the timezone you want.

How to remove milliseconds in datetime python?

I want to print the amount of days, hours, minutes and seconds until christmas day but when it prints, it also gives me the millisecond. I tried doing print(remain_until_xmas.strip(.) but that didn't work. Here is the code
import datetime as dt
xmas = dt.datetime(2020, 12, 25)
now = dt.datetime.now()
until_xmas = xmas - now
print(until_xmas)
To get the time live, you can use this code:
import time
time = str(time.strftime("%M")) + ":" + str(time.strftime("%S"))
print(time)
This will give you the current time in Minutes and Seconds, and if you put it in a loop, it will keep updating itself.
If you want the day and month, you can use
print(time.strftime("%A, %B %e")) -
With this code, you can then subtract the Xmas date from the current date, and retrieve what you want.
This would be your final code:
import time
month = time.strftime("%m")
day = time.strftime("%d")
hour = time.strftime("%H")
minute = time.strftime("%M")
second = time.strftime("%S")
chrmonth = 12
chrday = 23
chrhour = 12
chrminute = 60
chrsecond = 60
print("The time until christmas is, ", int(chrmonth) - int(month), "months", int(chrday) - int(day), "days", int(chrhour) - int(hour), "hours", int(chrminute) - int(minute), "minutes", int(chrsecond) - int(second), "seconds")
Hopefully this helps!
you can use .strftime()
print(until_xmas.strftime("%m/%d/%Y, %H:%M:%S"))
see more here about strftime.

Date Time difference between hour of the day and time now

Time = datetime.datetime.now().time()
I wanted to find the difference in seconds between the Time above^ and the hour of the day:
for example if the Time = 15:07:25.097519, so the hour of the day is 15:00:00, i want to store 445.097519‬ seconds to a variable.
How can I do that?
I am an amateur at this please help!!
import datetime
now = datetime.datetime.now()
hour = now.replace(minute=0, second=0, microsecond=0)
seconds = (now - hour).seconds + (now - hour).microseconds / 1000000
Here is one way to do it. Extract the hour from current time, and initialize a new datetime.time object with hour as input. Then you convert both of the timestamps to datetime and then do the subtraction. Code below does that
Time = datetime.datetime.now().time()
hour = str(Time).split(":")[0]
currentHourTime = datetime.datetime(2019,10,31,int(hour),0,0,0).time()
dateTimeCurr = datetime.datetime.combine(datetime.date.today(), Time)
dateTimeCurrHour = datetime.datetime.combine(datetime.date.today(), currentHourTime)
dateTimeDifference = dateTimeCurr - dateTimeCurrHour
dateTimeDifferenceInSeconds = dateTimeDifference.total_seconds()
print(dateTimeDifferenceInSeconds)

Resources