Reputation: 568
I need to send messages to an XMPP server. Only send - I don't need to process replies, make a bot, or anything like that. When using the xmpppy
module, it goes something like this:
from xmpp import Client
from xmpp.protocol import JID, Message
jabberid = '[email protected]'
password = 'secret'
receiver = '[email protected]'
message = 'Hello world!'
jid = JID(jabberid)
connection = Client(server=jid.getDomain(), debug=None)
connection.connect()
connection.auth(user=jid.getNode(), password=password, resource=jid.getResource())
connection.send(Message(to=receiver, body=message))
However, I need to do this using Twisted. Unfortunately, the documentation is mostly useless (seems machine-generated) and I have absolutely no idea what I am supposed to do. :-(
Maybe something like
from twisted.words.protocols.jabber.jid import JID
from twisted.words.protocols.jabber.client import XMPPAuthenticator
jabberid = '[email protected]'
password = 'secret'
jid = JID(jabberid)
XMPPAuthenticator(jid, password)
but what then?
Upvotes: 0
Views: 61
Reputation: 3006
The Ignite Realtime community has a document that provides a minimal working example of a client implementation using the Twisted Words library, making it connect to a running Openfire server.
The example that is used there is copied here (but the document contains more information).
#!/usr/bin/python
# Copyright (c) Twisted Matrix Laboratories.
# See LICENSE for details.
"""
A very simple twisted xmpp-client (Jabber ID)
To run the script:
$ python xmpp_client.py <jid> <secret>
"""
import sys
from twisted.internet.defer import Deferred
from twisted.internet.task import react
from twisted.internet._sslverify import (ClientTLSOptions,
OpenSSLCertificateOptions)
from twisted.names.srvconnect import SRVConnector
from twisted.words.xish import domish
from twisted.words.protocols.jabber import xmlstream, client
from twisted.words.protocols.jabber.jid import JID
class Client:
def __init__(self, reactor, jid, secret, configurationForTLS):
self.reactor = reactor
f = client.XMPPClientFactory(jid, secret,
configurationForTLS=configurationForTLS)
f.addBootstrap(xmlstream.STREAM_CONNECTED_EVENT, self.connected)
f.addBootstrap(xmlstream.STREAM_END_EVENT, self.disconnected)
f.addBootstrap(xmlstream.STREAM_AUTHD_EVENT, self.authenticated)
f.addBootstrap(xmlstream.INIT_FAILED_EVENT, self.init_failed)
connector = SRVConnector(reactor, "xmpp-client", jid.host, f, defaultPort=5222)
connector.connect()
self.finished = Deferred()
def rawDataIn(self, buf):
print("RECV: %r" % buf)
def rawDataOut(self, buf):
print("SEND: %r" % buf)
def connected(self, xs):
print("Connected.")
self.xmlstream = xs
# Log all traffic
xs.rawDataInFn = self.rawDataIn
xs.rawDataOutFn = self.rawDataOut
def disconnected(self, reason):
print("Disconnected.")
print(reason)
self.finished.callback(None)
def authenticated(self, xs):
print("Authenticated.")
presence = domish.Element((None, "presence"))
xs.send(presence)
self.reactor.callLater(5, xs.sendFooter)
def init_failed(self, failure):
print("Initialization failed.")
print(failure)
self.xmlstream.sendFooter()
def main(reactor, jid, secret):
"""
Connect to the given Jabber ID and return a L{Deferred} which will be
called back when the connection is over.
@param reactor: The reactor to use for the connection.
@param jid: A L{JID} to connect to.
@param secret: A C{str}
"""
configurationForTLS = ClientTLSOptions(JID(jid).host,
OpenSSLCertificateOptions().getContext())
return Client(reactor, JID(jid), secret,
configurationForTLS=configurationForTLS).finished
if __name__ == "__main__":
react(main, sys.argv[1:])
Upvotes: 0
Reputation: 48335
From https://twisted.org/ click the "View Document" button, then choose "Twisted Words (IRC and XMPP)" from the index on the left, then choose "Examples" on the resulting page, then download the xmpp_client.py example.
In this example, you'll see how to use the reactor to make your client connect to a server, how to use the bootstrap APIs to handle basic connection management events, and how to do basic presence management.
After that, it depends what kind of messages you want to send (presence is managed by sending messages, for example). If you want to send a XEP-0045 "groupchat" message, such as is described at https://xmpp.org/extensions/xep-0045.html#message, construct one using the xish APIs and send it instead of or along with your presence message.
If you want to send a message like:
<message
to='[email protected]'
from='[email protected]/balcony'
type='chat'
xml:lang='en'>
<body>Wherefore art thou, Romeo?</body>
</message>
which I'm guessing is what this line from your question does:
connection.send(Message(to=receiver, body=message))
Then you can do something like:
from twisted.words.xish import domish
message = domish.Element((None, 'message'))
message['to'] = '[email protected]'
message.addElement('body', content='Hi!')
This is adapted from an example in the documentation.
Then you can send the message after your client authenticates. If you modify the xmpp_client.py
example by replacing the authenticated
method with this one:
def authenticated(self, xs):
print("Authenticated.")
message = domish.Element((None, 'message'))
message['to'] = '[email protected]'
message.addElement('body', content='Hi!')
xs.send(message)
self.reactor.callLater(5, xs.sendFooter)
Upvotes: 0