Encoding a line break for Twilio SMS using C#? - c#

I'm using WebApi 2.2 to ramp up on the Twilio API. I have the Twilio C# libraries installed.
I'm using a form to capture a string in my web app, and I send that down to webAPI. I'm wondering how I can leverage the C# libraries to send a message with line breaks.
The example code shows the following:
var msg = twilio.SendMessage("+15084043345", "+15084043345", "Can you believe it's this easy to send an SMS?!");
However, I'm not sure how to include a line break in this message. Should I be inserting anything into this string clientside to represent a linebreak? Any guidance would be awesome.

Twilio Evangelist here.
This is actually super simple:
var msg = twilio.SendMessage("+15084043345", "+15084043345", "Hello.\nCan you believe it's this easy to send an SMS?!");
Will result in:
Hello.
Can you believe it's this easy to send an SMS?!
Just like printing strings to the console, \n, \r\n, and \r can be used to insert a new line. I can't say definitively what is best to use across all handsets, but I have found \n to be pretty reliable. (I can say all three of these work on my iOS 8 device perfectly...)

If you want to show new line in sms like
Account Name : suraj
Age : 24
then here is a code for asp.net VB
Dim value As String = "Account Name :" & "suraj" & vbCrLf & "Age :" & " 24"
it will show new line in SMS not in web page

Related

Discord.Net -- How to make Bot Ping users with "#"

I'm working on coding a bot that will retrieve an image based on search parameters. When the bot returns the message after the command, I want the bot to alert the user that sent the command with a ping. (the notification of a message using the "#" symbol in discord).
Here's what I've got so far:
await Context.Channel.SendMessageAsync("#" + Context.Message.Author + "\n" + imageNode.Attributes["src"].Value);
I'm able to correctly grab the author of the command and it sends as it should--
Output in channel:
However, it's not actually sent as a tag, just plain text.
Is there a way to actually ding the user with a notification?
Yes, using User.Mention.
await Context.Channel.SendMessageAsync(Context.Message.Author.Mention + "\n" + imageNode.Attributes["src"].Value);
You can also just put their id in between <#>. For example, "Hello <#1234>"
One of my favorite things about C# 6 is that you can also use String Interpolation. Very useful in Discord.Net!
var id = Context.Message.Author.Id;
await Context.Channel.SendMessageAsync($"<#{id}> \n {imageNode.Attributes["src"].Value}";

C# Imap Sort command with special characters

I'm working on a problem with imap sort extention:
My command is the following:
var query = "icône";
//byte[] bytes = Encoding.Default.GetBytes(query);
//query = Encoding.UTF8.GetString(bytes);
var command = "SORT (REVERSE ARRIVAL) UTF-8 " + "{" + query.Length + "}";
var imapAnswerString = client.Command(command);
imapAnswerString = client.Command(query);
I get the following error:
BAD Error in IMAP command SORT: 8bit data in atom
I found this:
C# Imap search command with special characters like á,é
But I don't see how to prepare my code to send this request sucessfully.
If you want to stick with MailSystem.NET, the answer that arnt gave is correct.
However, as I point out here (and below for convenience), MailSystem.NET has a lot of architectural design problems that make it unusable.
If you use an alternative open source library, like MailKit, you'd accomplish this search query far more easily:
var query = SearchQuery.BodyContains ("icône");
var orderBy = new OrderBy[] { OrderBy.ReverseArrival };
var results = folder.Search (query, orderBy);
Hope that helps.
Architectural problems in MailSystem.NET include:
MailSystem.NET does not properly handle literal tokens - either sending them (for anything other than APPEND) or for receiving them (for anything other than the actual message data in a FETCH request). What none of the authors seem to have noticed is that a server may choose to use literals for any string response.
What does this mean?
It means that the server may choose to respond to a LIST command using a literal for the mailbox name.
It means that any field in a BODYSTRUCTURE may be a literal and does not have to be a quoted-string like they all assume.
(and more...)
MailSystem.NET, for example, also does not properly encode or quote mailbox names:
Example from MailSystem.NET:
public string RenameMailbox(string oldMailboxName, string newMailboxName)
{
string response = this.Command("rename \"" + oldMailboxName + "\" \"" + newMailboxName + "\"");
return response;
}
This deserves a Jean-Luc Picard and Will Riker face-palm. This code just blindly puts double-quotes around the mailbox name. This is wrong for at least 2 reasons:
What if the mailbox name has any double quotes or backslashes? It needs to escape them with \'s.
What if the mailboxName has non-ASCII characters or an &? It needs to encode the name using a modified version of the UTF-7 character encoding.
Most (all?) of the .NET IMAP clients I could find read the entire response from the server into 1 big string and then try and parse the response with some combination of regex, IndexOf(), and Substring(). What makes things worse is that most of them were also written by developers that don't know the difference between unicode character counts (i.e. string.Length) and octets (i.e. byte counts), so when they try to parse a response to a FETCH request for a message, they do this after parsing the "{}" value in the first line of the response:
int startIndex = response.IndexOf ("}") + 3;
int endIndex = startIndex + octets;
string msg = response.Substring (startIndex, endIndex - startIndex);
The MailSystem.NET developers obviously got bug reports about this not working for international mails, so their "fix" was to do this:
public string Body(int messageOrdinal)
{
this.ParentMailbox.SourceClient.SelectMailbox(this.ParentMailbox.Name);
string response = this.ParentMailbox.SourceClient.Command("fetch "+messageOrdinal.ToString()+" body", getFetchOptions());
return response.Substring(response.IndexOf("}")+3,response.LastIndexOf(" UID")-response.IndexOf("}")-7);
}
Essentially, they assume that the UID key/value pair will come after the message and use that as a hack-around for their incompetence. Unfortunately, adding more incompetence to existing incompetence only multiplies the incompetence, it doesn't actually fix it.
The IMAP specification specifically states that the order of the results can vary and that they may not even be in the same untagged response.
Not only that, but their FETCH request doesn't even request the UID value from the server, so it's up to the server whether to return it or not!
TL;DR
How to Evaluate an IMAP Client Library
The first thing you should do when evaluating an IMAP client library implementation is to see how they parse responses. If they don't use an actual tokenizer, you can tell right off the bat that the library was written by people who have no clue what they are doing. That is the most sure-fire warning sign to STAY AWAY.
Does the library handle untagged ("*") responses in a central place (such as their command pipeline)? Or does it do something retarded like try and parse it in every single method that sends a command (e.g. ImapClient.SelectFolder(), ImapClient.FetchMessage(), etc)? If the library doesn't handle it in a central location that can properly deal with these untagged responses and update state (and notify you of important things like EXPUNGE's), STAY AWAY.
If the library reads the entire response (or even just the "message") into a System.String, STAY AWAY.
You're almost there. Your final command should be something like
x sort (reverse arrival) utf-8 subject {6+}
icône
ie. you're just missing a search term to describe where the IMAP server should search for icône and sort the results. There are many other search keys, not just subject. See RFC3501 page 49 and following pages.
Edit: The + is needed after the 6 in order to send that as a single command (but requires that the server support the LITERAL+ extension). If the server doesn't support LITERAL+, then you will need to break up your command into multiple segments, like so:
C: a001 SORT (REVERSE ARRIVAL) UTF-8 SUBJECT {6}
S: + ok, whenever you are ready...
C: icône
S: ... <response goes here>
Thanks all for your answer.
Basically the way MailSystem.net sends requests (Command method) is the crux of this problem, and some others actually.
The command method should be corrected as follows:
First, when sending the request to imap, the following code works better than the original one:
//Convert stuff to have to right encoding in a char array
var myCommand = stamp + ((stamp.Length > 0) ? " " : "") + command + "\r\n";
var bytesUtf8 = Encoding.UTF8.GetBytes(myCommand);
var commandCharArray = Encoding.UTF8.GetString(bytesUtf8).ToCharArray();
#if !PocketPC
if (this._sslStream != null)
{
this._sslStream.Write(System.Text.Encoding.UTF8.GetBytes(commandCharArray));
}
else
{
base.GetStream().Write(System.Text.Encoding.UTF8.GetBytes(commandCharArray), 0, commandCharArray.Length);
}
#endif
#if PocketPC
base.GetStream().Write(System.Text.Encoding.UTF8.GetBytes(commandCharArray), 0, commandCharArray.Length);
#endif
Then, in the same method, to avoid some deadlock or wrong exceptions, improve the validity tests as follows:
if (temp.StartsWith(stamp) || temp.ToLower().StartsWith("* " + command.Split(' ')[0].ToLower()) || (temp.StartsWith("+ ") && options.IsPlusCmdAllowed) || temp.Contains("BAD Error in IMAP command"))
{
lastline = temp;
break;
}
Finally, update the return if as follows:
if (lastline.StartsWith(stamp + " OK") || temp.ToLower().StartsWith("* " + command.Split(' ')[0].ToLower()) && !options.IsSecondCallCommand || temp.ToLower().StartsWith("* ") && options.IsSecondCallCommand && !temp.Contains("BAD") || temp.StartsWith("+ "))
return bufferString;
With this change, all commands work fine, also double call commands. There are less side effects than with the original code.
This resolved most of my problems.

Sending newlines inside string through TCPclient

Trying to send a string containing a number of newline characters between words using TCPclient and C# where the newline characters needs to stay intact...
Working c++ example is here:
TCPClient->IOHandler->DefStringEncoding = enUTF8;
TCPClient->IOHandler->WriteLn("write text");
TCPClient->IOHandler->WriteLn("Test\n\n\nTest");
With this code the string shows up in the servers textfield the way I want: Test\n\n\nTest
But when trying c#:
clientStreamWriter.WriteLine("write text");
clientStreamWriter.WriteLine("Test\n\n\nTest");
This string shows up in the server textfield as: Test
Then the server returns a unknown command response... Seems as the StreamWriter breaks the string at the newline character and sends the rest as a new string and the server expects a new command.
How can I prevent this from happening? I have no idea what the server code is and writing in c++ is not an option for me :)
The problem is with your server protocol; you'll need to change the server to fix it. You need message framing.
Or you could just split your string up and send it as seperate calls ...
assuming your client is smart enough to figure out / your protocol defines an end messsage in some way?
TCPClient->IOHandler->DefStringEncoding = enUTF8;
TCPClient->IOHandler->WriteLn("write text");
TCPClient->IOHandler->WriteLn("[[begin]]");
TCPClient->IOHandler->WriteLn("Test");
TCPClient->IOHandler->WriteLn("");
TCPClient->IOHandler->WriteLn("");
TCPClient->IOHandler->WriteLn("");
TCPClient->IOHandler->WriteLn("Test");
TCPClient->IOHandler->WriteLn("[[end]]");

Getting attachments from a mail account with .NET

I'd like a free library for .NET to get attachments from an account (such as gMail, or others) via imap4 (not necessarely), and save them in a folder.
Ideally it would allow me to get a list of them, and download only some given ones (filtering by extension, name, and/or size) and be free.
I've already done this with a trial version of EAGetMail, but for the purpose of what i'm trying to attempt buying the unlimited version of this library isn't quite suitable (i didn't know that this functionality itself was one among the ones with limited time).
---[edit - Higuchi]---
I'm using the following code:
Dim cl As New Pop3Client()
cl.UserName = "marcelo.f.ramires#gmail.com"
cl.Password = "mypassword"
cl.ServerName = "pop.gmail.com"
cl.AuthenticateMode = Pop3AuthenticateMode.Pop
cl.Ssl = False
cl.Authenticate() //takes a while, but passes even if there's a wrong password
Dim mg As Pop3Message = cl.GetMessage(1) //gives me an exception: Message = "Pop3 connection is closed"
UPDATE: Setting the port to 995 gives me a "Response TimeOut" exception
As commented, I am having some issues while trying to connect and get the first e-mail. any help ?
Well, I know you specified IMAP4, but I figured I'd offer this anyway in case POP3 is an option, since it's been useful for me:
http://csharpmail.codeplex.com/
This library provides access to POP3 mail, which many e-mail services (including Gmail) do offer in addition to the newer IMAP.
The core class is Pop3Client, which provides access to POP3 functions such as ExecuteList, ExecuteTop, etc. I have used this for specifically what you are asking about -- scanning for and downloading attachments.
If you decide this is something you could use after all and need further guidance, let me know.
UPDATE: In response to your updated question, I have just a few preliminary suggestions:
Consider setting the Pop3Client.Port property to 995. I know this is what Gmail uses for POP3.
The Pop3Client.Authenticate method returns a bool value indicating whether or not authentication was successful. You can check this value after calling the method to know whether it will be possible to progress further.
UPDATE 2: I tried this at home with the following settings and it worked for me:
Using client As New Pop3Client
client.UserName = "username#gmail.com"
client.Password = "[insert password here]"
client.ServerName = "pop.gmail.com"
client.AuthenticateMode = Pop3AuthenticateMode.Pop
client.Ssl = True ' NOTICE: in your example code you have False here '
client.Port = 995
client.Authenticate()
Dim messageList = client.ExecuteList()
Console.WriteLine("# Messages: {0}", messageList.Count)
End Using
Try these settings and see if they work for you.
UPDATE 3: One more thing! Have you made sure to enable POP for your Gmail account? If not, you need to do that!
From your Gmail inbox, click "Settings" (top right).
From the Settings page, click the tab labeled "Forwarding and POP/IMAP."
In the POP Download section, select one of the radio buttons to enable POP mail.
Click "Save Changes" at the bottom.

Reading and parsing email from Gmail using C#, C++ or Python

I have to do a Windows application that from times to times access a Gmail account and checks if there is a new email. In case there is, it must read the email body and subject (a simple text email, without images or attachments).
Please, do not use paid libs, and in case of any other libs used, give the download path.
And I need the email body and subject only. So if the long and complex message that comes from Gmail could be parsed and only two strings containing the subject and the body, it would be perfect.
Finally, I only have to get the new messages arrived since the last execution. So the read messages could be marked as "read" and only the new ones (marked as "new") are considered.
The code can be written in Python or C++, but I prefer it in C#.
Related question:
Properly formatted example for Python iMAP email access?
This prints the subject and body of unseen messages, and marks those messages as seen.
import imaplib
import email
def extract_body(payload):
if isinstance(payload,str):
return payload
else:
return '\n'.join([extract_body(part.get_payload()) for part in payload])
conn = imaplib.IMAP4_SSL("imap.gmail.com", 993)
conn.login("user", "password")
conn.select()
typ, data = conn.search(None, 'UNSEEN')
try:
for num in data[0].split():
typ, msg_data = conn.fetch(num, '(RFC822)')
for response_part in msg_data:
if isinstance(response_part, tuple):
msg = email.message_from_string(response_part[1])
subject=msg['subject']
print(subject)
payload=msg.get_payload()
body=extract_body(payload)
print(body)
typ, response = conn.store(num, '+FLAGS', r'(\Seen)')
finally:
try:
conn.close()
except:
pass
conn.logout()
Much of the code above comes from Doug Hellmann's tutorial on imaplib.
Use one of the many C# IMAP libraries.
Note that there are some differences between Gmail-IMAP and IMAPA. For example, due to the fact that Gmail treats folders like labels, the code like the one below doesn't delete message if it's tagged with some other folder:
imap_instance.uid('store', uid, '+FLAGS', '\\Deleted')
imap_instance.expunge()
I know this is an old post but I wanted to add the following link to the Open Source ImapX 2 Library discussion: https://imapx.codeplex.com/ the developers seem to be keeping the project up to date. Great job to those all involved
Google has opened it's Gmail API for accessing your gmail account. You can check a quickstart sample with the basic functionalities at this link:
https://developers.google.com/gmail/api/quickstart/python
from imap_tools import MailBox, Q
# This prints the subject and body of unseen messages, and marks those messages as seen.
with MailBox('imap.mail.com').login('test#mail.com', 'password') as mailbox:
# *mark_seen param = True by default
print([(m.subject, m.html or m.text) for m in mailbox.fetch(Q(seen=False), mark_seen=True)])
imap_tools

Categories