mirror of
https://github.com/LCTT/TranslateProject.git
synced 2025-02-03 23:40:14 +08:00
commit
7f13fe4947
317
published/20160604 How to Build Your First Slack Bot with Python.md
Executable file
317
published/20160604 How to Build Your First Slack Bot with Python.md
Executable file
@ -0,0 +1,317 @@
|
||||
如何运用 Python 建立你的第一个 Slack 聊天机器人?
|
||||
============
|
||||
|
||||
[聊天机器人(Bot)](https://www.fullstackpython.com/bots.html) 是一种像 [Slack](https://slack.com/) 一样的实用的互动聊天服务方式。如果你之前从来没有建立过聊天机器人,那么这篇文章提供了一个简单的入门指南,告诉你如何用 Python 结合 [Slack API](https://api.slack.com/) 建立你第一个聊天机器人。
|
||||
|
||||
我们通过搭建你的开发环境, 获得一个 Slack API 的聊天机器人令牌,并用 Pyhon 开发一个简单聊天机器人。
|
||||
|
||||
### 我们所需的工具
|
||||
|
||||
我们的聊天机器人我们将它称作为“StarterBot”,它需要 Python 和 Slack API。要运行我们的 Python 代码,我们需要:
|
||||
|
||||
* [Python 2 或者 Python 3](https://www.fullstackpython.com/python-2-or-3.html)
|
||||
* [pip](https://pip.pypa.io/en/stable/) 和 [virtualenv](https://virtualenv.pypa.io/en/stable/) 来处理 Python [应用程序依赖关系](https://www.fullstackpython.com/application-dependencies.html)
|
||||
* 一个可以访问 API 的[免费 Slack 账号](https://slack.com/),或者你可以注册一个 [Slack Developer Hangout team](http://dev4slack.xoxco.com/)。
|
||||
* 通过 Slack 团队建立的官方 Python [Slack 客户端](https://github.com/slackhq/python-slackclient)代码库
|
||||
* [Slack API 测试令牌](https://api.slack.com/tokens)
|
||||
|
||||
当你在本教程中进行构建时,[Slack API 文档](https://api.slack.com/) 是很有用的。
|
||||
|
||||
本教程中所有的代码都放在 [slack-starterbot](https://github.com/mattmakai/slack-starterbot) 公共库里,并以 MIT 许可证开源。
|
||||
|
||||
### 搭建我们的环境
|
||||
|
||||
我们现在已经知道我们的项目需要什么样的工具,因此让我们来搭建我们所的开发环境吧。首先到终端上(或者 Windows 上的命令提示符)并且切换到你想要存储这个项目的目录。在那个目录里,创建一个新的 virtualenv 以便和其他的 Python 项目相隔离我们的应用程序依赖关系。
|
||||
|
||||
```
|
||||
virtualenv starterbot
|
||||
|
||||
```
|
||||
|
||||
激活 virtualenv:
|
||||
|
||||
```
|
||||
source starterbot/bin/activate
|
||||
|
||||
```
|
||||
|
||||
你的提示符现在应该看起来如截图:
|
||||
|
||||
![已经激活的 starterbot 的 virtualenv的命令提示符](https://www.fullstackpython.com/source/static/img/160604-simple-python-slack-bot/virtualenv-activate.png)
|
||||
|
||||
这个官方的 slack 客户端 API 帮助库是由 Slack 建立的,它可以通过 Slack 通道发送和接收消息。通过这个 `pip` 命令安装 slackclient 库:
|
||||
|
||||
```
|
||||
pip install slackclient
|
||||
|
||||
```
|
||||
|
||||
当 `pip` 命令完成时,你应该看到类似这样的输出,并返回提示符。
|
||||
|
||||
![在已经激活的 virtualenv 用 pip 安装 slackclient 的输出](https://www.fullstackpython.com/source/static/img/160604-simple-python-slack-bot/pip-install-slackclient.png)
|
||||
|
||||
我们也需要为我们的 Slack 项目获得一个访问令牌,以便我们的聊天机器人可以用它来连接到 Slack API。
|
||||
|
||||
### Slack 实时消息传递(RTM)API
|
||||
|
||||
Slack 允许程序通过一个 [Web API](https://www.fullstackpython.com/application-programming-interfaces.html) 来访问他们的消息传递通道。去这个 [Slack Web API 页面](https://api.slack.com/) 注册建立你自己的 Slack 项目。你也可以登录一个你拥有管理权限的已有账号。
|
||||
|
||||
![使用 Web API页面的右上角登录按钮](https://www.fullstackpython.com/source/static/img/160604-simple-python-slack-bot/sign-in-slack.png)
|
||||
|
||||
登录后你会到达 [聊天机器人用户页面](https://api.slack.com/bot-users)。
|
||||
|
||||
![定制聊天机器人用户页面](https://www.fullstackpython.com/source/static/img/160604-simple-python-slack-bot/custom-bot-users.png)
|
||||
|
||||
给你的聊天机器人起名为“starterbot”然后点击 “Add bot integration” 按钮。
|
||||
|
||||
![添加一个bot integration 并起名为“starterbot”](https://www.fullstackpython.com/source/static/img/160604-simple-python-slack-bot/starterbot.jpg)
|
||||
|
||||
这个页面将重新加载,你将看到一个新生成的访问令牌。你还可以将标志改成你自己设计的。例如我给的这个“Full Stack Python”标志。
|
||||
|
||||
![为你的新 Slack 聊天机器人复制和粘贴访问令牌](https://www.fullstackpython.com/source/static/img/160604-simple-python-slack-bot/slack-token.png)
|
||||
|
||||
在页面底部点击“Save Integration”按钮。你的聊天机器人现在已经准备好连接 Slack API。
|
||||
|
||||
Python 开发人员的一个常见的做法是以环境变量输出秘密令牌。输出的 Slack 令牌名字为`SLACK_BOT_TOKEN`:
|
||||
|
||||
```
|
||||
export SLACK_BOT_TOKEN='你的 slack 令牌粘帖在这里'
|
||||
|
||||
```
|
||||
|
||||
好了,我们现在得到了将这个 Slack API 用作聊天机器人的授权。
|
||||
|
||||
我们建立聊天机器人还需要更多信息:我们的聊天机器人的 ID。接下来我们将会写一个简短的脚本,从 Slack API 获得该 ID。
|
||||
|
||||
### 获得我们聊天机器人的 ID
|
||||
|
||||
这是最后写一些 Python 代码的时候了! 我们编写一个简短的 Python 脚本获得 StarterBot 的 ID 来热身一下。这个 ID 基于 Slack 项目而不同。
|
||||
|
||||
我们需要该 ID,当解析从 Slack RTM 上发给 StarterBot 的消息时,它用于对我们的应用验明正身。我们的脚本也会测试我们 `SLACK_BOT_TOKEN` 环境变量是否设置正确。
|
||||
|
||||
建立一个命名为 print_bot_id.py 的新文件,并且填入下面的代码:
|
||||
|
||||
```
|
||||
import os
|
||||
from slackclient import SlackClient
|
||||
|
||||
|
||||
BOT_NAME = 'starterbot'
|
||||
|
||||
slack_client = SlackClient(os.environ.get('SLACK_BOT_TOKEN'))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
api_call = slack_client.api_call("users.list")
|
||||
if api_call.get('ok'):
|
||||
# retrieve all users so we can find our bot
|
||||
users = api_call.get('members')
|
||||
for user in users:
|
||||
if 'name' in user and user.get('name') == BOT_NAME:
|
||||
print("Bot ID for '" + user['name'] + "' is " + user.get('id'))
|
||||
else:
|
||||
print("could not find bot user with the name " + BOT_NAME)
|
||||
|
||||
```
|
||||
|
||||
我们的代码导入 SlackClient,并用我们设置的环境变量 `SLACK_BOT_TOKEN` 实例化它。 当该脚本通过 python 命令执行时,我们通过会访问 Slack API 列出所有的 Slack 用户并且获得匹配一个名字为“satrterbot”的 ID。
|
||||
|
||||
这个获得聊天机器人的 ID 的脚本我们仅需要运行一次。
|
||||
|
||||
```
|
||||
python print_bot_id.py
|
||||
|
||||
```
|
||||
|
||||
当它运行为我们提供了聊天机器人的 ID 时,脚本会打印出简单的一行输出。
|
||||
|
||||
![在你的 Slack 项目中用 Python 脚本打印 Slack 聊天机器人的 ID](https://www.fullstackpython.com/source/static/img/160604-simple-python-slack-bot/printed-bot-id.png)
|
||||
|
||||
复制这个脚本打印出的唯一 ID。并将该 ID 作为一个环境变量 `BOT_ID` 输出。
|
||||
|
||||
```
|
||||
(starterbot)$ export BOT_ID='bot id returned by script'
|
||||
|
||||
```
|
||||
|
||||
这个脚本仅仅需要运行一次来获得聊天机器人的 ID。 我们现在可以在我们的运行 StarterBot 的 Python应用程序中使用这个 ID 。
|
||||
|
||||
### 编码我们的 StarterBot
|
||||
|
||||
现在我们拥有了写我们的 StarterBot 代码所需的一切。 创建一个新文件命名为 starterbot.py ,它包括以下代码。
|
||||
|
||||
```
|
||||
import os
|
||||
import time
|
||||
from slackclient import SlackClient
|
||||
|
||||
```
|
||||
|
||||
对 `os` 和 `SlackClient` 的导入我们看起来很熟悉,因为我们已经在 theprint_bot_id.py 中用过它们了。
|
||||
|
||||
通过我们导入的依赖包,我们可以使用它们获得环境变量值,并实例化 Slack 客户端。
|
||||
|
||||
```
|
||||
# starterbot 的 ID 作为一个环境变量
|
||||
BOT_ID = os.environ.get("BOT_ID")
|
||||
|
||||
# 常量
|
||||
AT_BOT = "<@" + BOT_ID + ">:"
|
||||
EXAMPLE_COMMAND = "do"
|
||||
|
||||
# 实例化 Slack 和 Twilio 客户端
|
||||
slack_client = SlackClient(os.environ.get('SLACK_BOT_TOKEN'))
|
||||
|
||||
```
|
||||
|
||||
该代码通过我们以输出的环境变量 `SLACK_BOT_TOKEN 实例化 `SlackClient` 客户端。
|
||||
|
||||
```
|
||||
if __name__ == "__main__":
|
||||
READ_WEBSOCKET_DELAY = 1 # 1 从 firehose 读取延迟 1 秒
|
||||
if slack_client.rtm_connect():
|
||||
print("StarterBot connected and running!")
|
||||
while True:
|
||||
command, channel = parse_slack_output(slack_client.rtm_read())
|
||||
if command and channel:
|
||||
handle_command(command, channel)
|
||||
time.sleep(READ_WEBSOCKET_DELAY)
|
||||
else:
|
||||
print("Connection failed. Invalid Slack token or bot ID?")
|
||||
|
||||
```
|
||||
|
||||
Slack 客户端会连接到 Slack RTM API WebSocket,然后当解析来自 firehose 的消息时会不断循环。如果有任何发给 StarterBot 的消息,那么一个被称作 `handle_command` 的函数会决定做什么。
|
||||
|
||||
接下来添加两个函数来解析 Slack 的输出并处理命令。
|
||||
|
||||
```
|
||||
def handle_command(command, channel):
|
||||
"""
|
||||
Receives commands directed at the bot and determines if they
|
||||
are valid commands. If so, then acts on the commands. If not,
|
||||
returns back what it needs for clarification.
|
||||
"""
|
||||
response = "Not sure what you mean. Use the *" + EXAMPLE_COMMAND + \
|
||||
"* command with numbers, delimited by spaces."
|
||||
if command.startswith(EXAMPLE_COMMAND):
|
||||
response = "Sure...write some more code then I can do that!"
|
||||
slack_client.api_call("chat.postMessage", channel=channel,
|
||||
text=response, as_user=True)
|
||||
|
||||
def parse_slack_output(slack_rtm_output):
|
||||
"""
|
||||
The Slack Real Time Messaging API is an events firehose.
|
||||
this parsing function returns None unless a message is
|
||||
directed at the Bot, based on its ID.
|
||||
"""
|
||||
output_list = slack_rtm_output
|
||||
if output_list and len(output_list) > 0:
|
||||
for output in output_list:
|
||||
if output and 'text' in output and AT_BOT in output['text']:
|
||||
# 返回 @ 之后的文本,删除空格
|
||||
return output['text'].split(AT_BOT)[1].strip().lower(), \
|
||||
output['channel']
|
||||
return None, None
|
||||
|
||||
```
|
||||
|
||||
`parse_slack_output` 函数从 Slack 接受信息,并且如果它们是发给我们的 StarterBot 时会作出判断。消息以一个给我们的聊天机器人 ID 的直接命令开始,然后交由我们的代码处理。目前只是通过 Slack 管道发布一个消息回去告诉用户去多写一些 Python 代码!
|
||||
|
||||
这是整个程序组合在一起的样子 (你也可以 [在 GitHub 中查看该文件](https://github.com/mattmakai/slack-starterbot/blob/master/starterbot.py)):
|
||||
|
||||
```
|
||||
import os
|
||||
import time
|
||||
from slackclient import SlackClient
|
||||
|
||||
# starterbot 的 ID 作为一个环境变量
|
||||
BOT_ID = os.environ.get("BOT_ID")
|
||||
|
||||
# 常量
|
||||
AT_BOT = "<@" + BOT_ID + ">:"
|
||||
EXAMPLE_COMMAND = "do"
|
||||
|
||||
# 实例化 Slack 和 Twilio 客户端
|
||||
slack_client = SlackClient(os.environ.get('SLACK_BOT_TOKEN'))
|
||||
|
||||
def handle_command(command, channel):
|
||||
"""
|
||||
Receives commands directed at the bot and determines if they
|
||||
are valid commands. If so, then acts on the commands. If not,
|
||||
returns back what it needs for clarification.
|
||||
"""
|
||||
response = "Not sure what you mean. Use the *" + EXAMPLE_COMMAND + \
|
||||
"* command with numbers, delimited by spaces."
|
||||
if command.startswith(EXAMPLE_COMMAND):
|
||||
response = "Sure...write some more code then I can do that!"
|
||||
slack_client.api_call("chat.postMessage", channel=channel,
|
||||
text=response, as_user=True)
|
||||
|
||||
def parse_slack_output(slack_rtm_output):
|
||||
"""
|
||||
The Slack Real Time Messaging API is an events firehose.
|
||||
this parsing function returns None unless a message is
|
||||
directed at the Bot, based on its ID.
|
||||
"""
|
||||
output_list = slack_rtm_output
|
||||
if output_list and len(output_list) > 0:
|
||||
for output in output_list:
|
||||
if output and 'text' in output and AT_BOT in output['text']:
|
||||
# 返回 @ 之后的文本,删除空格
|
||||
return output['text'].split(AT_BOT)[1].strip().lower(), \
|
||||
output['channel']
|
||||
return None, None
|
||||
|
||||
if __name__ == "__main__":
|
||||
READ_WEBSOCKET_DELAY = 1 # 1 second delay between reading from firehose
|
||||
if slack_client.rtm_connect():
|
||||
print("StarterBot connected and running!")
|
||||
while True:
|
||||
command, channel = parse_slack_output(slack_client.rtm_read())
|
||||
if command and channel:
|
||||
handle_command(command, channel)
|
||||
time.sleep(READ_WEBSOCKET_DELAY)
|
||||
else:
|
||||
print("Connection failed. Invalid Slack token or bot ID?")
|
||||
|
||||
```
|
||||
|
||||
现在我们的代码已经有了,我们可以通过 `python starterbot.py` 来运行我们 StarterBot 的代码了。
|
||||
|
||||
![当 StarterBot 开始运行而且连接到 API 的输出通道](https://www.fullstackpython.com/source/static/img/160604-simple-python-slack-bot/starterbot-running.png)
|
||||
|
||||
在 Slack 中创建新通道,并且把 StarterBot 邀请进来,或者把 StarterBot 邀请进一个已经存在的通道中。
|
||||
|
||||
![在 Slack 界面创建一个新通道并且邀请 StarterBot](https://www.fullstackpython.com/source/static/img/160604-simple-python-slack-bot/create-channel.png)
|
||||
|
||||
现在在你的通道中给 StarterBot 发命令。
|
||||
|
||||
![在你的 Slack 通道里给你的 StarterBot 发命令](https://www.fullstackpython.com/source/static/img/160604-simple-python-slack-bot/working-starterbot.png)
|
||||
|
||||
如果你从聊天机器人得到的响应中遇见问题,你可能需要做一个修改。正如上面所写的这个教程,其中一行 `AT_BOT = "<@" + BOT_ID + ">:"`,在“@starter”(你给你自己的聊天机器人起的名字)后需要一个冒号。从`AT_BOT` 字符串后面移除`:`。Slack 似乎需要在 `@` 一个人名后加一个冒号,但这好像是有些不协调的。
|
||||
|
||||
### 结束
|
||||
|
||||
好吧,你现在已经获得一个简易的聊天机器人,你可以在代码中很多地方加入你想要创建的任何特性。
|
||||
|
||||
我们能够使用 Slack RTM API 和 Python 完成很多功能。看看通过这些文章你还可以学习到什么:
|
||||
|
||||
* 附加一个持久的[关系数据库](https://www.fullstackpython.com/databases.html) 或者 [NoSQL 后端](https://www.fullstackpython.com/no-sql-datastore.html) 比如 [PostgreSQL](https://www.fullstackpython.com/postgresql.html)、[MySQL](https://www.fullstackpython.com/mysql.html) 或者 [SQLite](https://www.fullstackpython.com/sqlite.html) ,来保存和检索用户数据
|
||||
* 添加另外一个与聊天机器人互动的通道,比如 [短信](https://www.twilio.com/blog/2016/05/build-sms-slack-bot-python.html) 或者[电话呼叫](https://www.twilio.com/blog/2016/05/add-phone-calling-slack-python.html)
|
||||
* [集成其它的 web API](https://www.fullstackpython.com/api-integration.html),比如 [GitHub](https://developer.github.com/v3/)、[Twilio](https://www.twilio.com/docs) 或者 [api.ai](https://docs.api.ai/)
|
||||
|
||||
有问题? 通过 Twitter 联系我 [@fullstackpython](https://twitter.com/fullstackpython) 或 [@mattmakai](https://twitter.com/mattmakai)。 我在 GitHub 上的用户名是 [mattmakai](https://github.com/mattmakai)。
|
||||
|
||||
这篇文章感兴趣? Fork 这个 [GitHub 上的页面](https://github.com/mattmakai/fullstackpython.com/blob/gh-pages/source/content/posts/160604-build-first-slack-bot-python.markdown)吧。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
via: https://www.fullstackpython.com/blog/build-first-slack-bot-python.html
|
||||
|
||||
作者:[Matt Makai][a]
|
||||
译者:[jiajia9llinuxer](https://github.com/jiajia9linuxer)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出aa
|
||||
|
||||
[a]: https://www.fullstackpython.com/about-author.html
|
@ -1,139 +0,0 @@
|
||||
translating by theArcticOcean.
|
||||
|
||||
Part III - How to apply Advanced Mathematical Processing Effects on Audio files with Octave 4.0 on Ubuntu
|
||||
=====
|
||||
|
||||
The third part of our Digital Audio processing tutorial series covers the signal Modulation, we explain how to apply Amplitude Modulation, Tremolo Effect, and Frequency Variation.
|
||||
|
||||
### Modulation
|
||||
|
||||
#### Amplitude Modulation
|
||||
|
||||
As its name implies, this effect varies the amplitude of a sinusoid according to the message to be transmitted. A sine wave is called a carrier because it carries the information. This type of modulation is used in some commercial broadcasting and transmission citizen bands (AM).
|
||||
|
||||
#### Why use the Amplitude Modulation?
|
||||
|
||||
**Modulation Radiation.**
|
||||
|
||||
If the communication channel is a free space, then antennas are required to radiate and receive the signal. It requires an efficient electromagnetic radiation antenna whose dimensions are of the same order of magnitude as the wavelength of the signal being radiated. Many signals, including audio components, have often 100 Hz or less. For these signals, it would be necessary to build antennas about 300 km in length if the signal were to be radiated directly. If signal modulation is used to print the message on a high-frequency carrier, let's say 100 MHz, then the antenna needs to have a length of over a meter (transverse length) only.
|
||||
|
||||
**Concentration modulation or multi-channeling.**
|
||||
|
||||
If more than one signal uses a single channel, modulation can be used for transferring different signals to different spectral positions allowing the receiver to select the desired signal. Applications that use concentration ("multiplexing") include telemetry data, stereo FM radio and long-distance telephony.
|
||||
|
||||
**Modulation to Overcome Limitations on equipment.**
|
||||
|
||||
The performance of signal processing devices such as filters and amplifiers, and the ease with which these devices can be constructed, depends on the situation of the signal in the frequency domain and the relationship between the higher frequency and low signal. Modulation can be used to transfer the signal to a position in the frequency domain where design requirements are met easier. The modulation can also be used to convert a "broadband signal" (a signal for which the ratio between the highest and lowest frequency is large) into a sign of "narrow band".
|
||||
|
||||
**Audio Effects**
|
||||
|
||||
Many audio effects use amplitude modulation due to the striking and ease with which it can handle such signals. We can name a few such as tremolo, chorus, flanger, etc. This utility is where we focus in this tutorial series.
|
||||
|
||||
### Tremolo effect
|
||||
|
||||
The tremolo effect is one of the simplest applications of amplitude modulation, to achieve this effect, we have to vary (multiply) the audio signal by a periodic signal, either sinusoidal or otherwise.
|
||||
|
||||
```
|
||||
>> tremolo='tremolo.ogg';
|
||||
>> fs=44100;
|
||||
>> t=0:1/fs:10;
|
||||
>> wo=2*pi*440*t;
|
||||
>> wa=2*pi*1.2*t;
|
||||
>> audiowrite(tremolo, cos(wa).*cos(wo),fs);
|
||||
```
|
||||
|
||||
[![Tremolo](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/tremolo.png)](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/big/tremolo.png)
|
||||
|
||||
This will generate a sinusoid-shaped signal which effect is like a 'tremolo'.
|
||||
|
||||
[![Tremolo Shape](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/tremoloshape.png)](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/big/tremoloshape.png)
|
||||
|
||||
### Tremolo on real Audio Files
|
||||
|
||||
Now we will show the tremolo effect in the real world, First, we use a file previously recorded by a male voice saying 'A'. The plot for this signal is the following:
|
||||
|
||||
```
|
||||
>> [y,fs]=audioread('A.ogg');
|
||||
>> plot(y);
|
||||
```
|
||||
|
||||
[![Vocal](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/avocalmale.png)](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/big/avocalmale.png)
|
||||
|
||||
Now we have to create an enveloping sinusoidal signal with the following parameters:
|
||||
|
||||
```
|
||||
Amplitude = 1
|
||||
Frequency= 1.5Hz
|
||||
Phase = 0
|
||||
```
|
||||
|
||||
```
|
||||
>> t=0:1/fs:4.99999999;
|
||||
>> t=t(:);
|
||||
>> w=2*pi*1.5*t;
|
||||
>> q=cos(w);
|
||||
>> plot(q);
|
||||
```
|
||||
|
||||
Note: when we create an array of values of the time, by default, this is created in the form of columns, ie, 1x220500 values. To multiply this set of values must transpose it in rows (220500x1). This is the t=t(:) command
|
||||
|
||||
[![Sinusodial](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/sinusoidal.png)](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/big/sinusoidal.png)
|
||||
|
||||
We will create a second ogg file which contains the resulting modulated signal:
|
||||
|
||||
```
|
||||
>> tremolo='tremolo.ogg';
|
||||
>> audiowrite(tremolo, q.*y,fs);
|
||||
```
|
||||
|
||||
[![](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/tremsignal1.png)](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/big/tremsignal1.png)[![Tremolo Signal](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/tremolsignal1.png)](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/big/tremolsignal1.png)
|
||||
|
||||
### Frequency Variation
|
||||
|
||||
We can vary the frequency to obtain quite interesting musical effects such as distortion, sound effects for movies and games among others.
|
||||
|
||||
#### Effect of sinusoidal frequency modulation
|
||||
|
||||
This is the code where the sinusoidal modulation frequency is shown, according to equation:
|
||||
|
||||
```
|
||||
Y=Ac*Cos(wo*Cos(wo/k))
|
||||
```
|
||||
|
||||
Where:
|
||||
|
||||
```
|
||||
Ac = Amplitude
|
||||
|
||||
wo = fundamental frequency
|
||||
|
||||
k = scalar divisor
|
||||
```
|
||||
|
||||
```
|
||||
>> fm='fm.ogg';
|
||||
>> fs=44100;
|
||||
>> t=0:1/fs:10;
|
||||
>> w=2*pi*442*t;
|
||||
>> audiowrite(fm, cos(cos(w/1500).*w), fs);
|
||||
>> [y,fs]=audioread('fm.ogg');
|
||||
>> figure (); plot (y);
|
||||
```
|
||||
|
||||
The plot of the signal is:
|
||||
|
||||
[![](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/fmod.png)](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/big/fmod.png)
|
||||
|
||||
You can use almost any type of periodic function as the frequency modulator. For this example, we only used a sine function here. Please feel free to experiment with changing the frequencies of the functions, mixing with other functions or change, even, the type of function.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.howtoforge.com/tutorial/ubuntu-octave-audio-processing-part-3/
|
||||
|
||||
作者:[David Duarte][a]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.howtoforge.com/tutorial/ubuntu-octave-audio-processing-part-3/
|
@ -1,181 +0,0 @@
|
||||
ucasFL 翻译中
|
||||
Using webpack with the Amazon Cognito Identity SDK for JavaScript
|
||||
=====
|
||||
|
||||
This blog post is aimed at developers of all experience levels who develop and deploy JavaScript based applications (whether server-side with Node.js or client side) that incorporate the AWS SDK, the Amazon Cognito Identity SDK for JavaScript and who also use the popular [webpack][1] module bundler.
|
||||
|
||||
In July 2016, Amazon Web Services [launched Amazon Cognito User Pools][2], a feature that makes it easy for developers to add sign-up and sign-in functionality to mobile and web applications. To help developers easily realize the power of user pools within their own applications, we also released the [Amazon Cognito Identity SDK for JavaScript][3].
|
||||
|
||||
Amazon Cognito User Pools allows you to easily add user sign-up and sign-in to your mobile and web applications. The fully managed user pool can scale to hundreds of millions of users and you can have multiple directories per AWS account. Creating a user pool takes just a few minutes and allows you to decide exactly which attributes (including address, email, phone number as well as custom attributes) are mandatory and even optional when a new user signs up for your application or service. Your application can also specify the desired password strength, whether the use of Multi-Factor Authentication (MFA) is required, and verify new users via phone number or email address to further enhance the security of your application.
|
||||
|
||||
If you are new to the Amazon Cognito Identity SDK for JavaScript [this AWS blog post][4] is a great place to start.
|
||||
|
||||
### Why Use Asset & Module Bundling with the Amazon Cognito Identity SDK for JavaScript
|
||||
|
||||
Today, modern web applications for both mobile and desktop have to provide the user with a secure, fast, responsive, and native-app-like experience. There is no doubt that modern browsers are extremely powerful and cater to a vast array of possible implementation approaches. Many of the more popular implementations rely heavily on the deployment of a JavaScript application through some form of asset packaging and/or module bundling. This allows a developer to take their JavaScript application and create one or more files that can be loaded by the client browser by using script tags.
|
||||
|
||||
There are many schools of thought on how you can achieve this packaging , including task runners such as [Grunt][5] and [Gulp][6], and bundlers such as [Browserify][7]. However, there is a general consensus that asset packaging is not only about improving load times—it enables the modularization of your application while ensuring testability and robustness.
|
||||
|
||||
### Using webpack with the Amazon Cognito Identity SDK for JavaScript
|
||||
|
||||
In the many requests we get to provide more detail on how to integrate the Amazon Cognito Identity SDK for JavaScript within a webpack environment, we’re specifically asked how to ensure that webpack correctly manages the following third-party dependencies:
|
||||
|
||||
- [JavaScript BN library for BigInteger computation][8] (jsbn)
|
||||
- [an extension to jsbn][9] the with the rest of the jsbn methods including most public BigInteger methods (jsbn2)
|
||||
- the [Stanford JavaScript Crypto Library][10] (sjcl)
|
||||
|
||||
Throughout these examples, the following bower libraries are used by bower.json
|
||||
|
||||
```
|
||||
"aws-cognito-sdk": "https://raw.githubusercontent.com/aws/amazon-cognito-identity-js/master/dist/aws-cognito-sdk.js",
|
||||
"amazon-cognito-identity": "https://raw.githubusercontent.com/aws/amazon-cognito-identity-js/master/dist/amazon-cognito-identity.min.js",
|
||||
"sjcl": "https://raw.githubusercontent.com/bitwiseshiftleft/sjcl/master/sjcl.js",
|
||||
"jsbn": "https://raw.githubusercontent.com/andyperlitch/jsbn/master/index.js",
|
||||
```
|
||||
|
||||
For all the reasons we gave earlier for the importance of asset packaging to development processes, and unless your application is extremely small, the use of an asset packaging tool such as webpack is almost always recommended. Of course, one could simply pull in all of these dependencies using tags. However, this would pollute global namespace, and not provide the most optimal resource management and loading approach. Many developers start with a standard webpack.config.js file that has a standard babel loader, as shown here.
|
||||
|
||||
```
|
||||
{
|
||||
/** test for file ending in js or jsx
|
||||
* exclude node_module and bower_components - we dont want to babel these
|
||||
* use the babel loader
|
||||
* apply the react and es2015 (es6) transformations **/
|
||||
|
||||
test: /\.jsx?$/,
|
||||
exclude: /(node_modules|bower_components)/,
|
||||
loader: 'babel',
|
||||
query: {
|
||||
presets: ['react', 'es2015']
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
It’s important to remember that this configuration doesn’t take into account that some of third-party dependencies used by the Amazon Cognito Identity SDK for JavaScript currently do not use the [Universal Module Definition (UMD) pattern for JavaScript][11].
|
||||
|
||||
The UMD pattern attempts to offer Asynchronous Module Definition (AMD) based compatibility with the most popular script loaders of the day such as [RequireJS][12] and [CommonJS][13].
|
||||
|
||||
This is a pattern that webpack relies on, and so we must make some changes to how webpack loads these modules. Without these changes, you may encounter errors such as the following.
|
||||
|
||||
```
|
||||
amazon-cognito-identity.min.js:19 Uncaught ReferenceError: BigInteger is not defined
|
||||
```
|
||||
|
||||
Such an error may be encountered when making a call to AWSCognito.CognitoIdentityServiceProvider.CognitoUser property authenticateUser This is an example of where we can make use of the webpack imports and exports loader capability to overcome this error.
|
||||
|
||||
### Using webpack Loaders
|
||||
|
||||
According to the [webpack documentation][14] "loaders allow you to preprocess files as you require() or “load” them. Loaders are kind of like “tasks” are in other build tools, and provide a powerful way to handle front-end build steps. Loaders can transform files from a different language like, CoffeeScript to JavaScript, or inline images as data URLs"
|
||||
|
||||
In order to resolve the lack of UMD compatibility, you will rely to two specific loaders, import and export.
|
||||
|
||||
#### Using the Export Loader
|
||||
|
||||
In the case of the Amazon Cognito Identity SDK for JavaScript, we need to ensure we export theAWSCognito variables into the scope of the module that requires/imports (for ES6) them.
|
||||
|
||||
```
|
||||
{
|
||||
test: /aws-cognito-sdk\/index\.js/,
|
||||
loader: 'exports?AWSCognito'
|
||||
}
|
||||
```
|
||||
|
||||
Using the exports loader has the effect of exporting a module method within bundle created by webpack. As a result, both AWSCognito and AWS are now accessible when required or import(ed) (for ES6).
|
||||
|
||||
```
|
||||
var AWSCognito = require('aws-cognito-sdk')
|
||||
|
||||
/*** EXPORTS from export-loader ***/
|
||||
module.exports = AWSCongito
|
||||
```
|
||||
|
||||
More information about the exports loader can be found here
|
||||
|
||||
#### Using the Import Loader
|
||||
|
||||
The import loader is mostly used to inject (import) variables into the scope of another module. This is especially useful if third-party modules are relying on global variables like BitInteger or sjcl as is the case with Amazon Cognito Identity SDK for JavaScript.
|
||||
|
||||
If you don’t use the webpack loader, the following is generated within the bundle.
|
||||
|
||||
```
|
||||
__webpack_require__(431); // refers to jsbin
|
||||
__webpack_require__(432); // refers to sjcl
|
||||
```
|
||||
|
||||
Beacuse neither jsbin or sjcl export anything, any calls that rely on these modules will result in an error.
|
||||
|
||||
To resolve this, we can use the following webpack loader configuration:
|
||||
|
||||
```
|
||||
{
|
||||
test: /amazon-cognito-identity\/index\.js/,
|
||||
loader: 'imports?jsbn,BigInteger=>jsbn.BigInteger,sjcl'
|
||||
},
|
||||
{
|
||||
test: /sjcl\/index\.js/,
|
||||
loader: 'imports?sjcl'
|
||||
}
|
||||
```
|
||||
|
||||
This injects the following into the bundle (in this case bundle.js) created by webpack.
|
||||
|
||||
````
|
||||
/*** IMPORTS FROM imports-loader ***/
|
||||
var jsbn = __webpack_require__(431);
|
||||
var BigInteger = jsbn.BigInteger;
|
||||
var sjcl = __webpack_require__(432);
|
||||
```
|
||||
|
||||
As a result, jsbn, BigInteger and sjcl are all imported from their respective modules into Amazon Cognito Identity SDK for JavaScript.
|
||||
|
||||
More information about the import loader can be found [here][15]
|
||||
|
||||
### Next Steps
|
||||
|
||||
We encourage you to download the [Amazon Cognito Identity SDK for JavaScript][16] and start building your application. Coupled with webpack, and by following the guidance in this blog, you we hope you have a smooth development experience.
|
||||
|
||||
If you have any comments or questions, please free to comment below, reach out via email (teichtah@amazon.com) or raise an issue [here][17].
|
||||
|
||||
### References
|
||||
|
||||
This blog post makes reference to the following third party resources
|
||||
|
||||
- webpack - https://webpack.github.io/
|
||||
- webpack documentation - http://webpack.github.io/docs/what-is-webpack.html
|
||||
- webpack exports loader - https://github.com/webpack/exports-loader
|
||||
- webpack imports loader - https://github.com/webpack/imports-loader
|
||||
- JavaScript BN library for BigInteger computation - http://www-cs-students.stanford.edu/~tjw/jsbn/jsbn.js
|
||||
- jsbns - http://www-cs-students.stanford.edu/~tjw/jsbn/jsbn2.js
|
||||
- Stanford JavaScript Crypto Library - https://github.com/bitwiseshiftleft/sjcl
|
||||
- RequireJS - http://requirejs.org/
|
||||
- CommonJS - http://www.commonjs.org/
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://mobile.awsblog.com/post/Tx1A84CLMDJ744T/Using-webpack-with-the-Amazon-Cognito-Identity-SDK-for-JavaScript?utm_source=webopsweekly&utm_medium=email
|
||||
|
||||
作者:[Marc Teichtahl ][a]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://mobile.awsblog.com/blog/author/Marc+Teichtahl
|
||||
[1]: https://webpack.github.io/
|
||||
[2]: https://blogs.aws.amazon.com/security/post/Tx13NVD4AWG9QK9/Amazon-Cognito-Your-User-Pools-is-Now-Generally-Available
|
||||
[3]: https://github.com/aws/amazon-cognito-identity-js
|
||||
[4]: http://mobile.awsblog.com/post/Tx2O14ZY8A5LFHT/Accessing-Your-User-Pools-using-the-Amazon-Cognito-Identity-SDK-for-JavaScript
|
||||
[5]: http://gruntjs.com/
|
||||
[6]: http://gulpjs.com/
|
||||
[7]: http://browserify.org/
|
||||
[8]: http://www-cs-students.stanford.edu/~tjw/jsbn/jsbn.js
|
||||
[9]: http://www-cs-students.stanford.edu/~tjw/jsbn/jsbn2.js
|
||||
[10]: https://github.com/bitwiseshiftleft/sjcl
|
||||
[11]: https://github.com/umdjs/umd
|
||||
[12]: http://requirejs.org/
|
||||
[13]: http://www.commonjs.org/
|
||||
[14]: http://webpack.github.io/docs/what-is-webpack.html
|
||||
[15]: https://github.com/webpack/imports-loader
|
||||
[16]: https://github.com/aws/amazon-cognito-identity-js
|
||||
[17]: https://github.com/aws/amazon-cognito-identity-js/issues
|
||||
|
@ -1,315 +0,0 @@
|
||||
# 如何运用Python建立你的第一个Slack Bot?
|
||||
|
||||
[Bots](https://www.fullstackpython.com/bots.html) 是一种像 [Slack](https://slack.com/) 一样实用的互动聊天服务方式. 如果你之前从来没有建立过bot, 这篇文章提供了一个简单的用Python建立你第一个bot的关于 [Slack API](https://api.slack.com/) 集合的入门教程.
|
||||
|
||||
我们通过设置你的开发环境, 获得一个Slack API bot标记和我们用Pyhon编码的简单bot.
|
||||
|
||||
### 我们所需的工具
|
||||
|
||||
我们的bot, 我们将它称作为 "StarterBot", 它需要 Python 和 the Slack API. 然后运行我们需要的Python代码:
|
||||
|
||||
* [Python 2 或者 Python 3](https://www.fullstackpython.com/python-2-or-3.html)
|
||||
* [pip](https://pip.pypa.io/en/stable/) 和 [virtualenv](https://virtualenv.pypa.io/en/stable/) 处理 Python [应用程序依赖关系](https://www.fullstackpython.com/application-dependencies.html)
|
||||
* 一个你可以拥有API访问和注册Slack Developer Hangout team](http://dev4slack.xoxco.com/)的[免费Slack账号](https://slack.com/)
|
||||
* 通过Slack团队建立的官方Python [Slack客户端](https://github.com/slackhq/python-slackclient)代码库
|
||||
* [Slack API 测试标志](https://api.slack.com/tokens)
|
||||
|
||||
这也是一个方便你建立本教程的有用[Slack API 文档](https://api.slack.com/)
|
||||
|
||||
对于本教程,所有的代码都是在[slack-starterbot](https://github.com/mattmakai/slack-starterbot)公共库里通过MIT许可证的可获得的开放源码.
|
||||
|
||||
### 搭建我们的环境
|
||||
|
||||
我们现在已经知道我们的项目需要什么样的工具,因此我们要获得我们所建立的开发环境。首先到终端上(或者用Windows上的命令提示符)并且改变你想要存储这个项目的目录。在那个目录里,创建一个新的virtualenv以便从其他的Python项目来隔离我们的应用程序依赖关系。
|
||||
|
||||
```
|
||||
virtualenv starterbot
|
||||
|
||||
```
|
||||
|
||||
Activate the virtualenv 激活virtualenv:
|
||||
|
||||
```
|
||||
source starterbot/bin/activate
|
||||
|
||||
```
|
||||
|
||||
你的提示现在应该看起来像在一个这样的截图里。
|
||||
|
||||
![Command prompt with starterbot's virtualenv activated 已经激活的starterbot's virtualenv的命令提示:](https://www.fullstackpython.com/source/static/img/160604-simple-python-slack-bot/virtualenv-activate.png)
|
||||
|
||||
|
||||
这个官方的slackclient API帮助库是通过Slack可以发送和接收消息的Slack通道所建立的。安装slackclient库是通过这个pip命令:
|
||||
|
||||
```
|
||||
pip install slackclient
|
||||
|
||||
```
|
||||
|
||||
当pip命令完成时,你应该看到这样的输出和你将返回的提示.
|
||||
|
||||
![Output from using the pip install slackclient command with a virtualenv activated 在已经激活的virtualenv输出用pip安装slackclient的命令.](https://www.fullstackpython.com/source/static/img/160604-simple-python-slack-bot/pip-install-slackclient.png)
|
||||
|
||||
我们也需要从Slack项目获得一个访问提示,因此我们的bot可以用它来连接这个Slack API.
|
||||
|
||||
### Slack实时消息传递(RTM)API
|
||||
|
||||
Slack同意程序通过一个 [网络应用程序API](https://www.fullstackpython.com/application-programming-interfaces.html)访问他们的消息传递通道. 去这个[Slack网络应用程序API页面](https://api.slack.com/) 并且注册建立你自己的Slack项目.你也可以通过一个你拥有管理权限的有效账号登陆.
|
||||
|
||||
![Use the sign in button on the top right corner of the Slack API page 在网络应用程序API页面的右上角使用登陆按钮.](https://www.fullstackpython.com/source/static/img/160604-simple-python-slack-bot/sign-in-slack.png)
|
||||
|
||||
然后你可以到[Bot用户页面](https://api.slack.com/bot-users)登陆.
|
||||
|
||||
![Custom bot users webpage 定制bot用户网页.](https://www.fullstackpython.com/source/static/img/160604-simple-python-slack-bot/custom-bot-users.png)
|
||||
|
||||
给你的bot起名为 "starterbot" 然后点击 “Add bot integration” 按钮.
|
||||
|
||||
![Add a bot integration named starterbot 添加一个bot integration并起名为“starterbot”.](https://www.fullstackpython.com/source/static/img/160604-simple-python-slack-bot/starterbot.jpg)
|
||||
|
||||
这个页面将重新加载,你将看到一个新生成的访问令牌。你还可以将标志改成自定义设计。例如我给的这个“Full Stack Python”标志.
|
||||
|
||||
![Copy and paste the access token for your new Slack bot为你的新Slack bot复制和粘贴访问提示.](https://www.fullstackpython.com/source/static/img/160604-simple-python-slack-bot/slack-token.png)
|
||||
|
||||
在页面底部点击 "Save Integration"按钮. 你的 bot 现在已经准备好连接Slack's API.
|
||||
|
||||
Python开发人员的一个常见的做法是输出秘密令牌提示作为环境变量。输出的Slack令牌名字为“SLACK_BOT_TOKEN”.:
|
||||
|
||||
```
|
||||
export SLACK_BOT_TOKEN='your slack token pasted here'
|
||||
|
||||
```
|
||||
|
||||
好了,我们现在将被作为bot授权使用这个Slack API .
|
||||
|
||||
这个是一个更多的我们需要建立我们的bot的信息: 我们的bot的ID. 接下来我们将会写一个简短的脚本来从这个Slack API获得ID.
|
||||
|
||||
### 获得我们Bot的ID
|
||||
|
||||
这是最后一次写的一些Python代码! 我们将会在编译一个简短的Python脚本来获得StarterBot的ID时获得热身. 这个ID基于Slack项目而改变.
|
||||
|
||||
我们需要ID,因为当消息被解析为从Slcak RTM在StarterBot上指导的,他会允许我们的应用程序作出终止.我们的脚本也会测试我们SLACK_BOT_TOKEN环境变量是否设置正确.
|
||||
|
||||
建立一个新文件并命名为print_bot_id.py 并且填写下面的代码.
|
||||
|
||||
```
|
||||
import os调用外部程序
|
||||
from slackclient import SlackClient从slackclient调用SlackClient
|
||||
|
||||
BOT_NAME = 'starterbot'
|
||||
|
||||
slack_client = SlackClient(os.environ.get('SLACK_BOT_TOKEN'))
|
||||
|
||||
if __name__ == "__main__":
|
||||
api_call = slack_client.api_call("users.list")
|
||||
if api_call.get('ok'):
|
||||
# retrieve all users so we can find our bot检索所有的用户以便我们可以找到我们的bot
|
||||
users = api_call.get('members')
|
||||
for user in users:
|
||||
if 'name' in user and user.get('name') == BOT_NAME:
|
||||
print("Bot ID for '" + user['name'] + "' is " + user.get('id'))
|
||||
else:
|
||||
print("could not find bot user with the name " + BOT_NAME)
|
||||
|
||||
```
|
||||
|
||||
当我们设置为一个环境变量时,我们的代码调用于SlackClient并且为我们的SLACK_BOT_TOKEN而将它实例化. 当脚本通过pyhon命令执行时,我们通过会访问Slack API列出所有的Slack用户并且获得匹配一个名字为"satrterbot"的ID.
|
||||
|
||||
我们仅仅需要运行一次脚本来获得我们bot的ID.
|
||||
|
||||
```
|
||||
python print_bot_id.py
|
||||
|
||||
```
|
||||
|
||||
当它运行为我们提供我们bot的ID时,脚本会打印出简单的一行输出.
|
||||
|
||||
![在你的Slack项目中用Python脚本打印Slack bot的ID.](https://www.fullstackpython.com/source/static/img/160604-simple-python-slack-bot/printed-bot-id.png)
|
||||
|
||||
复制脚本打印出的唯一ID.并将ID作为一个环境变量命名为BOT_ID输出.
|
||||
|
||||
```
|
||||
(starterbot)$ export BOT_ID='bot id returned by script'
|
||||
|
||||
```
|
||||
|
||||
这个脚本仅仅需要运行一次来获得bot的ID. 我们现在可以使用这个ID在我们的Python应用程序中来运行StarterBot.
|
||||
|
||||
### 编码我们的StarterBot
|
||||
|
||||
我们通过我们拥有的一切来写我们需要书写的StarterBot代码. 创建一个新文件命名为starterbot.py ,它包括以下代码.
|
||||
|
||||
```
|
||||
import os
|
||||
import time
|
||||
from slackclient import SlackClient
|
||||
|
||||
```
|
||||
|
||||
操作系统和SlackClient调用将会看起来很熟悉,因为我们会使用它们在theprint_bot_id.py中.
|
||||
|
||||
在我们的依赖关系调用中,我们可以使用它们获得环境变量值并且在Slack client中将它们实例化.
|
||||
|
||||
```
|
||||
# starterbot's ID as an environment variable starterbot的ID作为一个环境变量
|
||||
BOT_ID = os.environ.get("BOT_ID")
|
||||
|
||||
# constants 常量
|
||||
AT_BOT = "<@" + BOT_ID + ">:"
|
||||
EXAMPLE_COMMAND = "do"
|
||||
|
||||
# instantiate Slack & Twilio clients 实例化Slack和Twilio clients
|
||||
slack_client = SlackClient(os.environ.get('SLACK_BOT_TOKEN'))
|
||||
|
||||
```
|
||||
|
||||
代码在我们的SLACK_BOT_TOKEN中将SlackClient client实例化并且作为一个环境变量输出.
|
||||
|
||||
```
|
||||
if __name__ == "__main__":
|
||||
READ_WEBSOCKET_DELAY = 1 # 1 second delay between reading from firehose 从firehose阅读间延迟1秒
|
||||
if slack_client.rtm_connect():
|
||||
print("StarterBot connected and running!")
|
||||
while True:
|
||||
command, channel = parse_slack_output(slack_client.rtm_read())
|
||||
if command and channel:
|
||||
handle_command(command, channel)
|
||||
time.sleep(READ_WEBSOCKET_DELAY)
|
||||
else:
|
||||
print("Connection failed. Invalid Slack token or bot ID?")
|
||||
|
||||
```
|
||||
|
||||
Slack client连接到Slack RTM API WebSocket(Slack RTM API 双向通信),然后当解析信息来自firehose时会不断循环.如果任何这些消息都指向StarterBot,那么一个被称作handle_command的函数会决定做什么.
|
||||
|
||||
接下来添加两个函数来解析Slack输出和handle commands.
|
||||
|
||||
```
|
||||
def handle_command(command, channel):
|
||||
"""
|
||||
Receives commands directed at the bot and determines if they
|
||||
are valid commands. If so, then acts on the commands. If not,
|
||||
returns back what it needs for clarification.
|
||||
"""
|
||||
response = "Not sure what you mean. Use the *" + EXAMPLE_COMMAND + \
|
||||
"* command with numbers, delimited by spaces."
|
||||
if command.startswith(EXAMPLE_COMMAND):
|
||||
response = "Sure...write some more code then I can do that!"
|
||||
slack_client.api_call("chat.postMessage", channel=channel,
|
||||
text=response, as_user=True)
|
||||
|
||||
def parse_slack_output(slack_rtm_output):
|
||||
"""
|
||||
The Slack Real Time Messaging API is an events firehose.
|
||||
this parsing function returns None unless a message is
|
||||
directed at the Bot, based on its ID.
|
||||
"""
|
||||
output_list = slack_rtm_output
|
||||
if output_list and len(output_list) > 0:
|
||||
for output in output_list:
|
||||
if output and 'text' in output and AT_BOT in output['text']:
|
||||
# return text after the @ mention, whitespace removed 在@之后提到返回文本,空格删除
|
||||
return output['text'].split(AT_BOT)[1].strip().lower(), \
|
||||
output['channel']
|
||||
return None, None
|
||||
|
||||
```
|
||||
|
||||
parse_slack_output函数从Slack接受信息并且如果他们指向我们的StarterBot时会作出判断.消息通过给我们bot的ID一个直接命令启动,然后交由我们的代码处理.-目前只是通过SLack管道发布一个消息回去告诉用户去多写一些Python代码!
|
||||
|
||||
这是整个程序看上去应该如何组合在一起 (你也可以 [在GitHub中查看文件](https://github.com/mattmakai/slack-starterbot/blob/master/starterbot.py)):
|
||||
|
||||
```
|
||||
import os
|
||||
import time
|
||||
from slackclient import SlackClient
|
||||
|
||||
# 把 starterbot 的 ID作为一个环境变量
|
||||
BOT_ID = os.environ.get("BOT_ID")
|
||||
|
||||
# constants 常量
|
||||
AT_BOT = "<@" + BOT_ID + ">:"
|
||||
EXAMPLE_COMMAND = "do"
|
||||
|
||||
# 实例化Slack和Twilio clients
|
||||
slack_client = SlackClient(os.environ.get('SLACK_BOT_TOKEN'))
|
||||
|
||||
def handle_command(command, channel):
|
||||
"""
|
||||
Receives commands directed at the bot and determines if they
|
||||
are valid commands. If so, then acts on the commands. If not,
|
||||
returns back what it needs for clarification.
|
||||
"""
|
||||
response = "Not sure what you mean. Use the *" + EXAMPLE_COMMAND + \
|
||||
"* command with numbers, delimited by spaces."
|
||||
if command.startswith(EXAMPLE_COMMAND):
|
||||
response = "Sure...write some more code then I can do that!"
|
||||
slack_client.api_call("chat.postMessage", channel=channel,
|
||||
text=response, as_user=True)
|
||||
|
||||
def parse_slack_output(slack_rtm_output):
|
||||
"""
|
||||
The Slack Real Time Messaging API is an events firehose.
|
||||
this parsing function returns None unless a message is
|
||||
directed at the Bot, based on its ID.
|
||||
"""
|
||||
output_list = slack_rtm_output
|
||||
if output_list and len(output_list) > 0:
|
||||
for output in output_list:
|
||||
if output and 'text' in output and AT_BOT in output['text']:
|
||||
# 在@之后提到返回文本,空格删除
|
||||
return output['text'].split(AT_BOT)[1].strip().lower(), \
|
||||
output['channel']
|
||||
return None, None
|
||||
|
||||
if __name__ == "__main__":
|
||||
READ_WEBSOCKET_DELAY = 1 # 1 second delay between reading from firehose
|
||||
if slack_client.rtm_connect():
|
||||
print("StarterBot connected and running!")
|
||||
while True:
|
||||
command, channel = parse_slack_output(slack_client.rtm_read())
|
||||
if command and channel:
|
||||
handle_command(command, channel)
|
||||
time.sleep(READ_WEBSOCKET_DELAY)
|
||||
else:
|
||||
print("Connection failed. Invalid Slack token or bot ID?")
|
||||
|
||||
```
|
||||
|
||||
现在这是我们在这里所有的在命令行上通过python starterbot.py可以启动我们StarterBot的代码.
|
||||
|
||||
![当StarterBot开始运行而且连接到API的输出通道.](https://www.fullstackpython.com/source/static/img/160604-simple-python-slack-bot/starterbot-running.png)
|
||||
|
||||
在 Slack 中创建新管道并且把 StarterBot 添加进来,或者直接把 StarterBot 添加进一个已经存在的管道。
|
||||
|
||||
![在Slack界面创建一个新通道并且请求StarterBot.](https://www.fullstackpython.com/source/static/img/160604-simple-python-slack-bot/create-channel.png)
|
||||
|
||||
现在在管道中启动 StarterBot。
|
||||
|
||||
![在你的Slack通道里给的StarterBot命令.](https://www.fullstackpython.com/source/static/img/160604-simple-python-slack-bot/working-starterbot.png)
|
||||
|
||||
当你从bot得到的响应中遇见问题时,这是你一种可能你想去做的修改.正如上面所写的这个教程,其中一行AT_BOT = "<@" + BOT_ID + ">:",在"@starter"后需要一个冒号(或者任何你自己所命名的特定bot).移除这些:从AT_BOT结束后的字符串.Slack clients似乎需要在@一个人名后加一个冒号,但这好像是有些不协调的.
|
||||
|
||||
### 结束
|
||||
|
||||
好吧,你现在已经获得一个简易的你可以在代码中很多地方加入你想创建任何特性的StarterBot.
|
||||
|
||||
这里有很多你可以使用的Slack RTM API 和 Python.看看通过这些文章你还可以学习到什么:
|
||||
|
||||
* 附加一个持久的[relational database 关系数据库](https://www.fullstackpython.com/databases.html) 或者 [NoSQL back-end](https://www.fullstackpython.com/no-sql-datastore.html) 比如 [PostgreSQL](https://www.fullstackpython.com/postgresql.html),[MySQL](https://www.fullstackpython.com/mysql.html) 或者 [SQLite](https://www.fullstackpython.com/sqlite.html) 用来保存和检索用户数据
|
||||
* 添加另外一个与bot互动的通道 [via SMS](https://www.twilio.com/blog/2016/05/build-sms-slack-bot-python.html) 或者 [phone calls](https://www.twilio.com/blog/2016/05/add-phone-calling-slack-python.html)
|
||||
* [Integrate other web APIs](https://www.fullstackpython.com/api-integration.html) 比如 [GitHub](https://developer.github.com/v3/), [Twilio](https://www.twilio.com/docs) 或者 [api.ai](https://docs.api.ai/)
|
||||
|
||||
有问题? 通过Twitter联系我 [@fullstackpython](https://twitter.com/fullstackpython) or [@mattmakai](https://twitter.com/mattmakai). 这是我在GitHub上的用户名 [mattmakai](https://github.com/mattmakai).
|
||||
|
||||
这篇文章还有问题? Fork [this page's source on GitHub 这是在GitHub上的页面源](https://github.com/mattmakai/fullstackpython.com/blob/gh-pages/source/content/posts/160604-build-first-slack-bot-python.markdown).
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
via: https://www.fullstackpython.com/blog/build-first-slack-bot-python.html
|
||||
|
||||
作者: [Matt Makai][a]
|
||||
译者:[jiajia9llinuxer](https://github.com/jiajia9linuxer)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出aa
|
||||
|
||||
[a]: https://www.fullstackpython.com/about-author.html
|
@ -0,0 +1,136 @@
|
||||
第3部分 - 如何使用Ubuntu系统上Octave 4.0的先进数学技术处理音频文件
|
||||
=====
|
||||
|
||||
我们的数字音频处理技术第三部分涵盖了信号调制内容,将解释如何进行调幅,颤音效果,和频率变化。
|
||||
### 调制
|
||||
|
||||
#### 调幅
|
||||
|
||||
正如它的名字暗示的那样, 影响正弦信号的振幅变化依据传递的信息不断改变。正弦波因为承载者大量的信息被称作载波。这种调制技术被用于许多的商业广播和市民信息传输波段(AM).
|
||||
|
||||
#### 为何要使用调幅技术?
|
||||
|
||||
**调制发射.**
|
||||
|
||||
假设信道是免费资源,我们需要天线发射和接收信号。这要求有效的电磁信号发射天线,它的大小和要被发射的信号的波长应该是同一数量级。很多信号,包括音频成分,通常100赫兹或更少。对于这些信号,如果直接发射,我们就需要建立300公里的天线。如果信号调制用于在100MZ的高频载波中打印信息,那么天线仅仅需要1米(横向长度)。
|
||||
|
||||
**集中调制与多通道.**
|
||||
|
||||
假设多个信号占用一个通道,可以调制不同的信号到接收特定信号的不同位置。使用集中调制(“复用”)的应用有遥感探测数据,立体声调频收音机和长途电话。
|
||||
|
||||
**克服设备限制的调制.**
|
||||
|
||||
信号处理设备,比如过滤器,放大器,以及可以被重新创建的设备它们的性能依赖于信号在频域中的境况以及高频率和低频信号的关系。调制可以用于传递信号在频域中的位置,更容易满足设计的要求。调制也可以将“宽带信号“(高频和低频的比例很大的信号)转换成”窄带“信号
|
||||
|
||||
**音频特效**
|
||||
|
||||
许多音频特效由于引人注目和处理信号的便捷性使用了调幅技术。我们可以说出很多,比如颤音、合唱、镶边等等。这种实用性就是我们关注它的原因。
|
||||
|
||||
### 颤音效果
|
||||
|
||||
颤音效果是调幅最简单的应用,为实现这样的效果,我们会用周期信号改变(乘)音频信号,使用正弦或其他。
|
||||
|
||||
```
|
||||
>> tremolo='tremolo.ogg';
|
||||
>> fs=44100;
|
||||
>> t=0:1/fs:10;
|
||||
>> wo=2*pi*440*t;
|
||||
>> wa=2*pi*1.2*t;
|
||||
>> audiowrite(tremolo, cos(wa).*cos(wo),fs);
|
||||
```
|
||||
|
||||
[![Tremolo](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/tremolo.png)](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/big/tremolo.png)
|
||||
|
||||
这将创造一个正弦形状的信号,它的效果就像‘颤音’。
|
||||
|
||||
[![Tremolo Shape](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/tremoloshape.png)](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/big/tremoloshape.png)
|
||||
|
||||
### 在真实音频文件中的颤音
|
||||
|
||||
现在我们将展示真实世界中的颤音效果。首先,我们使用之前记录过男性发声‘A’的音频文件。这个信号图就像下面这样:
|
||||
|
||||
```
|
||||
>> [y,fs]=audioread('A.ogg');
|
||||
>> plot(y);
|
||||
```
|
||||
|
||||
[![Vocal](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/avocalmale.png)](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/big/avocalmale.png)
|
||||
|
||||
现在我们将创建一个完整的正弦信号,使用如下的参数:
|
||||
|
||||
```
|
||||
Amplitude = 1
|
||||
Frequency= 1.5Hz
|
||||
Phase = 0
|
||||
```
|
||||
|
||||
```
|
||||
>> t=0:1/fs:4.99999999;
|
||||
>> t=t(:);
|
||||
>> w=2*pi*1.5*t;
|
||||
>> q=cos(w);
|
||||
>> plot(q);
|
||||
```
|
||||
|
||||
注意: 当我们创建一组时间值时,默认情况下,它是以列的格式呈现,如, 1x220500的值。为了乘以这样的值,必须将其变成行的形式(220500x1). 这就是t=t(:)命令的作用。
|
||||
|
||||
[![Sinusodial](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/sinusoidal.png)](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/big/sinusoidal.png)
|
||||
|
||||
我们将创建第二份ogg音频格式的文件,它包含了如下的调制信号:
|
||||
|
||||
```
|
||||
>> tremolo='tremolo.ogg';
|
||||
>> audiowrite(tremolo, q.*y,fs);
|
||||
```
|
||||
|
||||
[![](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/tremsignal1.png)](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/big/tremsignal1.png)[![Tremolo Signal](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/tremolsignal1.png)](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/big/tremolsignal1.png)
|
||||
|
||||
### 频率变化
|
||||
|
||||
我们可以改变频率保持一些有趣的音效,比如原音变形,电影音效,多人比赛。
|
||||
|
||||
#### 正弦频率调制的影响
|
||||
|
||||
这是正弦调制频率变化的演示代码,根据方程:
|
||||
|
||||
```
|
||||
Y=Ac*Cos(wo*Cos(wo/k))
|
||||
```
|
||||
|
||||
Where:
|
||||
|
||||
```
|
||||
Ac = Amplitude
|
||||
|
||||
wo = fundamental frequency
|
||||
|
||||
k = scalar divisor
|
||||
```
|
||||
|
||||
```
|
||||
>> fm='fm.ogg';
|
||||
>> fs=44100;
|
||||
>> t=0:1/fs:10;
|
||||
>> w=2*pi*442*t;
|
||||
>> audiowrite(fm, cos(cos(w/1500).*w), fs);
|
||||
>> [y,fs]=audioread('fm.ogg');
|
||||
>> figure (); plot (y);
|
||||
```
|
||||
|
||||
信号图:
|
||||
|
||||
[![](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/fmod.png)](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/big/fmod.png)
|
||||
|
||||
你可以使用几乎任何类型的周期函数频率调制。本例中,我们仅仅用了一个正弦函数。请大胆的改变函数频率,用复合函数,甚至改变函数的类型。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
经由: https://www.howtoforge.com/tutorial/ubuntu-octave-audio-processing-part-3/
|
||||
|
||||
作者:[David Duarte][a]
|
||||
译者:[theArcticOcean](https://github.com/theArcticOcean)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.howtoforge.com/tutorial/ubuntu-octave-audio-processing-part-3/
|
@ -0,0 +1,183 @@
|
||||
把具有亚马逊 Cognito 标志软件开发工具包(SDK)的 webpack 用于 JavaScript
|
||||
=====
|
||||
|
||||
这篇文章针对开发和部署基于 JavaScriot 应用(Node.js 服务器端或者客户端服务器端)的所有经验水平的开发者。通过本文,你将看到如何把 AWS SDK, 亚马逊标志软件开发工具包(SDK)嵌入到 JavaScript 中,以及如何使用流行的【webpack】【1】模块打包机。
|
||||
|
||||
2016年7月,亚马逊网站服务【推出亚马逊 Cognito 用户库】【2】,这个新特性极大的方便了开发者在移动和 Web 应用程序上添加注册和登录功能。为了让开发者更容易在自己的应用程序中实现用户库功能,我们也发布了【针对 JavaScript 的亚马逊 Cognito 特性 SDK】【3】。
|
||||
|
||||
亚马逊 Cognito 用户库可以让你在移动和 Web 应用程序上添加用户注册和登录功能更加容易。全托管用户库可以扩展到数以百万计的用户,你可以在一个 AWS 账户下有多重目录。创建一个用户库只需要几分钟的时间,并且你可以决定当一个新用户在你的应用程序或服务上注册时哪些属性(包括地址,邮箱,电话号码以及自定义属性)是强制的,哪些是可选择的。你的应用程序也可以指定所需的密码强度,指定用户需要进行多因素认证,通过电话号码或者邮件地址来验证新用户,从而进一步加强应用程序的安全性。
|
||||
|
||||
如果你是首次接触用于 JavaScript 的亚马逊 Cognito 标志 SDk,那么请先阅读【这篇 AWS 文章】【4】作为开始。
|
||||
|
||||
### 为什么在 JavaScript 上使用具有资产模块的亚马逊 Cogtito 标志 SDK
|
||||
|
||||
今天,针对移动和桌面的现代 Web 应用程序都能为用户提供安全、快捷、灵敏以及类本地应用的体验。毫无疑问,现代的浏览器功能强大,能够满足大量可能的实现方法。许多流行的实现很大程度上依赖于 JavaScript 应用程序通过某种形式的资产包装和/或模块捆绑进行部署。这使得许多开发人员能够很好的维护自己的 JavaScript 应用程序,并且可以通过使用脚本标签创建一个或多个可以加载到客户端浏览器上的文件。
|
||||
|
||||
关于如何实现打包有许多教育思想,包括任务运行者比如【Grunt】【5】和【Gulp】,还有打包机比如【Browserity】【7】。然而,一个普遍的共识是,资产打包不仅仅是关于缩短加载时间 - 它可以在确保可测试性和稳定性的前提下使你的应用程序模块化。
|
||||
|
||||
### 把具有亚马逊 Cognito 标志 SDK 的 webpack 用于 JavaScript
|
||||
|
||||
有许多请求需要我们提供如何在 webpack 环境下整合用于 JavaScript 的亚马逊 Cognito 标志 SDK 的更多细节。我们特地询问了如何确保 webpack 正确管理下面三方的关系:
|
||||
|
||||
- [JavaScript BN library for BigInteger computation][8] (jsbn)
|
||||
- [an extension to jsbn][9] the with the rest of the jsbn methods including most public BigInteger methods (jsbn2)
|
||||
- the [Stanford JavaScript Crypto Library][10] (sjcl)
|
||||
- 【用于 BigInteger 计算的 JavaScript 库】【8】(jsbn)
|
||||
- 【jsbn 扩展】【9】其余的 jsbn 方法包含大多数公共 BigInteger 方法(jsbn2)
|
||||
- 【标准 JavaScript Crypto 库】【10】(jscl)
|
||||
|
||||
通过这些例子,可以看到,下面这些 bower 库都被 bower.json 使用
|
||||
|
||||
```
|
||||
"aws-cognito-sdk": "https://raw.githubusercontent.com/aws/amazon-cognito-identity-js/master/dist/aws-cognito-sdk.js",
|
||||
"amazon-cognito-identity": "https://raw.githubusercontent.com/aws/amazon-cognito-identity-js/master/dist/amazon-cognito-identity.min.js",
|
||||
"sjcl": "https://raw.githubusercontent.com/bitwiseshiftleft/sjcl/master/sjcl.js",
|
||||
"jsbn": "https://raw.githubusercontent.com/andyperlitch/jsbn/master/index.js",
|
||||
```
|
||||
|
||||
出于我们前面给出的所有关于通过资产打包来改善进程重要性的原因,除非你的应用程序非常小,否则使用像 webpack 这样的资产打包工具几乎总是必须的。当然,还有一个方法是可以通过使用标签简单的处理所有依赖关系。然而,这会污染全局命名空间,而且不能够提供最理想的资源管理和加载方法。许多开发者首次使用的是具有标准 babel 加载机的标准 webpack.config.js 文件,像下面展示的这样。
|
||||
|
||||
```
|
||||
{
|
||||
/** test for file ending in js or jsx
|
||||
* exclude node_module and bower_components - we dont want to babel these
|
||||
* use the babel loader
|
||||
* apply the react and es2015 (es6) transformations **/
|
||||
|
||||
test: /\.jsx?$/,
|
||||
exclude: /(node_modules|bower_components)/,
|
||||
loader: 'babel',
|
||||
query: {
|
||||
presets: ['react', 'es2015']
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
需要重点记住的是,这个配置没有考虑一些第三方关系,这些被针对 JavaScript 的亚马逊 Cognito 标志 SDK 使用的第三方关系目前没有使用【JavaScript 通用模块定义(UMD)】【11】。
|
||||
|
||||
UMD 模式试图提供基于当前最流行的脚本加载器比如【RequireJS】【12】和【CommonJS】【13】兼容性的异步模块定义【AMD】。
|
||||
|
||||
这是 webpack 所依赖的模式,为了让 webpack 能够工作,我们必须进行一些改变。不做这些改变,你可能会遇到下面这些错误。
|
||||
|
||||
```
|
||||
amazon-cognito-identity.min.js:19 Uncaught ReferenceError: BigInteger is not defined
|
||||
```
|
||||
这样一个错误可能会在调用 AWSCognito.CognitoIdentityServiceProvider.CognitoUser property authenticateUser 的时候出现。这是一个错误出现的例子,我们可以利用 webpack 的导入导出加载能力来解决这个错误。
|
||||
|
||||
### 使用 webpack 加载器
|
||||
|
||||
根据【webpack 文件】,”加载器允许你按你的需求来预处理或“加载”文件。加载器是一种在其他搭建工具中类似 “tasks” 的工具,他可以提供一个处理前端搭建步骤的强大方法。加载器可以把一个文件从一种语言转化成另一种语言,比如把 CoffeeScript 转化成 JavaScript 或者作为数据 URLs 的内联图像。“
|
||||
|
||||
为了解决 UMD 的兼容性缺乏问题,你必须依赖两个具体的加载器,导入和导出加载器。
|
||||
|
||||
#### 使用导出加载器
|
||||
|
||||
在使用针对 JavaScript 的亚马逊 Cognito 标志 SDK 的情况下,我们需要确保把 theAWSCognito 变量导出到需要它们的模块/导出范围(针对 ES6).
|
||||
|
||||
```
|
||||
{
|
||||
test: /aws-cognito-sdk\/index\.js/,
|
||||
loader: 'exports?AWSCognito'
|
||||
}
|
||||
```
|
||||
|
||||
使用导出加载器可以在 webpack 创建的束【bundle】内导出模块。到目前, AWSCognito 和 AWS 都可以在需要它们的时候导出【针对 ES6】.
|
||||
|
||||
```
|
||||
var AWSCognito = require('aws-cognito-sdk')
|
||||
|
||||
/*** EXPORTS from export-loader ***/
|
||||
module.exports = AWSCongito
|
||||
```
|
||||
|
||||
这儿可以找到更多关于导出加载器的信息。
|
||||
|
||||
#### 使用导入加载器
|
||||
|
||||
导入加载器主要用于把(import)变量导入到另一个模块中。当第三方模块需要依赖全局变量的时候,导出加载器非常有用,比如针对 JavaScript 的亚马逊 Cognito 标志 SDK 需要依赖 BigInteger 或者sjcl 的时候。
|
||||
|
||||
如果你不使用 webpack 加载器,下面这些内容会在一个束【bundle】中生成。
|
||||
|
||||
```
|
||||
__webpack_require__(431); // refers to jsbin
|
||||
__webpack_require__(432); // refers to sjcl
|
||||
```
|
||||
|
||||
因为 jsbin 和 sjcl 都不能导出任何东西,因此任何依赖于这些模块的调用都会导致一个错误。
|
||||
|
||||
为了解决这个问题,我们需要使用下面的 webpack 加载器配置:
|
||||
|
||||
```
|
||||
{
|
||||
test: /amazon-cognito-identity\/index\.js/,
|
||||
loader: 'imports?jsbn,BigInteger=>jsbn.BigInteger,sjcl'
|
||||
},
|
||||
{
|
||||
test: /sjcl\/index\.js/,
|
||||
loader: 'imports?sjcl'
|
||||
}
|
||||
```
|
||||
|
||||
这个配置把下面的这些内容嵌入到了由 webpack 创建的束【bundle】中(此时是 bundle.js)。
|
||||
|
||||
````
|
||||
/*** IMPORTS FROM imports-loader ***/
|
||||
var jsbn = __webpack_require__(431);
|
||||
var BigInteger = jsbn.BigInteger;
|
||||
var sjcl = __webpack_require__(432);
|
||||
```
|
||||
|
||||
结果,jsbn, BigInteger 和 sjcl 都被从它们各自的模块中导入到了用于 JavaScript 的亚马逊 Cognito 标志 SDK 中。
|
||||
|
||||
有关导出加载器的更多信息可以在这儿找到【15】。
|
||||
|
||||
### 下一步
|
||||
|
||||
如果你具有快速学习经验,我们鼓励你下载【用于 JavaScript 的亚马逊 Cognito 标志 SDk】【16】,并在这篇文章的指导下通过 webpack 开始构建你的应用程序。
|
||||
|
||||
|
||||
如果你有任何意见或问题,请在下面自由评论,也可以发邮件到 teichtah@amazon.com 或者在这儿提出问题【17】.
|
||||
|
||||
### 引用
|
||||
|
||||
这篇文章引用了下面这些第三方资源
|
||||
|
||||
- webpack - https://webpack.github.io/
|
||||
- webpack 文件 - http://webpack.github.io/docs/what-is-webpack.html
|
||||
- webpack 导出加载器 - https://github.com/webpack/exports-loader
|
||||
- webpack 导入加载器 - https://github.com/webpack/imports-loader
|
||||
- 用于 BigInteger 计算的 JavaScript BN 库- http://www-cs-students.stanford.edu/~tjw/jsbn/jsbn.js
|
||||
- jsbns - http://www-cs-students.stanford.edu/~tjw/jsbn/jsbn2.js
|
||||
- 标准 JavaScript Crypto 库 - https://github.com/bitwiseshiftleft/sjcl
|
||||
- RequireJS - http://requirejs.org/
|
||||
- CommonJS - http://www.commonjs.org/
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://mobile.awsblog.com/post/Tx1A84CLMDJ744T/Using-webpack-with-the-Amazon-Cognito-Identity-SDK-for-JavaScript?utm_source=webopsweekly&utm_medium=email
|
||||
|
||||
作者:[Marc Teichtahl ][a]
|
||||
译者:[ucasFL](https://github.com/ucasFL)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://mobile.awsblog.com/blog/author/Marc+Teichtahl
|
||||
[1]: https://webpack.github.io/
|
||||
[2]: https://blogs.aws.amazon.com/security/post/Tx13NVD4AWG9QK9/Amazon-Cognito-Your-User-Pools-is-Now-Generally-Available
|
||||
[3]: https://github.com/aws/amazon-cognito-identity-js
|
||||
[4]: http://mobile.awsblog.com/post/Tx2O14ZY8A5LFHT/Accessing-Your-User-Pools-using-the-Amazon-Cognito-Identity-SDK-for-JavaScript
|
||||
[5]: http://gruntjs.com/
|
||||
[6]: http://gulpjs.com/
|
||||
[7]: http://browserify.org/
|
||||
[8]: http://www-cs-students.stanford.edu/~tjw/jsbn/jsbn.js
|
||||
[9]: http://www-cs-students.stanford.edu/~tjw/jsbn/jsbn2.js
|
||||
[10]: https://github.com/bitwiseshiftleft/sjcl
|
||||
[11]: https://github.com/umdjs/umd
|
||||
[12]: http://requirejs.org/
|
||||
[13]: http://www.commonjs.org/
|
||||
[14]: http://webpack.github.io/docs/what-is-webpack.html
|
||||
[15]: https://github.com/webpack/imports-loader
|
||||
[16]: https://github.com/aws/amazon-cognito-identity-js
|
||||
[17]: https://github.com/aws/amazon-cognito-identity-js/issues
|
||||
|
Loading…
Reference in New Issue
Block a user