How to check if an email is a draft, sent or received? (Openedge 11) - openedge

I'm trying to create a way to check whether a given email (either from Outlook itself or an MSG file) is a sent, received or a draft email. I got the bit to compare if it was sent or received somewhere else and that works fine but it's the part that determines if it's a draft or not that is the issue. Below is what I have currently.
L-EMAIL = Aspose.Email.Mapi.MapiMessage:FromFile(P-FILENAME).
L-EMAIL-FLAG = Integer(L-EMAIL:Properties[Aspose.Email.Mapi.MapiPropertyTag:PR_MESSAGE_FLAGS]:ToString()).
IF L-EMAIL-FLAG = 8 THEN
L-EMAIL-STATUS = "DRAFT".
ELSE
IF L-EMAIL:Properties[Aspose.Email.Mapi.MapiPropertyTag:PR_RECEIVED_BY_ENTRYID] = ? THEN
L-EMAIL-STATUS = "SENT".
ELSE
L-EMAIL-STATUS = "RECEIVED".
If there's no attachments to the emails, it works fine since the value of a draft email is always 8 but as soon as you add attachments, it gets all weird with the values so I can't get a range down (I've gotten values like 24 and 242613 while a sent email with an attachment has a value of 49). Anyone know a smarter way of telling if it's a draft or not?

I never had a good experience working with Outlook and Progress internally... what I've managed to accomplish on my project was to create a custom DLL with C# and integrated it on my system.
So, I have an char that triggers some procedures inside my DLL and sends and receives emails (saves as .msg), making my Progress code a lot more easier to manage.
In your case, you should try something like this:
Outlook MailItem: How to distinguish whether mail is incoming or outgoing?

Solution I found was to use a C# DLL to convert the email to an Outlook mail item using the interop:
public bool IsDraft(string path)
{
Outlook.Application oApp = (Outlook.Application)Marshal.GetActiveObject("Outlook.Application");
Outlook.MailItem email = oApp.Session.OpenSharedItem(path) as Outlook.MailItem;
bool isSent = email.Sent;
Marshal.ReleaseComObject(email);
email = null;
return !isSent;
}
I had to release the email object so that code further on wouldn't break.

The PidTagMessageFlags property value is a bitmask of flags. This means a bitwise operator must be applied to check a specific flag value.
IF L-EMAIL-FLAG = 8 THEN
Please replace above line with following line of code. Hope this helps you.
IF (L-EMAIL-FLAG AND 8) = 8 THEN
I work with Aspose as Developer Evangelist.

Related

Google reCAPTCHA response success: false, no error codes

UPDATE: Google has recently updated their error message with an additional error code possibility: "timeout-or-duplicate".
This new error code seems to cover 99% of our previously mentioned mysterious
cases.
We are still left wondering why we get that many validation requests that are either timeouts or duplicates. Determinining this with certainty is likely to be impossible, but now I am just hoping that someone else has experienced something like it.
Disclaimer: I cross posted this to Google Groups, so apologies for spamming the ether for the ones of you who frequent both sites.
I am currently working on a page as part of a ASP.Net MVC application with a form that uses reCAPTCHA validation. The page currently has many daily users.
In my server side validation** of a reCAPTCHA response, for a while now, I have seen the case of the reCAPTCHA response having its success property set to false, but with an accompanying empty error code array.
Most of the requests pass validation, but some keep exhibiting this pattern.
So after doing some research online, I explored the two possible scenarios I could think of:
The validation has timed out and is no longer valid.
The user has already been validated using the response value, so they are rejected the second time.
After collecting data for a while, I have found that all cases of "Success: false, error codes: []" have either had the validation be rather old (ranging from 5 minutes to 10 days(!)), or it has been a case of a re-used response value, or sometimes a combination of the two.
Even after implementing client side prevention of double-clicking my submit-form button, a lot of double submits still seem to get through to the server side Google reCAPTCHA validation logic.
My data tells me that 1.6% (28) of all requests (1760) have failed with at least one of the above scenarios being true ("timeout" or "double submission").
Meanwhile, not a single request of the 1760 has failed where the error code array was not empty.
I just have a hard time imagining a practical use case where a ChallengeTimeStamp gets issued, and then after 10 days validation is attempted, server side.
My question is:
What could be the reason for a non-negligible percentage of all Google reCAPTCHA server side validation attempts to be either very old or a case of double submission?
**By "server side validation" I mean logic that looks like this:
public bool IsVerifiedUser(string captchaResponse, string endUserIp)
{
string apiUrl = ConfigurationManager.AppSettings["Google_Captcha_API"];
string secret = ConfigurationManager.AppSettings["Google_Captcha_SecretKey"];
using (var client = new HttpClient())
{
var parameters = new Dictionary<string, string>
{
{ "secret", secret },
{ "response", captchaResponse },
{ "remoteip", endUserIp },
};
var content = new FormUrlEncodedContent(parameters);
var response = client.PostAsync(apiUrl, content).Result;
var responseContent = response.Content.ReadAsStringAsync().Result;
GoogleCaptchaResponse googleCaptchaResponse = JsonConvert.DeserializeObject<GoogleCaptchaResponse>(responseContent);
if (googleCaptchaResponse.Success)
{
_dal.LogGoogleRecaptchaResponse(endUserIp, captchaResponse);
return true;
}
else
{
//Actual code ommitted
//Try to determine the cause of failure
//Look at googleCaptchaResponse.ErrorCodes array (this has been empty in all of the 28 cases of "success: false")
//Measure time between googleCaptchaResponse.ChallengeTimeStamp (which is UTC) and DateTime.UtcNow
//Check reCAPTCHAresponse against local database of previously used reCAPTCHAresponses to detect cases of double submission
return false;
}
}
}
Thank you in advance to anyone who has a clue and can perhaps shed some light on the subject.
You will get timeout-or-duplicate problem if your captcha is validated twice.
Save logs in a file in append mode and check if you are validating a Captcha twice.
Here is an example
$verifyResponse = file_get_contents('https://www.google.com/recaptcha/api/siteverify?secret='.$secret.'&response='.$_POST['g-recaptcha-response'])
file_put_contents( "logfile", $verifyResponse, FILE_APPEND );
Now read the content of logfile created above and check if captcha is verified twice
This is an interesting question, but it's going to be impossible to answer with any sort of certainly. I can give an educated guess about what's occurring.
As far as the old submissions go, that could simply be users leaving the page open in the browser and coming back later to finally submit. You can handle this scenario in a few different ways:
Set a meta refresh for the page, such that it will update itself after a defined period of time, and hopefully either get a new ReCAPTCHA validation code or at least prompt the user to verify the CAPTCHA again. However, this is less than ideal as it increases requests to your server and will blow out any work the user has done on the form. It's also very brute-force: it will simply refresh after a certain amount of time, regardless of whether the user is currently actively using the page or not.
Use a JavaScript timer to notify the user about the page timing out and then refresh. This is like #1, but with much more finesse. You can pop a warning dialog telling the user that they've left the page sitting too long and it will soon need to be refreshed, giving them time to finish up if they're actively using it. You can also check for user activity via events like onmousemove. If the user's not moving the mouse, it's very likely they aren't on the page.
Handle it server-side, by catching this scenario. I actually prefer this method the most as it's the most fluid, and honestly the easiest to achieve. When you get back success: false with no error codes, simply send the user back to the page, as if they had made a validation error in the form. Provide a message telling them that their CAPTCHA validation expired and they need to verify again. Then, all they have to do is verify and resubmit.
The double-submit issue is a perennial one that plagues all web developers. User behavior studies have shown that the vast majority occur because users have been trained to double-click icons, and as a result, think they need to double-click submit buttons as well. Some of it is impatience if something doesn't happen immediately on click. Regardless, the best thing you can do is implement JavaScript that disables the button on click, preventing a second click.

Paypal Processing - Need to grab TransactionId, CorrelationId and TimeStamp

Current Project:
ASP.NET 4.5.2
MVC 5
PayPal API
I am using this example to build myself a PayPal transaction (and yes, my code is virtually identical), as I do not know of any other method that will return the three values in the title.
My main problem is that, the example I am utilizing is much more concise and compact than the one I used for a much older Web Forms application, and as such, I am unsure as to where or even how to grab the three values I need.
My initial thought was to do so right after the ACK, and indeed I was able to obtain the CorrelationId as well as the TimeStamp, but because this was prior to the user being carted off to PayPal’s site (sandbox in this case -- see the return new PayPalRedirect contained within the if), the TransactionId was blank. And in this example, PayPal explicitly redirects the user to a Success page without returning to the Action that sent the user to PayPal in the first place, and I am not seeing any GET values in the URL at all aside from the Token and the PayerId, much less ones that could provide me with the TransactionId.
Suggestions?
I have also looked at the following examples:
For ASP.NET Core, was unsure how to adapt to my current project particularly due to appsettings.json, but it looked quite well done. I really liked how the values were rolled up in lists.
For MVC 4, but I couldn’t find where ACK was being used to determine success or successwithwarning so I couldn’t hook into that.
I have also found the PayPal content to be like trying to drink from a fire hose at full blast -- not only was the content was hopelessly outdated (Web Forms code, FTW!) but there was also so many different examples it would have taken me days to determine which one was most appropriate to use.
Any assistance would be greatly appreciated.
Edit: my initial attempt at modifying the linked code has this portion:
values = Submit(values);
var ack = values["ACK"].ToLower();
if(ack == "success" || ack == "successwithwarning") {
using(_db = new ApplicationDbContext()) {
var updateOrder = await _db.Orders.FirstOrDefaultAsync(x => x.OrderId == order.OrderId);
if(updateOrder != null) {
updateOrder.OrderProcessed = false;
updateOrder.PayPalCorrelationId = values["CORRELATIONID"];
updateOrder.PayPalTransactionId = values["TRANSACTIONID"];
updateOrder.PayPalTimeStamp = values["TIMESTAMP"];
updateOrder.IPAddress = HttpContext.Current.Request.UserHostAddress;
_db.Entry(updateOrder).State = EntityState.Modified;
await _db.SaveChangesAsync();
}
}
return new PayPalRedirect {
Token = values["TOKEN"],
Url = $"https://{PayPalSettings.CgiDomain}/cgi-bin/webscr?cmd=_express-checkout&token={values["TOKEN"]}"
};
}
Everything within and including the using() is my added content. As I mentioned, the CorrelationId and the TimeStamp come through just fine, but I have yet to successfully obtain the TransactionId.
Edit 2:
More problems -- the transactions that are “successful” through the sandbox site (the ReturnUrl is getting called) aren’t reflecting properly on my Facilitator and Buyer accounts, even when I do payments straight from the buyer’s PayPal account (not using the Credit Card). I know I am supposed to see transactions in the Buyer’s account, either through the overall Dev account (Accounts -> Profile -> balance or Accounts -> Notifications) or through the Buyer’s account in the sandbox front end. And yet -- multiple transactions returning me to the ReturnUrl path, and yet no transactions in either.
Edit 3:
Okay, this is really, really weird. I have gone over all settings with a fine-toothed comb, and intentionally introduced errors to see where things should crap out. It turns out that the entire process goes swimmingly - except nothing shows up in my notifications and no amounts get moved between my different accounts (Facilitator and Buyer). It’s like all my transactions are going into /dev/null, yet the process is successful.
Edit 4: A hint!
In the sandbox, where Buyer accepts the transaction, there is a small note, “You will be able to review the transaction before completing it” or something like that -- suggesting that an additional page is not coming up and that the user is being uncerimoniously dumped back to the success page. Why the success page? No clue. But it’s happening.
It sounds like you are only doing the first part of the process.
Express Checkout consists of 3 API calls:
SetExpressCheckout
GetExpressCheckoutDetails
DoExpressCheckoutPayment
SEC generates a token, and then you redirect to PayPal where the user signs in and reviews the transactions before agreeing to pay.
They are then sent to the ReturnURL included in your SEC request, and this is where you'll call GECD in order to obtain all the buyer details that are now available since they signed in.
Using that data you can complete the final DECP request, which is what finalizes the procedure. No money is actually processed until this final call is completed successfully.

Telegram bot: How to mention user by its id (not its username)

I am creating a telegram bot and using sendMessage method to send the messages.
it is easy to mention user using #username, But how to mention user when they don't have username?
If using the telegram app/web, we can mentioned the user by #integer_id (name), and telegram app/web will convert it into clickable text. integer_id will be generated automatically when we select the user, after typing #.
another background:
I am trying to use forceReply and I want to target user, if they have username, I can easily target them, by mentioning them on the text on sendMessage method.
the bot I am creating is a "quiz" like bot. where each player need to take turn, and the bot is sending them the question, each msg from bot will target different player.
NOTE: I am not disabling the Privacy Mode, I don't want telegram bombing my server with msg I don't need. it was overloading my cheap nasty server. so, disabling it not an option.
I am open for other solution, where the bot can listen to selected player.
thanks.
UPDATE 21/10:
I've spoke to BotSupport for telegram, they said, for now Bots can't mention user without username.
so in my case, I still keep using forceReply, and also, gave a short msg to user which doesn't have username to set it up, so they can get the benefit from forceReply function.
According to official documentation it is possible to mention user by its numerical id with markup:
[inline mention of a user](tg://user?id=123456789)
According to this link :
it is possible to mention user by its numerical id with markup:
Markdown style
To use this mode, pass Markdown in the parse_mode field
when using sendMessage. Use the following syntax in your message:
[inline mention of a user](tg://user?id=123456789)
and you can also use HTML style :
HTML style
To use this mode, pass HTML in the parse_mode field when using sendMessage. The following tags are currently supported:
inline mention of a user
Try this:
#bot.message_handler(func=lambda message: True)
def echo_message(message):
cid = message.chat.id
message_text = message.text
user_id = message.from_user.id
user_name = message.from_user.first_name
mention = "["+user_name+"](tg://user?id="+str(user_id)+")"
bot_msg = f"Hi, {mention}"
if message_text.lower() == "hi":
bot.send_message(cid, bot_msg, parse_mode="Markdown")
For python-telegram-bot you can do the following:
user_id = update.message.from_user['id']
user_name = update.message.from_user['username']
mention = "["+user_name+"](tg://user?id="+str(user_id)+")"
response = f"Hi, {mention}"
context.bot.sendMessage(chat_id=update.message.chat_id,text=response,parse_mode="Markdown")
No, this restriction is related to Telegram's privacy policy and prevention of abuse.
It is possible to mention a user when sending messages (BOT API), but that is not what you need:
[inline mention of a user](tg://user?id=<user_id>)
Links tg://user?id= can be used to mention a user by their id without using a username. Please note:
These links will work only if they are used inside an inline link. For example, they will not work, when used in an inline keyboard button or in a message text.
These mentions are only guaranteed to work if the user has contacted the bot in the past, has sent a callback query to the bot via inline button or is a member in the group where he was mentioned.
https://core.telegram.org/bots/api#markdown-style
you need to link to the text: "tg://user?id=" and id
user_id = 123456XX # id of the user to mention
chat_id = 123456XXX # chat id where to mention
user_name = name of user
await bot.send_message(chat_id, f"<a href='tg://user?id={user_id}'>{user_name}</a>", "HTML")
here is an example:
#dp.message_handler()
async def mention(msg: types.Message):
await msg.answer(f"<a href='tg://user?id={msg.from_user.id}'>{msg.from_user.full_name}</a>", "HTML")
Bots are able to tag users by their ID, they just can't do this using the official HTTP Bot API.
Update: Not necessairy anymore, since Telegram added native Support for this.
If you log into your bots account with MadelineProto (PHP) you can use this 'link' to mention someone by it's ID with parse_mode set to markdown
[Daniil Gentili](mention:#danogentili)

Can't figure how phone number reveal works

I am pretty new to web-scraping and recently I am trying to automatically scrap phone number for pages like this. I am not supposed to use Selenium/headless url browser libraries and I am trying to find the a way to actually request the phone number using let say a web service or any other possible solution that could give me the phone number hopefully directly without having to go through the actual button press by selenium.
I totally understand that it may not even be possible to automatically reveal the phone number in one shut as it is meant not be accessible by nosy newbie web-scraper like me; but I still like to raise the question for my information to get detailed answer from an expert point of view.
If I search the "Reveal" button DOM element, it shows some tags which I have never seen before. I have two main questions which I believe could be helpful for newbies like me.
1) Given a set of unknown tags/attribues (ie. data-q and data-reveal in the blow button), how is one able to find out which scripts in the page are actually using them?
2) I googled the button element's tag like: data-q and data-reveal the only relevant I could find was this which for some reason I don't have access two even-if I use proxy.
Any clue particularly on the first question is much appreciate it.
Regards,
Below is the href-button code
Reveal
Ok, according to your demand there are several steps before you finally get a solution.
1st step : open your own browser and enter your target page(https://www.gumtree.com/p/vans/2015-ford-transit-custom-2.2tdci-290-l1-h1/1190345514)
2nd step : (Assume you are using Chrome as your favorite browser) Press Ctrl+Shift+I to open the console, and then select 'Network' tag in the console.
3rd step : Press the 'Reveal' button on that page, watch the console carefully, catch the http request which is sent immediately when you press the 'Reveal' button. You can see the request contains a long string of number in Query String Parameters, actually it is a timestamp.
4th step : Also you can see there is a part named 'Request Headers' in that http request, and you should copy the values of referer , user-agent , x-gumtree-token.
5th step : Try to construct your request (I am a fan of Python, So I am going to show you my example code in Python)
import time
import requests
import json
headers = {
'referer': 'please enter the value you just copied from that specific request',
'user-agent': 'please enter the value you just copied from that specific request',
'x-gumtree-token': 'please enter the value you just copied from that specific request'
}
url = 'https://www.gumtree.com/ajax/account/seller/reveal/number/1190345514?_='
current_time = time.time()
current_time = str(current_time)
current_time = current_time.split('.')[0] + current_time.split('.')[1] + '0'
url += current_time
response = requests.get(url=url,headers=headers)
response_result = json.loads(response.content)
phone_number = response_result['data']

Using caller id as twilio number in asp.net mvc

I've opened up a twilio trial account. I want to use my verified called ID number in my asp.net application instead of buying a new twilio number. But I don't know how to use it. Here are my codes,
public ActionResult SendSms()
{
string ACC_SID = ConfigurationManager.AppSettings["ACC_SID"];
string AUTH_TKN = ConfigurationManager.AppSettings["AUTH_TKN"];
TwilioRestClient client = new TwilioRestClient(ACC_SID, AUTH_TKN);
client.SendMessage("+8801941234567", "+8801671234567", string.Format("This is a test message!"));
return RedirectToAction("SmsView");
}
Nothing happened with it. How can I use my called ID to send sms?
I faced the same scenario while I was working on Twilio first time and at that time I used below steps to make things workable.
1) First of all I would suggest please add Try{} catch{} block in your SendSMS function. this will give you idea like SendMessage worked correctly.
2) In twilio we need to register mobile no before send SMS.
3) if your function works fine(no error occur) then in Twilio there is LOG tab where you can see weather your SMS send correctly or not.
Twilio developer evangelist here.
Jinesh's answer has some useful parts, like using a try/catch block to see errors.
However, the problem is that you are trying to send an SMS from your own number, not from a Twilio number. When sending SMS, you can only send from Twilio numbers. Please see this page for details on why.
You should have got a Twilio number when you signed up. Try using that number as the From number instead.

Resources