Quantcast
Channel: André Alves de Lima
Viewing all articles
Browse latest Browse all 210

Enviando SMS com C# e VB.NET

$
0
0

Eu não sei exatamente porque o tema “envio de SMS” foi um dos mais votados na minha última pesquisa de temas para próximos artigos. Não imaginava que essa fosse uma funcionalidade tão desejada assim nas aplicações de hoje em dia, mas aparentemente ela é. Atendendo aos seus pedidos, hoje vamos aprender a enviar SMS com C# e VB.NET utilizando basicamente duas estratégias. A primeira estratégia será através de um modem 3G conectado ao computador e a segunda estratégia será a utilização de serviços comerciais que possibilitam o envio de SMS automatizado.

Criando o “esqueleto” da aplicação

A aplicação que construiremos nesse artigo será muito simples. Nós teremos basicamente uma aplicação “Windows Forms” com um formulário contendo dois TextBoxes (um para definir o número do destinatário e outro para a mensagem) e um botão (para enviar a mensagem), bem como um ComboBox onde escolheremos o método de envio que deverá ser utilizado:

Chamei os TextBoxes de “tbTelefone” e “tbMensagem“. O botão recebeu o nome de “btEnviar” e o ComboBox recebeu o nome de “cbMetodo“. Dentro do ComboBox nós teremos os seguintes itens:

Observe que o primeiro método corresponderá ao envio pelo modem 3G, já os outros quatro métodos são serviços comerciais que possibilitam o envio automatizado de SMS.

É importante salientar que o tipo de projeto escolhido (“Windows Forms“) não tem nada a ver com questões de limitação das metodologias que serão apresentadas no artigo. Você pode utilizar exatamente a mesma implementação em outros tipos de projeto, como Console Application, WPF e ASP.NET.

O código do clique do botão “Enviar” terá um “switch case” que chamará o método correspondente dependendo da opção selecionada no ComboBox. Implementaremos cada um desses métodos nas próximas seções deste artigo:

        // C#
        private void btEnviar_Click(object sender, EventArgs e)
        {
            try
            {
                switch (cbMetodo.SelectedItem.ToString())
                {
                    case "Modem":
                        EnviarModem();
                        break;
                    case "Twilio":
                        EnviarTwilio();
                        break;
                    case "Ipipi":
                        EnviarIpipi();
                        break;
                    case "ViaNett":
                        EnviarViaNett();
                        break;
                    case "LocaSMS":
                        EnviarLocaSMS();
                        break;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
    ' VB.NET
    Private Sub BtEnviar_Click(sender As Object, e As EventArgs) Handles BtEnviar.Click
        Try
            Select Case CbMetodo.SelectedItem.ToString()
                Case "Modem"
                    EnviarModem()
                    Exit Select
                Case "Twilio"
                    EnviarTwilio()
                    Exit Select
                Case "Ipipi"
                    EnviarIpipi()
                    Exit Select
                Case "ViaNett"
                    EnviarViaNett()
                    Exit Select
                Case "LocaSMS"
                    EnviarLocaSMS()
                    Exit Select
            End Select
        Catch Ex As Exception
            MessageBox.Show(ex.Message, "Erro", MessageBoxButtons.OK, MessageBoxIcon.[Error])
        End Try
    End Sub

Opção 1: enviando SMS com modem 3G

A primeira opção que iremos implementar é o envio de SMS através de um modem 3G conectado ao computador. Essa é uma opção bem flexível porque você pode facilmente trocar o sim card do seu modem 3G para obter tarifas mais atrativas dependendo da região onde a aplicação será utilizada. Além disso, você não fica à mercê de uma empresa específica que fará o envio do SMS.

Depois de pesquisar um bocado, eu encontrei três links relacionados a esse tipo de implementação:

How to Send and Receive SMS using GSM Modem

Send SMS Using GSM Modem with C#

Send and Read SMS through a GSM Modem using AT Commands

Os dois primeiros utilizam bibliotecas terceiras que não estão disponíveis no NuGet. Elas são bibliotecas gratuitas, mas você tem que adicionar a referência no seu projeto “na mão“. Eu não queria ter que demonstrar isso no artigo, por isso fiquei feliz quando encontrei o terceiro artigo, que mostra como enviar SMS com modem 3G através de comandos diretos utilizando a classe SerialPort, que é basicamente o que a biblioteca dos outros dois artigos implementa por trás dos panos.

Depois de dar uma estudada no projeto apresentado no terceiro artigo, criei uma versão extremamente simplificada para podermos utilizar no nosso projeto de exemplo. Se você quiser mais opções de configuração, baixe o projeto do terceiro link e dê uma estudada na implementação dele.

Quando conectamos um modem 3G no nosso computador, os drivers do dispositivo farão com que esse modem fique acessível através de uma porta COM. Uma vez que você saiba a porta COM utilizada pelo seu dispositivo (no meu caso é sempre a porta COM5 – descobri isso através do gerenciador de dispositivos do Windows), basta utilizarmos um objeto do tipo SerialPort para executarmos comandos nesse modem 3G.

Para enviarmos uma mensagem SMS através de um modem 3G, precisamos executar 4 comandos. O primeiro comando inicia a comunicação com o modem. Em seguida, precisamos configurar o modo de envio para “texto“, já que estamos trabalhando com envio de SMS. Por fim, enviamos o número do destinatário e a mensagem, seguido de um caractere UTF32 de código 26 (que representa “fim de arquivo“). Cada um dos comandos (exceto o último) deverá ser seguido por um caractere de retorno de linha (carrier return – “\r“).

Veja como é que fica o código para enviarmos um SMS com C# e VB.NET utilizando o modem 3G conectado ao computador:

        // C#
        private void EnviarModem()
        {
            using (var port = new System.IO.Ports.SerialPort())
            {
                port.PortName = "COM5";
                port.Open();
                port.DtrEnable = true;
                port.RtsEnable = true;
                port.Write("AT\r"); // iniciando a comunicação
                port.Write("AT+CMGF=1\r"); // setando a comunicação para o modo texto
                port.Write(string.Format("AT+CMGS=\"{0}\"\r", tbTelefone.Text)); // setando o número do destinatário
                port.Write(tbMensagem.Text + char.ConvertFromUtf32(26)); // enviando a mensagem
            }
        }
    ' VB.NET
    Private Sub EnviarModem()
        Using Port = New System.IO.Ports.SerialPort()
            Port.PortName = "COM5"
            Port.Open()
            Port.DtrEnable = True
            Port.RtsEnable = True
            Port.Write("AT" & vbCr) ' iniciando a comunicação
            Port.Write("AT+CMGF=1" & vbCr) ' setando a comunicação para o modo texto
            Port.Write(String.Format("AT+CMGS=""{0}""" & vbCr, TbTelefone.Text)) ' setando o número do destinatário
            Port.Write(TbMensagem.Text + Char.ConvertFromUtf32(26)) ' enviando a mensagem
        End Using
    End Sub

E não é que funciona?

Opção 2: serviços comerciais para envio de SMS

Além do envio de SMS através de um modem 3G conectado ao computador, podemos utilizar também serviços comerciais que oferecem essa funcionalidade. Existem inúmeros serviços desse tipo, principalmente fora do Brasil. Depois de pesquisar um pouco, cheguei a uma lista de serviços que eu decidi testar para apresentar os resultados neste artigo.

Twilio

O Twilio é aparentemente o serviço mais completo no que diz respeito às funcionalidades de telefonia. Eles trabalham não somente com envio e recebimento de SMS, mas também MMS, mensagens de voz e outras funcionalidades que eu acabei não me aprofundando.

Uma parte chata do Twilio é o cadastro e configuração do número que será utilizado para enviar as mensagens. Depois de seguir todos os passos para criarmos uma conta trial (através deste link), cairemos no dashboard do Twilio, que terá duas informações importantíssimas que serão necessárias no desenvolvimento da aplicação: o SID e o token da nossa conta

Para enviarmos um SMS com o Twilio, primeiramente nós precisamos de um número de saída. Esse número de saída pode ser criado clicando no link “Programmable SMS“, depois em “Get Started” e, por fim, em “Get a number“:

Eu segui as instruções tentando criar um número aqui da Alemanha, porém, para números daqui eu teria que escanear um documento pessoal e anexar no sistema, de forma que eu conseguisse comprovar que era realmente eu quem estava criando aquele número (típica burocracia):

Obviamente, como eu só estava testando o serviço para escrever esse artigo, eu não queria anexar documento pessoal nenhum no sistema deles, então, resolvi tentar com um número brasileiro. Porém, números de saída brasileiros não têm suporte a SMS no Twilio:

Por fim, consegui criar um número americano, que obviamente tem suporte ao envio de SMS:

Uma vez criado o número de saída, anote essa informação, além do SID e token da conta que você encontra no dashboard principal do Twilio. Precisaremos desses três dados para implementarmos o envio de SMS com o Twilio.

Primeiramente, nós precisamos adicionar uma referência à biblioteca do Twilio via NuGet:

Feito isso, em algum lugar no código de inicialização da aplicação, nós temos que fazer a configuração inicial da biblioteca do Twilio, onde informaremos o SID e token da nossa conta. Você poderia fazer isso no arquivo “Program.cs“, antes de chamar o formulário principal. Porém, como essa aplicação de exemplo só tem um formulário, eu resolvi fazer essa inicialização do Twilio no construtor do formulário (ou no evento “Load” do formulário no VB.NET):

        // C#
        public Form1()
        {
            InitializeComponent();
            Twilio.TwilioClient.Init("SID", "TOKEN");
        }
    ' VB.NET
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Twilio.TwilioClient.Init("SID", "TOKEN")
    End Sub

Com as informações de autenticação configuradas, nós podemos enviar um SMS com o Twilio através do método “MessageResource.Create“. Veja só que fácil:

        // C#
        private void EnviarTwilio()
        {
            var resultado = Twilio.Rest.Api.V2010.Account.MessageResource.Create(
                to: new Twilio.Types.PhoneNumber(tbTelefone.Text),
                from: new Twilio.Types.PhoneNumber("SEU_NUMERO_TWILIO"),
                body: tbMensagem.Text);
        }
    ' VB.NET
    Private Sub EnviarTwilio()
        Dim Resultado = Twilio.Rest.Api.V2010.Account.MessageResource.Create(
            [to]:=New Twilio.Types.PhoneNumber(TbTelefone.Text),
            from:=New Twilio.Types.PhoneNumber("SEU_NUMERO_TWILIO"),
            body:=TbMensagem.Text)
    End Sub

Vamos testar para ver se funciona?

Observe que o número do remetente será o seu número do Twilio (que eu ocultei o meu por questões de segurança) e, no período trial, a mensagem original será precedida por uma mensagem indicando o trial. Além disso, você só conseguirá enviar mensagens no período de trial para números que estiverem confirmados na sua lista de telefones.

Se dermos uma olhada na seção de gastos da nossa conta, veremos que esse SMS de teste custou $0.085 dos créditos gratuitos que recebemos ao criar a conta trial. O valor final das mensagens varia de acordo com o país dos números remetente e destinatário. Você encontra todos os detalhes de preço por mensagem para cada país na página de preços do Twilio.

ViaNett

O próximo serviço que eu testei foi a ViaNett. Ao fazermos o cadastro da conta trial (a partir deste link), recebemos 5 mensagens para testarmos o serviço. Ao contrário do Twilio, o cadastro de uma conta trial na ViaNett é muito simples. Uma vez confirmado o e-mail, você receberá o usuário e senha na sua caixa de entrada. Com essa informação em mãos, nós conseguimos partir para a implementação do nosso código.

No caso da ViaNett, a utilização do serviço se dá a partir de um web service SOAP. Ou seja, nós temos que adicionar uma referência de serviço no nosso projeto apontando para a seguinte URL:

http://smsc.vianett.no/v3/cpa/cpawebservice.asmx

Dê o nome de “ViaNett” para a nova referência de serviço:

Com a referência criada, nós conseguimos instanciar um novo cliente da ViaNett. Através dessa instância, nós mandaremos o nosso SMS com o método “SendSMS_Simple1“:

        // C#
        private void EnviarViaNett()
        {
            using (var vianett = new ViaNett.CPAWebServiceSoapClient())
            {
                var resultado = vianett.SendSMS_Simple1(
                    "USER", "PWD",
                    Convert.ToInt64(tbTelefone.Text.Replace("+", string.Empty)),
                    tbMensagem.Text);
            }
        }
    ' VB.NET
    Private Sub EnviarViaNett()
        Using ViaNettClient = New ViaNett.CPAWebServiceSoapClient()
            Dim Resultado = ViaNettClient.SendSMS_Simple1("USER", "PWD", Convert.ToInt64(TbTelefone.Text.Replace("+", String.Empty)), TbMensagem.Text)
        End Using
    End Sub

Observe que o código é muito simples. O método “SendSMS_Simple1” recebe o nome do usuário, senha, número de telefone do destinatário (em formato numérico, sem o “+“) e a mensagem. Porém, ao tentarmos enviar uma mensagem com esse código, receberemos o seguinte erro:

Esse erro acontece porque a referência de serviço tem dois bindings no arquivo “app.config“. Um utiliza a versão 1.1 do protocolo SOAP e o outro utiliza a versão 1.2:

Vamos utilizar a versão mais nova indicando o nome do endpoint (“CPAWebServiceSoap12“) na hora de criarmos a instância do cliente:

// C#
using (var vianett = new ViaNett.CPAWebServiceSoapClient("CPAWebServiceSoap12"))
' VB.NET
Using ViaNettClient = New ViaNett.CPAWebServiceSoapClient("CPAWebServiceSoap12")

Uma vez realizada essa alteração, teste novamente a aplicação e veja que o SMS também será enviado corretamente através do serviço da ViaNett:

No caso da conta trial da ViaNett, nós não teremos nenhuma alteração na mensagem. Porém, o remetente será identificado como “DemoSMS“.

Ipipi

O Ipipi é outro serviço bem famoso que teoricamente tem a opção de criarmos uma conta trial (através deste link), mas eu não obtive resposta até o momento do fechamento da escrita deste artigo. Porém, vamos fazer de conta que nós temos um usuário e senha em mãos para esse serviço. Como é que nós fazemos para enviar um SMS com C# e VB.NET através dele? Simples! Da mesma maneira que fizemos com o ViaNett, nós também temos web services SOAP para envio de mensagens com o Ipipi.

Nesse caso, precisaremos de duas referências de serviço. Uma para conseguirmos um token através do usuário e senha (ou seja, o serviço de autenticação), cuja URL é a seguinte:

http://api.upsidewireless.com/soap/Authentication.asmx

O outro serviço é o que faz o envio da mensagem em si. A URL para esse segundo serviço é a seguinte:

http://api.upsidewireless.com/soap/SMS.asmx

Daremos o nome de “IpipiAuth” e “Ipipi” para as referências de serviço que serão criadas:

Com essas referências adicionadas, o código para enviarmos um SMS com o Ipipi seria o seguinte:

        // C#
        private void EnviarIpipi()
        {
            using (var ipipiAuth = new IpipiAuth.AuthenticationSoapClient())
            using (var ipipi = new Ipipi.SMSSoapClient())
            {
                var authInfo = ipipiAuth.GetParameters("user", "pwd");
                var resultado = ipipi.Send_Plain(authInfo.Token, authInfo.Signature, tbTelefone.Text, tbMensagem.Text, Ipipi.SmsEncoding.Seven);
            }
        }
    ' VB.NET
    Private Sub EnviarIpipi()
        Using IpipiAuthClient = New IpipiAuth.AuthenticationSoapClient()
            Using IpipiClient = New Ipipi.SMSSoapClient()
                Dim AuthInfo = IpipiAuthClient.GetParameters("user", "pwd")
                Dim Resultado = IpipiClient.Send_Plain(AuthInfo.Token, AuthInfo.Signature, TbTelefone.Text, TbMensagem.Text, Ipipi.SmsEncoding.Seven)
            End Using
        End Using
    End Sub

Os serviços do Ipipi também estão disponíveis tanto em SOAP 1.1 quanto em 1.2, portanto, se executarmos a aplicação sem especificarmos um endpoint, receberemos um erro:

Tentei utilizar a versão 1.2 (como fizemos com o ViaNett), porém, só recebi erros estranhos:

Dessa forma, resolvi utilizar os endpoints com a versão 1.1 do SOAP (“AuthenticationSoap” e “SMSSoap“), que retornou erros que faziam mais sentido, uma vez que eu não tenho credenciais válidas para esse serviço:

            // C#
            using (var ipipiAuth = new IpipiAuth.AuthenticationSoapClient("AuthenticationSoap"))
            using (var ipipi = new Ipipi.SMSSoapClient("SMSSoap"))
        ' VB.NET
        Using IpipiAuthClient = New IpipiAuth.AuthenticationSoapClient("AuthenticationSoap")
            Using IpipiClient = New Ipipi.SMSSoapClient("SMSSoap")

Imagino que se tivéssemos as credenciais válidas, o serviço funcionaria corretamente. Se alguém conseguir testar o código com credenciais válidas, por favor, avisa nos comentários se funcionou direitinho.

LocaSMS

Até agora eu só mostrei serviços internacionais para envio de SMS. Será que não existe nenhum serviço brasileiro que implemente esse tipo de funcionalidade?

Eu encontrei alguns, mas o único que fornecia uma conta trial era o LocaSMS. Entretanto, o site de cadastro só aceita números do Brasil. Tentei entrar em contato com a empresa para ver se eu não conseguia uma conta trial mesmo sem um número do Brasil, mas a resposta não foi nada animadora:

De qualquer forma, resolvi mesmo assim implementar o código que serviria para enviarmos SMS com o LocaSMS. Caso você consiga uma conta trial para testar, avisa depois nos comentários se o código funcionou ou não.

O serviço da LocaSMS funciona também baseado em web service SOAP. Nesse caso, temos que adicionar uma referência de serviço para a seguinte URL:

http://54.173.24.177/painel/ServiceSms.asmx

Uma vez adicionada a referência, conseguimos enviar a mensagem através do método “SendSMS“:

        // C#
        private void EnviarLocaSMS()
        {
            using (var locasms = new LocaSMS.ServiceSMSSoapClient())
            {
                var resultado = locasms.SendSMS("USER", "PWD",
                    new LocaSMS.rSMS()
                    {
                        Destinations = new [] 
                        {
                            new LocaSMS.Destination()
                            {
                                Number = tbTelefone.Text
                            }
                        },
                        Msg = tbMensagem.Text
                    });
            }
        }
    ' VB.NET
    Private Sub EnviarLocaSMS()
        Using locasms = New LocaSMS.ServiceSMSSoapClient()
            Dim resultado = locasms.SendSMS(
                "USER", "PWD",
                New LocaSMS.rSMS() With
                {
                    .Destinations =
                    {
                        New LocaSMS.Destination() With
                        {
                            .Number = TbTelefone.Text
                        }
                    },
                    .Msg = TbMensagem.Text
                })
        End Using
    End Sub

Obviamente, como eu não tenho credenciais válidas, eu recebi um erro de “falha de login” ao tentar enviar uma mensagem:

Outros serviços não testados

Neste artigo eu só mostrei serviços que tinham a possibilidade de criação de contas trial. Nas minhas pesquisas eu acabei me deparando com outros dois serviços brasileiros que não disponibilizavam a criação de contas para testes. Caso você queira pagar para testá-los, aqui vai o link para eles:

Mais Resultado (tutorial aqui)
Zenvia

Baixe o projeto de exemplo

Para baixar o projeto de exemplo desse artigo, assine a minha newsletter. Ao fazer isso, além de ter acesso ao projeto, você receberá um e-mail toda semana sobre o artigo publicado e ficará sabendo também em primeira mão sobre o artigo da próxima semana, além de receber dicas “bônus” que eu só compartilho por e-mail. Inscreva-se utilizando o formulário no final do artigo.

Concluindo

Como vimos no artigo de hoje, o envio de SMS com C# e VB.NET pode ser implementado basicamente de duas maneiras: ou utilizamos um modem 3G conectado ao computador, ou utilizamos serviços comerciais que implementem esse tipo de funcionalidade.

O projeto de exemplo implementado mostra primeiramente o envio de SMS através de um modem 3G, que pode ser feito tanto com bibliotecas externas quanto com comandos diretos via porta serial. Em seguida, aprendemos a enviar SMS através dos serviços Twilio, ViaNett, Ipipi e LocaSMS.

E você, já precisou enviar SMS na sua aplicação? Qual foi a estratégia que você utilizou? Se você contratou algum serviço, qual foi o que te proporcionou o melhor custo / benefício? Fico aguardando o resultado das suas experiências na caixa de comentários logo abaixo!

Até a próxima!

André Lima

Image by Pixabay used under Creative Commons
https://pixabay.com/en/sms-shortcuts-characters-symbol-1949054/

Newsletter do André Lima

* indicates required



Powered by MailChimp

The post Enviando SMS com C# e VB.NET appeared first on André Alves de Lima.


Viewing all articles
Browse latest Browse all 210