xmpp中取好友状态
magicgod
2008-03-16
为了把状态变更发为博客文章,需要知道好友状态。
监视了一下来往的xml,选中了presence回调方法。 监视很简单: j.add_xml_callback do |x| debug_log("xml: #{x}") false end 注意最后要返回false,这样就表示允许后面的回调处理,比如message, presence之类的。 加入presence的回调 j.add_presence_callback do |presence| begin #Robot.debug_log("presence: #{presence}") if presence!=nil && presence.from!=nil && presence.status!=nil && !presence.status.empty? email=Robot.split_email(presence.from) process_status(presence.status,email) end rescue => detail Robot.exception_log("process status error:",detail) end end 回调的参数非常简单就是一个对象presence, 是这个类:Jabber::Presence。具体参见:http://home.gna.org/xmpp4r/rdoc/classes/Jabber/Presence.html 里面的status属性就是好友发来的状态文本。 当然要处理的过程中要比较一下是否与原来的状态不同,另外忽略掉空状态,有些客户端是不发送状态的。 使用xmpp4r,已经在gtalk和openfire里试过了,可以正常使用。 |
|
greateWei
2009-07-03
confluence gtalk用户状态插件代码
package com.atlassian.confluence.extra.config; import com.atlassian.confluence.core.ConfluenceActionSupport; import com.atlassian.confluence.core.Administrative; import com.atlassian.confluence.setup.bandana.ConfluenceBandanaContext; import com.atlassian.confluence.extra.GtalkConnection; import com.atlassian.bandana.BandanaManager; import com.opensymphony.util.TextUtils; /** * Action to configure the API key for your Google Maps api. */ public class ConfigureGtalkAction extends ConfluenceActionSupport implements Administrative { BandanaManager bandanaManager; String gtalkAccount; String gtalkPassword; public void setBandanaManager(BandanaManager bandanaManager) { this.bandanaManager = bandanaManager; } public String execute() throws Exception { ConfluenceBandanaContext context = new ConfluenceBandanaContext(); if (TextUtils.stringSet(gtalkAccount)) { bandanaManager.setValue(context, GtalkConnection.GTALK_ACCOUNT, gtalkAccount); } gtalkAccount = (String) bandanaManager.getValue(context, GtalkConnection.GTALK_ACCOUNT); if (TextUtils.stringSet(gtalkPassword)) { bandanaManager.setValue(context, GtalkConnection.GTALK_PASSWORD, gtalkPassword); } gtalkPassword = (String) bandanaManager.getValue(context, GtalkConnection.GTALK_PASSWORD); return SUCCESS; } public String getGtalkAccount() { return gtalkAccount; } public String getGtalkPassword() { return gtalkPassword; } public void setGtalkAccount(String gtalk_account) { this.gtalkAccount = gtalk_account; } public void setGtalkPassword(String gtalk_password) { this.gtalkPassword = gtalk_password; } public String getActionName(String fullClassName) { return "Configure GTalk Presence Macro"; } } package com.atlassian.confluence.extra; import org.jivesoftware.smack.GoogleTalkConnection; import org.jivesoftware.smack.XMPPException; import org.apache.log4j.Category; import org.apache.commons.lang.StringUtils; import com.atlassian.confluence.setup.bandana.ConfluenceBandanaContext; import com.atlassian.bandana.BandanaManager; import bucket.container.ContainerManager; /** * Created by IntelliJ IDEA. * User: nolen * Date: Mar 1, 2006 * Time: 3:41:20 PM * To change this template use File | Settings | File Templates. */ public class GtalkConnection extends GoogleTalkConnection { public static final Category log = Category.getInstance(GtalkConnection.class); private static GtalkConnection con = null; public static final String GTALK_ACCOUNT = "extra.gtalk.account.key"; public static final String GTALK_PASSWORD = "extra.gtalk.password.key"; private GtalkConnection() throws XMPPException { } public static GtalkConnection getCon() { if(con == null){ BandanaManager bandanaManager = (BandanaManager) ContainerManager.getComponent("bandanaManager"); String account = getGtalkAccount(bandanaManager); String password = getGtalkPassword(bandanaManager); if(StringUtils.isEmpty(account) || StringUtils.isEmpty(password)){ // No account set up, so return null and let the macro handle it. log.error("No account set up, so return null and let the macro handle it."); return null; } try { log.debug("Getting Connection"); con = new GtalkConnection(); log.debug("Getting Login"); con.login(account, password); // Wait half second to let GTalk update the roster info. // If this fails, nothing bad happens, except the first // request may get no data try { log.debug("sleeping half sec."); Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } } catch (XMPPException e) { e.printStackTrace(); } } return con; } public static String getGtalkAccount(BandanaManager bandanaManager){ return (String) bandanaManager.getValue(new ConfluenceBandanaContext(), GTALK_ACCOUNT); } public static String getGtalkPassword(BandanaManager bandanaManager){ return (String) bandanaManager.getValue(new ConfluenceBandanaContext(), GTALK_PASSWORD); } } package com.atlassian.confluence.extra; import com.atlassian.confluence.renderer.radeox.macros.MacroUtils; import com.atlassian.confluence.user.AuthenticatedUserThreadLocal; import com.atlassian.confluence.util.velocity.VelocityUtils; import com.atlassian.confluence.setup.BootstrapManager; import com.atlassian.renderer.RenderContext; import com.atlassian.renderer.v2.RenderMode; import com.atlassian.renderer.v2.RenderUtils; import com.atlassian.renderer.v2.macro.BaseMacro; import com.atlassian.renderer.v2.macro.ResourceAware; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Category; import org.jivesoftware.smack.Roster; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.packet.Presence; import java.util.Map; /** * Created by IntelliJ IDEA. * User: nolen * Date: Feb 28, 2006 * Time: 7:18:00 PM * To change this template use File | Settings | File Templates. */ public class GtalkPresenceMacro extends BaseMacro implements ResourceAware { public static final Category log = Category.getInstance(GtalkPresenceMacro.class); private String resourcePath; private BootstrapManager bootstrapManager; public boolean hasBody() { return false; } public RenderMode getBodyRenderMode() { return RenderMode.ALL.and(RenderMode.suppress(RenderMode.F_PARAGRAPHS)); } public boolean isInline() { return true; } public String getResourcePath() { return resourcePath; } public void setResourcePath(String resourcePath) { this.resourcePath = resourcePath; } public void setBootstrapManager(BootstrapManager bootstrapManager) { this.bootstrapManager = bootstrapManager; } public String execute(Map params, String body, RenderContext context) { String id = (String) params.get("0"); id = id.trim(); if (StringUtils.isEmpty(id)) { return RenderUtils.error("There was a problem understanding the gtalk account your requested."); } else { return getGtalkPresence(id); } } private String getGtalkPresence(String user) { Map velocityContext = MacroUtils.defaultVelocityContext(); try { GtalkConnection con = GtalkConnection.getCon(); if (con == null) { log.error("Connection was null"); velocityContext.put("remoteUser", AuthenticatedUserThreadLocal.getUser()); return VelocityUtils.getRenderedTemplate("/templates/gtalk-not-configured.vm", velocityContext); } Roster roster = con.getRoster(); if (roster == null) { log.error("Roster is null. " + roster); return RenderUtils.error("There was a problem logging into the Google Talk service."); } if (!roster.contains(user)) { // Add the member to the roster roster.createEntry(user, null, null); return RenderUtils.error("We've attempted to add " + user + " to our roster. " + user + " will remain invisible until he gives us permission to see his presence."); } else { log.debug(user + " is in our roster."); } if (roster.getPresence(user) != null) { Presence presence = roster.getPresence(user); Presence.Mode mode = presence.getMode(); String status = presence.getStatus(); if(status == null) status = ""; if (mode == Presence.Mode.AVAILABLE) { return getPresenceUrl(user, "im_available", status); } else if (mode == Presence.Mode.AWAY) { return getPresenceUrl(user, "im_away", status); } else if (mode == Presence.Mode.CHAT) { return getPresenceUrl(user, "im_free_chat", status); } else if (mode == Presence.Mode.DO_NOT_DISTURB) { return getPresenceUrl(user, "im_dnd", status); } else if (mode == Presence.Mode.EXTENDED_AWAY) { return getPresenceUrl(user, "im_away", status); } else if (mode == Presence.Mode.INVISIBLE) { return getPresenceUrl(user, "im_invisible", status); } else { return getPresenceUrl(user, "im_invisible", status); } } else { return getPresenceUrl(user, "im_invisible", ""); } } catch (XMPPException e) { e.printStackTrace(); return RenderUtils.error("There was a problem getting presence info for " + user); } } private String getPresenceUrl(String user, String icon, String status) { return "<A href='jabber:" + user + "' title='" + status + "'>" + "<img src='" + bootstrapManager.getBaseUrl() + getResourcePath() + "/" + icon + ".gif' " + "style='vertical-align:bottom;' " + "/>" + user + "</a>"; } } |