I have a problem sending proactive messages using the Bot Framework with Python. First what I need is to get the message body from Outlook, and then the bot must send that as a message to all the chats where it was added.
To do that, first I created a new file and called it Email.py.
To read every incoming message body I simply used while true:
and time.sleep()
Here is my code example:
import imaplib, email, getpass
from email import policy
import json
import time
imap_host = 'outlook.office365.com'
imap_user = 'xx@xx.com'
# init imap connection
mail = imaplib.IMAP4_SSL(imap_host, 993)
rc, resp = mail.login(imap_user, 'xxxxxx')
while True:
# select only unread messages from inbox
mail.select('Inbox')
status, data = mail.search(None, '(UNSEEN)')
if not data[0].split():
time.sleep(120)
# Bot message variable
Message_for_bot = ''
# for each e-mail messages
for num in data[0].split():
# get a single message and parse it by policy.SMTP (RFC compliant)
status, data = mail.fetch(num, '(RFC822)')
email_msg = data[0][1]
email_msg = email.message_from_bytes(email_msg, policy=policy.SMTP)
# print only message parts that contain text data
for part in email_msg.walk():
if part.get_content_type() == "text/plain":
for line in part.get_content().splitlines():
Message_for_bot += '\n' + line
print(Message_for_bot)
After I successfully created a program to read and print all incoming messages, I tried to build my bot. I found a proactive message bot on the Internet and used it as an example.
First I thought to just run this file with os
in the background, but then my bot wasn't running. So then I tried adding an async
function in the bot file but it didn't work. My bot just ignores that function. (Then I found the async functions in activity_handler.py, but I didn't find any that could help me.)
Then I tried adding an on_message_activity
function and thought maybe it will start working if I call the bot like "@bot hi" for example in Teams. For that idea I must always run the while cycle and never stop the bot, but then I just get a message, and if there's a new incoming message then the bot doesn't write it anymore, and it's not a solution because if the bot is used for multiple chats then it simply doesn't work this way.
Then I try include my code on on_members_added_activity
it seems working on azure test in web chat perfectly, but in teams after 1-2 messages stopping to work.
my code
async def on_members_added_activity(
self, members_added: [ChannelAccount], turn_context: TurnContext
):
imap_host = 'outlook.office365.com'
imap_user = 'xxxxxx@xxxxxx.com'
# init imap connection
mail = imaplib.IMAP4_SSL(imap_host, 993)
rc, resp = mail.login(imap_user, 'xxxxxx')
while True:
# select only unread messages from inbox
mail.select('Inbox')
status, data = mail.search(None, '(UNSEEN)')
if not data[0].split():
time.sleep(5)
# Bot message variable
Message_for_bot = ''
# for each e-mail messages
for num in data[0].split():
# get a single message and parse it by policy.SMTP (RFC compliant)
status, data = mail.fetch(num, '(RFC822)')
email_msg = data[0][1]
email_msg = email.message_from_bytes(email_msg, policy=policy.SMTP)
# print only message parts that contain text data
for part in email_msg.walk():
if part.get_content_type() == "text/plain":
for line in part.get_content().splitlines():
Message_for_bot += '\n' + line
await turn_context.send_activity(f"{Message_for_bot}")
for member in members_added:
if member.id != turn_context.activity.recipient.id:
await turn_context.send_activity(
"bot starting work..."
)
So maybe it's possible to send a message to wherever the bot is added (it needs to get this information somehow, maybe it's kept in the bot memory) whenever Message_for_bot
is not empty.
All help will be appreciated.
As we have discussed some logic has to change
-Vinoth