apeescape2.com
  • メイン
  • その他
  • ブランドデザイン
  • リモートの台頭
  • アジャイルタレント
バックエンド

サポートアプリにEメールを使用する新しい方法:AWSチュートリアル

電子メールは他のコミュニケーションプラットフォームほどクールではないかもしれませんが、それでも作業は楽しいものです。私は最近、モバイルアプリにメッセージングを実装するという任務を負いました。唯一の落とし穴は、実際のコミュニケーションは電子メールを介して行う必要があるということでした。アプリユーザーは、テキストメッセージを送信するのと同じように、サポートチームと通信できるようにしたいと考えていました。サポートチームのメンバーは、これらのメッセージを電子メールで受信する必要があり、また、発信元のユーザーに応答できる必要がありました。エンドユーザーにとって、他の最新のメッセージングアプリと同じように見えて機能するために必要なものはすべてあります。

この記事では、JavaといくつかのAmazonのWebサービスを使用して、上記と同様のサービスを実装する方法を見ていきます。有効なAWSアカウント、ドメイン名、およびお気に入りのJavaIDEへのアクセスが必要です。

インフラストラクチャ

コードを作成する前に、メールのルーティングと利用に必要なAWSサービスを設定します。メールの送受信にはSESを使用し、受信メッセージのルーティングにはSNS + SQSを使用します。



AWSを使用してプログラムでEメールを消費する

AmazonSESを使用してサポートアプリケーションで電子メールを活性化します。 つぶやき

それはすべてここでSESから始まります。 AWSアカウントにログインし、SESコンソールに移動することから始めます。

始める前に、メールを送信できる確認済みのドメイン名が必要です。

これは、ユーザーがメールメッセージを送信し、サポートメンバーが返信するドメインアプリになります。 SESを使用したドメインの確認は簡単なプロセスであり、詳細情報を見つけることができます ここに 。

SESを初めて使用する場合、または送信制限をリクエストしていない場合、アカウントはサンドボックス化されます。これは、AWSで確認されていないアドレスにメールを送信できないことを意味します。これにより、チュートリアルの後半で架空のヘルプデスクに電子メールを送信するときにエラーが発生する可能性があります。これを回避するには、SESコンソールの[電子メールアドレス]タブで、ヘルプデスクとして使用する予定の電子メールアドレスを確認できます。

確認済みのドメインを取得したら、ルールセットを作成できます。 SESコンソールの[ルールセット]タブに移動し、新しい受信ルールを作成します。

受信ルールを作成するときの最初のステップは、受信者を定義することです。

受信者フィルターを使用すると、SESが消費する電子メールと、各受信メッセージの処理方法を定義できます。ここで定義する受信者は、アプリのユーザーメッセージが電子メールで送信されるドメインとアドレスパターンに一致する必要があります。ここでの最も単純なケースは、以前に確認したドメインの受信者を追加することです。 example.com 。これにより、SESは、に送信されるすべての電子メールにルールを適用するように構成されます。 example.com 。 (例えば。 [メール保護] 、 [メール保護] )。

ドメイン全体のルールを作成するには、次の受信者を追加します。 example.com 。

住所パターンを一致させることも可能です。これは、着信メッセージを異なるSQSキューにルーティングする場合に役立ちます。

キューAとキューBがあるとします。2つの受信者を追加できます。 [メール保護] そして [メール保護] 。キューAにメッセージを挿入する場合は、メールで送信します [メール保護] これの一部は私たちと一致します [メール保護] 受信者。 +と@の間はすべて任意のユーザーデータであり、SESのアドレス照合には影響しません。キューBに挿入するには、aをbに置き換えるだけです。

受信者を定義したら、次のステップは、新しい電子メールを消費した後にSESが実行するアクションを構成することです。最終的にはこれらをSQSにまとめたいと考えていますが、現在、SESからSQSに直接移動することはできません。ギャップを埋めるには、SNSを利用する必要があります。 SNSアクションを選択し、新しいトピックを作成します。最終的には、メッセージをSQSに挿入するようにこのトピックを設定します。

[Create SNSトピック]を選択して、名前を付けます。

トピックを作成したら、メッセージのエンコーディングを選択する必要があります。特殊文字を保持するためにBase64を使用します。選択したエンコーディングは、サービスでメッセージを使用するときにメッセージがデコードされる方法に影響します。

ルールを設定したら、名前を付けるだけです。

次のステップはSQSとSNSの設定です。そのために、SQSコンソールに移動して新しいキューを作成する必要があります。

簡単にするために、SNSトピックと同じ名前を使用しています。

キューを定義したら、アクセスポリシーを調整する必要があります。 SNSトピックに挿入の許可を与えるだけです。これは、SNSトピックarnに一致する条件を追加することで実現できます。

値フィールドには、SESが通知しているSNSトピックのARNを入力する必要があります。

SQSを設定したら、SNSコンソールに戻って、トピックを設定し、光沢のある新しいSQSキューに通知を挿入します。

SNSコンソールで、SESが通知しているトピックを選択します。そこから、新しいサブスクリプションを作成します。サブスクリプションプロトコルはAmazonSQSである必要があり、宛先は先ほど生成したSQSキューのARNである必要があります。

その後、方程式のAWS側をすべて設定する必要があります。私たちは自分自身に電子メールを送ることによって私たちの仕事をテストすることができます。 SESで設定されたドメインにメールを送信してから、SQSコンソールに移動してキューを選択します。あなたはあなたの電子メールを含むペイロードを見ることができるはずです。

メールを処理するJavaサービス

さあ、楽しい部分に移りましょう!このセクションでは、メッセージの送信と受信メールの処理が可能なシンプルなマイクロサービスを作成します。最初のステップは、ユーザーに代わってサポートデスクに電子メールを送信するAPIを定義することです。

簡単なメモ。このサービスのビジネスロジックコンポーネントに焦点を当て、RESTエンドポイントや永続性レイヤーを定義することはしません。

に Springサービスを構築する 、SpringBootとMavenを使用します。 Spring Initializerを使用して、プロジェクトを生成できます。 start.spring.io 。

まず、pom.xmlは次のようになります。

4.0.0 com.toptal.tutorials email-processor 0.0.1-SNAPSHOT jar email-processor A simple 'micro-service' for emailing support on behalf of a user and processing replies org.springframework.boot spring-boot-starter-parent 1.3.5.RELEASE UTF-8 1.8 org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin

ユーザーに代わってサポートにメールを送信する

まず、ユーザーに代わってサポートデスクにメールを送信するためのBeanを定義しましょう。このBeanの役割は、ユーザーIDからの受信メッセージを処理し、そのメッセージを事前定義されたサポートデスクの電子メールアドレスに電子メールで送信することです。

インターフェースを定義することから始めましょう。

public interface SupportBean { /** * Send a message to the application support desk on behalf of a user * @param fromUserId The ID of the originating user * @param message The message to send */ void messageSupport(long fromUserId, String message); }

そして空の実装:

@Component public class SupportBeanSesImpl implements SupportBean { /** * Email address for our application help-desk * This is the destination address user support emails will be sent to */ private static final String SUPPORT_EMAIL_ADDRESS = ' [email protected] '; @Override public void messageSupport(long fromUserId, String message) { //todo: send an email to our support address } }

また、AWS SDKをpomに追加しましょう。SESクライアントを使用して、メールを送信します。

com.amazonaws aws-java-sdk 1.11.5

最初に行う必要があるのは、ユーザーのメッセージを送信するためのメールアドレスを生成することです。私たちが生成するアドレスは、私たちのサービスの消費側で重要な役割を果たします。ヘルプデスクの返信を元のユーザーにルーティングするのに十分な情報が含まれている必要があります。

これを実現するために、生成されたメールアドレスに発信元のユーザーIDを含めます。物事をきれいに保つために、ユーザーIDを含むオブジェクトを作成し、そのオブジェクトのBase64エンコードされたJSON文字列をメールアドレスとして使用します。

ユーザーIDをメールアドレスに変換する新しいBeanを作成しましょう。

public interface UserEmailBean { /** * Returns a unique per user email address * @param userID Input user ID * @return An email address unique for the input userID */ String emailAddressForUserID(long userID); }

必要な同意と、JSONのシリアル化に役立つ単純な内部クラスを追加することから実装を始めましょう。

@Component public class UserEmailBeanJSONImpl implements UserEmailBean { /** * The TLD for all our generated email addresses */ private static final String EMAIL_DOMAIN = 'example.com'; /** * com.fasterxml.jackson.databind.ObjectMapper used to create a JSON object including our user ID */ private final ObjectMapper objectMapper = new ObjectMapper(); @Override public String emailAddressForUserID(long userID) { //todo: create the email address return null; } /** * Simple helper class we will serialize. * The JSON representation of this class will become our user email address */ private static class UserDetails{ private Long userID; public Long getUserID() { return userID; } public void setUserID(Long userID) { this.userID = userID; } } }

メールアドレスの生成は簡単です。必要なのは、UserDetailsオブジェクトを作成し、Base64でJSON表現をエンコードすることだけです。 createAddressForUserIDメソッドの完成版は、次のようになります。

@Override public String emailAddressForUserID(long userID) { UserDetails userDetails = new UserDetails(); userDetails.setUserID(userID); //create a JSON representation. String jsonString = objectMapper.writeValueAsString(userDetails); //Base64 encode it String base64String = Base64.getEncoder().encodeToString(jsonString.getBytes()); //create an email address out of it String emailAddress = base64String + '@' + EMAIL_DOMAIN; return emailAddress; }

これで、SupportBeanSesImplに戻り、作成したばかりの新しい電子メールBeanを使用するように更新できます。

private final UserEmailBean userEmailBean; @Autowired public SupportBeanSesImpl(UserEmailBean userEmailBean) { this.userEmailBean = userEmailBean; } @Override public void messageSupport(long fromUserId, String message) throws JsonProcessingException { //user specific email String fromEmail = userEmailBean.emailAddressForUserID(fromUserId); }

メールを送信するには、AWSSDKに含まれているAWSSESクライアントを使用します。

/** * SES client */ private final AmazonSimpleEmailService amazonSimpleEmailService = new AmazonSimpleEmailServiceClient( new DefaultAWSCredentialsProviderChain() //see http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/auth/DefaultAWSCredentialsProviderChain.html );

DefaultAWSCredentialsProviderChainを利用して認証情報を管理しています。このクラスは、定義されたAWS認証情報を検索します ここに 。

SES、最終的にはSQSへのアクセスがプロビジョニングされたAWSアクセスキーを使用します。詳細については、 アマゾンからのドキュメント 。

次のステップは、 messageSupport AWSSDKを使用してサポートにメールを送信する方法。 SES SDKは、これを簡単なプロセスにします。完成したメソッドは次のようになります。

@Override public void messageSupport(long fromUserId, String message) throws JsonProcessingException { //User specific email String fromEmail = userEmailBean.emailAddressForUserID(fromUserId); //create the email Message supportMessage = new Message( new Content('New support request from userID ' + fromUserId), //Email subject new Body().withText(new Content(message)) //Email body, this contains the user’s message ); //create the send request SendEmailRequest supportEmailRequest = new SendEmailRequest( fromEmail, //From address, our user's generated email new Destination(Collections.singletonList(SUPPORT_EMAIL_ADDRESS)), //to address, our support email address supportMessage //Email body defined above ); //Send it off amazonSimpleEmailService.sendEmail(supportEmailRequest); }

試してみるには、テストクラスを作成し、SupportBeanを挿入します。 SupportBeanSesImplで定義されているSUPPORT_EMAIL_ADDRESSが、所有している電子メールアドレスを指していることを確認してください。 SESアカウントがサンドボックス化されている場合は、このアドレスも確認する必要があります。電子メールアドレスは、SESコンソールの[電子メールアドレス]セクションで確認できます。

@Test public void emailSupport() throws JsonProcessingException { supportBean.messageSupport(1, 'Hello World!'); }

これを実行すると、受信トレイにメッセージが表示されます。さらに良いことに、メッセージに返信して、前に設定したSQSキューを確認してください。返信を含むペイロードが表示されます。

設計統一の原則の例

SQSからの返信の消費

最後のステップは、SQSからのメールを読み込み、メールメッセージを解析し、返信を転送する必要のあるユーザーIDがどのユーザーIDに属しているかを把握することです。

Amazon SQSのようなメッセージキューイングサービスは、速度、信頼性、またはスケーラビリティを損なうことなくサービスが相互に通信できるようにすることで、サービス指向アーキテクチャで重要な役割を果たします。

新しいSQSメッセージをリッスンするために、Spring CloudAWSメッセージングSDKを使用します。これにより、アノテーションを介してSQSメッセージリスナーを設定できるため、ボイラープレートコードをかなり回避できます。

まず、必要な依存関係。

SpringCloudメッセージングの依存関係を追加します。

org.springframework.cloud spring-cloud-aws-messaging

そして、Spring CloudAWSをpom依存関係管理に追加します。

org.springframework.cloud spring-cloud-aws 1.1.0.RELEASE pom import

現在、Spring Cloud AWSはアノテーション駆動型の設定をサポートしていないため、XMLBeanを定義する必要があります。幸いなことに、多くの構成はまったく必要ないため、Beanの定義はかなり軽くなります。このファイルの主なポイントは、アノテーション駆動型キューリスナーを有効にすることです。これにより、メソッドにSqsListenerとしてアノテーションを付けることができます。

リソースフォルダーにaws-config.xmlという名前の新しいXMLファイルを作成します。私たちの定義は次のようになります。

@SpringBootApplication @ImportResource('classpath:aws-config.xml') //Explicit import for our AWS XML bean definition public class EmailProcessorApplication { public static void main(String[] args) { SpringApplication.run(EmailProcessorApplication.class, args); } }

このファイルの重要な部分はです。デフォルトのリージョンも定義しています。これは必須ではありませんが、そうすることで、URLではなく名前でSQSキューを参照できるようになります。 AWS認証情報を定義していません。これらを省略すると、SpringはデフォルトでDefaultAWSCredentialsProviderChainになります。これは、以前にSESBeanで使用したのと同じプロバイダーです。詳細については、 Spring CloudAWSドキュメント 。

Spring BootアプリでこのXML構成を使用するには、明示的にインポートする必要があります。 @SpringBootApplicationクラスに移動して、インポートします。

/** * Bean reasonable for polling SQS and processing new emails */ @Component public class EmailSqsListener { @SuppressWarnings('unused') //IntelliJ isn't quite smart enough to recognize methods marked with @SqsListener yet @SqsListener(value = 'com-example-ses', deletionPolicy = SqsMessageDeletionPolicy.ON_SUCCESS) //Mark this method as a SQS listener //Since we already set up our region we can use the logical queue name here //Spring will automatically delete messages if this method executes successfully public void consumeSqsMessage(@Headers Map headers, //Map of headers returned when requesting a message from SQS //This map will include things like the relieved time, count and message ID @NotificationMessage String rawJsonMessage //JSON string representation of our payload //Spring Cloud AWS supports marshaling here as well //For the sake of simplicity we will work with incoming messages as a JSON object ) throws Exception{ //com.amazonaws.util.json.JSONObject included with the AWS SDK JSONObject jsonSqsMessage = new JSONObject(rawJsonMessage); } }

次に、着信SQSメッセージを処理するBeanを定義しましょう。 Spring Cloud AWSでは、単一のアノテーションでこれを実現できます。

//Pull out the array containing all email addresses this was sent to JSONArray emailAddressArray = jsonSqsMessage.getJSONObject('mail').getJSONArray('destination'); for(int i = 0 ; i

ここでの魔法は@SqsListenerアノテーションにあります。これにより、Springはエグゼキューターをセットアップし、SQSのポーリングを開始します。新しいメッセージが見つかるたびに、注釈付きのメソッドがメッセージの内容とともに呼び出されます。オプションで、受信メッセージをマーシャリングするようにSpring Cloudを構成して、キューリスナー内の強い型のオブジェクトを操作する機能を提供できます。さらに、基になるAWS呼び出しから返された単一のヘッダーまたはすべてのヘッダーのマップを挿入する機能があります。

以前にaws-config.xmlでリージョンを定義したので、ここで論理キュー名を使用できます。省略したい場合は、値を完全修飾SQSURLに置き換えることができます。削除ポリシーも定義しています。これにより、条件が満たされた場合にSQSから着信メッセージを削除するようにSpringが構成されます。 SqsMessageDeletionPolicyには複数のポリシーが定義されており、consumeSqsMessageメソッドが正常に実行された場合にメッセージを削除するようにSpringを構成しています。

また、@ Headersを使用して返されたSQSヘッダーをメソッドに挿入しています。挿入されたマップには、受信したキューとペイロードに関連するメタデータが含まれます。メッセージ本文は@NotificationMessageを使用して挿入されます。 Springは、Jacksonを利用するか、カスタムメッセージ本文コンバーターを介したマーシャリングをサポートします。便宜上、生のJSON文字列を挿入し、AWSSDKに含まれているJSONObjectクラスを使用して処理します。

SQSから取得したペイロードには、大量のデータが含まれます。 JSONObjectを見て、返されるペイロードをよく理解してください。ペイロードには、通過したすべてのAWSサービス、SES、SNS、そして最後にSQSからのデータが含まれています。このチュートリアルのために、私たちは実際には2つのことだけを気にします:これが送信された電子メールアドレスのリストと電子メールの本文です。メールを解析することから始めましょう。

/** * Returns true if the input email address matches our template * @param emailAddress Email to check * @return true if it matches */ boolean emailMatchesUserFormat(String emailAddress);

現実の世界では、ヘルプデスクの返信に元の送信者以外のものが含まれている可能性があるため、ユーザーIDを解析する前にアドレスを確認する必要があります。これにより、サポートデスクは、複数のユーザーに同時にメッセージを送信する機能と、アプリ以外のユーザーを含める機能の両方を利用できるようになります。

UserEmailBeanインターフェースに戻って、別のメソッドを追加しましょう。

@Override public boolean emailMatchesUserFormat(String emailAddress) { //not our address, return right away if(!emailAddress.endsWith('@' + EMAIL_DOMAIN)){ return false; } //We just care about the email part, not the domain part String emailPart = splitEmail(emailAddress); try { //Attempt to decode our email UserDetails userDetails = objectMapper.readValue(Base64.getDecoder().decode(emailPart), UserDetails.class); //We assume this email matches if the address is successfully decoded and marshaled return userDetails != null && userDetails.getUserID() != null; } catch (IllegalArgumentException | IOException e) { //The Base64 decoder will throw an IllegalArgumentException it the input string is not Base64 formatted //Jackson will throw an IOException if it can't read the string into the UserDetails class return false; } } /** * Splits an email address on @ * Returns everything before the @ * @param emailAddress Address to split * @return all parts before @. If no @ is found, the entire address will be returned */ private static String splitEmail(String emailAddress){ if(!emailAddress.contains('@')){ return emailAddress; } return emailAddress.substring(0, emailAddress.indexOf('@')); }

UserEmailBeanJSONImplでは、このメソッドを実装するために、2つのことを実行する必要があります。まず、アドレスがEMAIL_DOMAINで終わっているかどうかを確認してから、マーシャリングできるかどうかを確認します。

private final UserEmailBean userEmailBean; @Autowired public EmailSqsListener(UserEmailBean userEmailBean) { this.userEmailBean = userEmailBean; }

インターフェイスに追加したばかりのemailMatchesUserFormatと、@で電子メールアドレスを分割するための単純なユーティリティメソッドの2つの新しいメソッドを定義しました。 emailMatchesUserFormatの実装は、Base64でデコードし、アドレス部分をUserDetailsヘルパークラスにマーシャルして戻すことで機能します。これが成功した場合は、必要なuserIDが入力されていることを確認します。これがすべてうまくいけば、安全に一致すると見なすことができます。

EmailSqsListenerに戻り、新しく更新されたUserEmailBeanを挿入します。

//Pull our content, remember the content will be Base64 encoded as per our SES settings String encodedContent = jsonSqsMessage.getString('content'); //Create a new String after decoding our body String decodedBody = new String( Base64.getDecoder().decode(encodedContent.getBytes()) ); for(int i = 0 ; i

次に、consumesSqsMethodを更新します。まず、メール本文を解析してみましょう。

private void processEmail(String emailAddress, String emailBody){ }

次に、メールアドレスとメール本文を処理する新しいメソッドを作成しましょう。

//Loop over all sent to addresses for(int i = 0 ; i

そして最後に、一致するものが見つかった場合にこのメソッドを呼び出すように電子メールループを更新します。

/** * Returns the userID from a formatted email address. * Returns null if no userID is found. * @param emailAddress Formatted email address, this address should be verified using {@link #emailMatchesUserFormat(String)} * @return The originating userID if found, null if not */ Long userIDFromEmail(String emailAddress);

processEmailを実装する前に、UserEmailBeanにもう1つのメソッドを追加する必要があります。電子メールからユーザーIDを返すためのメソッドが必要です。 UserEmailBeanインターフェースに戻って、最後のメソッドを追加します。

@Override public Long userIDFromEmail(String emailAddress) { String emailPart = splitEmail(emailAddress); try { //Attempt to decode our email UserDetails userDetails = objectMapper.readValue(Base64.getDecoder().decode(emailPart), UserDetails.class); if(userDetails == null || userDetails.getUserID() == null){ //We couldn't find a userID return null; } //ID found, return it return userDetails.getUserID(); } catch (IllegalArgumentException | IOException e) { //The Base64 decoder will throw an IllegalArgumentException it the input string is not Base64 formatted //Jackson will throw an IOException if it can't read the string into the UserDetails class //Return null since we didn't find a userID return null; } }

このメソッドの目的は、フォーマットされたアドレスからユーザーIDを返すことです。実装は、検証方法と同様になります。 UserEmailBeanJSONImplにアクセスして、このメソッドに入力してみましょう。

private void processEmail(String emailAddress, String emailBody){ //Parse out the email address Long userID = userEmailBean.userIDFromEmail(emailAddress); if(userID == null){ //Whoops, we couldn't find a userID. Abort! return; } }

次に、EmailSqsListenerに戻り、processEmailを更新してこの新しいメソッドを使用します。

jitpack.io https://jitpack.io

すごい!これで、必要なものはほぼすべて揃っています。最後に行う必要があるのは、生のメッセージからの応答を解析することです。

電子メールクライアントは、数年前のWebブラウザと同様に、実装の不整合に悩まされています。

電子メールからの返信を解析することは、実際にはかなり複雑な作業です。電子メールメッセージの形式は標準化されておらず、さまざまな電子メールクライアント間で大きな違いが生じる可能性があります。生の応答には、応答と署名だけではありません。ほとんどの場合、元のメッセージも含まれます。賢い人は メールガン いくつかの課題を説明するすばらしいブログ投稿をまとめます。彼らはまた、電子メールを解析するための機械学習ベースのアプローチをオープンソース化しました。 ここに 。

MailgunライブラリはPythonで記述されているため、チュートリアルでは、より単純なJavaベースのソリューションを使用します。 GitHubユーザーedlioがMITライセンスをまとめました Javaの電子メールパーサー GitHubのライブラリの1つに基づいています。このすばらしいライブラリを使用します。

まず、pomを更新しましょう。https://jitpack.ioを使用してEmailReplyParserを取得します。

com.github.edlio EmailReplyParser v1.0

次に、GitHubの依存関係を追加します。

org.apache.commons commons-email 1.4

また、ApacheCommonsEメールを使用します。生のメールを解析してjavax.mailMimeMessageにした後、EmailReplyParserに渡す必要があります。コモンズの依存関係を追加します。

private void processEmail(String emailAddress, String emailBody) throws Exception { //Parse out the email address Long userID = userEmailBean.userIDFromEmail(emailAddress); if(userID == null){ //Whoops, we couldn't find a userID. Abort! return; } //Default javax.mail session Session session = Session.getDefaultInstance(new Properties()); //Create a new mimeMessage out of the raw email body MimeMessage mimeMessage = MimeMessageUtils.createMimeMessage( session, emailBody ); MimeMessageParser mimeMessageParser = new MimeMessageParser(mimeMessage); //Parse the message mimeMessageParser.parse(); //Parse out the reply for our message String replyText = EmailReplyParser.parseReply(mimeMessageParser.getPlainContent()); //Now we're done! //We have both the userID and the response! System.out.println('Processed reply for userID: ' + userID + '. Reply: ' + replyText); }

これで、EmailSqsListenerに戻って、processEmailを終了できます。この時点で、発信元のユーザーIDと生の電子メール本文があります。あとは、返信を解析するだけです。

これを実現するために、javax.mailとedlioのEmailReplyParserを組み合わせて使用​​します。

|_+_|

要約

以上です!これで、元のユーザーに応答を配信するために必要なすべてのものが揃いました。

見る?メールは楽しいと言ったよ!

この記事では、Amazon WebServicesを使用して複雑なパイプラインを調整する方法について説明しました。この記事では、パイプラインは電子メールを中心に設計されています。これらの同じツールを活用して、インフラストラクチャの保守について心配する必要がなく、代わりにソフトウェアエンジニアリングの楽しい側面に集中できる、さらに複雑なシステムを設計できます。

関連: アマゾンウェブサービスで生産性を高める

iOSで無限ランナーを構築する方法:Cocos2D、自動化など

モバイル

iOSで無限ランナーを構築する方法:Cocos2D、自動化など
OpenGLの概要:3Dテキストレンダリングチュートリアル

OpenGLの概要:3Dテキストレンダリングチュートリアル

技術

人気の投稿
Javaでのリモートフレームバッファサーバーの実装
Javaでのリモートフレームバッファサーバーの実装
ApeeScapeの迅速で実用的なCSSチートシート
ApeeScapeの迅速で実用的なCSSチートシート
ソフトウェアデプロイメントの強化-DockerSwarmチュートリアル
ソフトウェアデプロイメントの強化-DockerSwarmチュートリアル
エクイティクラウドファンディングの次は?
エクイティクラウドファンディングの次は?
AngularJSからReactに切り替えた理由
AngularJSからReactに切り替えた理由
 
パーム油への投資家向けガイド
パーム油への投資家向けガイド
RADフレームワークのエンジニアリング内部... NookuのPHP開発者として
RADフレームワークのエンジニアリング内部... NookuのPHP開発者として
Ro-Luを見る:ユーザビリティのケーススタディ
Ro-Luを見る:ユーザビリティのケーススタディ
ブラウザからウェブサイトのデザインプロセスにアプローチする
ブラウザからウェブサイトのデザインプロセスにアプローチする
意味のあるデザインと楽しいUXの芸術
意味のあるデザインと楽しいUXの芸術
人気の投稿
  • WordPressでAPIを呼び出す方法
  • Twitterからデータを抽出する方法
  • ファッションデザインのムードボード
  • C ++はどのように機能しますか
  • 初心者のためのC ++プログラミング
カテゴリー
ツールとチュートリアル トレンド モバイルデザイン アジャイルタレント プロジェクト管理 製品の担当者とチーム 製品ライフサイクル デザイナーライフ バックエンド ヒントとツール

© 2021 | 全著作権所有

apeescape2.com