I want read all messages with gmail account using Java and IMAP.
Can i do this, or now i need to use OAuth and Gmail API?
That is my Java simple code:
import java.util.*;
import javax.mail.*;
public class ReadingEmail {
public static void main(String[] args) {
Properties props = new Properties();
props.setProperty("mail.store.protocol", "imaps");
try {
Session session = Session.getInstance(props, null);
session.setDebug(true);
Store store = session.getStore("imaps");
store.connect("imap.gmail.com", "email", "pass");
Folder inbox = store.getFolder("INBOX");
inbox.open(Folder.READ_ONLY);
Message msg = inbox.getMessage(inbox.getMessageCount());
Address[] in = msg.getFrom();
for (Address address : in) {
System.out.println("FROM:" + address.toString());
}
Multipart mp = (Multipart) msg.getContent();
BodyPart bp = mp.getBodyPart(0);
System.out.println("SENT DATE:" + msg.getSentDate());
System.out.println("SUBJECT:" + msg.getSubject());
System.out.println("CONTENT:" + bp.getContent());
} catch (Exception mex) {
mex.printStackTrace();
}
}
}
But i have a error:
My client isn't accepting my username and password
IMAP is enabled in Gmail account settings. What to do?
Thank you!
Of course you can, that's the whole point of IMAP. You need to authenticate, though, either with OAuth2, or app-specific password (your account password will not work).
Related
I have used GmailQuickstart to modify email signatures. It updates my own gmail account, but I want o do that for all the users of the company.
How do I make my Google API project used be entire organization.
private static Credential getCredentials(final NetHttpTransport HTTP_TRANSPORT) throws IOException {
// Load client secrets.
InputStream in = GmailQuickstart.class.getResourceAsStream(CREDENTIALS_FILE_PATH);
GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));
// Build flow and trigger user authorization request.
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES)
.setDataStoreFactory(new FileDataStoreFactory(new java.io.File(TOKENS_DIRECTORY_PATH)))
.setAccessType("offline")
.build();
LocalServerReceiver receiver = new LocalServerReceiver.Builder().setPort(8888).build();
return new AuthorizationCodeInstalledApp(flow, receiver).authorize("user");
}
public static void main(String... args) throws IOException, GeneralSecurityException {
// Build a new authorized API client service.
final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
Gmail service = new Gmail.Builder(HTTP_TRANSPORT, JSON_FACTORY, getCredentials(HTTP_TRANSPORT))
.setApplicationName(APPLICATION_NAME)
.build();
// Print the labels in the user's account.
String user = "me";
final java.util.logging.Logger buggyLogger = java.util.logging.Logger.getLogger(FileDataStoreFactory.class.getName());
buggyLogger.setLevel(java.util.logging.Level.SEVERE);
SendAs primaryAlias = null;
ListSendAsResponse aliases = service.users().settings().sendAs().list("me").execute();
for (SendAs alias : aliases.getSendAs()) {
if (alias.getIsPrimary()) {
primaryAlias = alias;
break;
}
}
//service.users().getProfile().getUserId();
SendAs aliasSettings = new SendAs()
.setSignature("Email : " + primaryAlias.getSendAsEmail() + "Company name, Address, zip");
SendAs result = service.users().settings().sendAs().patch(
"me",
primaryAlias.getSendAsEmail(),
aliasSettings)
.execute();
System.out.println("Updated signature for " + result.getDisplayName());
}
The above code works, I can change my email signatire. I would like to change email signature acress the comapony for all the users. Please Let me know if there is any solution that you guys have implemented?
I'm trying to get current logged-in windows userId using .Net-Core 2.0.
What is the correct way to achieve this in .Net-core 2.0? Also what are the Groups which this user is member of?
This question is a bit old now, but I haven't found an answer on SO to this specific setup where:
ClaimsPrincipal currentUser = this.User;
var currentUserName = currentUser.FindFirst(ClaimTypes.NameIdentifier).Value;
currentUserName returns null
Setup
I have two servers:
Identity Server
Client Server
The Authentication server and the Client server on separate projects (or domains). So there isn't any communication between them (except for authorization)
The Identity server uses Jwt Tokens for authentication.
In Startup.cs of the Identity server:
public void ConfigureServices(IServiceCollection services)
{
...
var identityBuilder = services.AddIdentityServer();
identityBuilder
.AddInMemoryApiResources(
new List<ApiResource>
{
new ApiResource("app name", "app displayname", new[] { JwtClaimTypes.Role, JwtClaimTypes.Name}) {UserClaims = {JwtClaimTypes.Name, JwtClaimTypes.Role}}
};
)
...
}
^^ this is important for the Solution section
The problem
When a user does a call to the Client Server, the server can't really access the client's credentials without making an additional call to the Identity Server (and this might be technically incur a some form of a security risk)
Solution: Poor man's Jwt Claim Types username extractor
So I wrote a small extension function to extract some form of username from the ClaimsPrincipal, this isn't fool proof, but it should at least be of some use.
public static string GetUsername(this ClaimsPrincipal user)
{
var username = user?.Identity?.Name;
if (username != null)
{
return username;
}
// Get username from claim, this is usualy an email
var claim = user?.FindFirst(x => x.Type == JwtClaimTypes.PreferredUserName) ??
user?.FindFirst(x => x.Type == JwtClaimTypes.Name);
if (claim == null)
{
return null;
}
username = claim.Value;
var atIndex = username.IndexOf('#');
if (atIndex > 0)
{
username = username.Substring(0, atIndex);
var name = username.Split('.', StringSplitOptions.RemoveEmptyEntries);
username = "";
foreach (var n in name)
{
if (n.Length > 2)
{
username += n.First().ToString().ToUpper() + n.Substring(1) + " ";
}
else
{
username += n.ToUpper() + " ";
}
}
}
return username.Trim();
}
What this code basically does is: it takes the ClaimsPrincipal and tries to extract the Name of the user, since the username is almost always an email it tries to parse the email to return the User Name. It's only usable if the username is something parsable.
Hope this helps.
In your controller, do: User.Identity.GetUserId();.
Otherwise, you need to inject IHttpContextAccessor _http; in your class and then _http.HttpContext.User?.Identity?.GetUserId();. Sample beneath:
public class Test
{
private readonly IHttpContextAccessor _http;
public Test(IHttpContextAccessor http)
{
_http = http;
}
public int? GetUserId()
{
return _http.HttpContext.User?.Identity?.GetUserId();
}
}
I need help in using S22.IMAP library to get a new mail notification for Microsoft Exchange email server. I've been successful in getting the new mail notification for gmail, and for Microsoft Exchange email S22.IMAP is not throwing the new mail notification.
When I print Client Capabilities for gmail and Microsoft Exchange I get the following:
How can I get new mail notification for Microsoft Exchange email?
using System;
using System.Text.RegularExpressions;
using System.Collections.Generic;
using System.Net.Mail;
using S22.Imap;
namespace Test {
class Program {
static void Main(string[] args)
{
//For gmail I'm getting the new mail notification
//using (ImapClient Client = new ImapClient("imap.gmail.com", 993,
// "login", "password", AuthMethod.Login, true))
//For Microsoft exchange email I'm not getting new mail notification, even though it supports "IDLE"
using (ImapClient Client = new ImapClient("mail.exchangeglobal.com", 993,
"login", "password", AuthMethod.Login, true))
{
// Should ensure IDLE is actually supported by the server
if(Client.Supports("IDLE") == false) {
Console.WriteLine("Server does not support IMAP IDLE");
return;
}
Client.NewMessage += OnNewMessage;
// Put calling thread to sleep. This is just so the example program does
// not immediately exit.
System.Threading.Thread.Sleep(6000000);
}
}
static void OnNewMessage(object sender, IdleMessageEventArgs e)
{
Console.WriteLine("A new message arrived. Message has UID: "+
e.MessageUID);
//Fetch the new message's headers and print the subject line
MailMessage m = e.Client.GetMessage( e.MessageUID, FetchOptions.HeadersOnly );
Console.WriteLine("New message's subject: " + m.Subject);
}
}
}
I think S22.IMAP library would not work for me, and I've settled down with the following:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Exchange.WebServices.Data;
using System.Net;
namespace MX
{
class Program
{
static ExchangeService MdpMailBox;
static void Main(string[] args)
{
MdpMailBox = new ExchangeService(ExchangeVersion.Exchange2010_SP2);
NetworkCredential nc = new NetworkCredential("LOGIN", "PASSWORD");
nc.Domain = "SOMEDOMAIN";
MdpMailBox.Credentials = nc;
MdpMailBox.AutodiscoverUrl("LOGIN#SOMEglobal.com");
StreamingSubscription sc = MdpMailBox.SubscribeToStreamingNotifications(new FolderId[] { WellKnownFolderName.Inbox }, EventType.NewMail);
StreamingSubscriptionConnection scn = new StreamingSubscriptionConnection(MdpMailBox, 1);
scn.AddSubscription(sc);
scn.OnNotificationEvent += new StreamingSubscriptionConnection.NotificationEventDelegate(OnEvent);
scn.OnSubscriptionError += new StreamingSubscriptionConnection.SubscriptionErrorDelegate(OnError);
scn.OnDisconnect += new StreamingSubscriptionConnection.SubscriptionErrorDelegate(OnDisconnect);
scn.Open();
Console.WriteLine("Waiting for email");
System.Threading.Thread.Sleep(600000);
}
static private void OnDisconnect(object sender, SubscriptionErrorEventArgs args)
{
// Cast the sender as a StreamingSubscriptionConnection object.
Console.WriteLine("---Mail Box Disconnected---");
}
static void OnEvent(object sender, NotificationEventArgs args)
{
StreamingSubscription subscription = args.Subscription;
// Loop through all item-related events.
foreach (NotificationEvent notification in args.Events)
{
switch (notification.EventType)
{
case EventType.NewMail:
Console.WriteLine("\n-------------New Mail received:-------------");
break;
}
// Display the notification identifier.
if (notification is ItemEvent)
{
// The NotificationEvent for an email message is an ItemEvent.
ItemEvent itemEvent = (ItemEvent)notification;
FindItemsResults<Item> fi = MdpMailBox.FindItems(WellKnownFolderName.Inbox, new ItemView(1));
Console.WriteLine(fi.Items[0].Subject);
Console.WriteLine("\nItemId: " + itemEvent.ItemId.UniqueId);
}
else
{
// The NotificationEvent for a folder is a FolderEvent.
FolderEvent folderEvent = (FolderEvent)notification;
Console.WriteLine("\nFolderId: " + folderEvent.FolderId.UniqueId);
}
}
}
static void OnError(object sender, SubscriptionErrorEventArgs args)
{
// Handle error conditions.
Exception e = args.Exception;
Console.WriteLine("\n----MAIL BOX Error ---" + e.Message + "-------------");
}
}
}
For more details refer to Exchange Server 2010 Documentation
This is a sample function to send an email using Gmail
public void sendEmail(String from, ArrayList<String> to, String subject,
String content, boolean contentIsHtml) throws EmailException
{
try
{
Properties props = new Properties();
props.put("mail.transport.protocol", EmailConfig.getGmailTransportProtocol());
props.put("mail.smtp.host", EmailConfig.getGmailSMTPHost());
props.put("mail.smtp.socketFactory.port", EmailConfig.getGmailSMTPPort());
props.put("mail.smtp.socketFactory.class", EmailConfig.getSocketFactoryClass());
props.put("mail.smtp.auth", EmailConfig.getGmailAuthRequired());
props.put("mail.smtp.port", EmailConfig.getGmailSMTPPort());
SMTPAuthenticator authenticator = new SMTPAuthenticator();
Session session = Session.getDefaultInstance(props, authenticator);
//session.setDebug(true);
Transport transport = session.getTransport();
MimeMessage message = new MimeMessage(session);
message.setSubject(subject);
message.setSender(EmailUtil.getInternetAddress(
EmailConfig.getGmailUsername(), "jatin Shah"));
message.setRecipients(
RecipientType.TO,
EmailUtil.getInternetAddresses(to));
if(contentIsHtml)
message.setContent(content, "text/html");
else
message.setContent(content, "text/plain");
transport.connect();
transport.sendMessage(message, message.getRecipients(Message.RecipientType.TO));
transport.close();
System.out.println("Email Sent!!");
}
catch(Exception e)
{
e.printStackTrace();
throw new EmailException(e);
}
}
This sends an email using MyGmail account
I am sending an email from gmail account to another in my test
However, when I receive an email it is fine ... however, the full name of the sender is now shown
Instead of "Jatin Shah" (my name) ... it shows bhatin.shah (My Username)
First, read this FAQ entry of common mistakes.
To fix your problem, use setFrom instead of setSender.
package twitter4j.examples.tweets;
import twitter4j.Status;
import twitter4j.Twitter;
import twitter4j.TwitterFactory;
import twitter4j.auth.AccessToken;
import twitter4j.conf.*;
import java.io.IOException;
public final class UpdateStatus {
public static void main(String[] args) throws IOException {
String testPost = "hello from otc";
String consumerKey = "key";
String consumerSecret = "secret";
String accessToken = "access";
String accessSecret = "access_secret";
ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setDebugEnabled(true)
.setOAuthConsumerKey(consumerKey)
.setOAuthConsumerSecret(consumerSecret)
.setOAuthAccessToken(accessToken)
.setOAuthAccessTokenSecret(accessSecret);
try {
TwitterFactory factory = new TwitterFactory();
Twitter twitter = factory.getInstance();
AccessToken accestoken = new AccessToken(accessToken, accessSecret);
twitter.setOAuthAccessToken(accestoken);
Status status = twitter.updateStatus(testPost);
System.out.println("it worked!");
if (status.getId() == 0) {
System.out
.println("Error occured while posting tweets to twitter");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
why do i keep getting this error:
401:Authentication credentials (http://dev.twitter.com/pages/auth) were missing or incorrect. Ensure that you have set valid conumer key/secret, access token/secret, and the system clock in in sync.
error - Could not authenticate with OAuth.
request - /1/statuses/update.json
Relevant discussions can be on the Internet at:
http://www.google.co.jp/search?q=e06d87a8 or
http://www.google.co.jp/search?q=5851cbdb
TwitterException{exceptionCode=[e06d87a8-5851cbdb], statusCode=401, retryAfter=-1, rateLimitStatus=null, featureSpecificRateLimitStatus=null, version=2.2.3}
at twitter4j.internal.http.HttpClientImpl.request(HttpClientImpl.java:189)
at twitter4j.internal.http.HttpClientWrapper.request(HttpClientWrapper.java:65)
at twitter4j.internal.http.HttpClientWrapper.post(HttpClientWrapper.java:102)
at twitter4j.TwitterImpl.post(TwitterImpl.java:1871)
at twitter4j.TwitterImpl.updateStatus(TwitterImpl.java:459)
at twitter4j.examples.tweets.UpdateStatus.main(UpdateStatus.java:35)
i have set the credentials in the file already, have i not?
i figured it out heres a working code:
package twitter4j.examples.tweets;
import twitter4j.Status;
import twitter4j.Twitter;
import twitter4j.TwitterFactory;
import twitter4j.auth.AccessToken;
import java.io.IOException;
public final class UpdateStatus {
public static void main(String[] args) throws IOException {
String tweet = "your first tweet via java";
String accessToken = "your access token";
String accessSecret = "your access token secret";
try {
TwitterFactory factory = new TwitterFactory();
Twitter twitter = factory.getInstance();
AccessToken accestoken = new AccessToken(accessToken, accessSecret);
twitter.setOAuthAccessToken(accestoken);
Status status = twitter.updateStatus(tweet);
System.out.println("it worked!");
if (status.getId() == 0) {
System.out
.println("Error occured while posting tweets to twitter");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
note: for this to work you MUST create an application on twitter
you must have a twitter4j.properties file which contain the following
debug set to true
oauth.consumerKey
oauth.consumerSecret
oauth.accessToken
oauth.accessTokenSecret
all the keys and tokens are from the twitter application
make sure your application access level all say "read and write"