① Exécutez une action spécifique dans Slack. (* Commande Slash cette fois) (2) Démarrez Lambda via API Gateway. ③ Exécutez la fonction placée dans Lambda et renvoyez les informations.
↑ Cela ressemble à une image d'opération. Cette fois, je vais déplacer SlackBot qui renvoie la température actuelle d'une certaine zone.
--Les personnes qui veulent faire un simple SlackBot --Les personnes qui souhaitent toucher Lambda sur AWS
AWS Lambda est un service informatique qui vous permet d'exécuter du code sans avoir à provisionner ou gérer un serveur. AWS Lambda exécute le code uniquement lorsque cela est nécessaire et passe automatiquement de quelques demandes par jour à des milliers de demandes par seconde. Vous ne payez que pour le temps de calcul que vous utilisez, sans frais sauf si le code est en cours d'exécution. AWS Lambda vous permet d'exécuter virtuellement du code dans n'importe quelle application ou service back-end sans aucune gestion requise. AWS Lambda exécute le code sur une infrastructure informatique hautement disponible et gère toutes vos ressources informatiques, y compris les serveurs et les systèmes d'exploitation, la maintenance du système, le provisionnement de la capacité et l'autoscaling, la surveillance du code et la journalisation. Éxécuter. Tout ce que vous avez à faire est de spécifier le code dans l'une des langues prises en charge par AWS Lambda. (Citation: document officiel d'Amazon)
Il est difficile de comprendre si c'est juste cela, mais le fait est que vous n'avez pas besoin d'un serveur pour exécuter le programme.
Normalement, si vous souhaitez exécuter une sorte de programme, l'achat d'un serveur et l'installation de divers middlewares prennent beaucoup de temps, mais dans Lambda, AWS gère tout cela, donc les développeurs Il semble que vous n'ayez qu'à vous concentrer sur la création du code source.
Dans le cas d'un SlackBot comme celui-ci, je pense qu'il est juste d'utiliser Lambda car il n'a pas besoin de fonctionner tout le temps, mais uniquement lorsque c'est nécessaire.
Si l'implémentation est aussi légère que SlackBot, la méthode de déploiement utilisant Heroku, etc. est standard, mais j'ai envie d'utiliser AWS de nos jours.
Langue: Ruby2.5 Cadre: Sinatra Infrastructure: AWS Lambda
Formulaire rempli: slack-bot-on-aws-lambda
Tout d'abord, créez le SlackBot essentiel.
$ mkdir slack-bot-on-aws-lambda
$ cd slack-bot-on-aws-lambda
# 2.N'importe quelle série 5 est OK
$ rbenv local 2.5.1
$ bundle init
Générez un Gemfile avec la commande ↑ et éditez-le comme suit.
./Gemfile
# frozen_string_literal: true
source "https://rubygems.org"
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
gem 'sinatra'
Ensuite, installez Gem.
$ bundle install --path vendor/bundle
Pour vérifier le fonctionnement, je vais implémenter une page qui renvoie "Hello World!" Pour le moment.
$ touch main.rb
ruby:./main.rb
require 'sinatra'
get '/' do
'Hello World!'
end
Après cela, démarrez Sinatra.
$ bundle exec ruby main.rb
[2020-09-21 20:47:35] INFO WEBrick 1.4.2
[2020-09-21 20:47:35] INFO ruby 2.5.1 (2018-03-29) [x86_64-darwin19]
== Sinatra (v2.1.0) has taken the stage on 4567 for development with backup from WEBrick
[2020-09-21 20:47:35] INFO WEBrick::HTTPServer#start: pid=50418 port=4567
Par défaut, Sinatra fonctionne sur le numéro de port "4567", alors accédez à "[localhost: 4567](localhost: 4567)".
Succès si "Hello World!" Est affiché.
Nous allons implémenter un programme qui renvoie des informations météorologiques, qui est la fonction principale du SlackBot créé cette fois.
Inscrivez-vous en tant que membre sur le site ci-dessus et obtenez une clé API.
Bien que le service soit rédigé en anglais, une explication détaillée est omise car il peut être exploité intuitivement dans une certaine mesure. Si vous ne comprenez vraiment pas, vous pouvez obtenir autant d'articles que vous le souhaitez par Google.
Puisqu'il y a des gemmes nécessaires pour un traitement futur, installez-les immédiatement à ce moment.
./Gemfile
gem 'faraday'
gem 'rack'
gem 'rack-contrib'
gem 'rubysl-base64'
gem 'slack-ruby-bot'
N'oubliez pas de "bundle installer".
$ bundle install --path vendor/bundle
$ mkdir src
$ touch src/weather.rb
Créez src / weather.rb et écrivez comme suit.
ruby:./src/weather.rb
require 'json'
class Weather
def current_temp(locate)
end_point_url = 'http://api.openweathermap.org/data/2.5/weather'
api_key = #Clé d'API OpenWeather obtenue précédemment
res = Faraday.get(end_point_url + "?q=#{locate},jp&APPID=#{api_key}")
res_body = JSON.parse(res.body)
temp = res_body['main']['temp']
celsius = temp - 273.15
celsius_round = celsius.round
return "La température actuelle de Nerima#{celsius_round.to_s}C'est ℃."
end
end
ruby:./main.rb
require 'slack-ruby-client'
require 'sinatra'
require './src/weather'
Slack.configure do |conf|
conf.token = #Jeton SlackBot
end
get '/' do
'This is SlackBot on AWS Lambda'
end
post '/webhook' do
client = Slack::Web::Client.new
channel_id = params['channel_id']
command = params['command']
case command
when '/nerima'
#Commande Slash "/Lorsque "nerima" est exécuté, le traitement suivant est exécuté.
weather = Weather.new
client.chat_postMessage channel: channel_id, text: weather.current_temp('Nerima'), as_user: true
# 'Nerima'Vous pouvez changer la partie de. Si vous changez pour "Shinjuku", la température à Shinjuku devrait être retournée.
end
return
end
Consultez l'article suivant pour savoir comment obtenir un jeton SlackBot.
Référence: [Création d'un bot à utiliser dans l'espace de travail](https://slack.com/intl/ja-jp/help/articles/115005265703-%E3%83%AF%E3%83%BC%E3%82% AF% E3% 82% B9% E3% 83% 9A% E3% 83% BC% E3% 82% B9% E3% 81% A7% E5% 88% A9% E7% 94% A8% E3% 81% 99% E3% 82% 8B% E3% 83% 9C% E3% 83% 83% E3% 83% 88% E3% 81% AE% E4% BD% 9C% E6% 88% 90) Voir aussi: Génération et régénération de jetons API (https://slack.com/intl/ja-jp/help/articles/215770388-API-%E3%83%88%E3%83%BC%E3%82 % AF% E3% 83% B3% E3% 81% AE% E7% 94% 9F% E6% 88% 90% E3% 81% A8% E5% 86% 8D% E7% 94% 9F% E6% 88% 90 )
Il y a quelques choses que vous devez faire pour appeler SlackBot avec la commande slash.
https://api.slack.com/apps/ Accédez à l'URL ci-dessus et sélectionnez le Bot concerné.
Il y a un élément appelé "Commandes Slash" dans le menu de gauche, alors sélectionnez-le et cliquez sur "Créer une nouvelle commande". Entrez chaque élément.
--Commande: toute commande de barre oblique. ――Cette fois, il est supposé que la température actuelle du Tokyo Degree Nerima Ward sera renvoyée, elle est donc définie sur "/ nerima", mais dans Shinjuku Ward, par exemple, "/ shinjuku" est OK. ) --Request URL: L'URL que vous souhaitez demander lorsque vous exécutez la commande slash.
Cliquez sur "Enregistrer" en bas à droite lorsque la saisie est terminée.
Après avoir créé la commande slash, essayez de taper "/ nerima" sur le canal où vous avez ajouté le SlackBot. J'espère que vous obtiendrez une réponse de SlackBot comme l'image. (Il est également possible de changer l'image et le nom dans les paramètres.) Si quelque chose ne va pas, le journal doit être sorti sur le terminal, donc déboguer le cas échéant.
Après avoir confirmé l'opération normalement, il est enfin prêt pour la production sur AWS Lambda.
Cette fois, nous procéderons au déploiement à l'aide d'un outil appelé «AWS CLI», donc si vous ne l'avez pas encore installé, installez-le.
$ brew install awscli
Créez un utilisateur IAM pour effectuer le travail de déploiement. Tout d'abord, allez dans "IAM" -> "Stratégie" -> "Créer une stratégie" et collez l'instruction suivante à partir de l'onglet JSON.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"apigateway:*",
"cloudformation:*",
"dynamodb:*",
"events:*",
"iam:*",
"lambda:*",
"logs:*",
"route53:*",
"s3:*"
],
"Resource": [
"*"
]
}
]
}
Voir aussi: Stratégie IAM de déploiement minimal (https://rubyonjets.com/docs/extras/minimal-deploy-iam/)
Entrez le nom et la description de la politique, le cas échéant, puis cliquez sur «Créer une politique».
Ensuite, allez dans "IAM" -> "Utilisateur" -> "Créer un utilisateur", donnez-lui un nom approprié, cochez "Accès par programme" et passez au suivant.
Sélectionnez «Déploiement minimal de la stratégie IAM» créée précédemment à partir de «Joindre directement la stratégie existante» et passez à la suivante.
(Les balises sont facultatives) Enfin, un écran de confirmation s'affiche. S'il n'y a pas de problème, cliquez sur "Créer un utilisateur".
Ensuite, deux «ID de clé d'accès» et «clé d'accès secrète» seront émis, alors gardez-le en lieu sûr pendant que vous téléchargez le fichier csv ou que vous en prenez note.
$ aws configure
AWS Access Key ID #ID de clé d'accès créé précédemment
AWS Secret Access Key #La clé d'accès secrète que vous avez créée précédemment
Default region name # ap-northeast-1
Default output format # json
Lorsque vous tapez "aws configure" dans le terminal, il vous sera demandé différentes choses de manière interactive, alors entrez les informations nécessaires pour chacune.
Après avoir configuré l'AWS CLI, créez divers fichiers requis pour le déploiement.
ruby:./config.ru
require 'rack'
require 'rack/contrib'
require_relative './main'
set :root, File.dirname(__FILE__)
run Sinatra::Application
ruby:./lambda.rb
require 'json'
require 'rack'
require 'base64'
$app ||= Rack::Builder.parse_file("#{__dir__}/config.ru").first
ENV['RACK_ENV'] ||= 'production'
def handler(event:, context:)
body = if event['isBase64Encoded']
Base64.decode64 event['body']
else
event['body']
end || ''
headers = event.fetch 'headers', {}
env = {
'REQUEST_METHOD' => event.fetch('httpMethod'),
'SCRIPT_NAME' => '',
'PATH_INFO' => event.fetch('path', ''),
'QUERY_STRING' => Rack::Utils.build_query(event['queryStringParameters'] || {}),
'SERVER_NAME' => headers.fetch('Host', 'localhost'),
'SERVER_PORT' => headers.fetch('X-Forwarded-Port', 443).to_s,
'rack.version' => Rack::VERSION,
'rack.url_scheme' => headers.fetch('CloudFront-Forwarded-Proto') { headers.fetch('X-Forwarded-Proto', 'https') },
'rack.input' => StringIO.new(body),
'rack.errors' => $stderr,
}
headers.each_pair do |key, value|
name = key.upcase.gsub '-', '_'
header = case name
when 'CONTENT_TYPE', 'CONTENT_LENGTH'
name
else
"HTTP_#{name}"
end
env[header] = value.to_s
end
begin
status, headers, body = $app.call env
body_content = ""
body.each do |item|
body_content += item.to_s
end
response = {
'statusCode' => status,
'headers' => headers,
'body' => body_content
}
if event['requestContext'].has_key?('elb')
response['isBase64Encoded'] = false
end
rescue Exception => exception
response = {
'statusCode' => 500,
'body' => exception.message
}
end
response
end
template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Resources:
SinatraFunction:
Type: 'AWS::Serverless::Function'
Properties:
FunctionName: SlackBot
Handler: lambda.handler
Runtime: ruby2.5
CodeUri: './'
MemorySize: 512
Timeout: 30
Events:
SinatraApi:
Type: Api
Properties:
Path: /
Method: ANY
RestApiId: !Ref SinatraAPI
SinatraAPI:
Type: AWS::Serverless::Api
Properties:
Name: SlackBotAPI
StageName: Prod
DefinitionBody:
swagger: '2.0'
basePath: '/Prod'
info:
title: !Ref AWS::StackName
paths:
/{proxy+}:
x-amazon-apigateway-any-method:
responses: {}
x-amazon-apigateway-integration:
uri:
!Sub 'arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${SinatraFunction.Arn}/invocations'
passthroughBehavior: 'when_no_match'
httpMethod: POST
type: 'aws_proxy'
/:
get:
responses: {}
x-amazon-apigateway-integration:
uri:
!Sub 'arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${SinatraFunction.Arn}/invocations'
passthroughBehavior: 'when_no_match'
httpMethod: POST
type: 'aws_proxy'
ConfigLambdaPermission:
Type: 'AWS::Lambda::Permission'
DependsOn:
- SinatraFunction
Properties:
Action: lambda:InvokeFunction
FunctionName: !Ref SinatraFunction
Principal: apigateway.amazonaws.com
Outputs:
SinatraAppUrl:
Description: App endpoint URL
Value: !Sub "https://${SinatraAPI}.execute-api.${AWS::Region}.amazonaws.com/Prod/"
J'omettrai ici ce que chacun représente. (Parce que cette zone utilise le document officiel aws presque tel quel) Voir aussi: aws-samples / serverless-sinatra-sample
Puisqu'il est nécessaire de préparer le compartiment AWS S3 à l'avance, créez un compartiment S3 approprié.
Référence: Comment créer un compartiment pour AWS S3
Exécutez la commande suivante.
$ aws cloudformation package \
--template-file template.yaml \
--output-template-file serverless-output.yaml \
--s3-bucket #Nom du compartiment S3 créé précédemment
Uploading to a3a55f6abf5f21a2e1161442e53b27a8 12970487 / 12970487.0 (100.00%)
Successfully packaged artifacts and wrote output template to file serverless-output.yaml.
Execute the following command to deploy the packaged template
aws cloudformation deploy --template-file /Users/Nom d'utilisateur/Nom du répertoire/serverless-output.yaml --stack-name <YOUR STACK NAME>
Ensuite, un fichier appelé "serverless-output.yaml" devrait être automatiquement généré dans le répertoire, alors exécutez la commande suivante en fonction de cela.
$ aws cloudformation deploy --template-file serverless-output.yaml \
--stack-name slack-bot \
--capabilities CAPABILITY_IAM
Waiting for changeset to be created..
Waiting for stack create/update to complete
Successfully created/updated stack - slack-bot
Si «Successfully» s'affiche, le déploiement est réussi.
Si vous allez dans "Lambda" -> "Fonction", le contenu que vous avez déployé précédemment sera affiché, alors accédez au point de terminaison de l'API décrit dans "Passerelle API".
ruby:./main.rb
get '/' do
'This is SlackBot on AWS Lambda'
end
Si "Ceci est SlackBot sur AWS Lambda" est renvoyé comme prévu dans la requête get '/' dans main.rb, il est normal de juger qu'il fonctionne correctement.
Revenez à la page des paramètres de SlackBot et changez l'URL de demande de "Commandes Slash" au point de terminaison que vous venez de créer. (Https: //********.execute-api.ap-northeast-1.amazonaws.com/Prod/webhook ")
Enfin, j'ai de nouveau tapé "/ nerima" sur le canal Slack, et j'étais heureux si la réponse revenait correctement.
Si cela ne fonctionne pas, le journal doit être envoyé vers CloudWatch, alors déboguez-le en conséquence.
Je vous remercie pour votre travail acharné!
Cette fois, j'ai touché AWS Lambda avec le thème de l'exécution d'un simple SlackBot avec Lambda. Je ne pouvais pas vraiment réaliser toute la grandeur de Lamda car je n'ai pas implémenté beaucoup de fonctions, mais je pense que c'est un service très pratique s'il est bien utilisé.
Je n'ai pas fait d'opérations difficiles, donc fondamentalement, cela devrait fonctionner si vous suivez la procédure, mais s'il y a quelque chose de coincé, j'apprécierais que vous puissiez le signaler dans les commentaires.
Recommended Posts