--Je veux apprendre en touchant les services AWS
un service | Utilisation |
---|---|
AWS Lambda | Pour récupérer des articles stockés depuis l'API Qiita et notifier Slack |
Amazon DynamoDB | Étant donné que l'article obtenu à partir de l'API Qiita ne contient pas d'informations sur "quand il a été stocké", les informations de notification sont dupliquées. Pour éviter cela, conservez les informations précédemment notifiées |
Amazon CloudWatch | Pour une exécution régulière de Lambda |
AWS SAM (modèle d'application sans serveur) | Pour déployer des applications construites localement sur chaque service |
Qiita API | Pour acquérir des informations stockées |
↑ se résume comme suit.
[0. Préparation](# 0-Préparation) [1. Créer un modèle](# 1-Créer un modèle) [2. Déployer à l'aide de SAM](# 2-Déployer à l'aide de sam) [3. Notify Slack](# 3-Notify slack) [4. Notifier Slack des informations boursières à l'aide de l'API Qiita](Notifier Slack des informations boursières à l'aide de # 4-qiita-api) [5. Gérer l'historique des notifications à l'aide de DynamoDB](# 5-Gérer l'historique des notifications à l'aide de dynamodb) [6. Faire exécuter CloudWatch Lambda périodiquement à tout moment](# 6-faire en sorte que cloudwatch exécute lambda à tout moment)
AWS
Si ce qui suit n'a pas été créé ou installé, exécutez-le comme il convient.
--Créer un compte AWS
Slack
Installez l'application webhook
sur le canal dont vous souhaitez être averti et vérifiez le fonctionnement.
Référence: Procédure d'acquisition d'URL Slack Webhook --Qiita
Créez un modèle avec la commande sam.
$ sam init -n qiita-stocks-notifier -r ruby2.5
option | La description |
---|---|
-n, --name TEXT | initLe nom du projet créé par la commande. |
-r, --runtime | Spécification du runtime. Cette foisrubyJe l'ai fait. |
Référence: sam init --AWS serverless application model
J'ai choisi la valeur par défaut pour les questions posées dans la console. Lorsque la commande est terminée, un modèle avec la structure suivante est créé sous le répertoire.
$ tree
.
├── Gemfile
├── README.md
├── events
│ └── event.json
├── hello_world
│ ├── Gemfile
│ └── app.rb
├── template.yaml
└── tests
└── unit
└── test_handler.rb
Le contenu de ** hello_world / app.rb ** ne produit qu'un message.
Maintenant que le modèle a été créé, déployons-le sur Lambda. Référence: [Tutoriel: Deploying Hello World Applications-AWS Serverless Application Model](https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/serverless-getting-started-hello- world.html)
$ sam build
$ sam deploy --guided
#Je vais répondre à la question.
Lorsque le déploiement est terminé normalement, la chaîne de caractères est sortie vers la console et vous pouvez confirmer qu'elle est fluide.
{"message": "hello world"}
Confirmez que l'application déployée est reflétée dans l'écran de gestion de Lambda.
Ajoutez slack-notifier
à ** hello_world / Gemfile ** et ** bundle install **.
stevenosloan/slack-notifier: A simple wrapper for posting to slack channels
gem "slack-notifier"
$ bundle
Initialisez ʻapp.rb en passant l'URL de Hooks à
slack-notifier` comme indiqué ci-dessous, et essayez d'envoyer le libellé de test.
app.rb
require "json"
require "slack-notifier"
def lambda_handler(event:, context:)
notifier = Slack::Notifier.new "https://hooks.slack.com/services/**/**" do
defaults channel: "#qiita-slacks-notification"
end
notifier.ping "yeah"
end
Une fois la modification terminée, générez-la et déployez-la pour vérifier l'opération.
$ sam build
$ sam deploy
Sélectionnez "Sélectionner un événement de test" -> "Définir un événement de test" sur l'écran d'administration Lambda.
Ce sera un écran pour sélectionner les paramètres de l'application créée, mais cette fois le comportement ne change pas en fonction des paramètres Laissez la valeur par défaut.
Après avoir terminé le "Set Test Event", sélectionnez "Test" et confirmez que le message est envoyé à Slack.
Vous pouvez maintenant confirmer la communication de ** Lambda ** à Slack.
Ensuite, récupérez le stock de l'utilisateur dans Qiita API
et notifiez-le.
Voici l'API pour obtenir les articles stockés par l'utilisateur. Documentation API Qiita v2 - Qiita: Développeur
Insérez la gemme ** Faraday
** pour faciliter l'interaction avec les API externes.
Référence: lostisland / faraday: bibliothèque client HTTP simple mais flexible, avec prise en charge de plusieurs backends.
gem "faraday"
$ bundle
Le schéma de la partie mise en œuvre est le suivant.
-Obtenir des informations boursières de l'API en utilisant ** Faraday ** --Notifiez Slack de la réponse dans un tableau par ** titre ** et ** URL **
app.rb
require 'json'
require 'faraday'
require 'slack-notifier'
USER_ID = "{Mon ID utilisateur}".freeze
def lambda_handler(event:, context:)
#Obtenez des informations sur les stocks de l'API
response = Faraday.get("https://qiita/api/v2/user/#{USER_ID}/stocks", page: 1, per_page: 10)
#Organisez les titres et les URL dans un tableau
messages = JSON.parse(response.body).each_with_object([]) do |res, ary|
ary << [res["title"], res["url"]]
end
notifier = Slack::Notifier.new "https://hooks.slack.com/services/**/**" do
defaults channel: "#qiita-slacks-notification"
end
notifier.ping "Je publierai l'article stocké chez Qiita la semaine dernière"
messages.each do |message|
notifier.ping message[0]
notifier.ping message[1]
notifier.ping "- - - - - - - - - - - - - - - - - - - - "
end
end
Une fois le correctif terminé, essayez d'utiliser sam local invoke
, qui vous permet de tester votre application localement.
sam local invoke --no-event
option | La description |
---|---|
--no-event | Appelez la fonction avec un événement vide. Utilisez une autre option si vous souhaitez transmettre des paramètres pour la vérification. |
Référence: [sam local invoke --AWS serverless application model](https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-local- invoke.html)
Vous pouvez confirmer que les informations boursières ont été envoyées à Slack en exécutant la commande.
La partie notification est terminée, mais si elle est laissée telle quelle, les mêmes informations peuvent circuler à chaque fois, je voudrais donc éviter que l'article une fois notifié ne soit notifié.
Utilisez ** DynamoDB
** pour enregistrer les informations de notification et empêcher la notification d'informations dans la base de données.
Utilisez la gemme ** ʻaws-record` ** pour échanger des données avec DynamoDB. aws/aws-sdk-ruby-record: Official repository for the aws-record gem, an abstraction for Amazon DynamoDB.
template.yml
AWSTemplateFormatVersion: '2010-09-09'
...
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: hello_world/
Handler: app.lambda_handler
Runtime: ruby2.5
Policies:
+ #Créer dans DynamoDB/Read/Update/Accorder la permission de supprimer
+ - DynamoDBCrudPolicy:
+ TableName: !Ref NotifiedMessageDDBTable
+ #Variable d'environnement
+ Environment:
+ Variables:
+ DDB_TABLE: !Ref NotifiedMessageDDBTable
Events:
HelloWorld:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /hello
Method: get
+ NotifiedMessageDDBTable:
+ Type: AWS::Serverless::SimpleTable
...
app.rb
require 'aws-record'
require 'json'
require 'faraday'
require 'slack-notifier'
USER_ID = "{Mon ID utilisateur}".freeze
class NotifiedMessage
include Aws::Record
set_table_name ENV['DDB_TABLE']
string_attr :id, hash_key: true
string_attr :title
string_attr :url
end
def lambda_handler(event:, context:)
#Recevoir des informations notifiées
already_notified_messages = []
NotifiedMessage.scan.each do |notified_message|
already_notified_messages << notified_message.url
end
#Obtenez des articles stockés à partir de l'API et organisez uniquement les articles non annoncés dans un tableau
response = Faraday.get("https://qiita.com/api/v2/users/#{USER_ID}/stocks", page: 1, per_page: 10)
messages = JSON.parse(response.body).each_with_object([]) do |res, ary|
ary << [res["title"], res["url"]] unless already_notified_messages.include? res["url"]
end
notifier = Slack::Notifier.new "https://hooks.slack.com/services/xx/xx" do
defaults channel: "#qiita-stocks-notification"
end
notifier.ping "Je n'avais aucun article en stock cette semaine" and return if messages.size.zero?
#Notifier Slack et enregistrer dans la base de données
notifier.ping "Je publierai l'article stocké chez Qiita la semaine dernière"
messages.each do |message|
notifier.ping message[0]
notifier.ping message[1]
notifier.ping "- - - - - - - - - - - - - - - - - - - -"
notified_message = NotifiedMessage.new(id: SecureRandom.uuid, title: message["title"], url: message["url"])
notified_message.save!
end
end
Si vous déployez et testez cela, vous pouvez vérifier la table ajoutée sur l'écran de gestion de DynamoDB, et vous pouvez insérer les 10 dernières informations boursières.
Enfin, assurez-vous de recevoir des notifications à Slack à un moment agréable chaque semaine.
Si vous sélectionnez ** ʻAjouter un déclencheur` ** et sélectionnez "** CloudWatch Events / Event Bridge **" dans la recherche, vous pouvez définir les règles d'exécution, donc je les ai définies comme suit.
Bien que la compression ait été divulguée, la partie de la ** formule de planification ** a été correctement définie avec cron (0 12? * SAT *)
(tous les samedis à midi).
Référence: Schedule expression using Rate or Cron --AWS Lambda
Si vous vérifiez le planificateur de CloudWatch, vous pouvez voir qu'il s'exécute ** tous les samedis à midi ** comme indiqué ci-dessous.
Vous avez maintenant reçu des notifications de stock hebdomadaires de Qiita. Cependant, s'il est laissé tel quel, le nombre de lectures de DynamoDB augmentera et le portefeuille sera pincé, il est donc nécessaire de restreindre les informations à acquérir en passant «query» à «scan». J'ai beaucoup appris des services AWS car je ne les comprends souvent qu'en les touchant.
Je vous serais reconnaissant si vous pouviez signaler des erreurs.