You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

132 lines
4.5 KiB

import logging
import argparse
from sleekxmpp import ClientXMPP
from sleekxmpp.exceptions import IqError, IqTimeout
import os, subprocess
import urllib.request
import datetime
import ssl
from PIL import Image
from pprint import pprint
# python3 -j -p ******* -m -o ./stream/
# rewrite script to work with slixmpp >>>
parser = argparse.ArgumentParser()
parser.add_argument("-j", "--jid", help="jabber identifier", type=str, required=True)
parser.add_argument("-p", "--password", help="password", type=str, required=True)
parser.add_argument("-m", "--muc", help="destination muc", type=str, required=True)
parser.add_argument("-n", "--nick", help="nickname of the bot", default="streambot", type=str)
parser.add_argument("-o", "--output", help="output folder", default="./stream/", type=str)
args = parser.parse_args()
# This was a useful tutorial:
class ArchivistBot(ClientXMPP):
def __init__(self, jid, password, room, nick, output):
ClientXMPP.__init__(self, jid, password)
self.datadir = output = room
self.nick = nick
self.add_event_handler("session_start", self.session_start)
self.add_event_handler("message", self.archive_msg) # by using 'message' instead of 'groupchat_message' every message received can be archived (also personal msgs)
# self.add_event_handler("groupchat_message", self.archive_msg2)
self.register_plugin('xep_0096') # Transfer files..
self.register_plugin('xep_0066') # Transfer files..
def session_start(self, event):
roster = self.get_roster()
print('\nRoster:', roster)
self.plugin['xep_0045'].joinMUC(, self.nick) # MUC plugin
with open('avatar.png', 'rb') as avatar_file:
avatar =
avatar_id = self['xep_0084'].generate_id(avatar)
info = {
'id': avatar_id,
'type': 'image/png',
'bytes': len(avatar)
# XEP-0153: vCard-Based Avatars
# Not working ATM
self['xep_0153'].set_avatar(avatar=avatar, mtype='image/png')
def archive_msg(self, msg):
print('\nMessage TYPE:{}'.format(msg['type']))
print('\nMessage OOB:{}'.format(msg['oob']))
print('\nMessage OOB URL:{}'.format(msg['oob']['url']))
print('\nMessage MUCK NICK:{}'.format(msg['mucnick']))
# Always check that a message is not the bot itself, otherwise you will create an infinite loop responding to your own messages.
if msg['mucnick'] != self.nick:
if msg['type'] in ('groupchat', 'normal'):
# only works if messages are not encrypted
if len(msg['oob']['url']) > 0:
# logging.getLogger().debug("received OOB from %s with %s" % (self.nick, msg['oob']['url']))
filename = os.path.basename(msg['oob']['url'])
targetDir = self.datadir
if not os.path.exists(targetDir):
os.mkdir(targetDir, '0755')
targetFile = os.path.join(targetDir, filename)
print('\n targetFile', targetFile)
#needed to disable certificate validation:
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
# save image to file
# urllib.request.urlretrieve(msg['oob']['url'], targetFile, context=ctx)
# with urllib.request.urlopen(msg['oob']['url'], context=ctx) as u, \
# open(targetFile, 'w+') as f:
# f.write(
# f.close()
# Download the file from `url` and save it locally under `file_name`:
with urllib.request.urlopen(msg['oob']['url']) as response:
data = # a `bytes` object
f = open(targetFile, 'wb')
logging.getLogger().debug("saved to %s" % targetFile)
#["make","publish"], cwd="/srv/gitea/clones/")
msg.reply("Thanks for sending! I will store that for you." % msg).send() # works! also for omemo messages, but it cannot decrypt them.
if __name__ == '__main__':
# Ideally use optparse or argparse to get JID,
# password, and log level.
logging.basicConfig(level=logging.DEBUG, format='%(levelname)-8s %(message)s')
client = ArchivistBot(args.jid, args.password, args.muc, args.nick, args.output)
if client.connect():
logging.getLogger().error("Can't connect.")