I am new to this OpenFire and asmack, i want the user to have a functionality of Multi Users Chatting so i searched around and i found MUC i have implemented this for creating a room and sending invitation to other users these works, other user receives the invitation but the other user is not able to join the room.
I am doing this on other user invitation receiving
Here connection is the connection of this user and room is the room name that we getting in invitation.
MultiUserChat muc3 = new MultiUserChat(connection,room);
muc3.join("testbot3");
testbot3 is just some random name.
But this throws 404 error.
Do i need to join the user before sending the invitation i.e if A user sending invitation to B , before invitation sent do A needs to join these users by default to room and then it depends on B to decline or just keep quite.
What i am doing is B receives invitation from A in that InvitationListner of B i am trying to join with the above code.
I have been trying for long now i am not sure what is going wrong, some one can give a sample code of how to do this it would be great help for me.
Thanks
Here is more information on my issue
As i go and check on Openfire i can see the room created by the user and he has been added himself as an owner so i dont think so it would be an issue with room getting created.
May be this can be an issue with room getting locked, as i have read through the room is locked when the room is not completely created , i guess this is an issue with form filling when we create the room, i am not filling in the password in the form can this be an issue ?
Please see the following code below inside the handler i am calling a method "checkInvitation" which does the same as above code posted still i get 404. Can you please tell me what i wrong in my code.
Do the nickname that needs to be added can be anything or it needs to something user specific ?
public void createChatroom(){
MultiUserChat muc = null;
try {
muc = new MultiUserChat(connection, "myroom#conference.localhost");
muc.create("testbot");
// Get the the room's configuration form
Form form = muc.getConfigurationForm();
// Create a new form to submit based on the original form
Form submitForm = form.createAnswerForm();
// Add default answers to the form to submit
for (Iterator fields = form.getFields(); fields.hasNext();) {
FormField field = (FormField) fields.next();
if (!FormField.TYPE_HIDDEN.equals(field.getType()) && field.getVariable() != null) {
// Sets the default value as the answer
submitForm.setDefaultAnswer(field.getVariable());
}
}
// Sets the new owner of the room
List owners = new ArrayList();
owners.add("admin#localhost");
submitForm.setAnswer("muc#roomconfig_roomowners", owners);
// Send the completed form (with default values) to the server to configure the room
muc.sendConfigurationForm(submitForm);
muc.join("d");
muc.invite("b#localhost", "Meet me in this excellent room");
muc.addInvitationRejectionListener(new InvitationRejectionListener() {
public void invitationDeclined(String invitee, String reason) {
// Do whatever you need here...
System.out.println("Initee "+invitee+" reason"+reason);
}
});
} catch (XMPPException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void setConnection(XMPPConnection connection) {
this.connection = connection;
if (connection != null) {
// Add a packet listener to get messages sent to us
PacketFilter filter = new MessageTypeFilter(Message.Type.chat);
connection.addPacketListener(new PacketListener() {
public void processPacket(Packet packet) {
Message message = (Message) packet;
if (message.getBody() != null) {
String fromName = StringUtils.parseBareAddress(message
.getFrom());
Log.i("XMPPClient", "Got text [" + message.getBody()
+ "] from [" + fromName + "]");
messages.add(fromName + ":");
messages.add(message.getBody());
// Add the incoming message to the list view
mHandler.post(new Runnable() {
public void run() {
setListAdapter();
checkInvitation();
}
});
}
}
}, filter);
mHandler.post(new Runnable() {
public void run() {
checkInvitation();
}
});
}
}
The 404 error indicates that:
404 error can occur if the room does not exist or is locked
So, ensure that your room is not locked or existed! The code below is how I join the room when there's an in-comming invitation:
private void setChatRoomInvitationListener() {
MultiUserChat.addInvitationListener(mXmppConnection,
new InvitationListener() {
#Override
public void invitationReceived(Connection connection,
String room, String inviter, String reason,
String unKnown, Message message) {
//MultiUserChat.decline(mXmppConnection, room, inviter,
// "Don't bother me right now");
// MultiUserChat.decline(mXmppConnection, room, inviter,
// "Don't bother me right now");
try {
muc.join("test-nick-name");
Log.e("abc","join room successfully");
muc.sendMessage("I joined this room!! Bravo!!");
} catch (XMPPException e) {
e.printStackTrace();
Log.e("abc","join room failed!");
}
}
});
}
Hope this helps your error!
Edit:this is how I config the room:
/*
* Create room
*/
muc.create(roomName);
// muc.sendConfigurationForm(new Form(Form.TYPE_SUBMIT));
Form form = muc.getConfigurationForm();
Form submitForm = form.createAnswerForm();
for (Iterator fields = form.getFields(); fields.hasNext();) {
FormField field = (FormField) fields.next();
if (!FormField.TYPE_HIDDEN.equals(field.getType())
&& field.getVariable() != null) {
show("field: " + field.getVariable());
// Sets the default value as the answer
submitForm.setDefaultAnswer(field.getVariable());
}
}
List<String> owners = new ArrayList<String>();
owners.add(DataConfig.USERNAME + "#" + DataConfig.SERVICE);
submitForm.setAnswer("muc#roomconfig_roomowners", owners);
submitForm.setAnswer("muc#roomconfig_roomname", roomName);
submitForm.setAnswer("muc#roomconfig_persistentroom", true);
muc.sendConfigurationForm(submitForm);
// submitForm.
show("created room!");
muc.addMessageListener(new PacketListener() {
#Override
public void processPacket(Packet packet) {
show(packet.toXML());
Message mess = (Message) packet;
showMessageToUI(mess.getFrom() + ": " + mess.getBody());
}
});
With this cofiguration, I can join a room easily without password.
You may use the code snippet to join the chat:
public void joinMultiUserChatRoom(String userName, String roomName) {
// Get the MultiUserChatManager
MultiUserChatManager manager = MultiUserChatManager.getInstanceFor(connection);
// Create a MultiUserChat using an XMPPConnection for a room
MultiUserChat multiUserChat = manager.getMultiUserChat(roomName + "#conference.localhost");
DiscussionHistory history = new DiscussionHistory();
history.setMaxStanzas(-1);
try {
multiUserChat.join(userName, "", history, connection.getPacketReplyTimeout());
} catch (Exception e) {
e.printStackTrace();
}
}
Invite a friend:
/**
* Invites another user to this room.
*
* #param userAddress the address of the user to invite to the room.(one
* may also invite users not on their contact list).
* #param reason a reason, subject, or welcome message that would tell
* the the user why they are being invited.
*/
public void invite(String userAddress, String reason)
{
multiUserChat.invite(userAddress, reason);
}
Related
I want to send a status update-message when an admin goes online, idle, .... offline. My Code is working but there is a bug.
The bot will send update-messages for all users on the server .. i just want to get status updates of admins ..
This is my code:
public class LoginMessageListener extends ListenerAdapter {
public void onUserUpdateOnlineStatus(UserUpdateOnlineStatusEvent event) {
OnlineStatus os = event.getGuild().getMember(event.getUser()).getOnlineStatus();
if (event.getGuild().getRoleById("628650613152153640") != null) {
TextChannel channel = event.getGuild().getTextChannelById("628645905955815454");
EmbedBuilder builder = new EmbedBuilder();
builder.setThumbnail("http://i.epvpimg.com/t43Pfab.gif");
builder.setFooter("Powered by Backxtar.");
builder.setTimestamp(OffsetDateTime.now());
builder.setColor(0xf22613);
builder.setDescription("Admin **" + event.getUser().getAsMention() + "** is now **" + os + "**!\nI'm __always available__ for questions,\nsuggestions or problems!\n:point_right: [**Da Hood - Join NOW!**](https://discord.gg/xyz) :point_left:");
channel.sendMessage(builder.build()).complete().delete().queueAfter(15, TimeUnit.SECONDS);
}
else {
return;
}
}
}
Your check with if (event.getGuild().getRoleById("628650613152153640") != null) only checks if the role exists in the server. To check if the user has the role you have to check the roles with event.getMember():
private static boolean isAdmin(Member member) {
return member.getRoles().stream()
.mapToLong(Role::getIdLong) // we check by id
.anyMatch(id -> id == 628650613152153640L); // true if any role has that id
}
#Override
public void onUserUpdateOnlineStatus(UserUpdateOnlineStatusEvent event) {
OnlineStatus os = event.getGuild().getMember(event.getUser()).getOnlineStatus();
if (isAdmin(event.getMember())) {
// code
}
// the else here is unnecessary
}
I want to implement a very simple Java Telegram Client, which is capable of sending and receiving messages and store the sessions across multiple starts. I already managed to authenticate and receive messages
api = new TelegramApi(apiState, new AppInfo(API_ID, "console", "1", "1", "en"), new ApiCallback() {
#Override
public void onAuthCancelled(TelegramApi api) {
Log.d(TAG, "-----------------CANCELLED----------------");
Log.d(TAG, api.getApiContext().toString());
}
#Override
public void onUpdatesInvalidated(TelegramApi api) {
Log.d(TAG, "-----------------INVALIDATED----------------");
Log.d(TAG, api.getApiContext().toString());
}
#Override
public void onUpdate(TLAbsUpdates tlAbsUpdates) {
Log.d(TAG, "-----------------UPDATE----------------");
Log.d(TAG, tlAbsUpdates.toString());
if (tlAbsUpdates instanceof TLUpdateShortMessage) {
Log.d(TAG, "-----------------UPDATE CHAT MESSAGE----------------");
int senderId = ((TLUpdateShortMessage) tlAbsUpdates).getUserId();
Log.d(TAG, "Message from " + senderId);
String message = ((TLUpdateShortMessage) tlAbsUpdates).getMessage();
Log.d(TAG, message);
activity.appendMessage(TAG, message);
}
}
});
api.switchToDc(2);
TLConfig config = null;
try {
config = api.doRpcCallNonAuth(new TLRequestHelpGetConfig());
} catch (TimeoutException | IOException e) {
e.printStackTrace();
}
apiState.updateSettings(config);
However, I struggle to send messages to another user. For the beginning, it would be enough if I could send a message back to the user, who sent me a message before (by retrieving the senderId, as you can see in the onUpdate method before). However, if someone could also help me with retrieving the ids of my saved contacts, it would be perfect.
Furthermore, I want to store the sessions accross multiple startups, since I get a FLOOD_WAIT error (420), if I test my code to often.
For this I used https://github.com/rubenlagus/TelegramApi/blob/51713e9b6eb9e0ae0d4bbbe3d4deffff9b7f01e4/src/main/java/org/telegram/bot/kernel/engine/MemoryApiState.java and its used classes (e.g. TLPersistence), which stores and loads the ApiState. However, apparently it does not store the signin status, since I always have to authenticate my number every time I update the code.
By the way, I am using Api layer 66 (https://github.com/rubenlagus/TelegramApi/releases).
UPDATE 1:
Problems with sending messages solved myself:
private void sendMessageToUser(int userId, String message) {
TLInputPeerUser peer = new TLInputPeerUser();
peer.setUserId(userId);
TLRequestMessagesSendMessage messageRequest = new TLRequestMessagesSendMessage();
messageRequest.setFlags(0);
messageRequest.setPeer(peer);
messageRequest.setRandomId(new SecureRandom().nextLong());
messageRequest.setMessage(message);
api.doRpcCallNonAuth(messageRequest, 1500, new RpcCallback<TLAbsUpdates>() {
#Override
public void onResult(TLAbsUpdates tlAbsUpdates) {
Log.d(TAG, "-----------------------MESSAGE SENT-----------------------");
}
#Override
public void onError(int i, String s) {
Log.d(TAG, "-----------------------MESSAGE SENT ERROR-----------------------");
Log.d(TAG, String.valueOf(i));
if(s != null) {
Log.d(TAG, s);
}
}
});
}
However, now I am stuck at finding the userIds of my contacts.
After first update this is left:
Saving the session state (and signin state)
Find userIds of contacts
Update 2:
I managed to fetch the users, with which there are already dialogs. This is enough for my use case, however, loading all contacts would be perfect. This is how to load users from existing dialogs:
private int getUserId(String phone) throws InterruptedException {
TLRequestMessagesGetDialogs dialogs = new TLRequestMessagesGetDialogs();
dialogs.setOffsetId(0);
dialogs.setLimit(20);
dialogs.setOffsetPeer(new TLInputPeerUser());
CountDownLatch latch = new CountDownLatch(1);
api.doRpcCallNonAuth(dialogs, 1500, new RpcCallback<TLAbsDialogs>() {
#Override
public void onResult(TLAbsDialogs tlAbsDialogs) {
Log.d(TAG, "----------------------getUsers--------------------");
for(TLAbsUser absUser : ((TLDialogs) tlAbsDialogs).getUsers()) {
users.add((TLUser) absUser);
}
latch.countDown();
}
#Override
public void onError(int i, String s) {
Log.d(TAG, "----------------------getUsers ERROR--------------------");
latch.countDown();
}
});
latch.await();
for(TLUser user : users) {
if(user.getPhone().equals(phone)) {
return user.getId();
}
}
return 0;
}
After second update this is left:
Saving the session state (and signin state)
Get user ids from contacts instead of dialogs
I am trying to create multi user chat using XMPP(smack). After creation of room when i try to join to chat room then there is no entry of joined member in ofmucmember.
Creation of room code is as below :
public void createMultiUserChatRoom(String roomName, String nickName) {
MultiUserChatManager multiUserChatManager = MultiUserChatManager.getInstanceFor(connection);
MultiUserChat multiUserChat = multiUserChatManager.getMultiUserChat(roomName+"#conference.localhost");
try {
multiUserChat.create(nickName);
Form form = multiUserChat.getConfigurationForm();
Form submitForm = form.createAnswerForm();
List<FormField> formFieldList = submitForm.getFields();
for (FormField formField : formFieldList) {
if(!FormField.Type.hidden.equals(formField.getType()) && formField.getVariable() != null) {
submitForm.setDefaultAnswer(formField.getVariable());
}
}
submitForm.setAnswer("muc#roomconfig_persistentroom", true);
submitForm.setAnswer("muc#roomconfig_publicroom", true);
submitForm.setAnswer("muc#roomconfig_enablelogging", true);
submitForm.setAnswer("x-muc#roomconfig_reservednick", false);
submitForm.setAnswer("x-muc#roomconfig_canchangenick", false);
submitForm.setAnswer("x-muc#roomconfig_registration", false);
submitForm.setAnswer("muc#roomconfig_passwordprotectedroom", false);
submitForm.setAnswer("muc#roomconfig_roomname", roomName);
submitForm.setAnswer("muc#roomconfig_whois", Arrays.asList("none"));
multiUserChat.sendConfigurationForm(submitForm);
} catch (Exception e) {
e.printStackTrace();
}
}
Code for joining the created room is as below:
public void joinMultiUserChatRoom(String userName, String roomName) {
MultiUserChatManager manager = MultiUserChatManager.getInstanceFor(connection);
MultiUserChat multiUserChat = manager.getMultiUserChat(roomName + "#conference.localhost");
DiscussionHistory history = new DiscussionHistory();
history.setMaxStanzas(0);
try {
multiUserChat.join(userName);
multiUserChat.sendMessage(userName +" : You have joined the group : " + roomName);
Presence presence = multiUserChat.getOccupantPresence(roomName + "#conference.localhost/" + userName);
presence.setMode(Presence.Mode.available);
connection.sendStanza(presence);
} catch (Exception e) {
e.printStackTrace();
}
}
Response from server :
<message to="admin#localhost/Smack" id="h7axM-14" type="groupchat" from="team6#conference.localhost/roy"><body>roy : You have joined the group : team6</body><x xmlns="jabber:x:delay" stamp="20160623T12:15:50" from="team6#conference.localhost/roy"/></message>
presence :<presence to='admin#localhost/Smack' id='WR9Dy-12'><x xmlns='http://jabber.org/protocol/muc#user'><item affiliation='owner' jid='admin#localhost/Smack' role='moderator'></item></x><c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='http://www.igniterealtime.org/projects/smack' ver='NfJ3flI83zSdUDzCEICtbypursw='/></presence>
I am not getting any error. Can anybody tell me where i am wrong here?
When you fill the configuration form, you need to fill following sections:
<field
label='Room Admins'
type='jid-multi'
var='muc#roomconfig_roomadmins'>
<value>wiccarocks#shakespeare.lit</value>
<value>hecate#shakespeare.lit</value>
</field>
<field
label='Room Owners'
type='jid-multi'
var='muc#roomconfig_roomowners'/>
Admins and Owner are saved in ofMucAffiliation table and if the configuration is updated and existing admin or owner is not mentioned then server assumes that it's affiliation has been changed to member, so it moves the entry to ofMucMember table.
You don't get a member just because you join a room. After you have joined a room, you are a Participant in the terminology of XEP-0045.
smack presence listener in multi user chat not getting called. Used Smack Api to login and then added roster.addRosterListener(mRoasterListener); but could not get any success to listen when presence of other user of the chat room changes. I tried following code to get the presence listener to work :
connection.login(loginUser, passwordUser);
MultiUserChatManager manager =
MultiUserChatManager.getInstanceFor(connection);
muc = manager.getMultiUserChat(roomID + "#" +context.getString(R.string.group_chat_id));
Log.d("Join User: ", "Already Created");
muc.join(Utilities.getUserPhoneNo(context));
muc.addMessageListener(mGroupMessageListener);
Roster roster = Roster.getInstanceFor(connection);//luna
roster.addRosterListener(mRoasterListener);//roasterListener
Log.d("Joined User Phone: ", " " + Utilities.getUserPhoneNo(context));
and this class to listen for presence change...
public class RoasterListener implements RosterListener{
public RoasterListener(Context context){
}
#Override
public void entriesAdded(Collection<String> collection) {
}
#Override
public void entriesUpdated(Collection<String> collection) {
}
#Override
public void entriesDeleted(Collection<String> collection) {
}
#Override
public void presenceChanged(Presence presence) {
System.out.println("Presence changed: " + presence.getFrom() + " " + presence);
}
}
I tried many links available by stackoverflow but could not get any success.
Please Help!
For Multi User Chat you don't have to use Roster, because it's normal to meet people you don't have in Roster.
To know who is in a muc, first ask for occupants:
muc.join(user,password);
List<String> occupantsAtJoinTime = muc.getOccupants();
for (String occupant : occupantsAtJoinTime)
{
System.out.println("occupant: "+occupant);
//actions
}
then, to keep Occupants list updated, register a DefaultParticipantStatusListener to your muc and define that Listner:
muc.addParticipantStatusListener(new CustomParticipantStatusListner());
definied as (there are many methods to implement if you need):
public class CustomParticipantStatusListner extends DefaultParticipantStatusListener
{
public void joined(String participant)
{
System.out.println(participant + "just joined MUC");
//actions (add occupantsRightNow)
}
public void left(String participant)
{
System.out.println(participant + " just left MUC");
//actions (remove occupantsRightNow)
}
}
All this with smack 4.1.7
It's about the Manage role modifications in Multi User Chat.
This example shows how to grant voice to a visitor and listen for the notification events:
// User1 creates a room
muc = new MultiUserChat(conn1, "myroom#conference.jabber.org");
muc.create("testbot");
// User1 (which is the room owner) configures the room as a moderated room
Form form = muc.getConfigurationForm();
Form answerForm = form.createAnswerForm();
answerForm.setAnswer("muc#roomconfig_moderatedroom", "1");
muc.sendConfigurationForm(answerForm);
// User2 joins the new room (as a visitor)
MultiUserChat muc2 = new MultiUserChat(conn2, "myroom#conference.jabber.org");
muc2.join("testbot2");
// User2 will listen for his own "voice" notification events
muc2.addUserStatusListener(new DefaultUserStatusListener() {
public void voiceGranted() {
super.voiceGranted();
...
}
public void voiceRevoked() {
super.voiceRevoked();
...
}
});
// User3 joins the new room (as a visitor)
MultiUserChat muc3 = new MultiUserChat(conn3, "myroom#conference.jabber.org");
muc3.join("testbot3");
// User3 will lister for other occupants "voice" notification events
muc3.addParticipantStatusListener(new DefaultParticipantStatusListener() {
public void voiceGranted(String participant) {
super.voiceGranted(participant);
...
}
public void voiceRevoked(String participant) {
super.voiceRevoked(participant);
...
}
});
// The room's owner grants voice to user2
muc.grantVoice("testbot2");
Details can be refered in http://web.mit.edu/svalente/lib/smack_3_0_4/documentation/extensions/muc.html .
Firstly, join a chat room:
public MultiUserChat joinMultiUserChat(String user, String roomsName,
String password) {
if (getConnection() == null)
return null;
try {
MultiUserChat muc = new MultiUserChat(getConnection(), roomsName
+ "#conference." + getConnection().getServiceName());
DiscussionHistory history = new DiscussionHistory();
history.setMaxChars(0);
// history.setSince(new Date());
muc.join(user, password, history,
SmackConfiguration.getPacketReplyTimeout());
Log.i("MultiUserChat", "Chat room【"+roomsName+"】joined........");
return muc;
} catch (XMPPException e) {
e.printStackTrace();
Log.i("MultiUserChat", "Chat room【"+roomsName+"】failed........");
return null;
}
}
Then, use MultiChatUser to send Message:
try {
multiUserChat.sendMessage(message);
} catch (XMPPException e) {
e.printStackTrace();
}
Add a Listener:
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;
public class TaxiMultiListener implements PacketListener {
#Override
public void processPacket(Packet packet) {
Message message = (Message) packet;
String body = message.getBody();
}
}
Finally, call the Listener using MultiUserChat:
multiUserChat.addMessageListener(new TaxiMultiListener());
I have uploaded a test html page and servlet following this article exactly. This works and will send me an email. However, when I copy this code almost exactly into my SendEmail method in the code shown below it does not send an email. I know when I run this locally that it gets to the SendEmail method just fine (but you cannot send emails using the development server in GAE). When I deploy it there are no errors on the page or in the logs so it plain old seems like it is just not sending the email. Anyone see a reason why?
public class EmailService {
private static SimpleDateFormat dateFormatter = new SimpleDateFormat ("MM/dd/yyyy");
public static void SendDeadlineEmails() {
PersistenceManager pm = getPersistenceManager();
try {
List<DeadlineEmailObject> studentsWithDeadlineToday = populateEmailList(pm);
sendEmails(studentsWithDeadlineToday);
} finally {
pm.close();
}
}
private static List<DeadlineEmailObject> populateEmailList(PersistenceManager pm) {
List<Student> students = getStudents(pm);
List<DeadlineEmailObject> studentsWithDeadlineToday = new ArrayList<DeadlineEmailObject>();
String today = dateFormatter.format(System.currentTimeMillis());
for(Student student : students) {
Set<Charge> charges = student.getCharges();
if(charges != null) {
for(Charge charge : charges) {
String deadline = dateFormatter.format(charge.getDeadline());
if(deadline.equals(today)) {
studentsWithDeadlineToday.add(new DeadlineEmailObject(student, charge));
}
}
}
}
return studentsWithDeadlineToday;
}
#SuppressWarnings("unchecked")
private static List<Student> getStudents(PersistenceManager pm) {
return (List<Student>) pm.newQuery(Student.class).execute();
}
private static void sendEmails(List<DeadlineEmailObject> studentsWithDeadlineToday) {
for(DeadlineEmailObject emailObj : studentsWithDeadlineToday) {
sendEmail(emailObj);
System.out.println("Student: " + emailObj.getStudent().getFullName() + "\nAmount: " + emailObj.getCharge().getAmount() +
"\nDeadline: " + dateFormatter.format(emailObj.getCharge().getDeadline()));
}
}
private static void sendEmail(DeadlineEmailObject emailObj) {
Properties props = new Properties();
Session session = Session.getDefaultInstance(props, null);
try {
Message msg = new MimeMessage(session);
msg.setFrom(new InternetAddress("njbuwm#gmail.com", "Admin"));
msg.addRecipient(Message.RecipientType.TO, new InternetAddress(emailObj.getStudent().getEmail(), emailObj.getStudent().getFullName()));
msg.setSubject("Deadline Reached");
msg.setText(buildMessage(emailObj));
Transport.send(msg);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private static String buildMessage(DeadlineEmailObject emailObj) {
String email = "";
email += "Dear " + emailObj.getStudent().getFullName() + " ,\n";
email += "You owe us money. This much: $" + emailObj.getCharge().getAmount() + ".\n";
email += "For this reason: " + emailObj.getCharge().getReason() + ".\n";
email += "The deadline is today and I advise you to pay it or you will be deported to Idontpaymybills Island forever.\n";
email += "Thank you,\n Automated Emailer";
return email;
}
private static PersistenceManager getPersistenceManager() {
return JDOHelper.getPersistenceManagerFactory("transactions-optional").getPersistenceManager();
}
}
Change your call to setFrom() to use an email address permitted in the Developers Guide:
To set the sender address, the app calls the setFrom() method on the
MimeMessage object. The sender address must be one of the following
types:
The address of a registered administrator for the application
The address of the user for the current request signed in with a Google Account. You can determine the current user's email address with the Users API. The user's account must be a Gmail account, or be on a domain managed by Google Apps.
Any valid email receiving address for the app (such as xxx#APP-ID.appspotmail.com).