【VB】SalesforceのREST APIを利用してみる

本稿では、主に企業で利用されているであろうSalesforceというシステムから情報を取得したり更新したりするプログラムをC#で書いてみたいと思います。

Salesforceは顧客管理などができるWebシステムです。詳細は「https://www.salesforce.com/jp/」をご覧ください。

REST APIの詳細はこちらからどうぞ。



REST APIでログインを行う

ログインを行うには「https://login.salesforce.com/services/oauth2/token」へアクセスします。

methodはPOSTを指定し必要な認証パラメータを設定します。

grant_type=password
client_id=「コンシューマ鍵」
client_secret=「コンシューマの秘密」
username=「ユーザー名」
password=「パスワード」+「セキュリティートークン」

必要な値はSalesforceへログインして取得できます。

ユーザー名とパスワードはわかると思いますが、コンシューマ鍵、コンシューマの秘密、セキュリティートークンは取得方法がわからない方もいると思います。
これらの取得手順は、こちらの記事で紹介しております。

値が取得できたらログイン処理を実行してみましょう。

Imports System.IO
Imports System.Text

Module Module1

	Sub Main()
		login()
	End Sub

	Sub login()
		Dim url As String = "https://login.salesforce.com/services/oauth2/token"
		'Dim url As String = "https://test.salesforce.com/services/oauth2/token" ''Sandbox環境の場合'
		Dim method As String = "POST"
		Dim contentType = "application/x-www-form-urlencoded; charset=utf-8"
		Dim sb As New StringBuilder()
		sb.Append("grant_type=password").Append("&")
		sb.Append("client_id=54LOAKJL+DJALH.0224D.__jSSAFfsfM__oKLJLKFJSLKJkjLKJSdkjklsjlkdfk253Ge5153213faADdegft133").Append("&")
		sb.Append("client_secret=LSFJHLS2313221SAD325FAD21321").Append("&")
		sb.Append("username=test%40mail.co.jp").Append("&")
		sb.Append("password=aaaasdkjLKJHGK23DA2dda")
		Dim body() As Byte = Encoding.UTF8.GetBytes(sb.ToString())
		Dim result() As Byte = executeRequest(url,
			 method,
			 contentType,
			 Nothing,
			 body)

		If result?.Length > 0 Then
			Console.WriteLine(Encoding.UTF8.GetString(result))
		Else
			Console.WriteLine("レスポンスがないよ!!")
		End If
	End Sub

	Function executeRequest(ByRef url As String, ByRef method As String, ByRef contentType As String, ByRef accessToken As String, ByRef body As Byte()) As Byte()
		Try
			'WebRequestの作成'
			Dim req As System.Net.HttpWebRequest =
					System.Net.WebRequest.Create(url)

			'アクセストークンの指定'
			If Not (accessToken Is Nothing) Then req.Headers("Authorization") = "Bearer " & accessToken

			'メソッドの指定'
			req.Method = method

			'コンテントタイプの指定'
			req.ContentType = contentType

			'POST送信するデータの長さを指定'
			If Not (body Is Nothing) Then req.GetRequestStream().Write(body, 0, body.Length)

			'サーバーからの応答を受信するためのWebResponseを取得'
			Dim res As System.Net.WebResponse = Nothing
			Try
				res = req.GetResponse()
			Catch e As System.Net.WebException
				res = e.Response
			End Try

			'応答データを受信するためのStreamを取得'
			Using mem As New MemoryStream,
				  resStream As Stream = res.GetResponseStream()

				Dim buf(4096) As Byte
				Dim r As Integer
				While 1
					r = resStream.Read(buf, 0, buf.Length)
					If r <= 0 Then Exit While
					mem.Write(buf, 0, r)
				End While
				Return mem.ToArray()
			End Using

		Catch e As Exception
			Console.WriteLine(e.StackTrace)
		End Try
		Return Nothing
	End Function
End Module
実行結果コンソール(インデント付与済み)

{ "access_token": "000A000A0a0A0!QAKAJDSKLNDLAS5215153153AD21312A.LKJHSADLKJAL2465461256151111010000254", "instance_url": "https://app.salesforce.com", "id": "https://login.salesforce.com/id/00D0ED/00392HJGJH00XM000000", "token_type": "Bearer", "issued_at": "73268", "signature": "fkhjsakdfl/jksfdljk2/b1olCBVsdsDG+zZC76ad7889DFDJKY=" }

重要なのはaccess_tokenとinstance_urlです。

これらはデータ取得や更新などをする際に必要な値となります。

access_tokenはログインした証となるものでデータ取得などをする際に必要となります。

instance_urlは実際にデータ取得などするときにアクセスするベースURLとなります。

インスタンスID(appの部分)は使用者によって変わると思います。

テストで必要であれば実際に取得できた値をメモっておきましょう。

この記事では、以降この結果をキーに設定したサンプルを掲載していきます。

REST APIでレコードを作成する

レコードを作成するには
「https://<インスタンスID>.salesforce.com/services/data/<APIバージョン>/sobjects/<オブジェクト名>」
にアクセスし、POSTを指定してリクエストします。

登録内容はJSONデータなどで指定します。

それでは取引先にレコード追加してみましょう。

取引先のオブジェクト名はAccountです。

Imports System.IO
Imports System.Text

Module Module1

	Sub Main()
		create()
	End Sub

	Sub create()
		Dim url As String = "https://app.salesforce.com/services/data/v44.0/sobjects/Account"
		Dim method As String = "POST"
		Dim contentType As String = "application/json; charset=utf-8"
		Dim accessToken As String = "000A000A0a0A0!QAKAJDSKLNDLAS5215153153AD21312A.LKJHSADLKJAL2465461256151111010000254"
		Dim body As String = "{""Name"":""Test""}"
		Dim result As Byte() = executeRequest(url,
			method,
			contentType,
			accessToken,
			Encoding.UTF8.GetBytes(body))

		If result?.Length > 0 Then
			Console.WriteLine(Encoding.UTF8.GetString(result))
		Else
			Console.WriteLine("レスポンスがないよ!!")
		End If
	End Sub

	Function executeRequest(ByRef url As String, ByRef method As String, ByRef contentType As String, ByRef accessToken As String, ByRef body As Byte()) As Byte()
		Try
			'WebRequestの作成'
			Dim req As System.Net.HttpWebRequest =
					System.Net.WebRequest.Create(url)

			'アクセストークンの指定'
			If Not (accessToken Is Nothing) Then req.Headers("Authorization") = "Bearer " & accessToken

			'メソッドの指定'
			req.Method = method

			'コンテントタイプの指定'
			req.ContentType = contentType

			'POST送信するデータの長さを指定'
			If Not (body Is Nothing) Then req.GetRequestStream().Write(body, 0, body.Length)

			'サーバーからの応答を受信するためのWebResponseを取得'
			Dim res As System.Net.WebResponse = Nothing
			Try
				res = req.GetResponse()
			Catch e As System.Net.WebException
				res = e.Response
			End Try

			'応答データを受信するためのStreamを取得'
			Using mem As New MemoryStream,
				  resStream As Stream = res.GetResponseStream()

				Dim buf(4096) As Byte
				Dim r As Integer
				While 1
					r = resStream.Read(buf, 0, buf.Length)
					If r <= 0 Then Exit While
					mem.Write(buf, 0, r)
				End While
				Return mem.ToArray()
			End Using

		Catch e As Exception
			Console.WriteLine(e.StackTrace)
		End Try
		Return Nothing
	End Function
End Module
実行結果

実行結果コンソール(インデント付与済み)

{ "id": "0011903JO01", "success": true, "errors": [] }

取引先にTestが追加されていれば成功です。

設定できるフィールドはName以外にも多数あります。
指定フィールドはAPIでも取得することはできますし、SOAP APIのレファレンスとかも見てみると案外取れたりします。

idはデータ取得、更新、削除などで使用するキーとなります。

テストで必要であれば実際の値をメモっておきましょう。この記事では以降、この結果をキーに設定したサンプルを掲載していきます。

REST APIでレコードを取得する

レコードを取得するには
「https://<インスタンスID>.salesforce.com/services/data/<APIバージョン>/sobjects/<オブジェクト名>/<オブジェクトID>」
にアクセスし、GETを指定してリクエストします。

先ほど作成したTestレコードのidを設定してデータ取得してみましょう。

Imports System.IO
Imports System.Text

Module Module1

	Sub Main()
		getData()
	End Sub

	Sub getData()
		Dim url As String = "https://app.salesforce.com/services/data/v44.0/sobjects/Account/0011903JO01"
		Dim method As String = "GET"
		Dim contentType As String = "application/json; charset=utf-8"
		Dim accessToken As String = "000A000A0a0A0!QAKAJDSKLNDLAS5215153153AD21312A.LKJHSADLKJAL2465461256151111010000254"
		Dim result() As Byte = executeRequest(url,
			method,
			contentType,
			accessToken,
			Nothing)

		If result?.Length > 0 Then
			Console.WriteLine(Encoding.UTF8.GetString(result))
		Else
			Console.WriteLine("レスポンスがないよ!!")
		End If
	End Sub

	Function executeRequest(ByRef url As String, ByRef method As String, ByRef contentType As String, ByRef accessToken As String, ByRef body As Byte()) As Byte()
		Try
			'WebRequestの作成'
			Dim req As System.Net.HttpWebRequest =
					System.Net.WebRequest.Create(url)

			'アクセストークンの指定'
			If Not (accessToken Is Nothing) Then req.Headers("Authorization") = "Bearer " & accessToken

			'メソッドの指定'
			req.Method = method

			'コンテントタイプの指定'
			req.ContentType = contentType

			'POST送信するデータの長さを指定'
			If Not (body Is Nothing) Then req.GetRequestStream().Write(body, 0, body.Length)

			'サーバーからの応答を受信するためのWebResponseを取得'
			Dim res As System.Net.WebResponse = Nothing
			Try
				res = req.GetResponse()
			Catch e As System.Net.WebException
				res = e.Response
			End Try

			'応答データを受信するためのStreamを取得'
			Using mem As New MemoryStream,
				  resStream As Stream = res.GetResponseStream()

				Dim buf(4096) As Byte
				Dim r As Integer
				While 1
					r = resStream.Read(buf, 0, buf.Length)
					If r <= 0 Then Exit While
					mem.Write(buf, 0, r)
				End While
				Return mem.ToArray()
			End Using

		Catch e As Exception
			Console.WriteLine(e.StackTrace)
		End Try
		Return Nothing
	End Function
End Module
実行結果コンソール(インデント付与済み)

{ "attributes": { "type": "Account", "url": "/services/data/v44.0/sobjects/Account/0011903JO01" }, "Id": "0011903JO01", "IsDeleted": false, "MasterRecordId": null, "Name": "Test", "Type": null, "ParentId": null, "BillingStreet": null, "BillingCity": null, "BillingState": null, "BillingPostalCode": null, "BillingCountry": null, "BillingLatitude": null, "BillingLongitude": null, "BillingGeocodeAccuracy": null, "BillingAddress": null, "ShippingStreet": null, "ShippingCity": null, "ShippingState": null, "ShippingPostalCode": null, "ShippingCountry": null, "ShippingLatitude": null, "ShippingLongitude": null, "ShippingGeocodeAccuracy": null, "ShippingAddress": null, "Phone": null, "Fax": null, "Website": null, "PhotoUrl": "/services/images/photo/0011903JO01", "Industry": null, "NumberOfEmployees": null, "Description": null, "Site": null, "OwnerId": "039012930", "CreatedDate": "2019-09-29T11:03:41.000+0000", "CreatedById": "039012930", "LastModifiedDate": "2019-09-29T11:03:41.000+0000", "LastModifiedById": "039012930", "SystemModstamp": "2019-09-29T11:03:41.000+0000", "LastActivityDate": null, "LastViewedDate": "2019-09-29T11:04:37.000+0000", "LastReferencedDate": "2019-09-29T11:04:37.000+0000", "Jigsaw": null, "JigsawCompanyId": null, "AccountSource": null, "SicDesc": null, }

ほとんど値を設定していないのでnullですね。

REST APIでレコードを更新する

レコードの更新を行うには
「https://<インスタンスID>.salesforce.com/services/data/<APIバージョン>/sobjects/<オブジェクト名>/<オブジェクトID>」
にアクセスし、PATCHを指定してリクエストします。

Java11以前の標準HTTPリクエスト機能はPATCHが使えなくなっていますので、リフレクションで無理やり使えるようにしてみました。

Java11をご利用の方は新しいほうのAPIを利用することをお勧めします。

更新内容はJSON文字列で指定します。

試しに作成したTestのレコードをTest2という名前に変更してみましょう。

Imports System.IO
Imports System.Text

Module Module1

	Sub Main()
		update()
	End Sub

	Sub update()
		Dim url As String = "https://app.salesforce.com/services/data/v44.0/sobjects/Account/0011903JO01"
		Dim method As String = "PATCH"
		Dim contentType As String = "application/json; charset=utf-8"
		Dim accessToken As String = "000A000A0a0A0!QAKAJDSKLNDLAS5215153153AD21312A.LKJHSADLKJAL2465461256151111010000254"
		Dim body = "{""Name"":""Test2""}"
		Dim result() As Byte = executeRequest(url,
			method,
			contentType,
			accessToken,
			Encoding.UTF8.GetBytes(body))

		If result?.Length > 0 Then
			Console.WriteLine(Encoding.UTF8.GetString(result))
		Else
			Console.WriteLine("レスポンスがないよ!!")
		End If
	End Sub

	Function executeRequest(ByRef url As String, ByRef method As String, ByRef contentType As String, ByRef accessToken As String, ByRef body As Byte()) As Byte()
		Try
			'WebRequestの作成'
			Dim req As System.Net.HttpWebRequest =
					System.Net.WebRequest.Create(url)

			'アクセストークンの指定'
			If Not (accessToken Is Nothing) Then req.Headers("Authorization") = "Bearer " & accessToken

			'メソッドの指定'
			req.Method = method

			'コンテントタイプの指定'
			req.ContentType = contentType

			'POST送信するデータの長さを指定'
			If Not (body Is Nothing) Then req.GetRequestStream().Write(body, 0, body.Length)

			'サーバーからの応答を受信するためのWebResponseを取得'
			Dim res As System.Net.WebResponse = Nothing
			Try
				res = req.GetResponse()
			Catch e As System.Net.WebException
				res = e.Response
			End Try

			'応答データを受信するためのStreamを取得'
			Using mem As New MemoryStream,
				  resStream As Stream = res.GetResponseStream()

				Dim buf(4096) As Byte
				Dim r As Integer
				While 1
					r = resStream.Read(buf, 0, buf.Length)
					If r <= 0 Then Exit While
					mem.Write(buf, 0, r)
				End While
				Return mem.ToArray()
			End Using

		Catch e As Exception
			Console.WriteLine(e.StackTrace)
		End Try
		Return Nothing
	End Function
End Module
実行結果

取引先名がTest2に変更されればOKです。

実行結果コンソール

レスポンスがないよ!!

REST APIでレコードを削除する

レコードの削除を行うには
「https://<インスタンスID>.salesforce.com/services/data/<APIバージョン>/sobjects/<オブジェクト名>/<オブジェクトID>」
にアクセスし、DELETE を指定してリクエストします。

それでは、先ほど更新したTest2のレコードを削除してみましょう。

Imports System.IO
Imports System.Text

Module Module1

	Sub Main()
		delete()
	End Sub

	Sub delete()
		Dim url As String = "https://app.salesforce.com/services/data/v44.0/sobjects/Account/0011903JO01"
		Dim method As String = "DELETE"
		Dim accessToken As String = "000A000A0a0A0!QAKAJDSKLNDLAS5215153153AD21312A.LKJHSADLKJAL2465461256151111010000254"
		Dim result() As Byte = executeRequest(url,
			method,
			Nothing,
			accessToken,
			Nothing
			)

		If result?.Length > 0 Then
			Console.WriteLine(Encoding.UTF8.GetString(result))
		Else
			Console.WriteLine("レスポンスがないよ!!")
		End If
	End Sub

	Function executeRequest(ByRef url As String, ByRef method As String, ByRef contentType As String, ByRef accessToken As String, ByRef body As Byte()) As Byte()
		Try
			'WebRequestの作成'
			Dim req As System.Net.HttpWebRequest =
					System.Net.WebRequest.Create(url)

			'アクセストークンの指定'
			If Not (accessToken Is Nothing) Then req.Headers("Authorization") = "Bearer " & accessToken

			'メソッドの指定'
			req.Method = method

			'コンテントタイプの指定'
			req.ContentType = contentType

			'POST送信するデータの長さを指定'
			If Not (body Is Nothing) Then req.GetRequestStream().Write(body, 0, body.Length)

			'サーバーからの応答を受信するためのWebResponseを取得'
			Dim res As System.Net.WebResponse = Nothing
			Try
				res = req.GetResponse()
			Catch e As System.Net.WebException
				res = e.Response
			End Try

			'応答データを受信するためのStreamを取得'
			Using mem As New MemoryStream,
				  resStream As Stream = res.GetResponseStream()

				Dim buf(4096) As Byte
				Dim r As Integer
				While 1
					r = resStream.Read(buf, 0, buf.Length)
					If r <= 0 Then Exit While
					mem.Write(buf, 0, r)
				End While
				Return mem.ToArray()
			End Using

		Catch e As Exception
			Console.WriteLine(e.StackTrace)
		End Try
		Return Nothing
	End Function
End Module
実行結果

実行結果コンソール

レスポンスがないよ!!

取引先からTest2が削除されたらOKです。

VBSalesforce

Posted by nompor