What makes Outlook/Exchange able to resolve a recipient or not? - python-3.x

I am trying to test whether staff are still employed in the organization.
The best approach I have found so far has to try send them an email.
So, using Outlook, Exchange and Python, I put the email addresses into a new email and try "Resolve" the recipient.
The behavior seems erratic. In most cases, this will produce a result, or "None".
for recipient in msg.Recipients:
try:
exchangeSays = recipient.AddressEntry.GetExchangeUser()
But now in my test case, I have a person john.smith#company.com and whilst the person does exist, is real and present, the entry will not resolve.
I've also noticed that sometimes email addresses resolve to "John Smith" and other recipients will resolve to "john.smith#company.com". I know it's resolved when the name is underlined in the email window.
What's going on here? Some questions:
Is this the best way of checking whether an person is still current?
Am i doing something wrong in my attempt to resolve the recipient?

Firstly, there is no need to create a message and send it - use Application.Session.CreateRecipient / Recipient.Resolve. If Recipient.Resolve returns true, check Recipient.AddressEntry.Type, If it is "EX", the name was resolved to a GAL user. You can however run into problems if you have a contact with the same name in your Contacts folder, and OOM does not allow to resolve against a particular container (e.g. GAL).
Note that Outlook Object Model cannot handle ambiguous names (e.g. "John Smith" will also match "John Smither") - it will simply return an error. If using Redemption is an option (I am its author), it exposes RDOSession.AddressBook.ResolveNameEx, which returns a list of matches.
On the Extended MAPI level (PR_ANR restriction) you can also resolve against a particular container, but OOM does not expose that functionality. In Redemption, you can use RDOSession.AddressBook.GAL.ResolveName/ResolveNameEx. Note however that in this case GAL provider won't resolve an SMTP address of a GAL user (go figure).
Outlook (UI only) also exposes search containers (PR_SEARCH in MAPI, you can see the one exposed by GAL if you click Ctrl + Shift + B to open the address book, then click Tools | Find). You can specify one or more fields to match (e.g. the whole display name or first and last names separately), but OOM, again, does not expose it. In Redemption, you can use RDOSession.Addressbook.GAL.Search:
set Session = CreateObject("Redemption.RDOSession")
Session.MAPIOBJECT = Application.Session.MAPIOBJECT
set AddrList = Session.Addressbook.GAL
set Search = AddrList.Search
Search.FirstName = "John"
Search.LastName = "Smith"
set AddressEntries = Search.GetResults
for each AddressEntry in AddressEntries
MsgBox AddressEntry.Name
next

Related

How to get information out of a list

So iam coding an discord bot and i want to get information out of an list that looks like this and this output is in "information = await guild.invites()"
[<Invite code='GZqCe8EF' guild=<Guild id=847546806937059338 name='Testing' shard_id=None chunked=False member_count=2> online=None members=None>, <Invite code='jQ2HeQfx' guild=<Guild id=847546806937059338 name='Testing' shard_id=None chunked=False member_count=2> online=None members=None>]
is it possible to get single things out like guild id or maybe 2 things like name and invite code and is it possible that u can output every line from it like the first invite code and the second one?
To output every invite code, you can use:
for invite in information:
print(invite.code) #invite.code returns the invite code, do whatever you want to do with it
# you can also add invite.guild.name to for the guild name etc
To output only from one invite:
print(information[0].code)
References
invite object with every possible paramenter after .
Yes it is possible, the invites() method returns list of Invite objects. To check what attributes does this object have look here.
to access an attribute you have to do this: InviteObject.{name of attribute}. Example:
for invite in information:
print(invite.guild.id)
It works the same for any discordpy object:
Look for the method that you are using in discordpy docs (In your case invites())
See what does it return (In your case list of Invite objects)
Search for the object (In your case Invite)

mail-listener2 - How to prevent function from reading wrong emails?

In my E2E test, I'am using the mail-listener2 to retrieve e-mails. It works fine, except one issue which is driving me crazy and just can't solve it... I have been searching and found different topics and issues regarding this library/package, but just couldn't really find the fix for that.
Following:
I use the function in more than one spec file (register, login, confirmation etc.), and this means that when retrieving the emails, I get from time to time the wrong one. In other words, the function reads the last e-mail in the Inbox which normally belongs to the first test.
Or sometimes the e-mail comes in the Inbox a little bit later that the function is reading them, so it reads the wrong one.
And as I do have an expectation in my it() function:
expect(email.subject).toEqual("subject for e-mail 1");
expect(email['headers'].to).toEqual( userEmail );
therefore the test breaks, and it get following error:
- Expected 'user registration' to equal 'user confirmation'.
- Failed: Cannot read property '1' of null
- Expected 'john.doe#foo.de' to equal 'jane.doe#foo.com'.
- Failed: Cannot read property '1' of null
Is there a way how to force the function reads just the specific email per subject and per user?
Yes, you can find this documented on node-imap (which is used by mail-listener2). Search for the paragraph/bullet on search within that package, here's a snippet to help you find it:
For criteria types that require arguments, use an array instead of just the string criteria type name (e.g. ['FROM', 'foo#bar.com']).
Below that, they list several other search criteria you can use, they have to/from for your user criteria, and subject for that one. So applying this to mail-listener2, you would use this in the searchFilter property:
mailListener = new MailListener({
...(other options),
searchFilter: [['FROM', 'automated#message.com'], ['SUBJECT', 'subject for e-mail 1']],
});
And if you need different search criteria for different tests, you can start a new mail-listener session for each test with the new searchFilter criteria.

Getting arguments/parameters values from api.ai

I'm now stuck on the problem of getting user input (what user says) in my index.js. For example, the user says: please tell me if {animals} can live between temperature {x} to {y}. I want to get exact value (in string) for what animals, x and y so that I can check if it is possible in my own server. I am wondering how to do that since the entities need to map to some exact key values if I annotate these three parameters to some entities category.
The methods for ApiAiApp is very limited: https://developers.google.com/actions/reference/nodejs/ApiAiApp
And from my perspective, none of the listed methods work in this case.
Please help!
Generally API.AI entities are for some set of known values, rather than listening for any value and validating in the webhook. First, I'd identify the kinds of entities you expect to validate against. For the temperatures (x and y), I'd use API.AI's system entities. Calling getArgument() for those parameters (as explained in the previous answer) should return the exact number value.
For the animals, I'd use API.AI's developer entities. You can upload them in the Entity console using JSON or CSV. You can enable API.AI's automated expansion to allow the user to speak animals which you don't support, and then getArgument() in webhook the webhook will return the new value recognized by API.AI. You can use this to validate and respond with an appropriate message. For each animal, you can also specify synonymous names and when any of these are spoken, and getArgument() will return the canonical entity value for that animal.
Extra tip, if you expect the user might speak more than one animal, make sure to check the Is List box in the parameter section of the API.AI intent.
If "animals", "x", and "y" are defined as parameters in your Intent in API.AI, then you can use the getArgument() method defined in ApiAiApp.
So the following should work:
function tempCheck( app ){
var animals = app.getArgument('animals');
var x = app.getArgument('x');
var y = app.getArgument('y');
// Check the range and then use something like app.tell() to give a response.
}

how to set the From field in an email

If I send an email from javascript, the email arrives at the destination address with the "From" field containing Anonymous%<Notes domain>#Company.com. I tried setting the fields "reply-to", "return-path", "From", "Sender", & "Principal" with what I want to appear in the "From" field.
But that often results in a bounce-back message because, I believe, it looks like the "From" address is being spoofed (which is actually is but for a good cause!). How can I modify the "From" field?
Here's the code using mail.box that's throwing the error:
function sendTestEmail(emailAddr){
print("enter sendTestEmail function");
print("emailAddr: "+emailAddr);
var mailboxdb:NotesDatabase = sessionAsSigner.getDatabase("<server>", "mail.box");
var emaildoc:NotesDocument = mailboxdb.createDocument();
emaildoc.replaceItemValue("form", "Memo");
emaildoc.replaceItemValue("sendTo", emailAddr);
emaildoc.replaceItemValue("subject", "testing email");
var body:NotesRichTextItem = emaildoc.createRichTextItem("body");
body.addNewLine();
body.appendText(" testing from javascript. ");
emaildoc.replaceItemValue("SMTPOriginator", "support#abc.com");
emaildoc.replaceItemValue("From","\"support#abc.com\" <support#abc.com>");
emaildoc.replaceItemValue("Principal","\"support#abc.com\" <support#abc.com>");
emaildoc.save(true, false);
print("exiting sendTestEmail function");
}
Copy the mail into server's database mail.box instead of sending it and set fields "Principal" and "From" to your alternative address.
Have a look at this answer too.
Set the SMTPOriginator field to the address it should be from. You might still need to populate the From, Sender and Principal as well.
Just another idea, because to me the mail.box idea should be a last resort approach.
If the mail is always to be sent by the same person (e.g. support), you could prepare a draft mail somewhere, for instance in your current database, and have a signed, scheduled agent (LS, Java) that sends the mails out.
I once used a special Extension Manager DLL to rename certain fields in outgoing mails, but I'm not going to propose that idea here...

Postfix and save to sent mail dir

I know this might be a dummy question or a question that comes from lack of knowledge, but I hope someone can still answer it. I did try to read a lot of Postfix documentation but found no answer to this. I don't even know if it's a Postfix specific or mail servers general question.
So I have a mail server, just a clean Postfix install that delivers email.
I've defined my users and connected with IMAP and SMTP using Thunderbird.
When I went to Thunderbird account settings and disabled "place a copy", Postfix did not put a copy of the sent message in the user .Sent folder.
However, I've also connected my Gmail, Hotmail or Yahoo mail and disabled the "place a copy" and still have a copy in the sent items folder.
So in this case there are 2 options:
Something is wrong with my Postfix configuration
Gmail, Hotmail, Yahoo put a copy in their sent folder as a different process on the server side
Just for the record, having searched around for a how to, and not finding one, I am posting it here:
The only (easy) way I've found to save sent emails is the sender_bcc solution (with it's attendant faults):
I am using postfix / dovecot / sieve / mysql virtual boxes
In /etc/postfix/main.cf add:
sender_bcc_maps = mysql:/etc/postfix/mysql-virtual-bcc-maps.cf
Create file /etc/postfix/mysql-virtual-bcc-maps.cf:
user = (database user)
password = (database password)
hosts = 127.0.0.1
dbname = (database databasename)
query = SELECT CONCAT_WS('',LEFT('%s', LOCATE('#', '%s')-1),'+sent#',SUBSTRING('%s', LOCATE('#', '%s')+1)) AS destination FROM virtual_users WHERE email='%s' AND autosent=1
You'll note in my query, I've added a (tinyint default 0) column to my virtual_users table so I can turn on/off this automatic sent items feature per user. This query takes the sender email address that postfix gives it, splits it in half at the # sign, and adds +sent to the address so it looks like sender+sent#domain.tld. This allows sieve in the next step to pick it up and drop it straight to sent items.
In /etc/dovecot/sieve/default.sieve add:
require ["fileinto", "mailbox", "envelope", "subaddress","imap4flags"];
if envelope :detail "to" "sent" {
addflag "\\Seen";
fileinto :create "Sent";
stop;
}
Also helpful to modify /etc/dovecot/conf.d/15-mailboxes.conf and add the auto subscribe to sent (and junk and trash and others for that matter):
mailbox Sent {
special_use = \Sent
auto = subscribe
}
I think that is all (I'm posting this the next day after doing it, so I think I got it all...)
Postfix itself does not place copies of sent messages anywhere; it receives messages and delivers them to the recipient. Saving sent messages to your own mailbox is the responsibility of your user agent (Thunderbird, in your case).
It's important to understand that Postfix (and other traditional Unix SMTP servers) don't have a "user" concept. Yes, if so configured it's possible to authenticate by supplying a username and a password, but Postfix doesn't use this identity information.
That said, it's not impossible to configure Postfix to do what you expected – sender_bcc_maps can be used to add a recipient to messages sent by you, and by adding yourself and using a filter in your mail client (or mail delivery agent like procmail) you can make sure that messages sent by you end up in the Sent folder.
I am running a Installation with automatic copies created by sender_bcc_maps. It's working fine. You have to check the sender, otherwise everyone can create sent mails in foreign sent folders.
I have solved it with two virtual domains. One for the user and one for the copy.
But there is a big problem with sender_bcc_maps. All bcc senders will be deleted in the sent copy. You cannot see anymore, who got a blind copy of this mail.
As 'ego2dot0' said above, you don't need any MDA filters (sieve etc.) to do this. It can be done using Postfix alone, although it took me a while to figure out how to do it.
You have to use sender_bcc_maps AND virtual_mailbox_maps features together.
You have to use a virtual domain dedicated specially for copies to self. If your actual domain is "your.domain.tld", you can use eg. subdomain "copyself.your.domain.tld". This subdomain does not have to actually exist, ie. be defined in the DNS (moreover, it's better that it isn't defined, so nobody accidentally sends mail to it from outside). It is a purely virtual domain that is recognized only by Postfix.
1) Configure sender_bcc_maps to BCC mail coming from user#your.domain.tld to user#copyself.your.domain.tld. You can do it for only a few selected users using a regular "hash" type map, or you can do it for all users at once using PCRE type map and regular expressions.
2) You have to define your virtual domain in virtual_mailbox_domains, like this:
virtual_mailbox_domains=copyself.your.domain.tld
3) Configure virtual_mailbox_maps so that the destination mailbox for address "user#copyself.your.domain.tld" is the actual "Sent" mailbox of the user "user". For example (assumed that you are using regular system users and Maildir format - like in my case) the path to "Sent" mailbox for user "user" will be "/home/user/Maildir/.Sent". So, you can define common part of the path as virtual_mailbox_base, eg.
virtual_mailbox_base=/home
and then in the virtual mailbox map enter the rest of the path like this:
user#copyself.your.domain.tld user/Maildir/.Sent/
(the trailing / is important to indicate the Maildir format).
Again, you can use PCRE type map to do this for all users.
4) To properly save mail to the mailbox, Postfix need to also know the proper UID and GID for the particular user, so you have to use virtual_uid_maps and virtual_gid_maps parameters as well. If you are using virtual users, it's probably enough to define "static" type maps specifying a single UID and GID of the system user that owns all the virtual mailboxes. However, if you are using system users like me, you need the proper actual UID and GID for any user. If you have only a few users, you can use a regular "hash" type map, with entries like these:
user#copyself.your.domain.tld 2001
or you can try to setup a pipeline with "pipemap" map type, that uses some PCRE maps and "unix:passwd.byname" map to obtain the UIDs and GIDs for all users (I haven't done this part, as my Postfix installation is compiled without "pipemap" type support).
So to sum everything up, use something like this:
In /etc/postfix/main.cf file, add the following lines:
sender_bcc_maps=hash:/etc/postfix/sender_bcc
virtual_mailbox_domains=copyself.your.domain.tld
virtual_mailbox_base=/home
virtual_mailbox_maps=hash:/etc/postfix/copyself
virtual_uid_maps=hash:/etc/postfix/copyself_uids
virtual_gid_maps=hash:/etc/postfix/copyself_gids
/etc/postfix/sender_bcc contains a bunch of lines like:
user#your.domain.tld user#copyself.your.domain.tld
/etc/postfix/copyself contains - respectively - lines like:
user#copyself.your.domain.tld user/Maildir/.Sent/
/etc/postfix/copyself_uids and /etc/postfix/copyself_gids contain - respectively - lines like:
user#copyself.your.domain.tld 2001
I have done this on my server and it works great for me.

Resources