LINUX.ORG.RU
решено ФорумAdmin

2020 год, как отправить XMPP сообщение?

 ,


3

3

Как отправить сообщение из python или терминала?

Пробовал

  1. xmpppy - перекати поле. Толи с новым Python разломан, пишет про непонятную ошибку сплитинга строк или типа того

  2. slixmpp - тяжело ставится с кучей зависимостей. До документации руки не доходят явно. Всё обмазано как попало асинхронными вызовами. В итоге вся эта ерунда виснет даже на тестовых примерах (наверно какая-то гонка ресурсов).

  3. sendxmpp - Jabber - sendxmpp не отправляются сообщения

Короче третий день уже ковыряюсь, чтобы такую элементарную задачу сделать… И зачем я с уютненьких Telegram ботов вылез в эти технологии для старых пердунов…

Как?

UPDATE: Короче использовал aioxmpp. При завершении выбивает исключения OpenSSL, ну и ладно - работает.

★★★★★

Последнее исправление: fornlr (всего исправлений: 4)

Я не выдержал и для этого написал свою программу, которую уже можно дёргать «из python или терминала»

O02eg ★★★★★
()

Я на Tcl писал бота для XMPP. Не помню какая там либа была, но сработала без всяких проблем. Может дропнуть питон и перейти на нормальный язык? Тем более у питона фрагментация и Python2 и Python3 — два почти разных языка.

Xenius ★★★★★
()
Ответ на: комментарий от Xenius

Я на Tcl писал бота для XMPP. Не помню какая там либа была

тут ключевое слово не в языке, а прошедшим времени – сейчас всё тухнет. Ну и задачи писать ботов для XMMP у меня нет, с приёмами команд и прочего.

Просто образно запустить

send -s 10.0.0.1:69 -u 'pony@host' -p 'password' -t 'unicorn@host' -m 'message text'

и не сдалось обмазываться кучей всего

fornlr ★★★★★
() автор топика
Последнее исправление: fornlr (всего исправлений: 1)

sendxmpp - Jabber - sendxmpp не отправляются сообщения

31.05.15 13:41:17

Сейчас проверил sendxmpp из Debian testing. Работает, даже с TLS:

echo "Hello world" | sendxmpp -t -j send_server -u send_username -p password receive_username@receive_server

gag ★★★★★
()
Ответ на: комментарий от fornlr

Ну вместо бота можно было написать это, с той же либой. И даже если оно протухло ты можешь взять старую версию.

Xenius ★★★★★
()
Ответ на: комментарий от swarnk

В теме и написал первым

Traceback (most recent call last):
  File "send_test2.py", line 49, in <module>
    connection.auth(user=jid.getNode(), password=args.password, resource=jid.getResource())
  File "/home/myuser/.local/lib/python3.8/site-packages/xmpp/client.py", line 228, in auth
    while self.SASL.startsasl=='in-process' and self.Process(1): pass
  File "/home/myuser/.local/lib/python3.8/site-packages/xmpp/dispatcher.py", line 126, in Process
    raise _pendingException[0](_pendingException[1]).with_traceback(_pendingException[2])
  File "/home/myuser/.local/lib/python3.8/site-packages/xmpp/dispatcher.py", line 304, in dispatch
    handler['func'](session,stanza)
  File "/home/myuser/.local/lib/python3.8/site-packages/xmpp/auth.py", line 179, in SASLHandler
    self.DEBUG('Got challenge:'+data,'ok')
TypeError: can only concatenate str (not "bytes") to str
fornlr ★★★★★
() автор топика
Ответ на: комментарий от a_Sadducee

Не ты его разрабатывал, не тебе решать, «почивший» он или нет.

Это, кстати, одна из серьёзных проблем опенсорса — вместо того, чтобы довести до ума на 95% готовую технологию, зачастую норовят её бросить и начинать пилить другую, причём каждая следующая технология страшнее предыдущей.

hobbit ★★★★★
()
Последнее исправление: hobbit (всего исправлений: 1)
Ответ на: комментарий от AlexKiriukha

aioxmpp

Ну почти

Fatal read error on STARTTLS transport
protocol: <aioxmpp.protocol.XMLStream object at 0x7f47b84f80d0>
transport: <aioopenssl.STARTTLSTransport object at 0x7f47b850b600>
Traceback (most recent call last):
  File "/home/myuser/.local/lib/python3.8/site-packages/aioopenssl/__init__.py", line 459, in _read_ready
    data = self._sock.recv(self.MAX_SIZE)
  File "/usr/lib/python3/dist-packages/OpenSSL/SSL.py", line 1791, in recv
    self._raise_ssl_error(self._ssl, result)
  File "/usr/lib/python3/dist-packages/OpenSSL/SSL.py", line 1626, in _raise_ssl_error
    raise ZeroReturnError()
OpenSSL.SSL.ZeroReturnError

Сообщение посылается. Хоть и выбрасывается исключение - так-то забить можно. Учитывая что становится просто, вроде как самое лучшее решение из перечисленных.

Что-то видать с завершением потоков с asyncio

fornlr ★★★★★
() автор топика
Последнее исправление: fornlr (всего исправлений: 4)
Ответ на: комментарий от alfix

sasl=0

Implements old Non-SASL (XEP-0078) authentication used in jabberd1.4 and transport authentication.

Да не - ерунда какая-то.

DEBUG: dispatcher   warn  Registering protocol "error" as <class 'xmpp.protocol.Protocol'>(http://etherx.jabber.org/streams)

DEBUG: socket       warn  SSL_WANT_READ while receiving data, asking for a retry


DEBUG: socket       warn  SSL_WANT_READ while receiving data, asking for a retry
DEBUG: gen_auth     error No result node arrived! Aborting...
fornlr ★★★★★
() автор топика
Последнее исправление: fornlr (всего исправлений: 2)

предлагаю написать соответствующий XML ручками самостоятельно и отправить через сокеты :)

Harald ★★★★★
()
Ответ на: комментарий от fornlr

TypeError: can only concatenate str (not «bytes») to str

Причём в «self.DEBUG»…

Добавили на бегу, а в третьем питоне строки с байтами больше не складываются. Прилепи к data перевод в строку .decode(«utf-8») и всего делов. Или дебаг отключи, чтоб чуть дальше не подорваться на чём-то похожем.

frob ★★★★★
()
Ответ на: комментарий от frob

Прилепи к data перевод в строку .decode(«utf-8») и всего делов

Делать мне нечего - патчи к чужой библиотеке писать

fornlr ★★★★★
() автор топика
Последнее исправление: fornlr (всего исправлений: 1)
Ответ на: комментарий от frob

С этим это так просто не получится

connection = xmpp.Client(server=server, port=port, debug=False)
connection = xmpp.Client(server=server, port=port, debug=[])
connection = xmpp.Client(server=server, port=port, debug=None)

Ну и шиш. Всё одно и тоже. И главное пишешь таким тоном, что вот в одном месте такой косяк, а в остальном значит гарантия замечательности :D

fornlr ★★★★★
() автор топика
Последнее исправление: fornlr (всего исправлений: 5)
Ответ на: комментарий от fornlr

а в остальном значит

чтоб чуть дальше не подорваться

А вот если бы ты ещё пару раз своё сообщение исправил, то не просто вычитал бы каким тоном я пишу, но и в чём-нибудь вполне уголовном обвинил^W признал виновным.

Писано и какано под второй питон. В третьем запустилось и обломалось на какой-то ерунде. Тебе шашечки или поговниться на лоре?

frob ★★★★★
()
Ответ на: комментарий от frob

Ты предлагаешь на Python 2? Это не вариант - EOL

Переписывать на Python 3 эту библиотеку тоже желания нет.

fornlr ★★★★★
() автор топика
Последнее исправление: fornlr (всего исправлений: 1)
Ответ на: комментарий от alfix

Принудительное непонимание байтов как строк и обратно – это для нашего же блага.

Но то что раньше делалось лёгким взмахом ресниц теперь превратилось в советскую жужжалку для залезания в зад.

Строку прежде чем пихнуть в функцию надо конвертировать в байты, на выходе байты, которые надо сконвертировать в строку, чтоб с чем-то слепить, результат опять перегнать в байты, чтоб пихнуть в следующую функцию, которая нагло вернёт строку и обломится на конвертации, потому что это не байты. Ой, мамочки…

frob ★★★★★
()
Ответ на: комментарий от anonymous

могу переписать на Go или D с интерфейсом под пистон

anonymous
()
Ответ на: комментарий от fornlr

Предлагаешь мне поискать за тебя как отключить дебаг? Это не вариант – может он там вообще неотключаемый =)

Оно запустилось в третьепитоне и обломинго уже где-то довольно глубоко и на какой-то незначительной фигне. Ты уже на бубнёж про это на лоре потратил больше времени, чем потребовалось на добавление decode и в случае, если заработало – отправки патча авторам. Но бубнёж безусловно интереснее.

frob ★★★★★
()
Ответ на: комментарий от frob

может он там вообще неотключаемый

я про это и написал

чем потребовалось на добавление

не вариант. вероятность что заработает одной правкой стремится к нулю, и проще aioxmpp

2020 год, как отправить XMPP сообщение? (комментарий)

fornlr ★★★★★
() автор топика
Последнее исправление: fornlr (всего исправлений: 2)
  1. slixmpp - тяжело ставится с кучей зависимостей.

slixmpp - это, кстати, активный python 3 проект, в котором даже используется cpython для ускорения парсинга, если не ошибаюсь. И эта библиотека используется в консольном клиенте poezio.

Прямых зависимостей всего ничего:

  • aiodns
  • aiohttp
  • pyasn1
  • pyasn1-modules

На вид ничего лишнего.

gag ★★★★★
()
Ответ на: комментарий от Harald

предлагаю написать соответствующий XML ручками самостоятельно и отправить через сокеты :)

А с matrix подобное решается в два счёта: Matrix/Riot с шифрованием личных сообщений по умолчанию (комментарий) Не нужна никакая специальная matrix библиотека. shell да curl - и всё.

gag ★★★★★
()
Ответ на: комментарий от alfix

Но не факт, что поможет – сложить строку с байтами придётся всё равно, чтоб отдать это в debug.NoDebug…

Судя по гитхабу, добавили это добро месяц назад под эгидой совместимости с python 3.9. Но или не тестировали или тестировали там где SASL-а нет.

Есть мнение, что строковый re от байтовой data тоже порвётся.

Так что decode надо прилепить строкой выше к data=base64.b64decode(incoming_data)

А вот кому пул-реквест за майку от DO? ;)

frob ★★★★★
()
Ответ на: комментарий от frob

Ага.

Если скормить re.findall bytes:

  File "/usr/lib/python3.8/re.py", line 241, in findall
    return _compile(pattern, flags).findall(string)
TypeError: cannot use a string pattern on a bytes-like object

если str:

  File "/usr/tmp/xmpp/auth.py", line 29, in H
    def H(some): return md5(some).digest()
TypeError: Unicode-objects must be encoded before hashing
alfix
()
Последнее исправление: alfix (всего исправлений: 2)
Ответ на: комментарий от alfix

Всё как я и сказал парой комментов выше – надо гонять туда-сюда строки в байты и обратно.

«С» возвращает строку, «H» хочет байты. УРА! Больше encode/decode-ов.

frob ★★★★★
()

Sendxmpp нормально можно заставить работать. Во всяком случае я себе отправлял уведомления им, пока на мыло не переключился

gutaper ★★★★★
()
Ответ на: комментарий от hobbit

Ну дык проблема в отсутствии поддержки и продвижения нормального.

a_Sadducee
()
Ответ на: комментарий от a_Sadducee

А может закопать почивший протокол?

В принципе есть такое.

Но вот когда нужна связь в локальной сети фирмы, чтобы оно могло работать без интернетов, как-то не особо вариантов 🤨

fornlr ★★★★★
() автор топика
Ответ на: комментарий от anonymous

ну и кстати.. есть ещё целая куча вариантов: IRC, mailman, nntp..

anonymous
()
Ответ на: комментарий от pxrdsg

Да. У меня тоже отправилось и повисло намертво — скрипт не завершил работу.

Понятно, что можно прилепить костыль.

Тот же

man timeout

Собственно об этом и написал.

fornlr ★★★★★
() автор топика
Последнее исправление: fornlr (всего исправлений: 2)
Ответ на: комментарий от fornlr

Да. У меня тоже отправилось и повисло намертво — скрипт не завершил работу.

Я себе несколько сообщений подряд отправил и он не повис.

У меня Manjaro

python --version
Python 3.8.6
pacman -Qs python-slixmpp
local/python-slixmpp 1.6.0-2
    An XMPP library written for Python 3.7+ (SleekXMPP asyncio fork)
pxrdsg
()

slixmpp - тяжело ставится с кучей зависимостей. До документации руки не доходят явно. Всё обмазано как попало асинхронными вызовами. В итоге вся эта ерунда виснет даже на тестовых примерах (наверно какая-то гонка ресурсов).

Интересно… Не хватило свободных ресурсов?

Мне моих Pentium 2020M и 4 Гб памяти хватило.

А если перезагрузить комп и проверить?

pxrdsg
()
Ответ на: комментарий от pxrdsg

Интересно… Не хватило свободных ресурсов?

Нет, это когда обмазываются как попало асинхронными вызовами, а потом оно раком встаёт в дедлок.

fornlr ★★★★★
() автор топика
Последнее исправление: fornlr (всего исправлений: 1)
20 августа 2021 г.

когда крутил свой жабер-сервер (ejabbered), у меня работал некий xsend. хз, где я его взял, вот сам скрипт:

#!/usr/bin/python
# $Id: xsend.py,v 1.8 2006/10/06 12:30:42 normanr Exp $
import sys,os,xmpp,time

if len(sys.argv) < 2:
    print "Syntax: xsend JID text"
    sys.exit(0)

tojid=sys.argv[1]
text=' '.join(sys.argv[2:])

jidparams={}
if os.access(os.environ['HOME']+'/.xsend',os.R_OK):
    for ln in open(os.environ['HOME']+'/.xsend').readlines():
        if not ln[0] in ('#',';'):
            key,val=ln.strip().split('=',1)
            jidparams[key.lower()]=val
for mandatory in ['jid','password']:
    if mandatory not in jidparams.keys():
        open(os.environ['HOME']+'/.xsend','w').write('#Uncomment fields before use and type in correct credentials.\n#JID=romeo@montague.net/resource (/resource is optional)\n#PASSWORD=juliet\n')
        print 'Please point ~/.xsend config file to valid JID for sending messages.'
        sys.exit(0)

jid=xmpp.protocol.JID(jidparams['jid'])
cl=xmpp.Client(jid.getDomain(),debug=[])

con=cl.connect()
if not con:
    print 'could not connect!'
    sys.exit()
print 'connected with',con
auth=cl.auth(jid.getNode(),jidparams['password'],resource=jid.getResource())
if not auth:
    print 'could not authenticate!'
    sys.exit()
print 'authenticated using',auth

#cl.SendInitPresence(requestRoster=0)   # you may need to uncomment this for old server
id=cl.send(xmpp.protocol.Message(tojid,text))
print 'sent message with id',id

time.sleep(1)   # some older servers will not send the message if you disconnect immediately after sending

cl.disconnect()

логин-пароль пишется в конфиг
srv> ~$ cat .xsend 
#Uncomment fields before use and type in correct credentials.
JID=log@srv/python-xmpp
PASSWORD=log

зависимости хрен знает какие))

PerdunJamesBond
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.