Sende SMS med F#


lørdag 16. februar 2013 F# PSWinCom SMS XML

Jeg fortsetter å leke meg med F# – for å trene og lære. I dag vil jeg vise hvor enkelt det er å sende en SMS-melding fra F# ved å bruke PSWinCom's SMS API.

Alt jeg trenger å gjøre for å bruke API'et er å poste litt XML over http(s). XML'en skal se slik ut:

<?xml version="1.0"?>
<SESSION>
    <CLIENT>gatewaybruker</CLIENT>
    <PW>gatewaypassord</PW>
    <MSGLST>
        <MSG>
            <ID>1</ID>
            <SND>avsender</SND>
            <RCV>4799999999</RCV>
            <TEXT>meldingstekst</TEXT>
        </MSG>
    </MSGLST>
</SESSION>

Hjelpefunksjon for XML

Som sagt skal jeg bygge opp litt XML. Biblotekene i .NET-rammeverket har selvfølgelig klasser for å gjøre dette, men jeg holder det enkelt og lager i stedet en liten hjelpemetode jeg kaller tag:

let tag tag content = 
    sprintf "<%s>%s</%s>" tag content tag

tag tar to argumenter (hvor dene ene faktisk også heter tag), og returnerer en XML-streng. Denne funksjonen blir nesten som en liten mini-DSL for å bygge XML-dokumenter.

Formatere SMS XML'en

Jeg splitter opp konstruksjonen av XML-dokumentet i to funksjoner: En som formaterer en enkelt melding, og en som tar en liste med meldinger og formaterer det komplette dokumentet.

Her er den første:

let makeSms id sender receiver message =
    tag "MSG" (
        (tag "ID" id) + 
        (tag "SND" sender) + 
        (tag "RCV" receiver) +
        (tag "TEXT" message))

Og her følger den andre:

let makeRequest user password messages =
    """<?xml version="1.0"?>""" +
    tag "SESSION" (
        (tag "CLIENT" user) +
        (tag "PW" password) +
        (tag "MSGLST" <| String.concat "" messages))

Hvis jeg nå vil lage et dokument for å se at det ser riktig ut kan jeg for eksempel gjøre følgende:

let test = makeRequest 
            "tormar" "secretpassword" 
            [makeSms "1" "TMAN" "4799999999" 
                     "This is a test from FSharp"]

test inneholder nå XML'en.

Sende XML over HTTP

Å gjøre en HTTP POST fra .NET er også ganske enkelt. Til det bruker jeg en System.Net.WebClient. Da får jeg illustrert et par nyttige ting som hvordan man oppretter og bruker .NET-objekter i F#, og hvordan man sørger for at objekter som krever det blir disposet.

La meg først importere System.Net, og lage en variabel som holder på adressen til SMS gateway'en:

open System.Net
            
let gatewayUrl = "http://gw2-fro.pswin.com:81/"

Deretter lager jeg funksjonen postXml, som gjør det navnet sier at den gjør:

let postXml url xml =
    using (new WebClient()) ( fun client ->
        client.BaseAddress <- url
        client.Headers.Add("Content-Type", "application/xml")
        client.UploadString("/", xml) )

Legg merke til at using tar en anonym funksjon som siste argument. Denne får inn objektet (client) og gjør selve sendingen. using vil så sørge for at Dispose() blir kalt når den anonyme funksjonen har gjort sitt.

Send SMS'en

Jeg kan nå sende SMS'en og ta vare på XML-responsen ved å gjøre følgende kall:

let result = postXml gatewayUrl test

Og det var det hele! Så enkelt kan det være å sende SMS fra F#-kode.


comments powered by Disqus