Serverless! 运用 AWS 开发 Slack Slash Commands

《Serverless! 运用 AWS 开发 Slack Slash Commands》

本文介绍怎样运用 AWS Lambda & AWS API Gateway 搭建一个不须要伺服器的环境,供应 Slack Slash Commands 查询豆瓣电影。

《Serverless! 运用 AWS 开发 Slack Slash Commands》

在 Slack 输入 /movie 绝地救济,会显示相关的电影资料。

这篇文章运用到的技术:

  • Slack Slash Commands

  • AWS Lambda

  • AWS API Gateway

  • 豆瓣电影 API

阅读这篇文章须要具备什么才能:

  • Node.js 的基础才能

  • Amazon Web Services 的基础操纵

接下来我会逐渐讲解这些东西:

  1. Slack Slash Commands 的运作机制

  2. 竖立一个简单的 AWS Lambda function

  3. 竖立一个简单的 AWS API Gateway 执行 Lambda function

  4. 运用 Lambda 呼唤豆瓣电影 API

  5. 测试 AWS API Gateway

  6. 将 API Gateway endpoint 到场至 Slack Slash Command

Slack Slash Commands 的运作机制

《Serverless! 运用 AWS 开发 Slack Slash Commands》

当你在 Slack channel 输入 /movie 权力的游戏,Slack 会发出一个 content-type Header 设为 application/x-www-form-urlencoded 的 HTTP POST 请求,花样以下:

token=YOUR_SLASH_COMMAND_TOKEN
team_id=YOUR_TEAM_ID
team_domain=YOUR_TEAM_DOMAIN
channel_id=YOUR_CHANNEL_ID
channel_name=YOUR_CHANNEL_NAME
user_id=YOUR_USER_ID
user_name=YOUR_USER_NAME
command=/movie
text=权力的游戏
response_url=YOUR_HOOK_URL

然后 Slack 须要收到的 JSON 回应花样以下(详见 Attachments):

{
  "response_type": "in_channel",
  "attachments": [
    {
      "title": "权力的游戏 第五季",
      "title_link": "http://movie.douban.com/subject/25826612/",
      "text": "Game of Thrones\n2015年",
      "fields": [
        {
          "title": "导演",
          "value": "Michael Slovis\n...",
          "short": true
        }, ...
      ],
      "thumb_url": "https://img1.doubanio.com/view/movie_poster_cover/ipst/public/p2230256732.jpg"
    }
  ]
}

responsetype: inchannel 示意 channel 内的运用者都能够看见,若只想给运用敕令的本人看的话能够改成 ephemeral
Slack Slash Commands 有 3000 ms 的 response timeout 限定

竖立一个简单的 AWS Lambda function

《Serverless! 运用 AWS 开发 Slack Slash Commands》

  1. 前去 AWS Lambda

  2. 点选 Create a Lambda function

  3. 填写 Configure function,例:slackFunction

  4. Runtime 选择 Node.js

  5. Code entry type 选择 Edit code inline,输入简单的测试程式码:

exports.handler = function(event, context) {
  context.succeed("你好天下!");
};
  1. Role 运用 lambdabasicexecution

  2. 点选 Next 完成竖立

  3. 点选 Test 测试结果:

你好天下!

竖立一个简单的 AWS API Gateway 执行 Lambda function

《Serverless! 运用 AWS 开发 Slack Slash Commands》

  1. 前去 AWS API Gateway

  2. 点选 New API

  3. 填写 API name,例:Slack API

  4. 点选 Create API 完成新增

  5. 点选 Create Resource

  6. 填写 Resource Name & Resource Path,例:movie

  7. 点选 /movie

  8. 点选 Create Method

  9. 选择 POST

  10. Integration type 选择 Lambda Function

11. 选择 Lambda Region
12. 填写 Lambda Function,例:slackFunction
13. 点选 Save 完成竖立
14. 点选 Test 测试结果:

你好天下!

运用 Lambda 呼唤豆瓣电影 API

《Serverless! 运用 AWS 开发 Slack Slash Commands》

豆瓣电影搜刮 API 的花样以下:

GET https://api.douban.com/v2/movie/search?q={text}

例:https://api.douban.com/v2/movie/search?q=权力的游戏

{
  "count": 20,
  "start": 0,
  "total": 130,
  "subjects": [
    {
      "rating": {...},
      "genres": [...],
      "collect_count": 47770,
      "casts": [
        {...}, ...
      ],
      "title": "权利的游戏 第五季",
      "original_title": "Game of Thrones",
      "subtype": "tv",
      "directors": [
        {...}, ...
      ],
      "year": "2015",
      "images": {...},
      "alt": "http://movie.douban.com/subject/25826612/",
      "id": "25826612"
    }, ...
  ],
  "title": "搜刮 \"权力的游戏\" 的效果"
}

庖代 Edit code inline,在当地竖立一个 Node.js Lambda project:

$ npm init

到场一个支撑 promise 的 XMLHttpRequest 库:

$ npm install request-promise --save

新增 index.js:

var rp = require('request-promise');
exports.handler = function(event, context) {
  // 从传进来的参数当中提取要搜寻的字串
  var text = event.text ? event.text.trim() : null;

  // 向豆瓣 API 发出 HTTP GET 请求
  rp('https://api.douban.com/v2/movie/search?q=' + text)
    .then(function(data) {
      // 回传胜利的结果
      context.succeed(data);
    }).catch(function(error) {
      // 回传失败的结果
      context.fail(error);
    });
};

将档案压缩成 lambda.zip:

./index.js
./node_module/request-promise
  1. 回到 AWS Lambda

  2. 点选之前竖立的 function,例:slackFunction

  3. 将 Code entry type 从 Edit code inline 改为 Upload a .ZIP file

  4. 上传 lambda.zip

  5. 点选 Actions > Configure test event,到场测试用的请求

{
  "text": "权力的游戏"
}

点选 Test 测试豆瓣回应的结果:

{
  // ...
  "subjects": [
    {
      // ...
      "title": "权利的游戏 第五季",
      // ...
    }, ...
  ],
  "title": "搜刮 \"权力的游戏\" 的效果"
}

测试 AWS API Gateway

《Serverless! 运用 AWS 开发 Slack Slash Commands》

  1. 回到 AWS API Gateway

  2. 点选 /movie 的 POST method

  3. 点选 Test,并在 Request Body 到场测试用的请求:

{
  "text": "权力的游戏"
}

点选 Test 测试 Lambda 回应的豆瓣结果:

{
  // ...
  "subjects": [
    {
      // ...
      "title": "权利的游戏 第五季",
      // ...
    }, ...
  ],
  "title": "搜刮 \"权力的游戏\" 的效果"
}

将 API Gateway endpoint 到场至 Slack Slash Command

《Serverless! 运用 AWS 开发 Slack Slash Commands》

因为 Slack 发送的请求 Header 花样是 application/www-form-urlencoded,所以须要在 AWS API Gateway 当中将它转换成为 application/json 花样:

  1. 点选 /movie 的 POST method

  2. 点选 Method Execution

  3. 点选 Integration Request

  4. 点选 Mapping Templates

  5. 点选 Add mapping template

  6. Content-Type 填写 application/www-form-urlencoded

  7. 将 Input passthrough 改成 Mapping template

  8. 贴上 Ryan Ray 供应的 template gist

  9. Save

最后,一定要记得把 API Gateway 布置给外部运用:

  1. 点选 Deploy API

  2. Deployment stage 选择 New Stage

  3. 填写 Stage name,例:development

  4. 点选 Deploy 完成发布

  5. 然后会获得一个 Invoke URL 花样以下:

https://{hash}.execute-api.{region}.amazonaws.com/{stage}/movie

接下来的步骤,把 AWS API Gateway endpoint 整合进 Slack:

  1. 前去 https://YOURTEAMDOMAIN.slack.com/apps/manage

  2. 在 Search app directory 搜寻框输入 Slash Commands 并进入

  3. 点选 Add Configuration

  4. 填写 Choose a Command,例:/movie

  5. 点选 Add Slash Command Integration

  6. 填写 URL,贴上 AWS API Gateway Invoke URL

  7. Method 选择 POST

  8. 点选 Save Integration 完成新增

《Serverless! 运用 AWS 开发 Slack Slash Commands》

最后一个步骤,更新 Lambda function,让它能够处理 Slack 的请求与回应:

var rp = require('request-promise');
exports.handler = function(event, context) {
  /**
   * event 会收到来自 AWS API Gateway 转换过的 Slack POST JOSN
   * {
   *   token=YOUR_SLASH_COMMAND_TOKEN
   *   team_id=YOUR_TEAM_ID
   *   team_domain=YOUR_TEAM_DOMAIN
   *   channel_id=YOUR_CHANNEL_ID
   *   channel_name=YOUR_CHANNEL_NAME
   *   user_id=YOUR_USER_ID
   *   user_name=YOUR_USER_NAME
   *   command=/movie
   *   text=权力的游戏
   *   response_url=YOUR_HOOK_URL
   * }
   */
  if(event.token !== 'YOUR_SLASH_COMMAND_TOKEN') {
    return context.fail('未经授权的请求');
  }
  var text = event.text ? event.text.trim() : null;

  // 向豆瓣 API 发出 HTTP GET 请求
  rp('https://api.douban.com/v2/movie/search?q=' + text)
    .then(function(data) {
      // 提取第一笔电影的结果
      var subject = data.subjects[0];
      // 将豆瓣 API 返回的结果包装成 Slack 支撑的花样
      var result = {
        "response_type": "in_channel",
        "attachments": [{
          "title": subject.title,
          "title_link": subject.alt,
          "text": subject.original_title+"\n"+subject.year+"年",
          "fields": [
            {
              "title": "导演",
              "value": subject.directors[0].name,
              "short": true
            }
          ],
          "thumb_url": subject.images.small
        }]
      };
      // 回传结果
      context.succeed(result);
    }).catch(function(error) {
      // 回传失败的结果
      context.fail(error);
    });
};
  1. 从新压缩 lambda.zip 然后上传

  2. 在 Slack channel 输入 /movie 测试结果

总结

    原文作者:Amo
    原文地址: https://segmentfault.com/a/1190000004282941
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞