Salesforce(APEX) からAmazon SQSへのメッセージ送信
9月 21, 2023
Salesforce(Apex)で、AWSのAPIを利用してAmazon SQSへメッセージを挿入するサンプルになります。
SkyOnDemandのSQSアダプタでメッセージ受信する連携スクリプトを構築することで、Salesforce(Apex)からAmazon SQSを介したSkyOnDemandの連携処理を行うことが可能となります。
送信処理の呼出し
String message = 'YOUR-message';
AwsSqsClient sqsclient = new AwsSqsClient();
sqsclient.SendMessage(message);送信処理(AwsSqsClient)
上記の送信処理の呼出しにより、実際の送信処理を行うApexコードサンプルになります。
[AwsSqsClient]
[createHttpRequest]
[getSignature]
public without sharing class AwsSqsClient {
private static final String HASH_ALGORITHM = 'SHA-256';
private static final String MAC_ALGORITHM = 'HmacSHA256';
private static final String SIGNATURE_VERSION = 'AWS4';
private static final String SIGNATURE_ALGORITHM = 'AWS4-HMAC-SHA256';
private final String accessKeyId;
private final String secretAccessKey;
private final String serviceName;
private final String region;
private final String host;
private final String apiVersion;
private final String signedHeaders;
private final String method;
private final String quePath; //メッセージを挿入するキューのパス [アカウント名]/que名
private String now;
private String today;
private String xAmzTarget;
private String queryStr;
private String queryBody;
public AwsSqsClient() {
this.accessKeyId = 'YOUR-AccessKeyId';
this.secretAccessKey = 'YOUR-SecretAccessKey';
this.region = 'YOUR-AWS-region'; //ex.: ap-northeast-1
this.quePath = 'YOUR que-path'; //ex.:your-account name/target-que name'
this.serviceName = 'sqs';
this.apiVersion = '2012-11-05';
this.method = 'POST';
this.host = this.serviceName.toLowerCase() + '.' + this.region + '.amazonaws.com';
this.signedHeaders = 'content-type;host;x-amz-date';
}
public HttpResponse sendMessage(String message) {
HTTPRequest req = createHttpRequest(message,'SendMessage');
Http http = new Http();
return http.send(req);
}
private HTTPRequest createHttpRequest(String message, String apiName) {
Datetime dt = Datetime.now();
this.today = dt.formatGmt('yyyyMMdd');
this.now = this.today + 'T' + dt.formatGmt('HHmmss') + 'Z';
this.queryStr = 'AWSAccessKeyId=' + this.accessKeyId +
'&Action=' + apiName +
'&MessageBody=' + message +
'&SignatureMethod=' + MAC_ALGORITHM +
'&SignatureVersion=4' +
'&Version=' + this.apiVersion;
// Sign
String sign = getSignature();
// Credential
String credential = this.accessKeyId + '/' + this.today + '/' + this.region + '/' + this.serviceName.toLowerCase() + '/aws4_request';
// Create Request
HttpRequest req = new HttpRequest();
// Set Header
req.setHeader('Authorization',V4.SIGNATURE_ALGORITHM + ' Credential=' + credential + ',SignedHeaders=' + this.signedHeaders + ',Signature=' + sign);
req.setHeader('Host', this.host);
req.setHeader('x-amz-date', this.now);
req.setHeader('Content-Type', 'application/x-www-form-urlencoded');
// Set method
req.setMethod(this.method);
// Set End-point
req.setEndpoint('https://' + this.serviceName.toLowerCase() + '.' + this.region + '.amazonaws.com' + this.quePath + '?' + this.queryStr);
return req;
}
private String getSignature() {
// Task 1: Create a Canonical Request For Signature Version 4
String cs = this.method + '\n'
cs += this.quePath + '\n';
cs += this.queryStr + '\n';
cs += 'content-type:' + 'application/x-www-form-urlencoded' + '\n';
cs += 'host:' + this.host + '\n';
cs += 'x-amz-date:' + this.now + '\n\n';
cs += this.signedHeaders + '\n';
cs += EncodingUtil.convertToHex(Crypto.generateDigest(HASH_ALGORITHM, Blob.valueOf(this.queryBody)));
// Task 2: Create a String to Sign for Signature Version 4
String sts = SIGNATURE_ALGORITHM + '\n';
sts += this.now + '\n';
sts += this.today + '/' + this.region + '/' + this.serviceName.toLowerCase() + '/aws4_request\n';
// Task 3: Calculate the AWS Signature Version 4
Blob keyDate = Crypto.generateMac(MAC_ALGORITHM, Blob.valueOf(this.today), Blob.valueof(SIGNATURE_VERSION + this.secretAccessKey));
Blob keyRegion = Crypto.generateMac(MAC_ALGORITHM, Blob.valueOf(this.region), keyDate);
Blob keyService = Crypto.generateMac(MAC_ALGORITHM, Blob.valueOf(this.serviceName.toLowerCase()), keyRegion);
Blob keyCredentials = Crypto.generateMac(MAC_ALGORITHM, Blob.valueOf('aws4_request'), keyService);
// Task 1 + Task 2
sts += EncodingUtil.convertToHex(Crypto.generateDigest(HASH_ALGORITHM, Blob.valueOf(cs)));
// Task 2 + Task 3
return EncodingUtil.convertToHex(Crypto.generateMac(MAC_ALGORITHM, Blob.valueOf(sts), keyCredentials));
}
}public without sharing class AwsSqsClient {
private static final String HASH_ALGORITHM = 'SHA-256';
private static final String MAC_ALGORITHM = 'HmacSHA256';
private static final String SIGNATURE_VERSION = 'AWS4';
private static final String SIGNATURE_ALGORITHM = 'AWS4-HMAC-SHA256';
private final String accessKeyId;
private final String secretAccessKey;
private final String serviceName;
private final String region;
private final String host;
private final String apiVersion;
private final String signedHeaders;
private final String method;
private final String quePath; //メッセージを挿入するキューのパス [アカウント名]/que名
private String now;
private String today;
private String xAmzTarget;
private String queryStr;
private String queryBody;
public AwsSqsClient() {
this.accessKeyId = 'YOUR-AccessKeyId';
this.secretAccessKey = 'YOUR-SecretAccessKey';
this.region = 'YOUR-AWS-region'; //ex.: ap-northeast-1
this.quePath = 'YOUR que-path'; // ex. : 152270972222/test_scriptrunner_que'
this.serviceName = 'sqs';
this.apiVersion = '2012-11-05';
this.method = 'POST';
this.host = this.serviceName.toLowerCase() + '.' + this.region + '.amazonaws.com';
this.signedHeaders = 'content-type;host;x-amz-date';
}
public HttpResponse sendMessage(String message) {
HTTPRequest req = createHttpRequest(message,'SendMessage');
Http http = new Http();
return http.send(req);
}
private HTTPRequest createHttpRequest(String message, String apiName) {
Datetime dt = Datetime.now();
this.today = dt.formatGmt('yyyyMMdd');
this.now = this.today + 'T' + dt.formatGmt('HHmmss') + 'Z';
this.queryBody = 'AWSAccessKeyId=' + this.accessKeyId +
'&Action=' + apiName +
'&MessageBody=' + message +
'&SignatureMethod=' + MAC_ALGORITHM +
'&SignatureVersion=4' +
'&Version=' + this.apiVersion;
// Sign
String sign = getSignature();
// Credential
String credential = this.accessKeyId + '/' + this.today + '/' + this.region + '/' + this.serviceName.toLowerCase() + '/aws4_request';
// Create Request
HttpRequest req = new HttpRequest();
// Set Header
req.setHeader('Authorization',V4.SIGNATURE_ALGORITHM + ' Credential=' + credential + ',SignedHeaders=' + this.signedHeaders + ',Signature=' + sign);
req.setHeader('Host', this.host);
req.setHeader('x-amz-date', this.now);
req.setHeader('Content-Type', 'application/x-www-form-urlencoded');
// Set method
req.setMethod(this.method);
// Set End-point
req.setEndpoint('https://' + this.serviceName.toLowerCase() + '.' + this.region + '.amazonaws.com' + this.quePath);
//Set Body
req.setBody(this.queryBody);
return req;
}
private String getSignature() {
// Task 1: Create a Canonical Request For Signature Version 4
String cs = this.method + '\n'
cs += this.quePath + '\n';
cs += this.queryStr + '\n';
cs += 'content-type:' + 'application/x-www-form-urlencoded' + '\n';
cs += 'host:' + this.host + '\n';
cs += 'x-amz-date:' + this.now + '\n\n';
cs += this.signedHeaders + '\n';
cs += EncodingUtil.convertToHex(Crypto.generateDigest(HASH_ALGORITHM, Blob.valueOf(this.queryBody)));
// Task 2: Create a String to Sign for Signature Version 4
String sts = SIGNATURE_ALGORITHM + '\n';
sts += this.now + '\n';
sts += this.today + '/' + this.region + '/' + this.serviceName.toLowerCase() + '/aws4_request\n';
// Task 3: Calculate the AWS Signature Version 4
Blob keyDate = Crypto.generateMac(MAC_ALGORITHM, Blob.valueOf(this.today), Blob.valueof(SIGNATURE_VERSION + this.secretAccessKey));
Blob keyRegion = Crypto.generateMac(MAC_ALGORITHM, Blob.valueOf(this.region), keyDate);
Blob keyService = Crypto.generateMac(MAC_ALGORITHM, Blob.valueOf(this.serviceName.toLowerCase()), keyRegion);
Blob keyCredentials = Crypto.generateMac(MAC_ALGORITHM, Blob.valueOf('aws4_request'), keyService);
// Task 1 + Task 2
sts += EncodingUtil.convertToHex(Crypto.generateDigest(HASH_ALGORITHM, Blob.valueOf(cs)));
// Task 2 + Task 3
return EncodingUtil.convertToHex(Crypto.generateMac(MAC_ALGORITHM, Blob.valueOf(sts), keyCredentials));
}
}