
Nachrichten mit Nexmo über Golang und AWS Lambda senden
Lesedauer: 6 Minuten
Vor kurzem habe ich ein Tutorial von Tom Morris auf dem Nexmo-Blog mit dem Titel Senden von SMS aus Python mit Google Cloud Functionsund dachte, es sei ein interessantes Beispiel für den Einsatz von SMS, auch wenn Python und Google Cloud Functions nicht mein Ding sind.
Nachdem ich den Blog gelesen hatte, dachte ich, es wäre interessant, ihn auf AWS Lambda als Funktionsanbieter zu erweitern und die Sprache auf Golang umzustellen, etwas, das mir sehr am Herzen liegt.
In diesem Tutorial werden wir eine API mit AWS Lambda und AWS API Gateway erstellen, die eine SMS-Nachricht mit der Nexmo Messaging API, aber mit der Programmiersprache Go sendet.
Die Anforderungen
Es gibt ein paar Voraussetzungen, die erfüllt sein müssen, bevor Sie dieses Tutorial durcharbeiten können:
Sie müssen Go installiert haben und zumindest ein wenig mit der Sprache vertraut sein.
Sie benötigen einen Nexmo Developer Account.
Sie benötigen einen Amazon Web Services Account.
Da Go eine kompilierte Sprache ist, müssen wir in der Lage sein, lokal zu entwickeln und zu bauen. Unsere Builds werden auf AWS hochgeladen, daher benötigen wir einen AWS Account. Diese Applications werden die Nexmo Messaging API nutzen.
Erstellen einer Messaging-Funktion mit Go und dem AWS Lambda SDK
Was die Entwicklung der Go-Anwendung betrifft, so ist nicht allzu viel los. Was den Ablauf der Ereignisse betrifft, so sieht er in etwa so aus:
Der Benutzer wird eine Anfrage an die Funktion stellen.
Die Funktion sendet eine HTTP-Anfrage an die Nexmo Messages API.
Die Funktion antwortet mit der Fehler- oder Nachrichten-ID aus der API.
Während sich die Kernlogik um eine HTTP-Anfrage dreht, muss das Datenmodell für die Anfrage und die Antwort noch ein wenig eingerichtet werden.
Innerhalb der $GOPATHerstellen Sie ein neues Projekt mit einer main.go Datei, die Folgendes enthält:
package main
var NEXMO_API_KEY string = "API_KEY_HERE"
var NEXMO_API_SECRET string = "API_SECRET_HERE"
func main() {}Sowohl der API-Schlüssel als auch das API-Geheimnis können über das Nexmo-Entwicklerportal bezogen werden.
Da es sich um ein AWS Lambda-Projekt handeln wird, muss das Go SDK für Lambda installiert werden. Führen Sie in der Befehlszeile Folgendes aus:
go get github.com/aws/aws-lambda-go/lambdaWenn das SDK über den Go-Paketmanager installiert wurde, kann es innerhalb des Projekts verwendet werden. Um es innerhalb des Projekts zu verwenden, können wir die folgenden Änderungen vornehmen:
package main
import "github.com/aws/aws-lambda-go/lambda"
var NEXMO_API_KEY string = "API_KEY_HERE"
var NEXMO_API_SECRET string = "API_SECRET_HERE"
func Handler() {}
func main() {
lambda.Start(Handler)
}Wie Sie wahrscheinlich vermuten können, wird unsere gesamte Nachrichtenlogik in der Handler Funktion enthalten, da diese ausgeführt wird, wenn der Client eine Lambda-Anfrage stellt.
Bevor wir uns mit der Logik beschäftigen, müssen wir einige Datenmodelle für die verschiedenen Anfragen und Antworten definieren. Go erfordert, dass wir unsere Datenmodelle explizit durch struct Variablen zu definieren, damit JSON zwischen den Anfragen ordnungsgemäß übertragen werden kann.
Fügen Sie Folgendes zur Datei main.go Datei hinzu:
type NexmoMessageContent struct {
Type string `json:"type"`
Text string `json:"text"`
}
type NexmoMessage struct {
Content NexmoMessageContent `json:"content"`
}
type NexmoMessageService struct {
Type string `json:"type"`
Number string `json:"number"`
}
type NexmoMessagesRequest struct {
From NexmoMessageService `json:"from"`
To NexmoMessageService `json:"to"`
Message NexmoMessage `json:"message"`
}
type NexmoMessagesResponse struct {
Id string `json:"message_uuid"`
}Wenn Sie schon einmal die Nexmo Messages API verwendet haben, werden Sie mit dem JSON vertraut sein, das mit jeder Anfrage an die API gesendet werden muss. Die obigen Datenstrukturen stellen die Daten dar, die gesendet werden. Mit den JSON-Annotationen an Ort und Stelle würde das JSON etwa so aussehen:
{
"from": { "type": "sms", "number": "SENDER_NUMBER_HERE" },
"to": { "type": "sms", "number": "RECIPIENT_NUMBER_HERE" },
"message": {
"content": {
"type": "text",
"text": "Hello World"
}
}
}Wenn eine Anfrage an die Nexmo Messages API gesendet wird, wird eine Antwort mit einer UUID zurückgegeben, wenn sie erfolgreich war. Wir haben eine NexmoMessagesResponse struct geschrieben, die diese Daten enthält, und planen, sie an den Client zurückzuschicken.
Das Einzige, was uns jetzt noch fehlt, ist die Anfrage, die der Client an die Lambda-Funktion stellt. Wenn unser Beispiel das Beispiel von Google Cloud Functions imitieren soll, erwarten wir eine Telefonnummer des Empfängers und die von ihm verwendete mobile Plattform.
Mit diesen Informationen im Hinterkopf können wir eine Datenstruktur erstellen, die wie folgt aussieht:
type LambdaRequest struct {
Platform string `json:"platform"`
Recipient string `json:"recipient"`
}Wenn alle Datenmodelle erstellt sind, können wir uns auf den Rest unserer Arbeit konzentrieren, nämlich auf die Erstellung der Nachrichtenanforderung.
Die Erstellung von HTTP-Anfragen in Go ist kein schwieriger Prozess. Ich habe ein paar der Ansätze in einem früheren Tutorial mit dem Titel RESTful API Endpunkte in einer Golang-Anwendung nutzengeschrieben habe, obwohl meine persönliche Wahl die Verwendung einer Go http.Client Struktur zu verwenden. In diesem speziellen Beispiel müssen wir eine POST-Anfrage stellen, wie sie in der Nexmo-Dokumentation.
Beginnen wir mit der Erstellung einer SendMessage Funktion zu erstellen, die im Wesentlichen eine Anfrage wie die von Nexmo's vielen cURL-Beispielen erstellen wird:
func SendMessage(body map[string]string) (NexmoMessagesResponse, error) {
nexmoMessagesRequest := &NexmoMessagesRequest{
From: NexmoMessageService{
Type: "sms",
Number: body["from"],
},
To: NexmoMessageService{
Type: "sms",
Number: body["to"],
},
Message: NexmoMessage{
Content: NexmoMessageContent{
Type: "text",
Text: body["message"],
},
},
}
bodyData, _ := json.Marshal(nexmoMessagesRequest)
request, _ := http.NewRequest("POST", "https://api.nexmo.com/v0.1/messages", bytes.NewBuffer(bodyData))
request.Header.Set("Content-Type", "application/json")
request.Header.Set("Accept", "application/json")
request.Header.Set("Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte(NEXMO_API_KEY+":"+NEXMO_API_SECRET)))
client := &http.Client{}
response, err := client.Do(request)
if err != nil {
return NexmoMessagesResponse{}, err
} else {
data, _ := ioutil.ReadAll(response.Body)
var result NexmoMessagesResponse
json.Unmarshal(data, &result)
return result, nil
}
}
Die obige Funktion nimmt eine map[string]string und gibt eine NexmoMessagesResponse oder einen Fehler zurück. Der erste Teil der Funktion übernimmt Daten aus der Map und konstruiert ein Objekt, das in JSON umgewandelt wird. Bei der Erstellung der HTTP-Anforderung wird das Objekt als Körper verwendet und es werden verschiedene Kopfzeilen definiert, darunter eine Autorisierungskopfzeile.
Mit Nexmo kann ein JSON Web Token (JWT) oder der API-Schlüssel und das API-Geheimnis verwendet werden. In diesem Beispiel werden der API-Schlüssel und das API-Geheimnis verwendet.
Die SendMessage Funktion ist der größte Teil der Arbeit getan.
Da wir das AWS Lambda SDK für Go verwenden und eine Handler Funktion haben, ist der nächste Schritt zu definieren, was in der Handler Funktion. Sie sollte etwa so aussehen:
func Handler(request LambdaRequest) (NexmoMessagesResponse, error) {
return SendMessage(
map[string]string{
"from": "15404161937",
"to": request.Recipient,
"message": request.Platform,
},
)
}Denken Sie daran, dass der Kunde, der auf unsere API zugreift, die Informationen über die Plattform und den Empfänger bereitstellen muss. Denken Sie daran, dass er angeben muss, welche mobile Plattform er verwendet und an welche Telefonnummer die SMS-Nachricht gesendet werden soll.
Wenn Sie es glauben können, ist die AWS Lambda-Funktion vollständig. Wenn sie mit den entsprechenden Empfänger- und Plattforminformationen ausgelöst wird, wird die SMS-Nachricht gesendet und die ID der Nachricht zurückgegeben.
Als Nächstes müssen wir die Funktion in AWS Lambda aufnehmen und die Funktion als Teil von Standard-HTTP-Anforderungen zugänglich machen, wie es für eine API typisch ist.
Konfigurieren von AWS Lambda und AWS API Gateway als skalierbare Web-API
Bevor wir uns mit dem AWS-Portal beschäftigen, sollten wir unser Go-Projekt erstellen. Führen Sie in der Befehlszeile im Projektpfad Folgendes aus:
GOOS=linux go buildAWS verlangt von unserer Anwendung, dass sie mit Linux kompatibel ist. Zum Glück wird Go mit den richtigen Tool-Ketten für die Cross-Kompilierung ausgeliefert. Weitere Informationen zur Cross-Kompilierung mit Go finden Sie in meinem früheren Tutorial zu diesem Thema.
Als Teil einer Lambda-Anforderung muss die Binärdatei gezippt werden. Notieren Sie sich den Dateinamen und fügen Sie ihn einem ZIP-Archiv im Stammverzeichnis des Archivs hinzu. Der Dateiname der Binärdatei steht für den Namen des Handlers.
Wechseln Sie dann in die AWS-Entwicklerkonsole und wählen Sie die Option zum Erstellen einer neuen Lambda-Funktion. Der Name ist nicht allzu wichtig, stellen Sie nur sicher, dass die Funktion die Go-Laufzeit verwendet.
AWS Developer Console
Wählen Sie im Dashboard für die jeweilige Funktion die Option zum Hochladen des ZIP-Archivs, das Sie gerade erstellt haben. Denken Sie daran, den richtigen Dateinamen für die Handler-Informationen anzugeben.
Wir möchten auch API Gateway als Auslöser für die Funktion hinzufügen.
Geben Sie den API-Gateway-Teil der AWS Developer Console ein. Hier wird ein öffentlicher Endpunkt erstellt, der auf die Funktion verweist. Wählen Sie im Dashboard für das API-Gateway Methode erstellen innerhalb der Ressourcen Registerkarte.
Create Method
Bei der erstellten Methode sollte es sich um eine POST-Anforderung handeln, die bei der Abfrage auf den ARN-Wert der AWS Lambda-Funktion verweisen sollte. Wenn Sie fertig sind, vergessen Sie nicht, die API über das gleiche Menü wie bei der Erstellung einer neuen Methode bereitzustellen.
Zu diesem Zeitpunkt sollte die Lambda-Funktion über das konfigurierte API-Gateway erreichbar sein. Wir können die URL über die Stadien abrufen, wenn keine benutzerdefinierte Domäne konfiguriert ist.
Schlussfolgerung
Wir haben gerade gesehen, wie man mit AWS Lambda und der Programmiersprache Go Nachrichten an mobile Geräte sendet. Zusammenfassend lässt sich sagen, dass, wenn ein Benutzer eine Anforderung an die mit API Gateway verwaltete API stellt, die Anforderung an AWS Lambda fließt, an Nexmo gesendet wird und dann an das Gerät des Benutzers gesendet wird. Ein Anwendungsfall könnte, wie bereits erwähnt, darin bestehen, den App-Store-Link, sei es Google Play oder iTunes, per SMS an das Telefon des Benutzers zu senden.
Auch wenn dies in diesem Beispiel nicht untersucht wird, können wir dieses Projekt leicht erweitern, indem wir ein Frontend erstellen, mit dem Ihre Benutzer interagieren können, anstatt nur eine RESTful-API zu haben.