Search code examples
pythonconcatenationbyteimaplib

"TypeError: can't concat int to bytes" imaplib error


I am creating something so when it receives an email depending on what is the subject line it does a function now the code I have works in python 2.7 and runs in 3.7 but gives one error "TypeError: can't concat int to bytes" I've haven't tried much because I couldn't find anything online and im new to python please let me know

import imaplib
import email
from time import sleep
from ssh import myRoomOff, myRoomOn

count = 0 

mail = imaplib.IMAP4_SSL('imap.gmail.com')
mail.login('EMAIL', 'PASSWORD')
mail.list()
mail.select('inbox')

#need to add some stuff in here
while True:
    mail.select('inbox')
    typ, data = mail.search(None, 'UNSEEN')
    ids = data[0]
    id_list = ids.split()


    #get the most recent email id
    latest_email_id = int( id_list[-1] )

    #iterate through 15 messages in decending order starting with latest_email_id
    #the '-1' dictates reverse looping order
    for i in range( latest_email_id, latest_email_id-1, -1 ):
        typ, data = mail.fetch(i, '(RFC822)' )

    for response_part in data:
        if isinstance(response_part, tuple):
            msg = email.message_from_bytes(response_part[1])
            varSubject = msg['subject']

            count += 1
            print(str(count) + ", " + varSubject)
            if varSubject == "+myRoom":
                myRoomOn()
            elif varSubject == "-myRoom":
                myRoomOff()
            else:
                print("I do not understand this email!")
                pass
    sleep(2)

error

Traceback (most recent call last):
  File "/Users/danielcaminero/Desktop/alexaCommandThing/checkForEmail.py", line 28, in <module>
    typ, data = mail.fetch(i, '(RFC822)' )
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/imaplib.py", line 548, in fetch
    typ, dat = self._simple_command(name, message_set, message_parts)
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/imaplib.py", line 1230, in _simple_command
    return self._command_complete(name, self._command(name, *args))
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/imaplib.py", line 988, in _command
    data = data + b' ' + arg
TypeError: can't concat int to bytes

Solution

  • The first argument of mail.fetch() must be a string, but range() yields an int. So an string-cast would fix it:

    typ, data = mail.fetch(str(i), '(RFC822)')
    

    Not a necessary change to fix it, but a more pythonic way to reverse a list is to use list slicing [::-1]. You can save some lines and the range() call.
    Furthermore your indent is wrong, you handle only the data from the last iteration.

    ...
    id_list = ids.split()
    
    for i in id_list[::-1]:
        typ, data = mail.fetch(i, '(RFC822)')
        for response_part in data:
            if isinstance(response_part, tuple):
                msg = email.message_from_bytes(response_part[1])
                varSubject = msg['subject']
    
                count += 1
                print(str(count) + ", " + varSubject)
                if varSubject == "+myRoom":
                    myRoomOn()
                elif varSubject == "-myRoom":
                    myRoomOff()
                else:
                    print("I do not understand this email!")
                    pass
    

    (Here you don't need the string cast, because id_list is a list of byte-string. And a byte-string is a valid value for fetch() too.)