Skip to content

Instantly share code, notes, and snippets.

@stnor
Last active March 24, 2023 16:13
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stnor/f34a8c7a704340352ba0c5fa5b873855 to your computer and use it in GitHub Desktop.
Save stnor/f34a8c7a704340352ba0c5fa5b873855 to your computer and use it in GitHub Desktop.
Exports helpscout conversations to an IMAP server
# IMAP server need to have a folder Helpscout, see line 46.
# Replace IMAP-server, user, pass
# Create a Helpscout app and add your HS app key and secret below
from helpscout import HelpScout
from datetime import timedelta, date, datetime, timezone
import dateutil.parser
import imaplib
import email.message
import email.header
import email.utils
import logging
def get_mbox():
for mailbox in hs.hit('mailboxes', 'get'):
return mailbox
def list_conversations(status, query):
params = {'status': status, 'query': query}
return hs.conversations.get(params=params)
def daterange(start_date, end_date):
for n in range(int((end_date - start_date).days)):
yield start_date + timedelta(n)
def format_query(date):
return '(createdAt:[' + date.strftime('%Y-%m-%d') + 'T00:00:00Z TO ' + date.strftime('%Y-%m-%d') + 'T23:59:59Z])'
def create_email_message(fromAddr, fromName, toAddr, toName, subject, body):
new_message = email.message.Message()
new_message.set_unixfrom('Helpscout')
new_message['Subject'] = subject
new_message['From'] = fromAddr
new_message['To'] = toAddr
new_message.add_header('Content-Type', 'text/html;charset="utf-8"')
new_message.set_payload(body)
new_message.set_charset('utf-8')
return new_message
def open_connection():
# Connect to the server
connection = imaplib.IMAP4_SSL("YOUR_IMAP_SERVER")
connection.login("YOUR_IMAP_USERNAME", "YOUR_IMAP_PASSWOR")
typ, data = connection.select('Helpscout')
print(typ, data)
num_msgs = int(data[0])
print('There are %d messages in Helpscout' % num_msgs)
return connection
if __name__ == '__main__':
import http.client as http_client
http_client.HTTPConnection.debuglevel = 1
# You must initialize logging, otherwise you'll not see debug output.
logging.basicConfig()
logging.getLogger().setLevel(logging.DEBUG)
requests_log = logging.getLogger("requests.packages.urllib3")
requests_log.setLevel(logging.DEBUG)
requests_log.propagate = True
### docs https://pypi.org/project/python-helpscout-v2/
app_id = "YOUR_HELPSCOUT_APP_ID"
app_secret = "YOUR_HELPSCOUT_APP_SECRET"
hs = HelpScout(app_id=app_id, app_secret=app_secret)
print("Getting HS MBOX")
mailbox = get_mbox()
### date range to export
start_date = date(2017, 1, 1)
end_date = date(2021, 12, 31)
print( '(createdAt:[' + start_date.strftime('%Y-%m-%d') + 'T00:00:00Z TO ' + end_date.strftime('%Y-%m-%d') + 'T23:59:59Z])')
conversations = list_conversations('closed', '(createdAt:[' + start_date.strftime('%Y-%m-%d') + 'T00:00:00Z TO ' + end_date.strftime('%Y-%m-%d') + 'T23:59:59Z])')
for conv in conversations:
print("Opening IMAP conn")
c = open_connection()
threads_href = conv._links["threads"]["href"]
conv_threads = hs.hit(threads_href, 'get')
print(threads_href)
for conv_thread in conv_threads:
for t in conv_thread["threads"]:
threadType = t["type"]
if threadType == "message" or threadType == "customer":
custEmail = t["customer"]["email"]
custName = t["customer"]["first"] + " " + t["customer"]["last"]
fromAddr = custEmail if threadType == "customer" else "info@nomp.se"
fromName = custName if threadType == "customer" else "Mattesajten Nomp"
toAddr = custEmail if threadType == "message" else "info@nomp.se"
toName = custName if threadType == "message" else "Mattesajten Nomp"
created = dateutil.parser.parse(t["createdAt"])
subject = ''
if hasattr(conv, 'subject'):
subject = conv.subject
body = t["body"]
print("saving to imap", created, t["createdAt"], fromAddr, toAddr)
message = str(create_email_message(fromAddr, fromName, toAddr, toName,
subject, body))
c.append('Helpscout', '', created, message.encode())
c.close()
c.logout()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment