gmail api: get latest 2 emails from thread - python

The code below retrieves the latest email in the thread. How do I retrieve the latest 2 emails in the thread? Thanks in advance.
messages = service.users().threads().list(userId='me').execute().get('threads', [])
for message in messages:
if search in message['snippet']:
# add/modify the following lines:
thread = service.users().threads().get(userId='me', id=message['id'], fields='messages(id,internalDate)').execute() #.get( [])
last = len(thread['messages']) - 1
message_id = thread['messages'][last]['id']
# non-modified code:
full_message = service.users().messages().get(userId='me', id=message_id, format="raw").execute()
msg_str = base64.urlsafe_b64decode(full_message['raw'].encode('ASCII'))
mime_msg = email.message_from_bytes(msg_str)
y = re.findall(r'Delivered-To: (\S+)', str(mime_msg))
print(y[0])

The line last = len(thread['messages']) - 1 specifies that you want to retrieve the last message from a thread
Consequently, to retrieve the prelast message, you need to specify prelast = len(thread['messages']) - 2
And respectively prelast_message_id = thread['messages'][prelast]['id']
Now, you can push both last and prelast message Ids into an array and perform your # non-modified code in a for loop on both message ids.

Related

How to get actual slack username instead of user id

I have pulled data from a private slack channel, using conversation history, and it pulls the userid instead of username, how can I change the code to pull the user name so I can identify who each user is? Code below
CHANNEL = ""
MESSAGES_PER_PAGE = 200
MAX_MESSAGES = 1000
SLACK_TOKEN = ""
client = slack_sdk.WebClient(token=SLACK_TOKEN)
# get first page
page = 1
print("Retrieving page {}".format(page))
response = client.conversations_history(
channel=CHANNEL,
limit=MESSAGES_PER_PAGE,
)
assert response["ok"]
messages_all = response['messages']
# get additional pages if below max message and if they are any
while len(messages_all) + MESSAGES_PER_PAGE <= MAX_MESSAGES and response['has_more']:
page += 1
print("Retrieving page {}".format(page))
sleep(1) # need to wait 1 sec before next call due to rate limits
response = client.conversations_history(
channel=CHANNEL,
limit=MESSAGES_PER_PAGE,
cursor=response['response_metadata']['next_cursor']
)
assert response["ok"]
messages = response['messages']
messages_all = messages_all + messages
It isn't possible to change what is returned from the conversations.history method. If you'd like to convert user IDs to usernames, you'll need to either:
Call the users.info method and retrieve the username from the response.
or
Call the users.list method and iterate through the list and create a local copy (or store in a database) and then have your code look it up.

How can I input() using TeleBot?

I was wondering if i can make input() using TeleBot dependency.
e.g. console way:
POL = float(input("Enter your POL: ))
Is there a way to do using Telebot, like:
bot.send_message(message.chat.id, "Enter your POL")
## Get message.text into POL variable.
From what I understand, there isn't a direct way of doing this, but you can look at the message that the user has replied to from
replied_message = message.reply_to_message.message_id
If it matches the id of the message that you sent then that would be the reply to your message. You can get the id of your sent message from
sent_message = bot.send_message(message.chat.id, "Enter your POL")
sent_message_id = sent_message.message_id
import telebot
TELEGRAM_TOKEN = '<TOKEN>'
bot = telebot.TeleBot(TELEGRAM_TOKEN)
user_register_dict = {}
#bot.message_handler(commands=['start'])
def start(message):
bot.reply_to(message , 'now send your name')
user_register_dict[message.chat.id] = {}
bot.register_next_step_handler(message , start_step2)
def start_step2(message):
user_register_dict[message.chat.id]['name'] = message.text
bot.reply_to(message , 'now send your age')
bot.register_next_step_handler(message , start_step3)
def start_step3(message):
user_register_dict[message.chat.id]['age'] = message.text
bot.reply_to(message , 'your name is {} and you are {} years old!'
.format(user_register_dict[message.chat.id]['name'] ,
[message.chat.id]['age'] ))
start(message = message)
Create a dict for handling the data, which is important because if you use lists (eg.) maybe 2 people starts to register in same time and data gonna crash!
Difference between create bot.register_next_step_handler (line 13 for example) with connect directly for example start(message = message) in end line is in register_next_step_handler bot waits for new message and when received puts it in message and start defection but in direct start defection bot doesn't wait for user message, and start defection with current message start(message = message)

Telethon Telegram message filter

I would like to get all the messages from a chat that have been sent today.
import sys,datetime
from telethon import TelegramClient
api_id = 1234567
api_hash = "0986asdgshjfag"
client = TelegramClient('session_name', api_id, api_hash)
client.start()
dialogs = client.get_dialogs()
chat = client.get_input_entity('username')
filter = InputMessagesFilterEmpty()
result = client(SearchRequest(
peer=chat, # On which chat/conversation
q='', # What to search for
filter=filter, # Filter to use (maybe filter for media)
min_date=datetime.date.today(), # Minimum date
max_date=None, # Maximum date
offset_id=0, # ID of the message to use as offset
add_offset=0, # Additional offset
limit=5, # How many results
max_id=0, # Maximum message ID
min_id=0, # Minimum message ID
from_id=None, # Who must have sent the message (peer)
hash=0 # Special number to return nothing on no-change
))
for message in client.iter_messages(chat,filter=result):
print(message.message)
The filter doesn't work at all, I can see more than 5 messages (the whole chat) and it doesn't care about the time.
Why?
You can use 'message.date'.
If you want to get the message from today you need to check the sent day. and this would be like :
if datetime.datetime.now().strftime('%Y-%m-%d') == message.date.strftime('%Y-%m-%d')

update categories in emails using python

I am trying to update categories of emails available in one of the data frame using below code.
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
inbox = outlook.GetDefaultFolder(6)
messages = inbox.Items
i = 0
for message in messages:
try:
message.Categories = output.iat[i,2]
except:
message.Categories = 'No Category'
i = i + 1
Below script used to move updated emails from inbox to another folder and then remove to inbox
donebox = outlook.GetDefaultFolder(6).Folders[20]
def delay(time):
for j in range(time):
j=j+1
i = 0
while (messages.Count > 0):
print(i,messages.Count)
message = messages.GetLast()
message.Move(donebox)
delay(1000000)
i = i + 1
messages = donebox.Items
i = 0
while (messages.Count > 0):
print(i,messages.Count)
message = messages.GetLast()
message.Move(inbox)
delay(1000000)
i = i + 1
In outlook updated Categories from output dataframe for emails are able visible only once email selected. Is there any option which can refresh outlook and categories will be updated automatically. Please advice.
For everyone who cant save changing of non-selected mail Categories property by Python:
mail.Categories='Red category'
mail.Save()
It worked for me!
import win32com.client
from win32com.client import Dispatch
outlook=win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
folder = outlook.Folders.Item("Inbox")
messages = folder.Items
for i in range(messages.Count):
messages[i].GetInspector()
messages[i].Categories = 'Purple Category'
messages[i].Save()
If only one category needs to be assigned to each email, dmitrii.kotenko has provided the solution.
If you need to append more than one category, pass the categories as a string separated by commas
mail.Categories = "category1, category2, category3"
mail.Save()

Writing email reply bot using poplib and random emails keep showing up in me re.findall(...) call

I'm using poplib to connect to a gmail account and I want it to reply to emails that are sent to it.
However sometimes my regular expression's statement grabs random emails that aren't the one I wanted to reply to.
For example:
5952f967.8543630a.1c70d.283f#mx.google.com
Code below:
def checkEmail():
mail = poplib.POP3_SSL('pop.gmail.com')
mail.user(USER)
mail.pass_(PASS)
numEmails = len(mail.list()[1])
count = 0
if(numEmails>=1):
for i in range(numEmails):
for msg in mail.retr(i+1)[1]:
sender = re.findall(r'[\w\.-]+#[\w\.-]+',msg)
for s in sender:
if s and count == 0:
count += 1
replySender(s)
print s
message = email.message_from_string(msg)
count = 0
mail.quit()

Categories