之前說到XMPP已經成為即時訊息的標準,那就利用Facebook手機即時通的便捷快速來送Facebook Chat訊息。
其實只要拿之前GTalk的程式碼,稍微修改一下,就可發送了。其中差異在於DIGEST-MD5的認證機制。在Smack討論區已經有人實作出XMPP DIGEST-MD5的物件。只要將login部份加上DIGEST-MD5認證。
※注意:facebook chat發送對象的帳號是-XXXXX@@chat.facebook.com,而XXXXX是一組數字,必須由c.displayBuddyList();列出才會知道。
完整程式碼如下:

package messenger;


import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

import java.util.Collection;


import org.jivesoftware.smack.Chat;

import org.jivesoftware.smack.ConnectionConfiguration;

import org.jivesoftware.smack.MessageListener;

import org.jivesoftware.smack.Roster;

import org.jivesoftware.smack.RosterEntry;

import org.jivesoftware.smack.SASLAuthentication;

import org.jivesoftware.smack.XMPPConnection;

import org.jivesoftware.smack.XMPPException;

import org.jivesoftware.smack.packet.Message;


public class facebook implements MessageListener {

XMPPConnection connection;

private volatile static facebook fclient;

static String username = "xxxxxxxx";

static String password = "xxxxxxxx";

private facebook(){}

public static facebook getInstance(){

if (fclient == null) {

synchronized (facebook.class){

if (fclient == null) {

fclient = new facebook();

}

}

}

return fclient;

}


public void login(String userName, String password) throws XMPPException {

SASLAuthentication.registerSASLMechanism("DIGEST-MD5", MySASLDigestMD5Mechanism.class);

ConnectionConfiguration config = new ConnectionConfiguration(

"chat.facebook.com", 5222, "chat.facebook.com");

config.setCompressionEnabled(true);

config.setSASLAuthenticationEnabled(true);

connection = new XMPPConnection(config);


connection.connect();

connection.login(userName, password);

}

public void sendMessage(String message, String to) throws XMPPException {

Chat chat = connection.getChatManager().createChat(to, this);

chat.sendMessage(message);

}


public void displayBuddyList() {

Roster roster = connection.getRoster();

roster.setSubscriptionMode(Roster.SubscriptionMode.accept_all);

Collection<RosterEntry> entries = roster.getEntries();


System.out.println("\n\n" + entries.size() + " buddy(ies):");

for (RosterEntry r : entries) {

System.out.println(r.getUser());

}

}

public void addRoster(String bot, String email, String input){

facebook c = facebook.getInstance();

try {

addRoster(bot,input);

c.sendMessage(input, email);

} catch (XMPPException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

public void addRoster(String bot,String input){

facebook c = facebook.getInstance();

try {

c.login(username, password);

Roster roster = connection.getRoster();

roster.createEntry(input, null, null);

} catch (XMPPException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

c.disconnect();

}

public void disconnect() {

connection.disconnect();

}


public void processMessage(Chat chat, Message message) {

if (message.getType() == Message.Type.chat)

System.out.println(chat.getParticipant() + " says: "

+ message.getBody());

}


public static void main(String args[]) throws XMPPException, IOException {

// declare variables

facebook c = facebook.getInstance();

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

String msg;


// turn on the enhanced debugger

XMPPConnection.DEBUG_ENABLED = false;


// provide your login information here

c.login(username, password);


c.displayBuddyList();

System.out.println("-----");

System.out.println("Enter your message in the console.");

System.out.println("All messages will be sent to abhijeet.maharana");

System.out.println("-----\n");


while (!(msg = br.readLine()).equals("bye")) {

// your buddy's gmail address goes here

c.sendMessage(msg, "-xxxxxxxx@chat.facebook.com");

}


c.disconnect();

System.exit(0);

}


public void alert(String bot,String email, String msg) {

facebook c = facebook.getInstance();


// turn on the enhanced debugger

XMPPConnection.DEBUG_ENABLED = false;


// provide your login information here

try {

c.login(username, password);

c.sendMessage(msg, email);

} catch (XMPPException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

c.disconnect();

}

}

自由軟體鑄造場得知Microsoft 打開 Messenger 大門 開始支援 XMPP,因此目前主流即時訊息都支援XMPP,包括Facebook chat

既然如此,當然找看看熟悉的Smack套件是否也有MSN的sample code。果然Github上有MS放出的LiveSDK,便有JAVAAndroid的程式碼。有空再把拿token那程式改成用httpclient
JAVA程式碼如下:

package messenger;


import java.net.URL;

import java.net.URLDecoder;


import javax.swing.JOptionPane;


import org.jivesoftware.smack.ConnectionConfiguration;

import org.jivesoftware.smack.PacketListener;

import org.jivesoftware.smack.Roster;

import org.jivesoftware.smack.RosterEntry;

import org.jivesoftware.smack.SASLAuthentication;

import org.jivesoftware.smack.XMPPConnection;

import org.jivesoftware.smack.XMPPException;

import org.jivesoftware.smack.filter.MessageTypeFilter;

import org.jivesoftware.smack.filter.PacketFilter;

import org.jivesoftware.smack.filter.PacketTypeFilter;

import org.jivesoftware.smack.packet.Message;

import org.jivesoftware.smack.packet.Packet;

import org.jivesoftware.smack.packet.Presence;

import org.jivesoftware.smack.util.StringUtils;


/**

 * XmppClient class has all the XMPP specific logic. This class uses smack

 * library to connect to windows live messenger service. For Windows Live Xmpp

 * documentation see <link>

 */

public class msn {


public static final String Host = "xmpp.messenger.live.com";

public static final int Port = 5222;

public static final String Service = "messenger.live.com";


private String accessToken;

private XMPPConnection connection;


/**

* This block initializes smack with SASL mechanism used by Windows Live.

*/

static {

SASLAuthentication.registerSASLMechanism("X-MESSENGER-OAUTH2",

XMessengerOAuth2.class);

SASLAuthentication.supportSASLMechanism("X-MESSENGER-OAUTH2");

}


public static void main(String[] args) throws InterruptedException {

/**

* 1. Set up a string with the path to the website.

* 2. Create a desktop variable.  The desktop class uses the computer's default browser to open the URL.

* 3. Load the URL.

* 4. Browse to the URL.

*/


//TODO put your own clientId here.

//String clientId = "000000004807AE0A";

//String scopes = "wl.messenger";

//String signInUrl = "https://oauth.live.com/authorize?client_id=" + clientId + "&redirect_uri=https://oauth.live.com/desktop&response_type=token&scope=" + scopes;


try {

// launch a web browser to take the user through the OAuth 2.0 consent flow

//BareBonesBrowserLaunch.browse(signInUrl);


// pop a dialog that tells the developer to copy and paste the URL and put it into a text box in the dialog

//String returnUrlString = (String)JOptionPane.showInputDialog("After completing the OAuth consent flow in the browser, copy and paste the return URL into this dialog box");

String returnUrlString = "https://oauth.live.com/desktop#access_token=EwAoAq1DBAAUlbRWyAJjK5w968Ru3Cyt%2f6GvwXwAAcQc5qjgPRbE4InoTBM3bsPTd0eAZIcSZiRxdNSMn3K8jSLvqJjDBfhjf3fd71C%2fBlGBFqDAs%2fFZYb1WYDPUfbL239Y3sXKA8ZFZgMOKIWWb%2beib%2fyTpNIW6m4O4SUMhAu5GYe3DAiC7JsXAnLgu%2bUFeUpF%2fEMjmrdRGzVDUjNNuwfKgdqpgvBD5kWAU1A3NNGhwxJZZhwOpKcogIcWZ%2fR7eKdFsYjGN9riWjBh2gcmk%2bGiEMifAxI0PoqeECqq9otHAZ1fz9NxCUbFssIQuy5mxlzjPu%2fWl9wmwRvZnHkDY4EiuDrfUw6SHflWirQ74nQ2fjv7Ew7Dk4nl%2fvvTymxcDZgAACPsOZ%2fNUm4kh%2bABDsVcnU0eMbHeEikN9WrYIwYTrTQKy2WtThAVuuNwsJOiqgyP%2fInBCWZMudPy0qGOlFoJriKm16OiYrgf44t9aua6MO7Lq0hJchmmbBm9%2fEsSquOhKaLOrNgx%2fVPs%2bqycd6sBkqzPJMD69eIztb%2fPnllMbX%2f4qDz1cUU1ySkE%2f3%2bMlENfPDKiNARAvKxSpljsM6yjMgwPCTawChrUgExYjbeGxAR16vY1N7ibTmwcgIB9ewoyghGeNBI7GHBdpOMzBbp%2b6YZQYBDHwPc7SXYoxPq1s8TAlfdXrrpj2J2kEpxuwPGM6VnBJN1yOdFsolRENflmAkTCh4gAA&token_type=bearer&expires_in=3600&scope=wl.messenger";

// take the string URL from the dialog and programmatically cram it into the access token parameter

String accessToken = urlTokenizerHelper(returnUrlString);


// log in using the access token

msn client = new msn(accessToken);

client.logIn();

Roster r = client.getRoster();

System.out.println(r.toString());

// make sure the program hasn't already closed before the login has completed

// in a real XMPP client, this would be replaced with waiting on UI events and Xmpp events 

Thread.sleep(1000000);

} catch (Exception e) {

System.out.println(e);

}

}


/**

* This function helps to extract the access_token query string parameter from the return URL.

*/

public static String urlTokenizerHelper(String urlString) {

URL returnUrl = null;

try{

returnUrl = new URL(urlString);

}catch(Exception e){}

String queryParameters = returnUrl.getRef();

queryParameters = queryParameters.substring(queryParameters.indexOf("access_token"));

queryParameters = queryParameters.substring(queryParameters.indexOf("=")+1);


String encodedAccessToken = queryParameters.substring(0, queryParameters.indexOf("&"));


return URLDecoder.decode(encodedAccessToken);


}

/**

* Constructor

* @param accessToken

*            The OAuth2.0 access token to be used for login.

*/

public msn(String accessToken) {

this.accessToken = accessToken;

}


/**

* Get the Roster for this client instance.

* @return The full Roster for the client.

*/

public Roster getRoster() {

return this.connection.getRoster();

}


/**

* Get the Jid for this client instance.

*/

public String getLocalJid() {

return StringUtils.parseBareAddress(this.connection.getUser());

}


/**

* Log in the client to the messenger service.

*/

public void logIn() {


// Create a connection. We use service name in config and asmack will do

// SRV look up locate the xmpp server.

ConnectionConfiguration connConfig = new ConnectionConfiguration(

msn.Service);

connConfig.setRosterLoadedAtLogin(true);

this.connection = new XMPPConnection(connConfig);


try {

this.connection.connect();


// We do not need user name in this case.

this.connection.login("", this.accessToken);

} catch (XMPPException ex) {

this.connection = null;

return;

}


System.out.println(String.format("Logged in as %s",

this.connection.getUser()));

// set the message and presence handlers

this.setPacketFilters();


// Set the status to available

Presence presence = new Presence(Presence.Type.available);

this.connection.sendPacket(presence);

}


/**

* Send a text message to the buddy.

* @param to

*            The Buddy Jid.

* @param text

*            The text message to be sent.

*/

public void sendMessage(String to, String text) {

Message msg = new Message(to, Message.Type.chat);

msg.setBody(text);

this.connection.sendPacket(msg);

}


/**

* Set the packet filters for handling incoming stanzas.

*/

private void setPacketFilters() {

if (this.connection != null) {

PacketFilter presenceFilter = new PacketTypeFilter(Presence.class);

this.connection.addPacketListener(new PacketListener() {

public void processPacket(Packet packet) {

Presence presence = (Presence) packet;

handlePresenceReceived(presence);

}

}, presenceFilter);


PacketFilter messageFilter = new MessageTypeFilter(

Message.Type.chat);

this.connection.addPacketListener(new PacketListener() {

public void processPacket(Packet packet) {

Message message = (Message) packet;

if (message.getBody() != null) {

handleMessageReceived(message);

}

}

}, messageFilter);

}

}


/**

* Handle the presence stanza received.

* @param presence

*            The received presence stanza.

*/

private void handlePresenceReceived(Presence presence) {

String from = StringUtils.parseBareAddress(presence.getFrom());

System.out.println(String.format(

"Presence received from Jid: %s, Name: %s", from,

this.getContactName(from)));

}


/**

* Handle the message stanza received.

* @param message

*            The received message stanza.

*/

private void handleMessageReceived(Message message) {

String from = StringUtils.parseBareAddress(message.getFrom());

System.out.println(String.format(

"Message received from Jid: %s, Name: %s", from,

this.getContactName(from)));

}


/**

* Get friendly name of a contact given the jid.

* @param jid

*            Jid for the target contact.

* @return The friendly name by looking up roster.

*/

private String getContactName(String jid) {

Roster roster = this.connection.getRoster();

RosterEntry entry = roster.getEntry(jid);

return entry.getName();

}

}


January 2012

Sun Mon Tue Wed Thu Fri Sat
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        

Archives

Powered by Movable Type 4.34-en

Find recent content on the main index or look in the archives to find all content.